You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Essentially there is no support for worktrees created off a bare git repository (a practice I imagine will become more common with agentic coding).
GitDirLocator.resolveWorktree identifies a linked worktree by matching path names — the
worktree administrative directory must sit under a directory literally named .git. Git itself
places no such constraint: git worktree add from a bare repository produces <bare>/worktrees/<name>, where <bare> is conventionally something.git or, in the widely used
bare-clone layout, .bare.
For those repositories resolveWorktree returns the gitdir unchanged, NativeGitProvider then runs
git in its parent (<bare>/worktrees), which is not a work tree, and the build fails.
Steps to Reproduce (required)
#!/usr/bin/env bashset -e
BASE=$(mktemp -d);cd"$BASE"
cat > pom.xml <<'EOF' <project xmlns="http://maven.apache.org/POM/4.0.0"> <modelVersion>4.0.0</modelVersion> <groupId>example</groupId><artifactId>wt-repro</artifactId><version>1</version> <build><plugins><plugin> <groupId>io.github.git-commit-id</groupId> <artifactId>git-commit-id-maven-plugin</artifactId> <version>10.0.0</version> <configuration> <useNativeGit>true</useNativeGit> <generateGitPropertiesFile>true</generateGitPropertiesFile> <generateGitPropertiesFilename>${project.build.directory}/git.properties</generateGitPropertiesFilename> </configuration> <executions><execution><id>x</id><goals><goal>revision</goal></goals><phase>initialize</phase></execution></executions> </plugin></plugins></build> </project> EOF # ---- layout A: ordinary clone, plus a conventional linked worktree under <main>/.git/worktrees/ mkdir -p A/main && cd A/main git init -q -b main . && git config user.email t@t && git config user.name t cp ../../pom.xml . && git add pom.xml && git commit -qm "commit on main" git worktree add -q -b feature ../wt cd ../wt && git config user.email t@t && git config user.name t cp ../../pom.xml . && echo x > f.txt && git add . && git commit -qm "commit on feature worktree" cd "$BASE" # ---- layout B: bare clone, plus a linked worktree under <bare>/worktrees/ git clone -q --bare A/main B/.bare git -C B/.bare worktree add -q "$BASE/B/master" main cp pom.xml B/master/ for d in A/main A/wt B/master; do echo "=========== $d" echo " real HEAD : $(git -C $d rev-parse --abbrev-ref HEAD) @ $(git -C $d rev-parse --short=7 HEAD)" ( cd "$d" && mvn -q -B initialize 2>&1 | grep -E "ERROR.*(Failed|fatal)" | head -2 if [ -f target/git.properties ]; then echo " reported : $(grep -h -E 'git.branch=|git.commit.id.abbrev=' target/git.properties | tr '\n' ' ')" else echo " reported : (no git.properties written)" fi ) done echo; echo "workdir: $BASE"
Actual output
=========== A/main
real HEAD : main @ 88ae4cd
reported : git.branch=main git.commit.id.abbrev=88ae4cd
=========== A/wt
real HEAD : feature @ 920ca94
reported : git.branch=main git.commit.id.abbrev=88ae4cd
=========== B/master
real HEAD : main @ 88ae4cd
[ERROR] Failed to execute goal io.github.git-commit-id:git-commit-id-maven-plugin:10.0.0:revision (x) on project wt-repro: Git command exited with invalid status [128]: directory: `/tmp/tmp.hxld3BHkek/B/.bare/worktrees`, command: `git describe --always --dirty=-dirty --match=* --abbrev=7`, stdout: ``, stderr: `fatal: this operation must be run in a work tree
reported : (no git.properties written)
Expected: every row reports the branch and commit of the checkout the build ran in.
Two separate defects are visible:
B/master fails outright — the bare-repository worktree layout is not recognised at all.
A/wt silently reports the wrong commit — the worktree is recognised, but resolution lands
on the main checkout, so the build is stamped with main @ 88ae4cd instead of feature @ 920ca94. This is worktree processing not complete git-commit-id-maven-plugin#882, and it shares the root cause below.
Is there a (public) project where this issue can be reproduced? (optional)
No response
Your Environment (optional)
No response
Context (optional)
Root cause
staticFileresolveWorktree(FilefileLocation) {
Pathparent = fileLocation.toPath().getParent();
if (parent == null) {
returnfileLocation;
}
if (parent.endsWith(Path.of(".git", "worktrees"))) {
returnparent.getParent().toFile();
}
returnfileLocation;
}
parent.endsWith(Path.of(".git", "worktrees")) fails for <bare>/worktrees/<name> whenever the
repository directory is not named exactly .git — .bare/worktrees/master, froggy.git/worktrees/x
— which is defect 1. GitDirLocatorTest.testWorktreeResolution currently asserts "a.git/worktrees/b" as a noop case, so this is pinned by a test; I believe that assertion is
itself the bug, since that path is exactly what git worktree add creates from a bare clone.
parent.getParent() is the main checkout's git directory, not the linked worktree's, which is
defect 2.
Both come from inferring the layout from path names. Git records it explicitly instead: <worktree-admin-dir>/gitdir holds the absolute path of that worktree's own .git file — its parent is the working tree — and <worktree-admin-dir>/commondir points at the shared repository. Reading
those (or asking git rev-parse --path-format=absolute --git-common-dir --show-toplevel) fixes both
defects: native git would then run inside the worktree being built, which both succeeds for a bare
host repository and reports that worktree's own branch/commit.
Note on JGit
With <useNativeGit>false</useNativeGit> the same bare-repo layout fails differently — Could not get HEAD Ref, are you sure you have some commits in the dotGitDirectory (currently set to <bare>/worktrees/<name>)? — consistent with the long-standing git-commit-id/git-commit-id-maven-plugin#215. A fix to the native path won't cover JGit.
Workaround
Setting the environment explicitly makes native git resolve the right worktree and produces correct
properties:
Describe the bug (required)
Essentially there is no support for worktrees created off a bare git repository (a practice I imagine will become more common with agentic coding).
GitDirLocator.resolveWorktreeidentifies a linked worktree by matching path names — theworktree administrative directory must sit under a directory literally named
.git. Git itselfplaces no such constraint:
git worktree addfrom a bare repository produces<bare>/worktrees/<name>, where<bare>is conventionallysomething.gitor, in the widely usedbare-clone layout,
.bare.For those repositories
resolveWorktreereturns the gitdir unchanged,NativeGitProviderthen runsgit in its parent (
<bare>/worktrees), which is not a work tree, and the build fails.Steps to Reproduce (required)
Actual output
Expected: every row reports the branch and commit of the checkout the build ran in.
Two separate defects are visible:
B/masterfails outright — the bare-repository worktree layout is not recognised at all.A/wtsilently reports the wrong commit — the worktree is recognised, but resolution landson the main checkout, so the build is stamped with
main @ 88ae4cdinstead offeature @ 920ca94. This isworktree processing not complete git-commit-id-maven-plugin#882, and it shares the root cause below.
Is there a (public) project where this issue can be reproduced? (optional)
No response
Your Environment (optional)
No response
Context (optional)
Root cause
parent.endsWith(Path.of(".git", "worktrees"))fails for<bare>/worktrees/<name>whenever therepository directory is not named exactly
.git—.bare/worktrees/master,froggy.git/worktrees/x— which is defect 1.
GitDirLocatorTest.testWorktreeResolutioncurrently asserts"a.git/worktrees/b"as a noop case, so this is pinned by a test; I believe that assertion isitself the bug, since that path is exactly what
git worktree addcreates from a bare clone.parent.getParent()is the main checkout's git directory, not the linked worktree's, which isdefect 2.
Both come from inferring the layout from path names. Git records it explicitly instead:
<worktree-admin-dir>/gitdirholds the absolute path of that worktree's own.gitfile — its parentis the working tree — and
<worktree-admin-dir>/commondirpoints at the shared repository. Readingthose (or asking
git rev-parse --path-format=absolute --git-common-dir --show-toplevel) fixes bothdefects: native git would then run inside the worktree being built, which both succeeds for a bare
host repository and reports that worktree's own branch/commit.
Note on JGit
With
<useNativeGit>false</useNativeGit>the same bare-repo layout fails differently —Could not get HEAD Ref, are you sure you have some commits in the dotGitDirectory (currently set to <bare>/worktrees/<name>)?— consistent with the long-standinggit-commit-id/git-commit-id-maven-plugin#215. A fix to the native path won't cover JGit.
Workaround
Setting the environment explicitly makes native git resolve the right worktree and produces correct
properties:
Related
<main>/.git/worktrees/case (PR #642, v7.0.0)