G18 · Part 4 · Mastery
Cheat sheet
Every command worth knowing, grouped by the job you're doing, plus the setup to run once per machine.
14On this page
One-time setup on a new machine
Worth doing properly, once. These settings remove most everyday friction: no more "set upstream" errors, clearer conflicts, remembered resolutions and pruned remote branches.
git config --global user.name "Your Name"
git config --global user.email "you@company.com"
git config --global init.defaultBranch main
git config --global pull.rebase true
git config --global push.autoSetupRemote true
git config --global push.followTags true
git config --global fetch.prune true
git config --global merge.conflictStyle zdiff3
git config --global rerere.enabled true
git config --global rebase.autoSquash true
git config --global rebase.updateRefs true
git config --global diff.algorithm histogram
git config --global branch.sort -committerdate
git config --global core.editor "code --wait"
git config --global alias.lg "log --oneline --graph --decorate --all"
git config --global alias.st "status -sb"
git config --global alias.last "log -1 --stat"
git config --global alias.unstage "restore --staged"
git config --global alias.please "push --force-with-lease --force-if-includes"
Check where any setting comes from with git config --show-origin --get pull.rebase,
and list everything with git config --list --show-origin.
Which undo do I need?
Setup and config
| Command | Does |
|---|---|
git init | Start a repository in the current folder |
git clone <url> | Copy a remote repository with its full history |
git clone --filter=blob:none <url> | Clone all history, fetch file contents on demand |
git clone --depth 1 <url> | Latest commit only, for CI |
git config --global <key> <value> | Set an option for every repository you use |
git config --list --show-origin | Every setting, and the file it came from |
git config get / set / unset / list | The same jobs as the flag forms, as subcommands (Git 2.46 and later) |
git help <command> | The full manual page |
Inspect
| Command | Does |
|---|---|
git status -sb | Compact state: branch, ahead or behind, changed files |
git diff | Unstaged changes |
git diff --staged | Exactly what the next commit will contain |
git diff main...HEAD | What your branch changed since it left main |
git log --oneline --graph --all | The whole commit graph, one line per commit |
git log -p -- <file> | Every change to one file, with diffs |
git log main..feature | Commits on feature that main doesn't have |
git show <sha> | One commit's message and diff |
git show <sha>:path/file | A file as it was at that commit |
git shortlog -sn | Commit counts per author |
Stage and commit
| Command | Does |
|---|---|
git add <file> | Stage a file |
git add -p | Stage hunk by hunk |
git commit -m "..." | Commit the staged changes |
git commit -v | Write the message with the diff in view |
git commit --amend | Replace the last commit (unpushed only) |
git commit --amend --no-edit | Add staged changes to the last commit, keep the message |
git commit --fixup=<sha> | A fix to be squashed into an earlier commit |
git commit -s | Add a Signed-off-by trailer |
git commit -S | Sign the commit with your GPG or SSH key |
git rm --cached <file> | Stop tracking a file, keep it on disk |
git mv <old> <new> | Rename, including case-only renames |
Branch
| Command | Does |
|---|---|
git branch -vv | Local branches with their upstream and ahead or behind counts |
git switch <name> | Move to a branch |
git switch -c <name> | Create a branch and move to it |
git switch - | Back to the previous branch |
git switch --detach <sha> | Look at an old commit without a branch |
git branch -m <new> | Rename the current branch |
git branch -d <name> | Delete a merged branch |
git branch -D <name> | Delete even if unmerged |
git branch --merged main | Branches already merged, safe to delete |
Remote
| Command | Does |
|---|---|
git remote -v | List remotes and their URLs |
git remote add upstream <url> | Add a second remote, such as the original of a fork |
git fetch --prune | Download new commits, drop refs deleted on the remote |
git pull | Fetch, then merge or rebase into the current branch |
git push | Send the current branch to its upstream |
git push -u origin <branch> | First push, and set the upstream |
git push --force-with-lease | Force-push without overwriting commits you haven't seen |
git push origin --delete <branch> | Delete a remote branch |
Merge and rebase
| Command | Does |
|---|---|
git merge <branch> | Merge into the current branch, fast-forward if possible |
git merge --no-ff <branch> | Always record a merge commit |
git merge --squash <branch> | Stage the branch's changes as one commit |
git merge --abort | Back out of a conflicted merge |
git rebase main | Replay your commits on top of main |
git rebase -i <base> | Squash, reword, reorder or drop commits |
git rebase --onto <new> <old> | Move a branch from one base to another |
git rebase --continue / --abort | Carry on after resolving, or give up and restore |
git cherry-pick -x <sha> | Copy one commit here, noting the original hash |
git checkout --ours / --theirs <file> | Take one side of a conflicted file |
Undo
| Command | Does |
|---|---|
git restore <file> | Discard unstaged edits to a file |
git restore --staged <file> | Unstage, keep the edits |
git restore --source=<sha> <file> | Bring back a file as it was at a commit |
git reset --soft HEAD~1 | Undo the last commit, keep its changes staged |
git reset HEAD~1 | Undo the last commit, keep its changes unstaged |
git reset --hard <sha> | Move the branch and discard all uncommitted work |
git revert <sha> | New commit that undoes a pushed one |
git revert -m 1 <merge> | Undo a whole merge |
git reflog | Every place HEAD has been: find "lost" commits |
git reset --hard ORIG_HEAD | Undo the merge, rebase or reset you just did |
git clean -nd | Preview which untracked files clean -fd would delete |
Investigate
| Command | Does |
|---|---|
git blame -w -C <file> | Who last changed each line, ignoring whitespace and moves |
git blame -L 40,60 <file> | Blame just those lines |
git log -S "text" | Commits that added or removed that string |
git log -G "regex" | Commits whose diff matches a pattern |
git log -L :funcName:file | History of one function |
git log --follow <file> | A file's history through renames |
git grep "text" <sha> | Search the files of any commit |
git bisect start, good, bad | Binary-search for the commit that broke something |
git bisect run <cmd> | Let a script mark each step |
git merge-base main HEAD | Where your branch left main |
Stash and worktrees
| Command | Does |
|---|---|
git stash -u | Park all changes, including untracked files |
git stash push -m "msg" <file> | Stash specific files with a label |
git stash list | Show stashes |
git stash pop | Reapply the latest stash and drop it |
git stash apply stash@{2} | Reapply a stash and keep it |
git stash branch <name> | Turn a stash into a branch |
git worktree add ../hotfix main | A second working folder on another branch, no stashing |
git worktree list / remove <dir> | Manage extra worktrees |
Tags and releases
| Command | Does |
|---|---|
git tag -a v1.2.0 -m "msg" | Annotated tag, the kind to use for releases |
git tag -s v1.2.0 -m "msg" | Signed annotated tag |
git tag -l "v1.*" | List matching tags |
git push origin v1.2.0 | Push one tag |
git push --follow-tags | Push commits plus annotated tags that point at them |
git describe --tags --always | Label like v1.2.0-3-g8f2c9d1 for builds |
git tag -v v1.2.0 | Verify a tag's signature |
git tag -d v1.2.0 then git push origin --delete v1.2.0 | Delete a tag locally and on the remote |
git log v1.1.0..v1.2.0 --oneline | What changed between two releases |
Newer commands worth knowing
| Command | Does | Since |
|---|---|---|
git switch, git restore | Branches and files as two separate commands | 2.23 |
git diff --merge-base main | Your work, including uncommitted edits, against where you left main | 2.30 |
git push --force-with-lease --force-if-includes | Force-push that also refuses remote commits you never integrated | 2.30 |
git maintenance start | Schedule background upkeep for a big repository | 2.31 |
git log --remerge-diff | Show only what a person changed while resolving a merge | 2.36 |
git sparse-checkout set <dirs> | Only these folders on disk (cone mode is the default) | 2.37 |
git rebase --update-refs | Move every branch in a stack in one rebase | 2.38 |
git merge-tree --write-tree a b | Test a merge without touching your files | 2.38 |
git worktree add --orphan -b <name> <dir> | A new worktree on a branch with no history | 2.42 |
git replay --onto <base> <range> | Rebase without a working tree, for servers and tools (experimental) | 2.44 |
git refs migrate --ref-format=reftable | Move an existing repository to the reftable backend | 2.46 |
git clone --revision=<rev> --depth 1 | Exactly one commit, for a reproducible build | 2.49 |
git backfill | Fill in a blobless clone's history in batches (experimental) | 2.49 |
How to actually learn this
- Make a throwaway repository today. Break it on purpose: hard reset too far, force-push over yourself, create a conflict. Recover each time. Confidence comes from having already broken things somewhere it didn't matter.
- Run
git lgafter every operation for a week. Watching the graph move is how the pointer model stops being abstract. - Read your own diff before every commit. It's the highest-value habit on this page.
- When you're stuck, ask "where is the pointer, and where do I want it?" That question answers most Git problems.
Finished reading?
0 of 18 chapters read in this series