This is an old revision of the document!
How to create, use and remove worktrees, as an alternative to constantly stashing and popping when you need to change contexts.
From man 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". 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.
Also from man git-worktree
:
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>
Various online links related to worktrees:
Drawbacks of git stash
:
git stash
doesn't work with unmerged paths, after a merge or rebase with conflicts.Applications of worktrees:
Weaknesses of worktrees:
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:
$ git worktree add -b emergency ../temp master
cd
to that new worktree, work, commit your work on the emergency
branch, and return to your original working tree:
$ pushd ../temp ... hack hack hack hack hack hack hack hack hack fix ... $ git commit -a -m "commit emergency fix" $ popd
where you can see the additional branch you created in the worktree:
$ git branch emergency * master $
If you have no further use for the worktree, remove and prune, which has no effect on the branch that was created:
$ git worktree remove ../temp $ git worktree prune $ git branch emergency * master $
Using the “Pro Git” book as a test repo, start with some staged and unstaged changes on the master
branch:
$ 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 $
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:
$ git worktree list /home/rpjday/ebooks/progit/progit2 dd124f7 [master] $
Create a working tree off of an earlier tag (2.1.100
):
$ git worktree add -b emergency ../temp 2.1.100 Preparing ../temp (identifier temp) HEAD is now at 90bdf0a Stahp updating bundler $
List the working trees:
$ git worktree list /home/rpjday/ebooks/progit/progit2 dd124f7 [master] /home/rpjday/ebooks/progit/temp 90bdf0a [emergency] $
Note that nothing has changed in the current working tree:
$ 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 $
$ pushd ../temp
List all working trees:
$ git worktree list /home/rpjday/ebooks/progit/progit2 dd124f7 [master] /home/rpjday/ebooks/progit/temp 90bdf0a [emergency] $
Verify current branch, and current position in history:
$ git status On branch emergency nothing to commit, working tree clean $
$ git show commit 90bdf0a2cb410463a949ae9279ac7e065f7b023b (HEAD -> emergency, tag: 2.1.30) Author: Ben Straub <ben@straub.cc> Date: Tue Jan 16 10:31:13 2018 -0800 Stahp updating bundler diff --git a/.travis.yml b/.travis.yml index 9d0bcb2..cffacfd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: ruby cache: bundler before_install: -- gem install bundler - bundle install after_success: - script/tag_on_master $
Examine the .git
file in the linked working tree:
$ cat .git gitdir: /home/rpjday/ebooks/progit/progit2/.git/worktrees/temp $
$ git diff diff --git a/README.asc b/README.asc index d7810fd..0576243 100644 --- a/README.asc +++ b/README.asc @@ -1,4 +1,4 @@ -= Pro Git, Second Edition += Pro Git, Second Edition (rday) Welcome to the second edition of the Pro Git book. $
$ git commit -a -m "silly change" [emergency 6bf829d] silly change 1 file changed, 1 insertion(+), 1 deletion(-) $
$ git show commit 6bf829d7e63b1184c73546aa94625849054b1ebc (HEAD -> emergency) Author: Robert P. J. Day <rpjday@crashcourse.ca> Date: Tue Feb 6 09:48:48 2018 -0500 silly change diff --git a/README.asc b/README.asc index d7810fd..0576243 100644 --- a/README.asc +++ b/README.asc @@ -1,4 +1,4 @@ -= Pro Git, Second Edition += Pro Git, Second Edition (rday) Welcome to the second edition of the Pro Git book. $
$ popd ~/ebooks/progit/progit2 $
Still on master
branch:
$ git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working tree clean $
Linked working tree is still there and available:
$ git branch emergency * master $
$ git worktree list /home/rpjday/ebooks/progit/progit2 dd124f7 [master] /home/rpjday/ebooks/progit/temp 6bf829d [emergency] $
$ git show emergency commit 6bf829d7e63b1184c73546aa94625849054b1ebc (emergency) Author: Robert P. J. Day <rpjday@crashcourse.ca> Date: Tue Feb 6 09:48:48 2018 -0500 silly change diff --git a/README.asc b/README.asc index d7810fd..0576243 100644 --- a/README.asc +++ b/README.asc @@ -1,4 +1,4 @@ -= Pro Git, Second Edition += Pro Git, Second Edition (rday) Welcome to the second edition of the Pro Git book. $
Remove the directory itself:
$ rm -rf ../temp
Still seems to be there:
$ git worktree list /home/rpjday/ebooks/progit/progit2 dd124f7 [master] /home/rpjday/ebooks/progit/temp 6bf829d [emergency] $
We need to “prune” deleted working trees:
$ git worktree prune [rpjday@android-a172fe96dd584b41 progit2]$ git worktree list /home/rpjday/ebooks/progit/progit2 dd124f7 [master] $
But our work that was committed from that working tree is still there in the object store:
$ git show emergency commit 6bf829d7e63b1184c73546aa94625849054b1ebc (emergency) Author: Robert P. J. Day <rpjday@crashcourse.ca> Date: Tue Feb 6 09:48:48 2018 -0500 silly change diff --git a/README.asc b/README.asc index d7810fd..0576243 100644 --- a/README.asc +++ b/README.asc @@ -1,4 +1,4 @@ -= Pro Git, Second Edition += Pro Git, Second Edition (rday) Welcome to the second edition of the Pro Git book. $
extensions.worktreeConfig
gc.worktreePruneExpire
worktree.guessRemote
$GIT_DIR/config.worktree This is optional and is only searched when extensions.worktreeConfig is present in $GIT_DIR/config.