switch, restore, and checkout
switch, restore, and checkout
After this page you can change branches with git switch and files with git restore, and you can translate an old git checkout line.
Two commands, two jobs
Until Git 2.23, git checkout did both jobs. It still does, including in Git 2.55. Checking out a branch moves HEAD. Checking out a path copies bytes. One word for both is how a file gets overwritten when the goal was to change branches.
git switch moves HEAD and refuses a path. git restore copies bytes and leaves HEAD where it is.
| Older command | Command in this book |
|---|---|
git checkout main |
git switch main |
git checkout -b feat/x |
git switch -c feat/x |
git checkout -- README.md |
git restore README.md |
git checkout HEAD -- README.md |
git restore --source=HEAD --staged --worktree -- README.md |
git checkout <hash> |
git switch --detach <hash> |
Scripts and old notes still say checkout. Translate them with the table. Type switch and restore yourself.
Switch branches
cd ~/desk/desk-api
git switch main
git switch -c feat/switch-lab
git switch main
git switch -
git branch --show-currentgit switch - uses @{-1}, the checkout you were on before this one. The last command prints feat/switch-lab.
git switch main
git branch -d feat/switch-lab-d deletes a branch whose tip is already reachable from HEAD. You are on main, and feat/switch-lab names that same commit, so the delete succeeds.
A path is not a branch
git switch README.mdGit stops with fatal: invalid reference: README.md. The file is unchanged.
Local edits that would be overwritten
git switch -c feat/switch-lab
echo "other side" >> README.md
git add README.md
git commit -m "lab: other side"
git switch main
echo "main side" >> README.md
git switch feat/switch-labGit aborts. The message still says the files would be overwritten by checkout. README.md on main still ends with main side. feat/switch-lab still has other side.
git restore README.md
git branch -D feat/switch-lab
git status-D deletes a branch even when main does not contain its commits. Use it here to discard the throwaway lab: other side commit. When you need to keep the uncommitted line and still change branches, stash it (chapter 12).
Detached HEAD
git switch --detach HEAD
git switch main--detach points HEAD at a commit and at no branch. Chapter 1 is the trap: a commit made there needs a new branch before you leave it. From a detached HEAD with no new commit, git switch main attaches you again.
The lab next walks one scratch commit through soft, mixed, and hard, then brings it back from the reflog.