Cheat Sheet

Git Quick Reference

The four places a change can live, then the commands that move it between them, with the gotcha for each. Commands were run on Git 2.43 in a scratch repository.

4
Places
2.43
Git tested
9
Groups
Index ยท Spring ยท SQL ยท Git ยท Docker/kubectl ยท Kafka/Rabbit CLI ยท Redis ยท Big-O
01
Chapter 1 - The four places

Mental Model

Almost every Git command moves changes between four places. When a command surprises you, ask which two places it connects.

Where your change lives: four places
Working tree files on disk Index (staging) next commit Local repo commits, branches Remote origin/main add commit push fetch reset --soft restore --staged restore: index/repo to working tree. reset --mixed: repo to index. reset --hard: repo to index and working tree. pull = fetch + merge (or rebase). checkout/switch move HEAD.
02
Chapter 2 - Everyday

Daily Commands

Checked on Git 2.43 in a scratch repository.

CommandWhat it doesGotcha
git status -sShort status: staged and unstaged changesTwo letters: first = index, second = working tree
git add -pStage hunk by hunkThe best way to keep commits focused
git add -AStage everything including deletionsWill stage secrets and build output if not ignored
git commit -m "msg"Commit the staged changes-a stages tracked files only; it ignores new files
git commit --amend --no-editFold staged changes into the last commitRewrites the commit; do not do it after pushing shared work. With nothing changed it refuses unless --allow-empty
git diffWorking tree vs indexShows nothing for staged changes: use git diff --staged
git diff --stagedIndex vs last commitAlso called --cached
git diff A..B / A...BTwo dots: A to B. Three dots: B since the common ancestorThree dots is what a pull request shows
git diff --name-only HEAD~1List changed files since the previous commitAdd --stat for sizes
git log --oneline --graph --decorate --allCompact history of every branchDefine it as an alias
git log -p -- pathHistory of one file with patchesAdd --follow to continue across renames (single file)
git show <rev>:pathPrint a file as it was at a revisionWorks with main:a, HEAD~2:a, v1:a
git blame -L 10,20 fileWho last changed lines 10 to 20-w ignores whitespace, -C follows moved lines
git rm --cached fileStop tracking a file but keep it on diskAlso add it to .gitignore; .gitignore does not affect tracked files
git clean -n / -fdPreview / delete untracked filesAlways run with -n first; -x also removes ignored files
git mv old newRename and stageGit detects renames; there is no real rename record
03
Chapter 3 - Branching

Branches and Switching

switch (branches) and restore (files) split the old overloaded checkout.

CommandWhat it doesGotcha
git switch nameMove to a branchFails if local changes would be overwritten
git switch -c name [start]Create and switch (optionally from a start point)git switch -c x HEAD~1 branches from the previous commit
git switch -Back to the previous branchLike cd -
git switch --detach <rev>Look at a commit without a branchNew commits here are lost unless you create a branch
git branch -vvList branches with upstream and last commitShows gone for branches deleted on the remote
git branch --show-currentPrint the current branch nameEmpty when detached
git branch -d name / -D nameDelete merged / delete regardless-D can lose commits; they remain in the reflog for a while
git branch -m newRename the current branchUpdate the remote and upstream yourself
git branch --merged mainBranches already merged into mainGood for cleanup
git merge nameMerge into the current branch--no-ff always creates a merge commit; --ff-only refuses otherwise
git merge --squash nameStage the combined changes without committingLoses the individual commits and the merge link; commit yourself
git merge --abortBack out of a conflicted mergeOnly while the merge is in progress
git cherry-pick -x <rev>Copy a commit onto the current branch-x records the original id; duplicate commits cause conflicts on later merges
04
Chapter 4 - Undoing

Restore, Reset, Revert, Reflog

Choose by what you want to undo and whether the commit is already shared.

