Skip to content

Commit fe12ff8

Browse files
committed
fix: resolve main repo root from inside worktrees
1 parent a1702c2 commit fe12ff8

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
**Zoxide for Git worktrees** — zero-config dependency syncing, fuzzy switching, and AI-agent support.
44

5+
![workz demo](demo.gif)
6+
57
Git worktrees let you work on multiple branches simultaneously, but they leave behind your `.env` files and force you to re-install `node_modules` every time. **workz** fixes this automatically.
68

79
## The Problem

demo.gif

296 KB
Loading

src/git.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,32 @@ fn git_in(dir: &Path, args: &[&str]) -> Result<String> {
2424
git(&full_args)
2525
}
2626

27-
/// Find the root of the current git repository.
27+
/// Find the root of the main git repository (not a worktree).
28+
/// Uses --git-common-dir to always resolve to the main repo, even when
29+
/// called from inside a worktree.
2830
pub fn repo_root() -> Result<PathBuf> {
29-
let root = git(&["rev-parse", "--show-toplevel"])
31+
let toplevel = git(&["rev-parse", "--show-toplevel"])
3032
.context("not inside a git repository")?;
31-
Ok(PathBuf::from(root))
33+
let common_dir = git(&["rev-parse", "--git-common-dir"])?;
34+
35+
let common = PathBuf::from(&common_dir);
36+
// If common_dir is ".git", we're in the main repo — use toplevel
37+
// If common_dir is an absolute path (e.g. /repo/.git), parent is the main repo
38+
// If common_dir is a relative path (e.g. ../../repo/.git), resolve from toplevel
39+
if common_dir == ".git" {
40+
Ok(PathBuf::from(toplevel))
41+
} else {
42+
let abs = if common.is_absolute() {
43+
common
44+
} else {
45+
PathBuf::from(&toplevel).join(&common)
46+
};
47+
// common_dir points to the .git dir — parent is the repo root
48+
abs.parent()
49+
.map(|p| p.to_path_buf())
50+
.and_then(|p| p.canonicalize().ok())
51+
.ok_or_else(|| anyhow::anyhow!("could not resolve main repo root"))
52+
}
3253
}
3354

3455
/// Get the repository name from the root path.

0 commit comments

Comments
 (0)