iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

checkout / switch

git checkout is the classic Swiss-army knife: switch branches, restore files, view old commits. Modern git split it into switch (branches) and restore (files) for clarity — but checkout still works.

Branches, files, detached HEAD, modern aliases

EXAMPLE
# 1) Switch branches (classic)
git checkout main
git checkout -b feature/auth                  # create + switch
git checkout -b feature/auth main             # branch from main
git checkout -                                # last branch (like cd -)

# 2) Modern equivalent — git switch (clearer semantics)
git switch main
git switch -c feature/auth                    # create + switch
git switch -c feature/auth main
git switch -                                  # last branch
# Won't accidentally restore files; only switches branches.

# 3) Restore a file to HEAD's version
git checkout -- path/to/file.ts
# Discards uncommitted changes in that file.

# Modern equivalent:
git restore path/to/file.ts                    # discard changes
git restore --staged path/to/file.ts           # unstage
git restore --source=HEAD~3 path/to/file.ts    # restore from a specific commit

# 4) Restore everything
git checkout -- .                              # discard ALL working tree changes
git restore .                                  # modern equivalent

# 5) View an old commit (detached HEAD)
git checkout abc1234                          # detaches HEAD
# Now you can:
#   - inspect the old code
#   - create a branch FROM here: git switch -c experiment
#   - return to the previous branch: git switch -

# Detached HEAD warning:
#   'You are in detached HEAD state. You can look around, make experimental changes
#    and commit them, and you can discard any commits you make in this state
#    without impacting any branches.'
#
# If you commit while detached and don't create a branch, those commits become
# unreachable and may be garbage-collected.

# 6) Checkout a specific file from another branch
git checkout main -- path/to/file.ts
# Copies main's version into your current branch (working tree + staging).

# Modern:
git restore --source=main path/to/file.ts

# 7) Checkout a remote branch (track upstream)
git fetch origin
git checkout -b feature/auth origin/feature/auth
# Or simpler:
git checkout feature/auth                      # auto-track if it matches origin/feature/auth

# Modern:
git switch feature/auth

# 8) Checkout a tag (detached)
git checkout v1.4.2
# To work on top of it, create a branch:
git switch -c hotfix v1.4.2

# 9) Inspect file at a specific commit (without switching)
git show abc1234:path/to/file.ts
git show v1.0.0:package.json

# 10) Restore from a specific commit WITHOUT changing HEAD
git checkout abc1234 -- path/to/file.ts
# Brings file content from abc1234 into the current branch.
# HEAD doesn't move; just the file changes.

# 11) Reset vs checkout — common confusion
# git checkout <SHA>          → DETACHES HEAD (doesn't move branch pointer)
# git checkout <branch>        → moves HEAD by switching to <branch>
# git checkout <SHA> -- <file> → only the file changes; HEAD unchanged
# git reset --hard <SHA>       → moves branch pointer to <SHA> + working tree
# git reset <SHA> -- <file>    → unstages; doesn't change working tree

# 12) Common patterns

# a) 'I want to undo changes to a file I haven't committed'
git restore <file>                  # modern
git checkout -- <file>              # classic

# b) 'I want to undo all uncommitted changes'
git restore .
git clean -fd                       # also remove untracked files + directories

# c) 'I want to take the version of a file from main'
git restore --source=main <file>
git checkout main -- <file>

# d) 'I want to view the code as of last week'
git checkout HEAD@{1.week.ago}      # via reflog

# e) 'I want to revert a single file to 3 commits ago'
git checkout HEAD~3 -- <file>

# 13) Branch management with checkout
git checkout --orphan new-root      # create branch with no history (rare; for new root commits)
git checkout --track origin/feature # create local + track
git checkout --detach               # detach HEAD without moving to a SHA
git checkout --force <branch>       # discard local changes + switch (DESTRUCTIVE)

# 14) Pathspec — pattern-based file restore
git checkout HEAD -- 'src/**/*.test.ts'        # restore all test files
git checkout HEAD -- ':(exclude)dist'           # restore everything except dist

# 15) Conflict resolution flags
git checkout --ours <file>          # take OUR version of the conflict
git checkout --theirs <file>        # take THEIR version
git checkout --merge <file>         # re-apply 3-way merge
git checkout --conflict=diff3 <file>  # show all 3 sides in conflict markers

# 16) Modern preferred shortcuts
# git switch <branch>                — switch branches (replaces checkout <branch>)
# git switch -c <branch>              — create + switch (replaces checkout -b)
# git switch -                        — previous branch
# git restore <file>                  — discard changes (replaces checkout -- file)
# git restore --staged <file>         — unstage (replaces reset HEAD -- file)
# git restore --source=<commit> <file> — restore from specific commit

# 17) Common bugs
#   • git checkout <sha> commits → unreachable; recover via git reflog
#   • git checkout -- file followed by typo → no undo (file content is gone)
#   • git checkout <branch> with uncommitted changes that conflict → checkout aborts
#     Fix: commit / stash / restore before switching
#   • Confusing 'checkout file' (uses staged version) with 'checkout HEAD file' (uses committed)

# 18) When checkout is dangerous
#   • git checkout -- . discards EVERYTHING uncommitted — irreversible
#   • git checkout --force <branch> drops local changes — irreversible
#   • Always check git status first
#   • Use git stash to save work before drastic operations

# 19) Reflog rescue — recover lost commits
git reflog
# Shows every HEAD movement, even detached. Each entry is reachable.
git checkout HEAD@{3}              # jump back
git switch -c recovery HEAD@{3}    # save as branch

# 20) Best practices
#   ✅ Prefer git switch + git restore (clearer semantics)
#   ✅ git status before checkout to see what changes
#   ✅ Stash or commit before switching branches with uncommitted work
#   ✅ Use git reflog as your safety net — entries last ~30 days
#   ✅ Never use --force without understanding what it discards
#   ✅ Use --detach explicitly when you mean to inspect, not switch

Why it matters

Modern git split checkout into switch (branches) + restore (files) — clearer intent and harder to misuse. Reflog is your safety net; entries last ~30 days, even for detached-HEAD commits.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
git switch main             # modern
git switch -c feature/login # create + switch
git checkout 1234abc -- file.txt   # restore one file
Try it Yourself »

Discussion

Loading…