lesson ── git-labs ── ~18 мин ── 7 шагов
The goal is to solve the classic "I'm building a feature, a hotfix lands"
problem without stash. git worktree add creates a second working tree from
the same repository. You make the hotfix in one directory, then return to the
main one and your feature is still there.
интерактивный sandbox
Поднимется контейнер gitlab/git-base с git, bash, pre-commit. В браузере откроется терминал, можно сразу git init. Каждый шаг проверяется автоматически. Сеть air-gapped, github.com недоступен.
stack ── git · bash · 256 MB RAM · air-gapped · самоуничтожается через 30 мин простоя
cd /home/student/work
mkdir -p worktree-lab && cd worktree-lab
git init -b main
echo "stable" > prod.txt
git add . && git commit -m "init: prod baseline"
git switch -c feat/big-refactor
echo "wip stage 1" > refactor.txt
git add . && git commit -m "wip: stage 1"
echo "wip stage 2" >> refactor.txt
git status
You are now on feat/big-refactor with one commit and uncommitted work in refactor.txt. Now simulate an interruption.
✓ The feature is in progress, with uncommitted changes.
cd /home/student/work/worktree-lab
# worktree add <path> <branch>: create a second working tree on branch main
git worktree add ../wt-hotfix main
git worktree list # you see both trees, their paths and branches
A ../wt-hotfix directory appeared. This is the second working tree, with
its HEAD on main. The main worktree (with your feature) is untouched.
✓ The second worktree is created. One .git/, two trees.
cd /home/student/work/wt-hotfix # move into the second worktree
git status # on branch main, working tree clean
echo "fixed" >> prod.txt
git commit -am "fix: critical issue in prod"
git log --oneline
You are now in wt-hotfix/, on branch main. You made a commit and it went
into main. In the main worktree the feature is still in progress,
uncommitted.
✓ The hotfix is committed to main, with no stash and no switching.
cd /home/student/work/worktree-lab
git rev-parse --abbrev-ref HEAD # --abbrev-ref = name of the current branch, not the SHA
cat refactor.txt # both lines are still there
git status # the uncommitted stage 2 did not disappear
git log --oneline --graph --all
The branch is still feat/big-refactor. refactor.txt contains both
lines (stage 1 plus uncommitted stage 2). The graph shows the
fix: critical issue commit on main, with your branch sitting apart from
it.
✓ The feature is intact. Nothing was lost.
cd /home/student/work/worktree-lab
git worktree remove ../wt-hotfix # remove the worktree (directory plus registration)
git worktree list # one tree again
ls /home/student/work/ | grep wt-hotfix && echo "still there" || echo "removed"
The worktree is removed. The single .git/ remains, the objects are
saved, and branch main is saved too, with your hotfix commit.
✓ The worktree is removed. The hotfix history is preserved in main.
Git allows one worktree per branch. Otherwise you would get two "active" copies of the same state, with no clear source of truth.
cd /home/student/work/worktree-lab
git worktree add ../wt-fail feat/big-refactor # fails: the branch is already used by the main worktree
It should fail with fatal: 'feat/big-refactor' is already used by worktree at .... This is a guard, not a bug.
If you really need a second copy, create a new branch:
# -b <new> = create a new branch from <start-point> to get around the conflict
git worktree add -b feat/big-refactor-test ../wt-test feat/big-refactor
git worktree list
git worktree remove ../wt-test
The command fails: that is the correct behavior. Next, use `-b new-name`.
✓ You saw Git's guard, and you know the workaround.
cd /home/student/work/worktree-lab
git add refactor.txt
git commit -m "feat: complete refactor"
git switch main
# --no-ff = always a merge commit, so the feature boundary shows in the log
git merge --no-ff feat/big-refactor -m "merge refactor"
git log --oneline --graph --all
The final graph: main contains the hotfix and the refactor, each merged separately. This is the scenario where worktree saved you time. You never switched context or reached for stash, and nothing was lost.
✓ The hotfix and the feature are in main. Parallel work without stash is done.
git worktree add creates a second working tree next to the main one.
Both look into the same .git/. You remove it with worktree remove.
This is a full second workspace, not a stash.
команды
git worktree add ../hotfix maincreate a second working tree on branch maingit worktree listsee all worktrees of this repogit worktree remove ../hotfixremove a worktreegit worktree pruneclean up the record of a manually deleted worktreeконцепции