Cheatsheet

Git commands you reach for every day

Grouped by what you are trying to do, not by alphabet: the daily loop, the undo table you actually need at 2am, branching, rebasing, worktrees, and the search commands nobody remembers. Every entry is a real command you can paste.

The daily loop

Ninety percent of Git use is these fourteen commands.

Command What it does
git status -sb Short status plus the branch and its upstream tracking state, on one line.
git add -p Stage hunk by hunk. The single best habit for commits that review well.
git add -A Stage every change in the whole repo, including deletions and new files.
git commit -m "message" Commit whatever is staged, with an inline message.
git commit -am "message" Stage all modified tracked files and commit. Ignores untracked files.
git commit --amend --no-edit Fold the staged changes into the previous commit and keep its message.
git diff Unstaged changes: working tree compared to the index.
git diff --staged Staged changes: index compared to HEAD. This is what your commit will contain.
git diff main...feature Everything feature added since it forked from main. What a pull request shows.
git diff --stat Files changed with insertion and deletion counts, no diff body.
git pull --rebase Fetch, then replay your local commits on top. No merge bubble in the history.
git push -u origin HEAD Push the current branch under its own name and set the upstream at once.
git push --force-with-lease Force push that refuses if the remote moved since your last fetch.
git fetch --all --prune Refresh every remote and delete local refs for branches deleted upstream.
git log --oneline --graph --decorate -20 Compact visual history of the last twenty commits with refs marked.

Gotcha: two dots and three dots are not the same. main..feature compares the two tips; main...feature compares against the merge base, which is the diff a code review shows you.

Undo anything

Find the row that matches the mistake. The commands are ordered from least to most destructive.

Command Undoes
git restore file.ts Unstaged edits to one file. Modern replacement for checkout on paths.
git restore . Every unstaged edit in the tree. Staged work survives.
git restore --staged file.ts An accidental add. The file goes back to modified but unstaged.
git restore --source=HEAD~2 file.ts Pulls one file back to how it looked two commits ago.
git commit --amend A bad commit message or a forgotten file in the last commit.
git reset --soft HEAD~1 The commit only. All of its changes stay staged, ready to recommit.
git reset HEAD~1 The commit and the staging. Changes remain in the working tree. The default.
git reset --hard HEAD~1 The commit and every change in it. Nothing is left behind.
git revert HEAD The last commit, via a new commit that reverses it. Safe on shared branches.
git revert -n abc123..def456 A range of commits, staged as one change set for you to commit yourself.
git revert -m 1 abc123 A merge commit, keeping the first parent as mainline.
git reflog Nothing by itself: it lists every position HEAD has held, including "lost" commits.
git reset --hard HEAD@{2} A bad reset or rebase, by jumping to a reflog position from before it.
git switch - A wrong checkout: returns you to the previous branch.
git rm --cached secrets.env Tracking a file you should not have added, without deleting it from disk.
git clean -nd Dry run: lists the untracked files and directories a clean would delete.
git clean -fd Deletes every untracked file and directory for real.

Gotcha: the reflog can recover almost anything that was ever committed, and it keeps entries for 90 days by default. It cannot recover what was never committed, which is exactly what git reset --hard and git clean -fd destroy. Run git stash push -u first if you are unsure.

Branching and merging

Command What it does
git switch main Check out an existing branch. Clearer than the overloaded checkout command.
git switch -c feature/login Create a branch from the current HEAD and switch to it.
git switch -c hotfix origin/main Branch straight off a remote ref without checking that ref out first.
git switch --detach v1.4.0 Detached HEAD at a tag, for reading old code without creating a branch.
git branch -vv Local branches with their upstreams and ahead/behind counts.
git branch -m old-name new-name Rename a branch. Drop the first argument to rename the current one.
git branch --merged main Branches already merged into main, so the safe-to-delete list.
git branch -d feature Delete a branch, refusing if it has unmerged commits.
git branch -D feature Delete a branch even when it is unmerged. The reflog still has the commits.
git push origin --delete feature Delete the branch on the remote.
git merge --no-ff feature Always write a merge commit, so the branch shape survives in history.
git merge --squash feature Stage the branch's whole result as one uncommitted change set.
git merge --abort Back out of a conflicted merge and restore the pre-merge state.
git checkout --ours file.ts During a conflict, take your side of a file wholesale. Use --theirs for the other.

Gotcha: during a rebase, ours and theirs are swapped relative to a merge. In a rebase, "ours" is the branch you are replaying onto, and "theirs" is your own commit being replayed.

Rebase and history surgery

Command What it does
git rebase main Replay the current branch's commits on top of main.
git rebase -i HEAD~5 Interactive rebase: reword, squash, fixup, edit, drop, or reorder five commits.
git rebase --onto main old-base feature Move only feature's own commits onto main, dropping the old base entirely.
git rebase --continue Resume after you staged the resolution of a conflict.
git rebase --skip Drop the commit being applied and carry on.
git rebase --abort Cancel the rebase and put the branch back exactly where it was.
git commit --fixup abc123 Record a commit tagged as a fixup for abc123, to be squashed later.
git rebase -i --autosquash HEAD~10 Automatically order and mark every fixup commit for squashing.
git cherry-pick abc123 Copy a single commit from anywhere onto the current branch.
git cherry-pick -x abc123 Same, but records the source hash in the message. Use this for backports.
git cherry-pick --abort Give up on a conflicted cherry-pick and restore the previous state.
git rebase --exec "npm test" main Run a command after each replayed commit to find where a suite broke.

