Repository navigation
Description
Split out of #675, whose slice 5 (#731) repairs a linked worktree whose own folder was moved. The opposite case, the main repository's folder moving, was left out.
What happens
Each linked worktree's .git file holds an absolute path to <main>/.git/worktrees/<id>. Once the main folder is moved or renamed, that path is stale:
- From the moved main repository,
git worktree list --porcelainstill lists the linked worktree with its HEAD and branch, and not as prunable. So the WORKTREES group shows it as healthy. - Inside the linked worktree, every git command fails with
fatal: not a git repository: <old main>/.git/worktrees/<id>. git worktree repairwith no path, run in the main worktree, rewrites the broken.gitfiles. It printsrepair: .git file broken: <path>for each one and exits 0.
Checked with git 2.50.1 (Apple Git-155).
Why an automatic repair and not a menu action
Git documents a single fix for this case, git worktree repair from the main worktree, and it only touches links that are already broken. Unlike #731, the user has nothing to choose. Tower documents repair only for a moved worktree folder, and Fork and GitKraken document none. So GitX should repair on its own, with the user approving the change first because it writes into folders outside this repository.
Proposal
-
Detect it on refs reload by reading each linked worktree's
.gitfile and comparing itsgitdir:with this repository'sworktrees/<id>folder. The porcelain alone cannot show it. -
Ask once with a sheet on the repository window, listing the worktrees whose link is broken:
This repository was moved, so N of its worktrees can no longer find it: <path> (branch) ... GitX can reconnect them with "git worktree repair". [Cancel] [Repair] -
On Repair, run
git worktree repairand reload the worktree list. If git reports an error, show it and treat the result the same as Cancel. -
On git before 2.29, which has no
repair, the sheet only states the situation. It lists the same worktrees, names the git version found and the 2.29 needed, suggests upgrading git (or pointing GitX at a newer one in Preferences, where the git path is set), and has a single OK button. The rows are marked as below, and Repair Worktree Links is shown disabled with a tooltip naming both versions.
Git before 2.7 needs no handling: it has no worktree list --porcelain, so the WORKTREES group is empty and nothing is detected.
If the user cancels
The main repository works normally after the move; only the linked worktrees are broken, so Cancel must not block this window. GitX continues and marks the broken worktrees:
- The rows are dimmed like a missing folder, with a tooltip saying the link to this repository is broken.
- The row menu offers Repair Worktree Links, which runs the same repair.
- Open Worktree on such a row shows git's error and offers the repair again.
- Cancel (or OK on an older git) is not remembered: the sheet comes back each time the repository is opened while any link is still broken. This stays accurate when the user repairs from the command line instead.
Rejected alternatives: letting git fail with its raw not a git repository error, which names a path that no longer exists and does not say how to fix it; and closing the window or quitting, which refuses to show a repository that works over a problem in other folders.
Out of scope
- Opening a broken linked worktree directly (File > Open on its folder). GitX then has no way to find the main repository, since the path it knows is stale. It could offer to locate the main repository and run the repair from there, but that is a separate flow.
- Relative worktree links: worktrees created with
worktree.useRelativePaths(git 2.48) should not break this way, since their links do not hold absolute paths. Not verified.
Activity
[-]Enhance: [Worktrees] repair linked worktrees after the main repository's folder moves[/-][+]Enhance: [Worktrees] offer to repair linked worktrees after the main repository's folder moves[/+]goneng commentedon Oct 8, 2026
Before building this, I checked the proposal against git's own repair code (
repair_gitfileinworktree.c) and against a moved main repository with git 2.55. The approach holds, with three corrections and one addition.Detection
No git command reports this:
worktree list --porcelainshows the outside worktrees as healthy, andrepairhas no dry run. Proposal step 1 matches whatrepair_gitfiledoes, so it should mirror it exactly. For each linked worktree whose folder exists:<wt>/.gitand resolve a relativegitdir:against the worktree folder..git file broken).<commondir>/worktrees/<id>, the link points elsewhere (git:.git file incorrect).This is file reads only, so it is cheap enough for every refs reload.
Correction 1: a worktree inside the main folder becomes prunable
A worktree nested in the main folder moves with it, so its folder still exists, but both of its link files hold the old path. The porcelain then reports it as
prunable gitdir file points to non-existent location, andworktree prune --dry-runlists it for removal.git worktree repairskips it, because git considers its folder missing.git worktree repair <new path>fixes it. The new path is the old one with the old main folder replaced by the new one, and the old main folder can be read from the stale.gitfile.Correction 2: relative links break too
The "Out of scope" note expects links made with
worktree.useRelativePaths(git 2.48) not to break. They do break when only the main folder moves, the same way absolute ones do. They survive only when the worktree moves with it, for example a nested worktree.Correction 3: repair can rewrite the style of healthy links
Since git 2.48,
repairalso rewrites any link whose style does not match the requested one, healthy or not. The style always applies to every linked worktree: a path argument does not limit it, becauserepairgoes through all of them afterwards.repairworktree.useRelativePaths, absolute when unsetrepair --relative-pathsrepair --no-relative-pathsAddition: let the user choose the link style
The sheet can offer:
--relative-paths)--no-relative-paths)The style is one per run, so "keeping the current style" can only be done exactly when all links share one style. GitX would read that from the
.gitfiles and pass the matching flag. When the links are mixed, git cannot keep each one's style. GitX should then not offer Repair, and leave the choice between the other two to the user. Writing the link files itself would duplicate git's logic, so I am not proposing it.With git 2.29 to 2.47 there are no flags and links come out absolute, so the sheet offers only Repair and Cancel. If a link is relative, the sheet also says it will be rewritten as absolute. This needs a second version gate at 2.48, next to
PBGitWorktreeRepairVersion.An
NSAlertwith four buttons is crowded. An alternative is one Repair button with a style pop-up as the accessory view.[Worktree] Offer to repair worktree links after the main repository m…
[Worktree] Offer to repair worktree links after the main repository m…
[Worktree] Offer to repair worktree links after the main repository m…
[Worktree] Offer to repair worktree links after the main repository m…