Skip to content

fix: handle relative worktree linking files#2599

Merged
Sebastian Thiel (Byron) merged 3 commits into
mainfrom
relative-workree-path
May 26, 2026
Merged

fix: handle relative worktree linking files#2599
Sebastian Thiel (Byron) merged 3 commits into
mainfrom
relative-workree-path

Conversation

@Byron
Copy link
Copy Markdown
Member

@Byron Sebastian Thiel (Byron) commented May 16, 2026

Tasks

  • refackiew

Created by Codex on behalf of Byron. Byron will review before this is ready to merge.

Summary

Handle Git 2.48 relative linked-worktree metadata by resolving plain backlink files relative to their containing gitdir file, and use filesystem-aware realpath resolution for worktree backlinks so symlinked repository access keeps Git-compatible semantics.

Reported issue

Can you check that we can handle relative worktree paths, which are available as of Git 2.48?
For reference, here is the location of Git source code: /Users/byron/dev/github.com/git/git .

Git Reference

Git's worktree.c::write_worktree_linking_files() writes both sides of relative worktree links with relative_path(): the checkout .git file points to the private git dir, and .git/worktrees/<id>/gitdir points back to the checkout. Git's t/t2400-worktree-add.sh covers the resulting relative files for git worktree add --relative-paths.

Changes

  • Add a gix-discover helper for plain path files whose relative values are anchored at the containing file.
  • Use it for linked-worktree backlink resolution during discovery and Repository::worktrees() proxy base lookup.
  • Preserve symlink semantics by resolving backlink paths with filesystem-aware realpath behavior.
  • Add Git-2.48-gated regression tests for direct and symlinked relative linked worktrees.

Validation

  • cargo fmt --all --check
  • cargo test -p gix-discover --test discover
  • cargo test -p gix --test gix repository::worktree
  • git diff --check
  • codex review --commit 0a6aa7f870c6f4ad20f9af6932d4c78a738fbc2d

@Byron Sebastian Thiel (Byron) force-pushed the relative-workree-path branch 2 times, most recently from 4b30cde to 17e1f6b Compare May 26, 2026 07:51
@Byron Sebastian Thiel (Byron) marked this pull request as ready for review May 26, 2026 07:59
Copilot AI review requested due to automatic review settings May 26, 2026 07:59
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates gix-discover and gix worktree handling to correctly resolve relative linked-worktree metadata written by newer Git versions (notably the backlink worktrees/<id>/gitdir file), including symlink-related semantics.

Changes:

  • Added gix_discover::path::from_plain_file_relative_to_file() to resolve relative “plain path” files against the containing file’s directory.
  • Switched linked-worktree backlink resolution to use the new helper in both discovery and gix::worktree::Proxy::base().
  • Added fixture scripts and regression tests covering relative linking files (plus symlink scenarios on Unix).

Reviewed changes

Copilot reviewed 7 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
gix-discover/src/path.rs Adds helper to resolve relative plain-path file contents relative to the file location.
gix-discover/src/is.rs Uses new helper when reading linked-worktree backlink (gitdir) from private git dir.
gix/src/worktree/proxy.rs Uses new helper so Proxy::base() resolves relative backlink paths correctly.
gix-discover/tests/discover/upwards/mod.rs Adds regression tests for discovery from linked checkout and private git dir with relative linking files (+ symlink case).
gix/tests/gix/repository/worktree.rs Adds regression tests validating Repository::worktrees() proxy base resolution for relative linking files (+ symlinked main repo on Unix).
gix-discover/tests/fixtures/make_worktree_relative_linking.sh New fixture generator for relative linked-worktree metadata (+ symlinked linked checkout).
gix/tests/fixtures/make_worktree_relative_linking.sh New fixture generator for relative linked-worktree metadata (+ symlinked main repo).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread gix/tests/gix/repository/worktree.rs
Comment thread gix-discover/tests/discover/upwards/mod.rs
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 17e1f6b40e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment thread gix/tests/fixtures/make_worktree_relative_linking.sh
Copilot AI review requested due to automatic review settings May 26, 2026 08:27
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 9 changed files in this pull request and generated 4 comments.

