fix: resolve linked worktrees via git metadata instead of path names - #302
Open
delanym wants to merge 1 commit into
Open
fix: resolve linked worktrees via git metadata instead of path names#302delanym wants to merge 1 commit into
delanym wants to merge 1 commit into
Conversation
`resolveWorktree` recognised a linked worktree by testing whether the resolved gitdir sat below a directory literally named `.git`, and then returned that main `.git` directory. Both halves are wrong: * Worktrees of a bare repository live in `your-repository.git/worktrees/X` (or `.bare/worktrees/X`), which the name test never matched. The administrative directory was then handed to the native git executable as a working directory and every build failed with `fatal: this operation must be run in a work tree`. * Where the test did match, resolution landed on the git directory shared by all worktrees. The native git executable therefore ran in the main checkout and stamped the build with that checkout's branch and commit rather than the ones of the worktree being built (#882). Git records both locations explicitly in the administrative directory of every linked worktree: `commondir` points to the shared git directory and `gitdir` points back to the `.git` file inside the worktree. Reading those identifies a worktree without guessing from directory names, and works no matter what the repository directory is called. `resolveWorktree` now returns the shared git directory from `commondir`, which keeps jgit on the location it resolved to before, and `lookupGitDirectory` treats a linked worktree like a submodule for the native git executable: it falls back to the unresolved `.git` file, whose parent is the working tree that is actually being built. Since resolution now reads the files git wrote, a gitdir path that does not point at an existing worktree administrative directory is no longer rewritten -- the `a/.git/worktrees/b` noop cases in the test cover that. Relative `gitdir` values (`worktree.useRelativePaths`, git 2.48+) are resolved against the file that holds them, which the previous code only did for submodules. jgit still reports the shared git directory for a worktree; that is git-commit-id#215 and unchanged here. Fixes git-commit-id#301 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
resolveWorktreerecognised a linked worktree by testing whether the resolved gitdir sat below a directory literally named.git, and then returned that main.gitdirectory. Both halves are wrong:Worktrees of a bare repository live in
your-repository.git/worktrees/X(or.bare/worktrees/X), which the name test never matched. The administrative directory was then handed to the native git executable as a working directory and every build failed withfatal: this operation must be run in a work tree.Where the test did match, resolution landed on the git directory shared by all worktrees. The native git executable therefore ran in the main checkout and stamped the build with that checkout's branch and commit rather than the ones of the worktree being built (#882).
Git records both locations explicitly in the administrative directory of every linked worktree:
commondirpoints to the shared git directory andgitdirpoints back to the.gitfile inside the worktree. Reading those identifies a worktree without guessing from directory names, and works no matter what the repository directory is called.resolveWorktreenow returns the shared git directory fromcommondir, which keeps jgit on the location it resolved to before, andlookupGitDirectorytreats a linked worktree like a submodule for the native git executable: it falls back to the unresolved.gitfile, whose parent is the working tree that is actually being built.Since resolution now reads the files git wrote, a gitdir path that does not point at an existing worktree administrative directory is no longer rewritten -- the
a/.git/worktrees/bnoop cases in the test cover that. Relativegitdirvalues (worktree.useRelativePaths, git 2.48+) are resolved against the file that holds them, which the previous code only did for submodules.jgit still reports the shared git directory for a worktree; that is #215 and unchanged here.
Fixes #301
Context
Contributor Checklist
mvn clean packagecheckstylecoding style definition:mvn clean verify -Pcheckstyle -Dmaven.test.skip=true -B