Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ===== Overview ===== How to create, use and remove worktrees, as an alternative to constantly stashing and popping when you need to change contexts. ===== DESCRIPTION ===== From ''man git-worktree'': <code> 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". A repository has one main working tree (if it’s not a bare repository) and zero or more linked working trees. When you are done with a linked working tree, remove it with git worktree remove. </code> ===== SYNOPSIS ===== Also from ''man git-worktree'': <code> git worktree add [-f] [--detach] [--checkout] [--lock] [-b <new-branch>] <path> [<commit-ish>] git worktree list [--porcelain] git worktree lock [--reason <string>] <worktree> git worktree move <worktree> <new-path> git worktree prune [-n] [-v] [--expire <expire>] git worktree remove [-f] <worktree> git worktree unlock <worktree> </code> ===== Links ===== Various online links related to worktrees: * [[https://git-scm.com/docs/git-worktree|man page]] * [[https://stackoverflow.com/questions/31935776/what-would-i-use-git-worktree-for|Stack Overflow: What would I use git-worktree for?]] * [[https://spin.atomicobject.com/2016/06/26/parallelize-development-git-worktrees/|Atomic Object: Parallelize Development Using Git Worktrees]] * [[https://stacktoheap.com/blog/2016/01/19/using-multiple-worktrees-with-git/|StackToHeap: Using multiple worktrees with git]] * [[https://www.saltycrane.com/blog/2017/05/git-worktree-notes/|SaltyCrane Blog: git worktree notes]] * [[https://blog.reelworx.at/detail/git-worktree-making-typo3-core-development-more-efficient/|ReelWorx: git worktree - making TYPO3 Core development more efficient]] * [[https://152percent.com/blog/2018/4/17/code-review-with-git-worktrees|Code review with Git Worktree]] ===== Issues related to worktrees ===== Drawbacks of ''git stash'': * Constant stashing and unstashing to move between different working directory states. * ''git stash'' doesn't work with unmerged paths, after a merge or rebase with conflicts. * If you work with a compiled language, stashing means you'll have to recompile everything upon unstashing. Applications of worktrees: * Emergency fixes. * Having multiple released versions of the software open at a time, for maintenance. * Testing that takes a long time that would normally tie up your working directory. * Comparing the //behaviour// of different versions of the software. Weaknesses of worktrees: * Can't (normally) have the same branch checked out in two working trees. * Incomplete support for submodules. ===== Condensed example ===== ==== Create a new worktree ==== From within your current working tree, create a new worktree outside the working tree, with a new branch called ''emergency'' off of the current master branch: <code> $ git worktree add -b emergency ../temp master </code> ==== Work in that worktree ==== ''cd'' to that new worktree, work, commit your work on the ''emergency'' branch, and return to your original working tree: <code> $ pushd ../temp ... hack hack hack hack hack hack hack hack hack fix ... $ git commit -a -m "commit emergency fix" $ popd </code> where you can see the additional branch you created in the worktree: <code> $ git branch emergency * master $ </code> ==== Remove the worktree ==== If you have no further use for the worktree, remove it, which has no effect on the branch that was created: <code> $ git worktree remove ../temp $ git branch emergency * master $ </code> ===== Detailed example ===== ==== Initial state of the main working tree ==== Using the "Pro Git" book as a test repo, start with some staged and unstaged changes on the ''master'' branch: <code> $ git status On branch master Your branch is up to date with 'rpjday/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: README.asc Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: LICENSE.asc $ </code> The original working tree is referred to as the "main working tree", while subsequent worktrees are "linked working trees," so you always have at least one worktree: <code> $ git worktree list /home/rpjday/ebooks/progit/progit2 dd124f7 [master] $ </code> ==== Creating the linked working tree ==== Create a working tree off of an earlier tag (''2.1.100''): <code> $ git worktree add -b emergency ../temp 2.1.100 Preparing worktree (new branch 'emergency') HEAD is now at f2d0827 Merge pull request #1145 from rpjday/topic/rpjday/maintaining $ </code> List the working trees: <code> $ git worktree list /home/rpjday/ebooks/progit/progit2 dd124f7 [master] /home/rpjday/ebooks/progit/temp 90bdf0a [emergency] $ </code> Note that nothing has changed in the current working tree: <code> $ git status On branch master Your branch is up to date with 'rpjday/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: README.asc Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: LICENSE.asc $ </code> ==== Move to new working tree ==== <code> $ pushd ../temp </code> Check the status: <code> $ git status On branch emergency nothing to commit, working tree clean $ </code> List all working trees: <code> $ git worktree list /home/rpjday/ebooks/progit/progit2 dd124f7 [master] /home/rpjday/ebooks/progit/temp 90bdf0a [emergency] $ </code> Verify current branch, and current position in history: <code> $ git show commit f2d082747b0a9474f9d2d08c6945482b55691e4a (HEAD -> emergency, tag: 2.1.100) Merge: 7a13f5a 5c0663e Author: Ben Straub <ben@straub.cc> Date: Mon Dec 10 10:06:11 2018 -0800 Merge pull request #1145 from rpjday/topic/rpjday/maintaining maintaining: explain how "git describe" works with lightweight tags $ </code> Examine the ''.git'' //file// in this linked working tree -- this is what identifies a linked working tree: <code> $ cat .git gitdir: /home/rpjday/ebooks/progit/progit2/.git/worktrees/temp $ </code> ==== Make and commit a change in the worktree ==== Make a change, and stage it: <code> $ git diff --cached diff --git a/README.asc b/README.asc index fa40bad..9d69d12 100644 --- a/README.asc +++ b/README.asc @@ -1,3 +1,5 @@ +Change to README.asc on emergency branch in worktree + = Pro Git, Second Edition Welcome to the second edition of the Pro Git book. $ </code> Commit: <code> $ git commit -m "Change README.asc in worktree" [emergency 8b31c7b] Change README.asc in worktree 1 file changed, 2 insertions(+) $ </code> Verify: <code> $ git show commit 8b31c7b18e22fddca50eb9af706b6927f2c14ddc (HEAD -> emergency) Author: Robert P. J. Day <rpjday@crashcourse.ca> Date: Sun Feb 24 08:36:12 2019 -0500 Change README.asc in worktree diff --git a/README.asc b/README.asc index fa40bad..9d69d12 100644 --- a/README.asc +++ b/README.asc @@ -1,3 +1,5 @@ +Change to README.asc on emergency branch in worktree + = Pro Git, Second Edition Welcome to the second edition of the Pro Git book. $ </code> ==== Return to main working tree ==== <code> $ popd ~/ebooks/progit/progit2 $ </code> Everything here is just where we left it: <code> $ git status On branch master Your branch is up to date with 'rpjday/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: README.asc Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: LICENSE.asc $ </code> Linked working tree and ''emergency'' branch are still there: <code> $ git worktree list /home/rpjday/ebooks/progit/progit2 5df317d [master] /home/rpjday/ebooks/progit/temp 8b31c7b [emergency] $ </code> <code> $ git branch emergency * master $ </code> What you choose to do with the work committed to the ''emergency'' branch is up to you. ==== Remove working tree ==== Once you're done with the worktree, remove it and "prune" it: <code> $ git worktree remove ../temp [rpjday@localhost progit2]$ git worktree list /home/rpjday/ebooks/progit/progit2 5df317d [master] $ </code> Note that the ''emergency'' branch still exists. <code> $ git branch emergency * master $ </code> ===== Additional issues to cover ===== * locking and unlocking working trees * moving working trees * git config %%--%%worktree (man git-config) * config var ''extensions.worktreeConfig'' * config var ''gc.worktreePruneExpire'' * config var ''worktree.guessRemote'' * setting up tracking branches * detached HEAD state <code> $GIT_DIR/config.worktree This is optional and is only searched when extensions.worktreeConfig is present in $GIT_DIR/config. </code> git_worktree.txt Last modified: 2019/03/06 08:24by rpjday