Feat: add interactive git worktree operations
Check list
- [x] I have performed a self-review of my code
- [x] I have commented my code in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
Description
I recently adopted using multiple fixed worktrees as part of my workflow to help with productivity. Each worktree is used for a different type of concurrent activity:
mainfor looking at the pristine codeworkfor looking at my codereviewfor looking at someone else’s codebackgroundfor my computer to look at my code- operates in the detached head state
scratchfor everything else
. (bare repo)
├── background/ (* worktree)
├── config
├── description
├── HEAD
├── hooks/
├── info/
├── logs/
├── main/ (* worktree)
├── objects/
├── packed-refs
├── refs/
├── review/ (* worktree)
├── rr-cache/
├── scratch/ (*worktree)
├── work/(* worktree)
└── worktrees/
Example of worktrees in a bare clone
Another approach is to use worktrees as a replacement of, or a supplement to git branches. Instead of switching branches, you just change directories. So that would involve creating a new worktree and branch, then delete the worktree upon merging.
Worktree Operations (should we stick with these abbreviations?)
- locking a worktree -
gwl - unlocking a worktree -
gwu - removing a worktree -
gwr - jumping to a worktree -
gwj- similar to switching branches
- involves a combination of selecting a result of
git worktree listandcdinto that result (not a native git operation)
Screenshots
bash (repo with short history) - gwj
FORGIT_WORKTREE_PREVIEW_GIT_OPTS='--oneline --graph --decorate --color'
fish (repo with mid-length history) - gwj
FORGIT_WORKTREE_PREVIEW_GIT_OPTS='--oneline --graph --decorate --color'
bash (repo with mid-length history) - gwj
FORGIT_WORKTREE_PREVIEW_GIT_OPTS='--oneline --graph --decorate --color --max-count=100'
Closes #399.
Type of change
- [ ] Bug fix
- [X] New feature
- [ ] Refactor
- [ ] Breaking change
- [X] Documentation change
Test environment
- Shell
- [X] bash
- [ ] zsh
- [X] fish
- OS
- [ ] Linux
- [X] Mac OS X
- [ ] Windows
- [ ] Others:
@suft Thanks for your contribution! Is this ready for review or did you make it a draft on purpose?
@carlfriedrich I made it draft on purpose. Still have a few things to adjust.
@suft Great implementation so far, @sandr01d great review. This will be a good addition to forgit.
(it looks like there is very thorough reviewing going on here, please ping me if you need another pair of eyes, otherwise I completely defer to @sandr01d and @carlfriedrich )
Thanks for the changes @suft, looks good to me so far. Let me summarize the things that still need to be addressed:
- The default preview should look the same as for other commands that use
git log(feat: add interactive git worktree operations #402 (comment))_forgit_worktree_jumpdoes not change the directory when forgit is used as a git subcommand (feat: add interactive git worktree operations #402 (comment))- The root worktree should not be selectable with
gwl. We can make it non-interactable with--header-lines=1and also bring this back in the other functions that you used this with. Don't mind my earlier comment regarding this. (feat: add interactive git worktree operations #402 (comment))- We should add completions for the new commands (feat: add interactive git worktree operations #402 (comment))
- We should allow passing additional arguments to the underlying git commands (feat: add interactive git worktree operations #402 (comment)). The logic for detecting whether the git command should be executed immediately without using fzf needs to be adjusted to do so. Instead of testing if any arguments were passed, we need to test whether non flag arguments were passed. You can use
_forgit_contains_non_flagsto do so.
The root worktree doesn't show up as the first selection, so --header-lines=1 will affect a different worktree (which I'm guessing is not the behaviour we want), unless we reverse the fzf item list.
The root worktree doesn't show up as the first selection, so
--header-lines=1will affect a different worktree (which I'm guessing is not the behaviour we want), unless we reverse the fzf item list.
I'm not exactly sure what you mean. git worktree list always seems to give me the root worktree as the first line and git worktree list | fzf --header-lines 1 does not allow me to select the root worktree as I'd expect. Could you please provide an example on how to reproduce this?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
@suft @sandr01d Are you planning to finish this PR to get it merged anytime?
@suft @sandr01d Are you planning to finish this PR to get it merged anytime?
Sorry for the delay — things have been a bit hectic on my end. I’m hoping to take another look at it sometime this week, but totally understand if it makes sense to close the PR in the meantime.
Sorry for the late reply @suft. Just wanted to let you know that I saw your changes and will give you a review. Unfortunately I don't have much free time right now, so it might take a while until I get to it.