GoalCommandTouchesGotcha
Discard changes in a filegit restore fileWorking treeCannot be undone: the changes were never saved
Unstage a filegit restore --staged fileIndexWorking tree keeps your edits
Get a file from another revisiongit restore --source=HEAD~1 fileWorking treeAdd --staged to also stage it
Undo last commit, keep changes stagedgit reset --soft HEAD~1Moves the branch onlyGood for re-doing the commit message or splitting
Undo last commit, keep changes unstagedgit reset --mixed HEAD~1 (default)Branch and indexNew files stay untracked
Undo last commit, throw changes awaygit reset --hard HEAD~1Branch, index, working treeUncommitted work is gone; committed work is recoverable via reflog
Undo a commit already pushedgit revert <rev>Adds a new commitSafe on shared branches; reverting a merge needs -m 1
Find a "lost" commitgit reflogRead onlyLocal only; entries expire (by default after weeks), and gc can then remove the commits
Recover a deleted branchgit switch -c name <sha from reflog>New branchDo it soon
Stop a bad rebasegit rebase --abortRestores the pre-rebase stateOnly before it finishes; afterwards use git reset --hard ORIG_HEAD or the reflog
Move a branch pointergit reset --hard <rev>Rewrites the branchNever on commits others have pulled
05
Chapter 5 - Rebase vs merge

Combining Work

Both integrate branches. Merge records that a join happened; rebase replays your commits on a new base.

QuestionMergeRebase
History shapeKeeps true history with a merge commitLinear history
Commit idsUnchangedReplayed commits get new ids
Safe on pushed branchesYesNo, unless everyone agrees; push with --force-with-lease afterwards
ConflictsResolve onceMay resolve per replayed commit (git rerere can remember)
Typical useLand a feature into mainUpdate your own feature branch on top of main, tidy local commits
Commandgit merge maingit rebase main
Rebase part of a branchnot applicablegit rebase --onto newbase oldbase branch
Tidy commitsnot applicablegit rebase -i HEAD~5 (squash, reword, drop, reorder)
Auto-squash fixupsnot applicablegit commit --fixup <rev> then git rebase -i --autosquash <base>
After rebasing pushed worknot applicablegit push --force-with-lease, which refuses if the remote moved
06
Chapter 6 - Stash, tags, bisect, worktree

Everything Else Local

Small tools that save big time.

CommandWhat it doesGotcha
git stash push -m "wip"Shelve tracked changesUntracked files need -u; ignored need -a
git stash list / pop / applyList; restore and drop; restore and keeppop with conflicts keeps the stash entry
git stash show -p stash@{0}See what is in a stashStash is a stack, index 0 is the newest
git tag -a v1 -m "release"Annotated tag (has author, date, message)Prefer it over lightweight tags for releases
git tag -l 'v*'List tags matching a patternQuote the pattern
git push origin v1 / --tagsPublish a tag / all tagsTags are not pushed by plain git push
git tag -d v1; git push origin --delete v1Delete locally; delete on the remoteTwo steps
git bisect start / bad / good <rev>Binary search for the commit that broke somethingFinish with git bisect reset
git bisect run ./test.shAutomate itScript exit 0 = good, 1 to 127 except 125 = bad, 125 = skip
git worktree add ../wt branchCheck out another branch in a second folderA branch can be checked out in only one worktree
git worktree list / remove ../wtList; delete a worktreeDeleting the folder by hand needs git worktree prune
git range-diff A..B C..DCompare two versions of a rebased seriesUseful in reviews of force-pushed branches
07
Chapter 7 - Remotes

Fetch, Pull, Push

Remote branches are local copies named origin/main, updated only when you fetch.

CommandWhat it doesGotcha
git clone urlCopy a repository and set origin--depth 1 makes a shallow clone; some history commands fail
git remote -vList remotesFetch and push URLs can differ
git fetch --pruneDownload new commits and drop deleted remote branchesChanges no local branch
git pull --rebaseFetch, then rebase local commitsPlain pull merges by default unless configured; set pull.rebase
git pull --ff-onlyFetch and fast-forward onlyFails (safely) if histories diverged
git push -u origin namePush and set upstreamWith push.autoSetupRemote plain git push does this on first push
git push --force-with-leaseForce push only if the remote is where you last saw itPlain --force can erase teammates' commits
git push origin --delete nameDelete a remote branchTeammates keep a stale origin/name until they fetch --prune
git ls-remote --tags originList remote tags without fetchingHandy in CI
git remote set-url origin urlChange a remote URLCheck HTTPS vs SSH and which account owns it
08
Chapter 8 - Search history