Comment thread gix/tests/fixtures/make_worktree_relative_linking.sh
Comment thread gix-discover/tests/fixtures/make_worktree_relative_linking.sh
Comment thread gix-discover/tests/discover/upwards/mod.rs
Comment thread gix/tests/gix/repository/worktree.rs
Sebastian Thiel (Byron) pushed a commit that referenced this pull request May 26, 2026
The GitHub Actions `test-fast (windows-latest)` check was failing in PR #2599 because two symlink-specific relative worktree tests ran on Windows. The generated fixtures intentionally tolerate unavailable symlink creation there, leaving `main-symlink` and `linked-symlink` inaccessible.

Mark only those symlink-specific tests as Unix-only so Windows continues to exercise the non-symlink relative linking coverage while avoiding fixture paths that cannot be opened on that platform.

Validation:
- cargo test -p gix-discover --test discover from_symlinked_worktree_with_relative_linking_files
- cargo test -p gix --test gix repository::worktree::linked_worktree_proxy_base_with_symlinked_main_repo
- cargo fmt --all --check
Copilot AI review requested due to automatic review settings May 26, 2026 09:06
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 9 changed files in this pull request and generated 1 comment.

Comment thread gix-discover/src/path.rs Outdated
Codex (codex) and others added 2 commits May 26, 2026 18:50
Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
Git 2.48 can link worktrees with relative paths. In that layout the checkout
.git file points at the private git dir relative to the checkout, while
worktrees/<id>/gitdir points back to the checkout relative to the private git
dir.

Discovery already handled the checkout-side gitdir file, but paths read from the
private git dir were treated as-is. That made discovery from .git/worktrees/<id>
and Repository::worktrees() proxy base resolution produce relative paths
anchored to the process cwd instead of the gitdir file location.

Git reference: /Users/byron/dev/github.com/git/git
worktree.c:write_worktree_linking_files writes both relative links with
`relative_path()`, and t/t2400-worktree-add.sh covers the resulting relative
files.

Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
Copilot AI review requested due to automatic review settings May 26, 2026 10:51
- need to make sure the ignored-archive tests skip if the version isn't recent enough.
- only works on Unix it seems, on Windows the flag doesn't exist. Related to symlinks.

Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
@Byron Sebastian Thiel (Byron) marked this pull request as draft May 26, 2026 11:03
auto-merge was automatically disabled May 26, 2026 11:03

Pull request was converted to draft

@Byron Sebastian Thiel (Byron) marked this pull request as ready for review May 26, 2026 11:03
@Byron
Copy link
Copy Markdown
Member Author

Screenshot 2026-05-26 at 19 03 35

Forced the merge as CI seems to have stopped kicking in automatically. Retried, same result.
It should pass as it passed before, and I just reorganised commits.

@Byron Sebastian Thiel (Byron) merged commit a209dc1 into main May 26, 2026
@Byron Sebastian Thiel (Byron) deleted the relative-workree-path branch May 26, 2026 11:04
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 10 changed files in this pull request and generated 4 comments.

Comment thread gix-discover/src/path.rs
@@ -74,15 +98,21 @@ pub fn repository_kind(git_dir: &Path) -> Option<RepositoryKind> {

/// Reads a plain path from a file that contains it as its only content, with trailing newlines trimmed.
Comment thread gix-discover/src/path.rs
Comment on lines +104 to 116
/// Reads a plain path from a file like [`from_plain_file()`], resolving relative paths against
/// the file's containing directory as needed.
pub fn from_plain_file_relative_to_file(path: &std::path::Path) -> Option<std::io::Result<PathBuf>> {
read_plain_file_content(path).map(|res| {
res.map(|buf| {
let plain_path = gix_path::from_bstring(buf);
match (plain_path.is_relative(), path.parent()) {
(true, Some(parent)) => parent.join(plain_path),
_ => plain_path,
}
})
})
}
git -C "$base" init -q main
(
cd "$base/main"
git commit -q --allow-empty -m init
git -C "$base" init -q main
(
cd "$base/main"
git commit -q --allow-empty -m init
Sebastian Thiel (Byron) added a commit that referenced this pull request May 27, 2026
…`from_plain_file`

Follow up on review comments from PR #2599 after the PR was merged.

Update plain-path docs to describe trailing-whitespace trimming, invalid empty
path files, and relative path-file semantics for single-component relative
paths.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants