Skip to content

[Worktree] Add and remove worktrees (part 4) - #727

Merged
hannesa2 merged 1 commit into
masterfrom
add-and-remove-worktrees
Sep 27, 2026
Merged

hannesa2 merged 1 commit into
masterfrom
add-and-remove-worktrees

Conversation

@goneng

@goneng goneng commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Slice 4 of #675: add a worktree, from a branch or on a new one, and remove one.
(It builds on #723 (slice 3) and targets its branch so the diff shows this slice alone; merge #723 first.)

Changes

  • A local branch no worktree holds gains Checkout "X" in New Worktree... in its menu, in the sidebar and on its label in the history list, just below Copy name. It opens a save panel on the folder next to the repository, suggesting <repository>-<branch> (a / in the branch name becomes -). The branch checked out here shows it disabled, since git checks a branch out in one worktree at a time; remote branches do not get it.
  • The WORKTREES header gains Add Worktree... above Prune Worktrees...: it asks for a new branch name, which starts at the commit checked out here, then for the folder (git worktree add -b).
  • Remove Worktree... takes the place of Delete branch on a branch another worktree holds, and sits below the worktree group on a detached worktree's row. It confirms first, saying the folder goes and the branch stays. When git refuses because the worktree has changes or untracked files, the sheet shows git's reason without its fatal: prefix and use --force advice, and offers Remove Anyway (--force).
  • Remove is disabled with a reason for a locked worktree (unlock it first; git refuses even --force) and for the main worktree, which git never removes.

Screenshots

Checkout as New Worktree

image

Add (New) Worktree

image

Remove Worktree - Blocked if Locked

image

Older git

Following the plan agreed on the issue (comment) and the version check #723 adds:

Feature First git version
worktree add (and -b) 2.5
worktree remove 2.17

Before those versions the items are shown disabled, with a tooltip naming the version needed and the one found. There is no fallback for remove before 2.17 (such as deleting the folder and pruning).

Test plan

  • make unit-test: 279 tests, 16 of them new, among them the 2.4.6/2.5 and 2.16.6/2.17 boundaries, adding from an existing and a new branch, removing a clean worktree, a refused remove that only goes through when forced, and each disabled item's reason.
  • In the Debug build, on a scratch repository with linked worktrees: check a branch out in a new worktree through the save panel, add one on a new branch from the header, and remove one with an untracked file, first refused and then with Remove Anyway, checking git worktree list after each step.

@goneng
goneng force-pushed the prune-and-lock-worktrees branch from 7cb3df3 to e6d8e84 Compare September 25, 2026 18:49
@goneng
goneng force-pushed the add-and-remove-worktrees branch from 2f1caf0 to 9e93e8f Compare September 25, 2026 18:49
@goneng
goneng force-pushed the prune-and-lock-worktrees branch from e6d8e84 to 9d0bc62 Compare September 25, 2026 21:54
@goneng
goneng force-pushed the add-and-remove-worktrees branch from 9e93e8f to 9b960de Compare September 25, 2026 21:54
@goneng goneng changed the title [Worktree] Add and remove worktrees [Worktree] Add and remove worktrees (part 4) Sep 26, 2026
@goneng
goneng force-pushed the prune-and-lock-worktrees branch from 9d0bc62 to bca8a15 Compare September 26, 2026 07:59
@goneng
goneng force-pushed the add-and-remove-worktrees branch from 9b960de to 290c450 Compare September 26, 2026 07:59
@goneng
goneng force-pushed the prune-and-lock-worktrees branch from bca8a15 to 3fd4a4a Compare September 26, 2026 10:33
@goneng
goneng force-pushed the add-and-remove-worktrees branch from 290c450 to b924929 Compare September 26, 2026 10:33
Base automatically changed from prune-and-lock-worktrees to master September 26, 2026 16:01
@goneng
goneng force-pushed the add-and-remove-worktrees branch from b924929 to f48323c Compare September 26, 2026 18:59
@goneng
goneng marked this pull request as ready for review September 26, 2026 19:01
@goneng
goneng requested a review from hannesa2 September 26, 2026 19:01
@hannesa2
hannesa2 requested a lite review from Copilot September 26, 2026 20:30

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.

Copilot review overview

🟡 Changes recommended

Several unresolved issues affect UI responsiveness, destructive-action safety, error handling, and default worktree path selection.

Review effort: Lite
Findings: 2 Medium severity

Open (2)
What changed in this PR

Adds GitX support for creating and removing Git worktrees with version checks, safeguards, UI flows, and tests.

Changes:

  • Added repository APIs for adding and removing worktrees.
  • Added menus, dialogs, confirmations, and force-removal handling.
  • Added Git-version and worktree-management tests.
File Description
GitXTests/​PBGitWorktreeManagementTests.m Tests worktree management behavior.
GitXTests/​PBGitBinaryVersionTests.m Tests Git version boundaries.
Classes/​git/​PBGitRepository.m Implements worktree operations.
Classes/​git/​PBGitRepository.h Declares worktree APIs.
Classes/​git/​PBGitBinary.h Defines required Git versions.
Classes/​Controllers/​PBGitWindowController.m Implements worktree UI flows.
Classes/​Controllers/​PBGitWindowController.h Declares UI actions.
Classes/​Controllers/​PBGitHistoryController.m Adds contextual worktree actions and gating.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +938 to +940
dispatch_async(dispatch_get_main_queue(), ^{
[self offerToRemoveWorktree:worktree anywayAfter: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.

Good catch, fixed. Remove Anyway is now offered only for the refusals --force overrides: work that would be lost, and submodules (which git does not say --force fixes). Any other refusal, such as a worktree locked after the menu was built, shows git's error instead. Tests cover all three cases.

Comment on lines +469 to +471
- (BOOL)addWorktreeAtPath:(NSString *)path branch:(PBGitRef *)branch error:(NSError **)error
{
return [self changeWorktreesWithArguments:@[ @"add", path, branch.shortName ] failureTitle:@"Adding the worktree failed" error: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.

Same as on #723: this follows how GitX runs all its local git actions (checkout, merge, reset, rebase, stash), which are synchronous. Add and remove can take longer than lock or unlock on a large checkout, and PBTask's 30-second limit applies to them as it does to checkout. That is worth solving for all local actions together, so it is tracked in #732 rather than in this PR.

Let a branch get a worktree of its own from its menu, and let a
worktree be removed where its branch would otherwise be deleted.

- Offer "Checkout "X" in New Worktree..." on a local branch no worktree
  holds, and "Add Worktree..." on a new branch from the WORKTREES
  header; both suggest a folder next to the repository
- Put "Remove Worktree..." in place of deleting a branch a worktree
  holds; it keeps the branch, and when git refuses because of work
  that would be lost or of submodules, show git's reason and offer
  to remove anyway; any other refusal is shown as git gives it
- Disable each action with a reason when git is older than it needs
  (add 2.5, remove 2.17), and Remove for a locked or main worktree
@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

@goneng

goneng commented Sep 27, 2026

Copy link
Copy Markdown
Collaborator Author

Copilot review overview

🟡 Changes recommended

Several unresolved issues affect UI responsiveness, destructive-action safety, error handling, and default worktree path selection.

Review effort: Lite
Findings: 2 Medium severity

Open (2)
What changed in this PR

Adds GitX support for creating and removing Git worktrees with version checks, safeguards, UI flows, and tests.

Changes:

  • Added repository APIs for adding and removing worktrees.
  • Added menus, dialogs, confirmations, and force-removal handling.
  • Added Git-version and worktree-management tests.

| File | Description |

|---|---|

| GitXTests/​PBGitWorktreeManagementTests.m | Tests worktree management behavior. |

| GitXTests/​PBGitBinaryVersionTests.m | Tests Git version boundaries. |

| Classes/​git/​PBGitRepository.m | Implements worktree operations. |

| Classes/​git/​PBGitRepository.h | Declares worktree APIs. |

| Classes/​git/​PBGitBinary.h | Defines required Git versions. |

| Classes/​Controllers/​PBGitWindowController.m | Implements worktree UI flows. |

| Classes/​Controllers/​PBGitWindowController.h | Declares UI actions. |

| Classes/​Controllers/​PBGitHistoryController.m | Adds contextual worktree actions and gating. |


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

One issue resolved, the other is out-of-scope for this PR (I've opened a new issue to track it).
Pls review again.

@hannesa2
hannesa2 merged commit d9d5d8a into master Sep 27, 2026
3 checks passed
@hannesa2
hannesa2 deleted the add-and-remove-worktrees branch September 27, 2026 04:54
@hannesa2

hannesa2 commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

@goneng It looks like this pull request broke the recent master but it was green on this pull request
image
https://github.com/gitx/gitx/actions/runs/36316884747/job/108613153833?pr=414

Do you understand why ?

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.

3 participants