Skip to content

Commit 7296f2c

Browse files
committed
fix(worktree): find parent repo for bare clones
Running git-branchless from a linked worktree of a bare-clone repo caused a fatal crash rather than displaying output.
1 parent 0504b55 commit 7296f2c

File tree

2 files changed

+41
-15
lines changed

2 files changed

+41
-15
lines changed

git-branchless-lib/src/git/repo.rs

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -577,20 +577,7 @@ impl Repo {
577577
return Ok(None);
578578
}
579579

580-
// `git2` doesn't seem to support a way to directly look up the parent repository for the
581-
// worktree.
582-
let worktree_info_dir = self.get_path();
583-
let parent_repo_path = match worktree_info_dir
584-
.parent() // remove `.git`
585-
.and_then(|path| path.parent()) // remove worktree name
586-
.and_then(|path| path.parent()) // remove `worktrees`
587-
{
588-
Some(path) => path,
589-
None => {
590-
return Err(Error::OpenParentWorktreeRepository {
591-
path: worktree_info_dir.to_owned()});
592-
},
593-
};
580+
let parent_repo_path = self.inner.commondir();
594581
let parent_repo = Self::from_dir(parent_repo_path)?;
595582
Ok(Some(parent_repo))
596583
}

git-branchless-lib/tests/test_repo.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use branchless::git::{
44
AmendFastOptions, BranchType, CherryPickFastOptions, FileMode, FileStatus, GitVersion, Repo,
55
StatusEntry,
66
};
7-
use branchless::testing::{GitWorktreeWrapper, make_git, make_git_worktree};
7+
use branchless::testing::{Git, GitWorktreeWrapper, make_git, make_git_worktree};
88

99
#[test]
1010
fn test_parse_git_version_output() {
@@ -303,3 +303,42 @@ fn test_worktree_working_copy_path() -> eyre::Result<()> {
303303

304304
Ok(())
305305
}
306+
307+
#[test]
308+
fn test_open_worktree_parent_repo_bare_clone() -> eyre::Result<()> {
309+
let git = make_git()?;
310+
git.init_repo()?;
311+
git.commit_file("test1", 1)?;
312+
313+
let temp_dir = tempfile::tempdir()?;
314+
let bare_path = temp_dir.path().join("bare");
315+
let worktree_path = temp_dir.path().join("worktree");
316+
317+
// Create a bare clone.
318+
let source = format!("file://{}", git.repo_path.to_str().unwrap());
319+
git.run(&["clone", "--bare", &source, bare_path.to_str().unwrap()])?;
320+
321+
// Create a linked worktree from the bare clone.
322+
let bare_git = Git {
323+
repo_path: bare_path.clone(),
324+
..(*git).clone()
325+
};
326+
bare_git.run(&[
327+
"worktree",
328+
"add",
329+
"--detach",
330+
worktree_path.to_str().unwrap(),
331+
])?;
332+
333+
let worktree_repo = Repo::from_dir(&worktree_path)?;
334+
let parent_repo = worktree_repo
335+
.open_worktree_parent_repo()?
336+
.expect("expected to find parent repo for worktree of bare clone");
337+
assert_eq!(
338+
std::fs::canonicalize(parent_repo.get_path())?,
339+
std::fs::canonicalize(&bare_path)?,
340+
);
341+
342+
drop(temp_dir);
343+
Ok(())
344+
}

0 commit comments

Comments
 (0)