Repository navigation
[Worktree] Add and remove worktrees (part 4) - #727
Conversation
7cb3df3 to
e6d8e84
Compare
2f1caf0 to
9e93e8f
Compare
e6d8e84 to
9d0bc62
Compare
9e93e8f to
9b960de
Compare
9d0bc62 to
bca8a15
Compare
9b960de to
290c450
Compare
bca8a15 to
3fd4a4a
Compare
290c450 to
b924929
Compare
b924929 to
f48323c
Compare
There was a problem hiding this comment.
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
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.
| dispatch_async(dispatch_get_main_queue(), ^{ | ||
| [self offerToRemoveWorktree:worktree anywayAfter:error]; | ||
| }); |
There was a problem hiding this comment.
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.
| - (BOOL)addWorktreeAtPath:(NSString *)path branch:(PBGitRef *)branch error:(NSError **)error | ||
| { | ||
| return [self changeWorktreesWithArguments:@[ @"add", path, branch.shortName ] failureTitle:@"Adding the worktree failed" error:error]; |
There was a problem hiding this comment.
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
f48323c to
8150610
Compare
One issue resolved, the other is out-of-scope for this PR (I've opened a new issue to track it). |
|
@goneng It looks like this pull request broke the recent master but it was green on this pull request Do you understand why ? |




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
<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.git worktree add -b).fatal:prefix anduse --forceadvice, and offers Remove Anyway (--force).--force) and for the main worktree, which git never removes.Screenshots
Checkout as New Worktree
Add (New) Worktree
Remove Worktree - Blocked if Locked
Older git
Following the plan agreed on the issue (comment) and the version check #723 adds:
worktree add(and-b)worktree removeBefore 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.git worktree listafter each step.