Gotcha: rebasing rewrites hashes, so never rebase a branch other people have already pulled. If you must, warn them and have them run git pull --rebase instead of a plain pull. Turn on rerere if you rebase the same long branch repeatedly.

Worktrees for parallel checkouts

A worktree is a second working directory backed by the same repository. It beats stashing when a hotfix lands in the middle of a feature, and it lets a long build and a code review run side by side.

Command What it does
git worktree add ../hotfix hotfix Check the existing hotfix branch out into a sibling directory.
git worktree add -b fix ../fix main Create branch fix from main and check it out in a new directory.
git worktree add --detach ../review abc123 Inspect an arbitrary commit with no branch and no effect on your work.
git worktree list Every worktree with its path, HEAD, and checked out branch.
git worktree list --porcelain The same listing in a stable machine readable format for scripts.
git worktree remove ../hotfix Delete a clean worktree and its administrative files.
git worktree remove --force ../hotfix Remove it even with modified or untracked files present.
git worktree move ../fix ../fix-2 Relocate a worktree so Git keeps the bookkeeping in sync.
git worktree prune Clean up records for worktree directories you deleted by hand.
git worktree lock --reason "on USB" ../fix Stop a worktree from being pruned while its disk is disconnected.
git worktree repair Fix the two way links after you moved the repo or a worktree manually.

Gotcha: a branch can be checked out in only one worktree at a time, so git worktree add refuses duplicates unless you pass --force. Worktrees share one object database, so they are cheap on disk, but each one needs its own dependency install.

Stashing work in progress

Command What it does
git stash push -m "wip login" Stash tracked changes under a label you will recognize tomorrow.
git stash push -u Include untracked files, which a plain stash leaves behind.
git stash push -- src/app.ts Stash only the listed paths and keep working on the rest.
git stash list Show the stash stack, newest first.
git stash show -p stash@{1} Full patch for one stash entry before you apply it.
git stash pop Apply the newest stash and remove it from the stack.
git stash apply stash@{2} Apply an older stash and keep it in the stack.
git stash branch fix stash@{0} Branch off the commit the stash was made on, then apply it there.
git stash drop stash@{0} Delete one entry from the stack.
git stash clear Delete every stash. Recoverable only through the reflog, and only briefly.

Gotcha: a stash that conflicts on pop is applied but not dropped, so the entry is still there once you resolve. Check git stash list afterwards rather than assuming it is gone.

Finding when and why something changed

Command What it does
git log -S"createUser" Pickaxe search: commits that changed how many times a string appears.
git log -G"use[A-Z]\w+" Commits whose diff text matches a regular expression.
git log --follow -- src/db.ts History of one file, following it through renames.
git log --since="2 weeks ago" --author=rj Filter history by date range and author substring.
git log main..origin/main What you are about to pull: commits upstream has that you do not.
git blame -L 40,60 src/db.ts Who last touched lines 40 to 60, and in which commit.
git blame -w -C src/db.ts Blame that ignores whitespace and follows lines copied from other files.
git show abc123:src/db.ts Print a file exactly as it existed in one commit, without checking it out.
git bisect start HEAD v1.2.0 Begin a binary search between a known bad and a known good commit.
git bisect run npm test Automate the search with any command that exits non-zero when broken.
git bisect reset End the session and return to where you started.
git grep -n "TODO" v1.2.0 Grep the tree at any ref with line numbers, far faster than a checkout.

Remotes, tags, and config worth setting

Command What it does
git remote -v List remotes with their fetch and push URLs.
git remote add upstream URL Add the original repo as a second remote. The standard fork setup.
git remote set-url origin URL Repoint a remote, for example moving from HTTPS to SSH.
git tag -a v1.2.0 -m "Release 1.2.0" Create an annotated tag, which stores an author, date, and message.
git push origin v1.2.0 Push one tag. A plain push never sends tags.
git push --follow-tags Push commits plus the annotated tags reachable from them.
git describe --tags Human readable version string for the current commit, based on tags.
git config --global init.defaultBranch main Name the first branch of every new repository main.
git config --global pull.rebase true Make pull rebase by default and stop the accidental merge commits.
git config --global rerere.enabled true Record conflict resolutions and replay them the next time they recur.
git config --global fetch.prune true Delete stale remote tracking branches on every fetch, automatically.
git maintenance start Schedule background prefetch and repacking to keep a big repo fast.

Gotcha: per-repo config beats global config, so a repository with its own .git/config entry will ignore your global default. Run git config --list --show-origin when a setting seems to be lying to you.

Aliases worth pasting into your config

Drop these into the [alias] block of your global gitconfig.

[alias]
    s     = status -sb
    lg    = log --oneline --graph --decorate -20
    last  = log -1 HEAD --stat
    unstage = restore --staged
    amend = commit --amend --no-edit
    wip   = !git add -A && git commit -m "wip"
    undo  = reset --soft HEAD~1
    pushf = push --force-with-lease
    cleanup = !git branch --merged main | grep -v main | xargs -r git branch -d

Gotcha: an alias starting with ! runs as a shell command from the repository root, not from your current directory. That is why the cleanup alias above works no matter how deep you are.

Keep going

Shipping the code Git is tracking usually means a container and a package manager: the Docker cheatsheet covers the build and run side, and the npm, pnpm, and bun mapping covers installs and workspaces.

More quick references live in the cheatsheet index, and the tool directory maps out what to reach for at each layer of a stack.