theonedev/onedev · error · IllegalStateException
Shallow commits have already been initialized.
Error message
Shallow commits have already been initialized.
What it means
RevWalk initializes shallow-commit information (from the repository's shallow file) at most once. initializeShallowCommits() throws IllegalStateException if shallowCommitsInitialized is already true, protecting against re-reading and duplicating shallow roots mid-walk.
Source
Thrown at server-core/src/main/java/org/eclipse/jgit/revwalk/RevWalk.java:1831
* There is a sequencing problem if the first commit being parsed is a
* shallow commit, since {@link RevCommit#parseCanonical(RevWalk, byte[])}
* calls this method before its callers add the new commit to the
* {@link RevWalk#objects} map. That means a call from this method to
* {@link #lookupCommit(AnyObjectId)} fails to find that commit and creates
* a new one, which is promptly discarded.
* <p>
* To avoid that, {@link RevCommit#parseCanonical(RevWalk, byte[])} passes
* its commit to this method, so that this method can apply the shallow
* state to it directly and avoid creating the duplicate commit object.
*
* @param rc
* the initial commit being parsed
* @throws IOException
* if the shallow commits file can't be read
*/
void initializeShallowCommits(RevCommit rc) throws IOException {
if (shallowCommitsInitialized) {
throw new IllegalStateException(
JGitText.get().shallowCommitsAlreadyInitialized);
}
shallowCommitsInitialized = true;
if (reader == null) {
return;
}
for (ObjectId id : reader.getShallowCommits()) {
if (id.equals(rc.getId())) {
rc.parents = RevCommit.NO_PARENTS;
} else {
lookupCommit(id).parents = RevCommit.NO_PARENTS;
}
}
}
}View on GitHub (pinned to d44925c47c)
Solutions
- Do not call initializeShallowCommits directly; let RevWalk.parseCommit/parseAny trigger it once.
- Guard custom code with a flag before invoking it, or check walk.shallowCommitsInitialized state via subclass accessors.
- Use one RevWalk per thread; do not share walk instances across concurrent parsing.
Example fix
// before
walk.initializeShallowCommits(rc); // called for every parsed commit
// after
if (!shallowCommitsInitialized)
walk.initializeShallowCommits(rc); Defensive patterns
Strategy: try-catch
Validate before calling
// call at most once per walk instance
if (!initialized.getAndSet(true))
walk.initializeShallowCommits(rc); Type guard
AtomicBoolean shallowInit = new AtomicBoolean(false); boolean shouldInit = shallowInit.compareAndSet(false, true);
Try / catch
try {
walk.initializeShallowCommits(rc);
} catch (IllegalStateException e) {
// already initialized - safe to ignore
} Prevention
- Let RevWalk.parseCommit/parseAny trigger shallow init implicitly
- Never call initializeShallowCommits per commit in loops
- Use one RevWalk per thread to avoid concurrent double-init
When it happens
Trigger: Internally triggered when commit parsing re-enters initializeShallowCommits after it already ran; direct callers (subclasses/tests) invoking it twice on the same walk; reusing a walk instance across shallow setups.
Common situations: Custom RevWalk subclasses that manually parse commits and call initializeShallowCommits unconditionally per commit; concurrency where two threads parse the first commit of a shallow clone simultaneously on one walk.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Output has already been started.
- Commits have already been marked as start.
- Cannot combine TreeFilter {0} with RevFilter {1}.
- Cannot find merge base using first parent.
- Cannot combine topo sort with topo-keep-branch-together sort
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/96a1d7991fc6cffb.
Report an issue: GitHub.