Skip to content

fix(pwd): find origin from inside a linked git worktree#54

Open
clawedassistant26 wants to merge 1 commit into
moshcoder:mainfrom
clawedassistant26:fix/pwd-origin-missing-in-worktree
Open

fix(pwd): find origin from inside a linked git worktree#54
clawedassistant26 wants to merge 1 commit into
moshcoder:mainfrom
clawedassistant26:fix/pwd-origin-missing-in-worktree

Conversation

@clawedassistant26

Copy link
Copy Markdown
Contributor

Inside a linked git worktree, moshcode pwd (and the TUI /pwd) silently drops the origin: line. The same repo prints it fine from the main checkout.

Repro (real git, unmodified main @ 5029919)

git init -b main main-repo
cd main-repo
git remote add origin https://github.com/example/demo.git
git commit --allow-empty -m init
git worktree add ../wt-feature -b feature
cd ../wt-feature
moshcode pwd

Actual:

/tmp/wtrepro/wt-feature
repo:   wt-feature (feature)
root:   /tmp/wtrepro/wt-feature

From main-repo, same repo, same remote:

repo:   main-repo (main)
root:   /tmp/wtrepro/main-repo
origin: https://github.com/example/demo.git

Cause

locate() resolves the worktrees .gitfile to.git/worktrees/and then reads both HEAD andconfig from there. A linked worktrees git dir holds only its own HEAD, index and logs — there is no config file, so readOrigin() throws on the read, catches, and returns null. The shared config lives in the main repos git dir, which git names in a commondirfile next to that HEAD (normally the relative path../..`).

Branch still resolves because HEAD genuinely is per-worktree, which is what makes the missing origin look like "this repo has no remote" rather than a lookup failure.

Fix

src/pwd.mjs only. A small commonGitDir() helper reads commondir and resolves it against the worktree git dir (handles both the relative form git writes and an absolute one); readOrigin() is called with that. readBranch() is deliberately left on the worktree git dir.

No behaviour change elsewhere: a plain checkout and a submodule (.git/modules/<name>, which has its own config) have no commondir file, so the helper returns the git dir unchanged. Verified both against real git.

Tests

Two added to test/pwd.test.mjs, driving locate() over a git-shaped layout built with fs — no git on PATH required, in keeping with this module staying zero-dependency. One covers the relative commondir git actually writes, one the absolute form.

  • Stash-verified with git stash push -- src/: both FAIL on unpatched src (3 pass / 2 fail), pass with the fix.
  • Full suite node --test: 166 tests, 163 pass, 0 fail, 3 skipped (baseline on main this run: 164 / 161 / 0 fail / 3 skipped).

A linked worktree's git dir (.git/worktrees/<name>) carries only that
worktree's own HEAD and index. The shared config, and therefore every
remote, stays in the main repo's git dir, which git names in a
`commondir` file. readOrigin() was pointed at the worktree git dir, so
it read no config at all and `moshcode pwd` / `/pwd` silently dropped
the `origin:` line — the same repo shows it from the main checkout.

Resolve commondir (relative or absolute) before reading config. HEAD is
still read from the worktree's own git dir, because the branch really is
per-worktree. Plain repos and submodules have no commondir file, so they
take the unchanged path.
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.

1 participant