`but worktree swap`
I would like to enable a workflow where you create new worktrees (workspaces?) that has a target branch in the main workspace. You can generate code there or manually edit files, you can even commit in the worktree.
Then, committed or uncommitted changes, you can swap that worktree into the branch in your main workspace. If there is work in your workspace branch, it creates a worktree for it, swaps it out and swaps the other worktree state in (if possible).
For example, let's say that I want to try out two different variations of a prompt - one in Codex and one in Claude or something. I want the workflow to look like this:
❯ but wt new -a my-feature
Generating new worktree branch name: 'my-feature-a'
Preparing worktree (new branch 'gitbutler/worktree/my-feature-a')
- creating worktree from branch: my-feature
- worktree base at 204e309 [origin/main] Merge pull request #10 from schacon/sc-description
Checking out new tree...
Created worktree at: /Users/schacon/projects/gitbutler/.git/gitbutler/worktrees/my-feature-a
❯ but wt new -a my-feature my-feature-bee
Preparing worktree (new branch 'gitbutler/worktree/my-feature-bee')
- creating worktree from branch: my-feature
- worktree base at 204e309 [origin/main] Merge pull request #10 from schacon/sc-description
Checking out new tree...
Created worktree at: /Users/schacon/projects/gitbutler/.git/gitbutler/worktrees/my-feature-bee
❯ pushd .git/gitbutler/worktrees/my-feature-a; (claude prompt)&; popd
~/projects/why/.git/gitbutler/worktrees/my-feature-a ~/projects/why
~/projects/why
❯ pushd .git/gitbutler/worktrees/my-feature-bee; (codex prompt)&; popd
~/projects/why/.git/gitbutler/worktrees/my-feature-bee ~/projects/why
~/projects/why
Ok, now they can both run and when they're done we can inspect them, test them and choose which one we want like this:
(let's assume Claude auto-committed with our hooks, codex just dumped the files in the wd)
❯ but status
╭┄00 [Unassigned Changes]
┊
┊╭┄t6 [my-feature] (no commits)
┊.
┊├┄nd [my-feature-a] {worktree}
┊┊ (.git/gitbutler/worktrees/my-feature-a)
┊● 81269f3 claude work
┊.
┊├┄p3 [my-feature-bee] {worktree}
┊┊ (.git/gitbutler/worktrees/my-feature-bee)
┊│ x5 M Gemfile
┊│ gd A app/controllers/bookmarks_controller.rb
├╯
┊
● 204e309 (common base) [origin/main] Merge pull request #10 from schacon/sc-description
❯ but wt swap p3
Swapping in my-feature-bee worktree...
❯ (test)
❯ but wt swap nd
Swapping out my-feature-bee worktree...
Swapping in my-feature-a worktree...
❯ (test)
❯ but wt integrate --clean nd
Integrating my-feature-bee as the final version of my-feature branch...
Cleaning remaining feature worktrees...
- my-feature-a cleaned
❯ but status
╭┄00 [Unassigned Changes]
┊
┊╭┄t6 [my-feature]
┊│ x5 M Gemfile
┊│ gd A app/controllers/bookmarks_controller.rb
├╯
┊
● 204e309 (common base) [origin/main] Merge pull request #10 from schacon/sc-description
If there was work in my-feature before the swapping, it would have swapped it out first into a new worktree.
Without the --clean option, it would have kept the unapplied worktrees around until you manually destroy them.
That would be a great feature, and I think we 'kind of' have it already as long as the changes in these worktrees have been committed. Because then it's just a matter of making the branch with the separate worktree 'active' in the workspace, and merge it into the workspace commit. (This goes back to the idea of having a third state for stacks in a workspace, Inside, UnmergedTree, Outside, see #11089 ).
With that said, it feels a bit dangerous to swap uncommitted changes from one worktree to another as we don't have a notion of 'what is what' - the user would then have to remember to swap back the correct worktrees. So committing first seems like the way to go and assure we never lose track of what's currently visible in the workspace.