Git cheat sheet
Status: đźź© COMPLETE Last updated: 2026-06-21 Plain-English tagline: Daily-use Git commands grouped by intent. For the why, read Git basics.
Setup (once per machine)
git config --global user.name "George"
git config --global user.email "you@example.com"
git config --global init.defaultBranch main
git config --global core.autocrlf true # Windows
git config --global pull.rebase false # use merge for pulls (default)
git config --global core.editor "code --wait" # VS Code as Git editorSee what changed
git status # what's modified, staged, untracked
git diff # unstaged changes (vs working dir)
git diff --staged # staged but uncommitted changes
git diff main feature/x # difference between two branches
git diff HEAD~1 # what changed since the previous commit
git log --oneline -10 # last 10 commits, one line each
git log --graph --oneline --all # full history as ASCII graph
git blame <file> # who changed each line of a file
git show <hash> # everything about one commitStage and commit
git add <file> # stage one file
git add . # stage everything in current folder
git restore --staged <file> # unstage (move back to working dir)
git commit -m "Add dark mode toggle" # commit with a one-line message
git commit -m "Add X" -m "Longer explanation." # two -m flags = title + body
git commit --amend -m "Better message" # rewrite the last commit (local only)
git commit --no-verify -m "..." # skip pre-commit hooks (use sparingly)Branches
git branch # list local branches
git branch -a # include remote branches
git switch main # switch to existing branch
git switch -c feature/dark-mode # create AND switch
git branch -m new-name # rename current branch
git branch -d feature/old # delete (must be merged)
git branch -D feature/old # force-delete (even if unmerged)
git push origin --delete feature/old # delete on the remoteSync with the remote
git fetch # download remote changes, don't apply
git pull # fetch + merge in one step
git pull --rebase # fetch + rebase instead of merge
git push # push current branch
git push -u origin feature/x # first push: set upstream
git push --force-with-lease # force push, but refuse if remote moved
git push origin --delete feature/x # delete the remote branchMerge and rebase
git merge feature/x # merge feature/x INTO current branch
git merge --abort # back out of a failed merge
git rebase main # replay current branch onto main's tip
git rebase --continue # after fixing a conflict during rebase
git rebase --abort # back out of a rebase
git rebase -i HEAD~5 # interactive: squash, reorder, drop, rewordUndo
git restore <file> # discard unstaged changes to a file
git reset HEAD~1 # uncommit last; keep changes (unstaged)
git reset --soft HEAD~1 # uncommit last; keep changes (staged)
git reset --hard HEAD~1 # uncommit last; THROW AWAY changes
git revert <hash> # NEW commit that undoes <hash> (safe for pushed)
git reflog # see history of where HEAD has been
git reset --hard <hash-from-reflog> # recover from "I lost work"Stash (set aside uncommitted work)
git stash # tuck away uncommitted changes
git stash list # see what's stashed
git stash pop # apply most recent stash + remove
git stash apply stash@{2} # apply a specific stash without removing
git stash drop stash@{0} # delete a specific stash
git stash clear # delete all stashesRemotes
git remote -v # list remotes
git remote add origin https://github.com/u/r.git # add a remote
git remote set-url origin git@github.com:u/r.git # change a remote URL
git remote remove origin # removeClone / fresh start
git clone https://github.com/u/r.git # full clone (HTTPS)
git clone git@github.com:u/r.git # via SSH
git clone --depth 1 https://github.com/u/r.git # shallow clone (faster)
git clone -b feature/x https://github.com/u/r.git # clone a specific branchCommon workflows
A fresh feature, start to merge
git switch main
git pull
git switch -c feature/dark-mode
# ... work ...
git add lib/theme.ts components/Navbar.tsx
git commit -m "Add dark mode toggle"
git push -u origin feature/dark-mode
# (open PR via GitHub UI or `gh pr create`)
# (after PR is merged)
git switch main
git pull
git branch -d feature/dark-mode”I broke something — get me back"
git reflog # find a recent good commit
git reset --hard <hash> # snap back"I committed to the wrong branch"
git branch feature/x # create the branch you meant
git reset --hard HEAD~1 # move current branch back one
git switch feature/x # your work is now on feature/x"I want a clean linear history before opening a PR”
git rebase -i HEAD~5 # squash/reorder commits
git push --force-with-lease # update the remoteCommon gotchas
.env*files in Git history are leaked even if you delete them later. Add to.gitignoreBEFORE the first commit.git push --forceoverwrites teammates’ work. Use--force-with-leaseinstead.git reset --harddiscards uncommitted changes permanently. Stash first if uncertain.git add .can stage secret files you didn’t mean to commit. Alwaysgit statusbefore committing.git checkoutis overloaded — switches branches AND discards file changes. Prefergit switchandgit restorefor clarity.- Detached HEAD lets commits get lost. If
git checkout <hash>warns you, create a branch before committing:git switch -c rescue-branch. git commit -askips staging review. Convenient but bypasses the “review what’s in this commit” benefit.- Windows line endings (CRLF) vs Unix (LF). Use
git config core.autocrlf trueon Windows to avoid spurious “whole file changed” diffs.
See also
- Git basics 🟩 — the textbook
- Branches & merging đźź©
- Rebase vs merge đźź©
- Resolving merge conflicts đźź©
- Git rescue moves 🟩 — full rescue toolkit
- Common errors: Git errors 🟩 — paste-and-fix lookup
- gh CLI cheat sheet 🟩 — GitHub-specific operations
Sources
- Pro Git book (free) — canonical reference
- GitHub’s Git cheat sheet (PDF)
- Oh Shit, Git!?! — rescue scenarios in plain language