Skip to content

[Worktree] Offer to repair worktree links after the main repository moves - #763

Merged
hannesa2 merged 2 commits into
masterfrom
worktree-repair-links
Oct 11, 2026
Merged

hannesa2 merged 2 commits into
masterfrom
worktree-repair-links

Conversation

@goneng

@goneng goneng commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Notice when moving the main repository's folder has left its linked
worktrees unable to find it, and offer git worktree repair with a
choice of link style. Closes #739.

  • Check each linked worktree's .git link on every worktree reload,
    the way git worktree repair does internally.
    This needs file reads only, because git worktree list still shows
    these worktrees as healthy.
  • Also find a worktree that sat inside the main folder and moved along
    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.
  • Show a sheet once per window, with Repair as Absolute Paths,
    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.
  • After Skip, dim the broken rows, explain them in the tooltip, and
    offer Repair Worktree Links… in the row menu.
    Open Worktree and double-click show the sheet again.
git Absolute Relative Default
2.48 or later repair --no-relative-paths repair --relative-paths shared style; absolute when mixed
2.29 to 2.47 repair (writes absolute) disabled, tooltip names 2.48 Absolute
before 2.29 disabled disabled Skip (Return and Escape)

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

image

Tooltip - Broken Repo (after Skipping the Fix)

image

Tooltip - Fixed Repo

image

Test plan

  • PBGitWorktreeManagementTests, on real repositories: a moved
    main 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.
  • Moved a repository with an outside and a nested worktree, opened
    it in GitX: the sheet listed both. Repair as Relative Paths left both
    links relative and both worktrees working.
  • Moved it again: Relative was the default, Escape skipped, and the
    sheet stayed closed when the window became key again.

@goneng
goneng force-pushed the worktree-repair-links branch from b9403c2 to 7f37fdc Compare October 9, 2026 23:26
@goneng
goneng marked this pull request as ready for review October 10, 2026 00:06
@goneng
goneng requested a review from hannesa2 October 10, 2026 01:24
Copilot stopped work on behalf of hannesa2 due to an error October 10, 2026 06:10
@hannesa2

Copy link
Copy Markdown
Contributor

I merged #764 please rebase this one

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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.

Comment on lines +1014 to +1017
dispatch_async(dispatch_get_main_queue(), ^{
NSError *error = nil;
if (![self.repository repairWorktreeLinksInStyle:style error:&error])
[self showErrorSheet:error];

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +874 to +875
if (relative)
[arguments addObject:@"--relative-paths"];

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@goneng
goneng force-pushed the worktree-repair-links branch 2 times, most recently from 4a6ba33 to 67be714 Compare October 10, 2026 07:58
@goneng

goneng commented Oct 10, 2026

Copy link
Copy Markdown
Collaborator Author

I merged #764 please rebase this one

@hannesa2 , Rebased onto master with #764 - both builds are green, and
the run has dmgs to try: https://github.com/gitx/gitx/actions/runs/38036248144

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
@goneng
goneng force-pushed the worktree-repair-links branch from 67be714 to 04afc16 Compare October 10, 2026 22:15
@hannesa2

Copy link
Copy Markdown
Contributor

Screenshot differs: emulatorApi=arm64 with 2 screenshot(s)

setpoint (old) | diff | actual screenshot (new)

commit-context-menu.pngscreenshot

history-view.pngscreenshot

@hannesa2
hannesa2 merged commit f2df07b into master Oct 11, 2026
7 of 9 checks passed
@hannesa2
hannesa2 deleted the worktree-repair-links branch October 11, 2026 05:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enhance: [Worktrees] offer to repair linked worktrees after the main repository's folder moves

3 participants