A few scenarios have been problematic with git and I've now discovered git worktrees which help with each.
- If you've wanted to compare multiple files in different branches of the same tree - without needing to commit on either side.
- If you want to work on two (or more) versions of the same file at the same time, again without needing to commit.
- You have a file or a bunch of files that aren't ready to be committed, even locally.
- You are working on a development branch and an urgent fix is required on an old git tag.
- You have a large git repository which is a burden to clone (or has complex submodules).
You could go to the trouble of making a new directory and re-cloning the same tree. However, a local commit in one tree is then not accessible to the other tree.
You could commit everything every time, but with a dirty tree, that involves sorting out the .gitignore rules as well. That could well be pointless with an experimental change.
Git worktrees allow multiple filesystems from a single git tree. Commits on any branch are visible from other branches, even when the commit was on a different worktree. This makes things like cherry-picking easy, without needing to push pointless changes or branches.
Branches on a worktree can be rebased as normal, with the benefit that commit hashes from other local changes are available for reference and cherry-picks.
I'm sure git worktrees are not new. However, I've only started using them recently and others have asked about how the worktree operates.
Creating a new tree can be done with a new or existing branch. To make it easier, set the new directory at the same time, usually in ../
New branch (branched from the current branch):
git worktree add -b branch_name ../branch_name
Existing branch - note, slightly different syntax here, specify the commit-ish last (branch name, tag or hash):
git worktree add ../branch_name branch_name
git worktree list /home/neil/Documents/testing/testrepo 0612677 [master] /home/neil/Documents/testing/testtree d38f5a3 [testtree]
Use git worktree remove <name> to drop the entire directory for that tree and the git tracking.
I'm using this for work on the Debian Security Tracker. I have two local branches and having two worktrees allows me to have three terminals open, using the same files and the same git repository.
One to run make serve and update the local SQLite database. One to access master to run git pull One to make local changes without risking collisions on master.
git add data/CVE/list git commit # pre commit hook runs here git log -n 1 # copy the hash # switch to master terminal git pull git cherry-pick <HASH> git push # switch to server terminal git rebase master # no git pull or fetch, it's all local make # switch back to changes terminal git rebase master
Sadly, one area where this isn't as easy is with importing a new DSC into Salsa with git-buildpackage as that uses several branches at the same time. It would be possible but you'll need to have a separate upstream and possibly pristine-tar branches and supply the relevant options. Possibly something git-buildpackage to adopt - it is common to need to make changes to the packaging with a new upstream release & a lot of those changes are currently done outside git.
For the rest of the support, see git worktree (1)