Does one git worktree support multiple branches?

Viewed 627

Per the documentation, each git worktree serves one branch (dev/feature/prod and so on), but it also sound not reasonable to me, that each branch will have its own worktree as it will creates many folders, and at some point might be confusing.

Does one git worktree can support multiple branches? for example all the branches which belongs to feature and then switch between what relevant for the moment? Is it correct approach?

3 Answers

git worktree creates a new checkout which shares your existing local repository. It has its own HEAD, which tracks which commit is currently checked out, and its own staging area for building commits. It's main purpose is to be able to work on multiple branches at the same time without having to clone the whole repository or stash your changes.

A worktree works essentially like any other checkout. You can switch to any branch you like, unless it's already checked out by another worktree. You can run git-bisect. You can rebase.

A worktree does not have to be for a new branch, it can be for an existing branch. git worktree add ../temp master will make a worktree with master checked out.

You only need to make worktrees if you intend to work on multiple branches simultaneously. For example, you're working on a feature and have lots of uncommitted changes and an emergency fix comes in. You can make a worktree for that fix, do the fix in the worktree, and then return to your original feature work. Or maybe you want to test something against an old version, you can make a work tree and checkout the old version.

A good development process does not require you to be working on multiple branches at the same time.

From https://git-scm.com/docs/git-worktree

A git repository can support multiple working trees, allowing you to check out more than one branch at a time. With git worktree add a new working tree is associated with the repository. This new working tree is called a "linked working tree" as opposed to the "main working tree" prepared by git-init or git-clone.

If you want to add a new branches to worktree you need to write:
git worktree add <path> <branch_name>

For example:

git checkout -B new_branch
git checkout main
git worktree add ./new_branch new_branch

To remove it: git worktree remove

And that how does it look: in tree view

In path parameter you can pass anything. So you can manage your branches as you want for example you can create folder where you will store only branches with bugfixes or futures.

You can switch to any branch you like, unless it's already checked out by another worktree. You can run git-bisect. You can rebase.

But... you should not switch branch if you are, in your current worktree, in the middle of a bisect or rebase.

And that was not enforced before Git 2.38.

With Git 2.38 (Q3 2022), introduce a helper to see if a branch is already being worked on (hence should not be newly checked out in a working tree), which performs much better than the existing find_shared_symref() to replace many uses of the latter.

See commit 4b6e18f, commit b489b9d, commit 12d47e3, commit d2ba271, commit 31ad6b6 (14 Jun 2022) by Derrick Stolee (derrickstolee).
See commit 9bef0b1, commit b2463fc (18 Jun 2022) by Jeff King (peff).
(Merged by Junio C Hamano -- gitster -- in commit c2d0109, 11 Jul 2022)

branch: check for bisects and rebases

Signed-off-by: Derrick Stolee

The branch_checked_out() helper was added by the previous change, but it used an over-simplified view to check if a branch is checked out.
It only focused on the HEAD symref, but ignored whether a bisect or rebase was happening.

Teach branch_checked_out() to check for these things, and also add tests to ensure that we do not lose this functionality in the future.

Now that this test coverage exists, we can safely refactor validate_new_branchname() to use branch_checked_out().

Note that we need to prepend "refs/heads/" to the 'state.branch' after calling wt_status_check_*().
We also need to duplicate wt->path so the value is not freed at the end of the call.

Changing branch in a worktree which is being rebased (or bisected) would result in:

 cannot force update the branch <abranch> checked out at <worktree path>
Related