Finding Things

Three different searches, easy to confuse.

CommandWhat it doesGotcha
git log -S"text"Commits that changed the number of occurrences of text (pickaxe)Good for "when was this line added or removed"
git log -G"regex"Commits whose diff matches a regexSlower, finds modifications too
git log --grep="fix"Search commit messages-i for case-insensitive
git log --author="name"Filter by authorMatches a pattern, not an exact name
git log --since="2 weeks ago"Filter by dateAlso --until
git shortlog -snCommit counts per authorAdd --no-merges for fairness
git grep -n "text"Search tracked files in the working treeAdd a revision to search history snapshots
git rev-parse --abbrev-ref HEADCurrent branch name for scriptsPrints HEAD when detached
09
Chapter 9 - Config

Config and Aliases

Set these once per machine. Each was accepted by Git 2.43 in a scratch repository; check git help config for the minimum version of a key on your install (for example push.autoSetupRemote needs Git 2.37 or newer).

Useful config and aliases (each key was accepted by Git 2.43 in a test repository)
$ git config --global pull.rebase true # pull = fetch + rebase $ git config --global fetch.prune true # drop deleted remote branches on fetch $ git config --global push.autoSetupRemote true # first push sets upstream (Git 2.37+) $ git config --global rerere.enabled true # remember conflict resolutions $ git config --global rebase.autoSquash true # honour fixup! commits in rebase -i $ git config --global rebase.autoStash true # stash around rebase automatically $ git config --global merge.conflictStyle zdiff3 # show the base in conflict markers $ git config --global diff.algorithm histogram $ git config --global init.defaultBranch main $ git config --global branch.sort -committerdate $ git config --global alias.lg "log --oneline --graph --decorate --all" $ git config --global alias.st "status -s" $ git config --global --list
10
Chapter 10 - Common mistakes

Git Mistakes

โš  The ones that cost real time
  • **git reset --hard with uncommitted work.** It cannot be recovered; stash first.
  • Rebasing a branch others have pulled. Their history diverges; use merge, or agree and use --force-with-lease.
  • **git push --force.** Use --force-with-lease.
  • Committing secrets, then deleting them in a later commit. They stay in history; rotate the secret and rewrite or purge history.
  • **.gitignore on an already tracked file.** It does nothing; run git rm --cached first.
  • Working on a detached HEAD and switching away. The commits become reachable only through the reflog; create a branch first.
  • **Reverting a merge commit without -m 1.** Git does not know which parent to keep.
  • **git pull creating surprise merge commits.** Set pull.rebase or use --ff-only.
  • **git add -A at the repository root.** Look at git status first.
11
Chapter 11 - Go deeper

Long-form pages and what was checked

TopicPage
CI pipelines that run on push and pull requestsCI/CD Pipelines
Shell habits used with GitLinux & Shell Essentials
Release and rollout strategiesDeployment Strategies
More cheat sheetsAll cheat sheets
Version note

Checked on 2026-10-31 on Git 2.43.0: every command shape in chapters 2 to 8 (switch, restore, reset soft and mixed and hard, revert, reflog, stash push and pop, annotated tags, bisect, worktree add and list and remove, rebase --onto, amend, cherry-pick, range-diff, pickaxe search, branch and config commands) was run in a throw-away repository; conflict-resolution flows and remote commands (push, force-with-lease, clone) were not exercised against a real server and are listed from the documented behaviour. Config keys were accepted by git config, which does not prove their semantics; the one-line meanings follow the Git documentation. There is no long-form Git page on this site yet.