Lesson 6 of 6 in Undoing Things

In the wild

Story: The agency's oldest field manuals were written before your time. Learn to read them.

Until 2019, git had no switch and no restore. One command did both jobs: git checkout. It's still everywhere, in older tutorials, in answers online, in scripts and in your colleagues' fingers. It still works, so you need to be able to read it.

You'll see What it does The modern way
git checkout <branch> switches to a branch git switch <branch>
git checkout -b <name> creates a branch and switches to it git switch -c <name>
git checkout -b <name> <start> the same, starting at another branch or commit git switch -c <name> <start>
git checkout -- <file> throws away the unstaged changes to a file git restore <file>

In your own work, prefer switch and restore. When you meet checkout, translate it with this table.

One command, two jobs

git checkout works out what you meant from the name you give it. A branch name means "switch to it". A file or folder name means "throw away my changes to it". That's handy until a name is both.

If a branch and a file or folder share a name, a plain git checkout <name> picks the branch. You meant to throw away your edits, and instead you've switched branches, with your edits still there.

-- ends the guessing. Everything after it is a file or folder, never a branch:

git checkout -- docs

This always restores the docs folder, even when there's also a branch called docs. That's why careful guides always write the --, and why git 2.23 split checkout into switch and restore: each does one job, so neither can be mistaken for the other.

checkout -- copies from the index

Like git restore <file>, git checkout -- <file> copies the file from the index over your working tree. A change you've staged stays staged, and only the edits on top of it are thrown away.

And like git restore, it destroys work without asking. An unstaged edit it overwrites was never stored anywhere else, so it's gone.

Other forms you may meet

  • git checkout <commit> switches to a commit instead of a branch, leaving HEAD detached. Here, use git switch --detach <commit>.
  • Some older guides unstage with git reset HEAD <file>. Today git status suggests git restore --staged <file>, which does the same.

New commands

  • git checkout
  • git checkout -b
  • git checkout --

Explainer: Checkout, the older way to switch and restore

project: your repo, you are here2a3cb2b Write the menu2a3cb2bfa3d3f1 List the drinksfa3d3f1mainHEAD → dessertsdrinks
The repository at the end of the Explainer.
Graph as text

project: your repo, you are here

  • HEAD → desserts at fa3d3f1 "List the drinks"

Branches and tags

  • desserts at fa3d3f1 "List the drinks"
  • drinks at fa3d3f1 "List the drinks"
  • main at 2a3cb2b "Write the menu"

Commits, newest first

  1. fa3d3f1 "List the drinks"; parent 2a3cb2b; refs: HEAD → desserts, drinks
  2. 2a3cb2b "Write the menu"; no parent; refs: main

Challenge 1 of 3

Story: The Archivist's field manual predates switch. Follow it to the letter.

An older guide on your team's wiki uses git checkout. Follow it: create a branch called fix-hours that starts at the last commit on drafts, and switch to it. You're on main now.

Unlocks after Branching & Merging.

Terminal

Unlocks after Branching & Merging.

This Lesson can be played once Branching & Merging is complete. Its text and Explainer are open to everyone.