Skip to content

Commit 52f54f2

Browse files
fix: worktree when .git is symlink (#2052)
1 parent 442f800 commit 52f54f2

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

gix/src/open/repository.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,20 @@ impl ThreadSafeRepository {
301301
| gix_config::Source::EnvOverride => wt_path,
302302
_ => git_dir.join(wt_path).into(),
303303
};
304-
worktree_dir = gix_path::normalize(wt_path, current_dir).map(Cow::into_owned);
304+
305+
// the reason we use realpath instead of gix_path::normalize here is because there
306+
// could be any intermediate symlinks (for example due to a symlinked .git
307+
// directory)
308+
worktree_dir = gix_path::realpath(&wt_path).ok();
309+
// restore the relative path if possible after resolving the absolute path
310+
if wt_path.is_relative() {
311+
if let Ok(cwd) = std::env::current_dir() {
312+
if let Some(rel_path) = worktree_dir.as_deref().and_then(|p| p.strip_prefix(&cwd).ok()) {
313+
worktree_dir = Some(rel_path.to_path_buf());
314+
}
315+
}
316+
}
317+
305318
#[allow(unused_variables)]
306319
if let Some(worktree_path) = worktree_dir.as_deref().filter(|wtd| !wtd.is_dir()) {
307320
gix_trace::warn!("The configured worktree path '{}' is not a directory or doesn't exist - `core.worktree` may be misleading", worktree_path.display());

gix/tests/fixtures/make_submodules.sh

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,18 @@ git clone with-submodules not-a-submodule
151151
git add m1 && git commit -m "no submodule in index and commit, but in configuration"
152152
)
153153

154-
git init unborn
154+
git init unborn
155+
156+
mkdir symlinked-git-dir
157+
(cd symlinked-git-dir
158+
git init -q r1
159+
(cd r1
160+
git commit -q --allow-empty -m "init"
161+
)
162+
163+
git config -f r1/.git/config core.worktree `pwd`
164+
ln -s r1/.git .git
165+
166+
git -c protocol.file.allow=always submodule add ../module1 m1
167+
git commit -m "add module 1"
168+
)

gix/tests/gix/status.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,22 @@ mod index_worktree {
310310
);
311311
}
312312

313+
#[test]
314+
fn submodule_in_symlinked_dir() -> crate::Result {
315+
let repo = submodule_repo("symlinked-git-dir")?;
316+
let status = repo
317+
.status(gix::progress::Discard)?
318+
.index_worktree_options_mut(|opts| {
319+
opts.sorting =
320+
Some(gix::status::plumbing::index_as_worktree_with_renames::Sorting::ByPathCaseSensitive);
321+
})
322+
.into_index_worktree_iter(None)?;
323+
for change in status {
324+
change?;
325+
}
326+
Ok(())
327+
}
328+
313329
#[test]
314330
fn submodule_modification() -> crate::Result {
315331
let repo = submodule_repo("modified-untracked-and-submodule-head-changed-and-modified")?;

0 commit comments

Comments
 (0)