Repository navigation
[Worktree] Offer to repair worktree links after the main repository moves - #763
Conversation
b9403c2 to
7f37fdc
Compare
|
I merged #764 please rebase this one |
There was a problem hiding this comment.
🟡 Changes recommended
Startup version handling can incorrectly disable repair, repair blocks the main thread, and relative-link tests require an unsupported host Git version.
3 open findings
What changed in this PR
Adds detection and repair flows for worktree links broken after moving the main repository.
Changes:
- Detects broken and moved worktree links during reloads.
- Offers version-aware absolute or relative repair options.
- Updates worktree menus, tooltips, availability, and tests.
| File | Description |
|---|---|
GitXTests/PBGitWorktreeManagementTests.m |
Tests detection, repair, menus, and alerts. |
Classes/git/PBSourceViewGitWorktreeItem.m |
Marks broken links unavailable and explains them. |
Classes/git/PBSourceViewGitWorktreeItem.h |
Documents expanded unavailability behavior. |
Classes/git/PBGitWorktree.m |
Implements link detection and moved-path discovery. |
Classes/git/PBGitWorktree.h |
Exposes link state and style APIs. |
Classes/git/PBGitRepository.m |
Integrates detection and repair execution. |
Classes/git/PBGitRepository.h |
Declares the repair API. |
Classes/git/PBGitBinary.h |
Defines the link-style Git version requirement. |
Classes/Controllers/PBGitWindowController.m |
Implements repair sheets and actions. |
Classes/Controllers/PBGitWindowController.h |
Exposes the repair action. |
Classes/Controllers/PBGitSidebarController.m |
Routes broken-row double-clicks to repair. |
Classes/Controllers/PBGitHistoryController.m |
Adds repair menus and protects moved worktrees from pruning. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| dispatch_async(dispatch_get_main_queue(), ^{ | ||
| NSError *error = nil; | ||
| if (![self.repository repairWorktreeLinksInStyle:style error:&error]) | ||
| [self showErrorSheet:error]; |
There was a problem hiding this comment.
GitX runs its local git actions synchronously on the main thread throughout, and moving them off it is tracked in #732, so this repair keeps the existing pattern until then. The dispatch_async is there so the sheet has closed before an error sheet opens on the same window.
| if (relative) | ||
| [arguments addObject:@"--relative-paths"]; |
There was a problem hiding this comment.
Fixed in 4a6ba33: the five tests that need relative links, either from /usr/bin/git for the fixtures or from GitX's git for repair --relative-paths / --no-relative-paths, now skip with XCTSkipUnless when either git is older than 2.48, naming both versions.
4a6ba33 to
67be714
Compare
@hannesa2 , Rebased onto master with #764 - both builds are green, and |
A git path set in the preferences is accepted at launch and its version read in the background, so code that needs the version can run before it is there, with nothing to tell it when it arrives. - Post PBGitBinaryVersionDidChangeNotification on the main queue whenever the version is set, for a git found by searching as well as for a configured one once its check passes
…oves Moving the main repository's folder leaves every linked worktree pointing at the old place, while `git worktree list` still reports them as healthy (#739). - Check each linked worktree's .git link on every worktree reload, the way `git worktree repair` does, including a worktree nested in the main folder that moved along with it - Offer a sheet once per window: Repair as Absolute Paths, Repair as Relative Paths (git 2.48), or Skip Repair; the default follows the style the links already share, absolute when they differ - After Skip, dim the broken rows, offer Repair Worktree Links in the row menu, and hold Prune back while a moved-along worktree would be forgotten
67be714 to
04afc16
Compare




Summary
Notice when moving the main repository's folder has left its linked
worktrees unable to find it, and offer
git worktree repairwith achoice of link style. Closes #739.
.gitlink on every worktree reload,the way
git worktree repairdoes internally.This needs file reads only, because
git worktree liststill showsthese worktrees as healthy.
with it. git lists it at its old place as prunable, so Prune is held
back while one exists, and the repair passes its new path.
Repair as Relative Paths and Skip Repair.
Repair writes every link in one style, so the default button is
the style the links already share, or absolute when they differ.
offer Repair Worktree Links… in the row menu.
Open Worktree and double-click show the sheet again.
repair --no-relative-pathsrepair --relative-pathsrepair(writes absolute)Skip Repair always answers Escape.
A worktree whose link points at another repository that still exists, such as a copy of this one,
is left alone, since repairing it from here would take it away from that repository.
Screenshots
Popup Screen at Opening the Repo
Tooltip - Broken Repo (after Skipping the Fix)
Tooltip - Fixed Repo
Test plan
PBGitWorktreeManagementTests, on real repositories: a movedmain folder, relative links, a nested worktree that moved along, a
copied repository, both repair styles, the menus and Prune, and the
sheet's buttons and defaults per git version and link style. Full
suite: 342 tests pass.
it in GitX: the sheet listed both. Repair as Relative Paths left both
links relative and both worktrees working.
sheet stayed closed when the window became key again.