Overview
This card groups git commands by intent and ends with the aliases worth setting. Principles (rebase vs merge, commit hygiene) live in git; interactive rebase is in git-rebase and merge options in git-merge-strategies.
Inspect
Read state before you change it.
| Command | What it does |
|---|---|
git status -sb | One line per file plus branch tracking. |
git log --oneline --graph --all | Branch topology across all refs. |
git log -S "needle" | Commits that added or removed the literal string. |
git log --grep "pat" | Commits whose message matches. |
git show <ref> | One commit with its patch. |
git log -G "regex" | Commits whose diff matches the regex. |
git log -p --follow <file> | Patch history of one file across renames. |
git blame -L 10,20 <file> | Last commit per line for lines 10 to 20. |
git diff main...HEAD | What this branch adds since it left main. |
git diff --staged | Changes already in the index. |
git shortlog -sn --no-merges | Commit count per author. |
Undo
Pick the narrowest undo; never rewrite pushed history.
| Command | What it undoes |
|---|---|
git restore <file> | Unstaged edits to a file. |
git restore --staged <file> | Staging only; the working tree stays. |
git restore --source=HEAD~1 <file> | Roll one file back to an older version. |
git commit --amend | Replace the tip commit (local only). |
git reset --soft HEAD~1 | Drop the last commit; keep changes staged. |
git reset HEAD~1 | Drop the last commit; keep changes unstaged (--mixed, the default). |
git reset --hard HEAD~1 | Drop the last commit and its changes. |
git revert <ref> | New commit that inverts an old one; safe on shared branches. |
git clean -nd, then git clean -fd | Preview, then delete untracked files and directories. |
Branch and sync
Fetch first, then choose how to integrate.
| Command | Effect |
|---|---|
git switch -c <b> | Create and switch. |
git switch -c <b> --track origin/<b> | Create a local branch tracking a remote one. |
git branch -d <b> / -D <b> | Delete if merged / delete regardless. |
git branch -m old new | Rename a branch. |
git branch --merged main | Branches already merged into main. |
git worktree add ../wt <branch> | Second working copy without a second clone. |
git fetch --all --prune | Update remote refs and drop deleted ones. |
git pull --ff-only | Fail instead of creating a merge commit. |
git push -u origin <b> | Push and set upstream. |
git push --force-with-lease | Force-push only if the remote has not moved. |
Delete local branches whose upstream is gone:
git for-each-ref --format='%(refname:short) %(upstream:track)' refs/heads \
| awk '$2=="[gone]"{print $1}' | xargs -r git branch -dStash and recover
Almost nothing committed is lost while it is in the reflog.
| Command | Effect |
|---|---|
git stash push -u -m "wip" | Stash tracked and untracked files with a label. |
git stash list, git stash pop | List; apply the top stash and drop it. |
git reflog | Every HEAD move; find the lost commit. |
git reset --hard <reflog-ref> | Restore a discarded commit. |
git bisect start, then good / bad | Binary-search the commit that broke something. |
Reflog entries expire after 90 days when reachable and 30 when unreachable (gc.reflogExpire, gc.reflogExpireUnreachable).
Aliases
Put these under [alias] in ~/.gitconfig; keep only the ones you type daily.
[alias]
st = status -sb
sw = switch
lg = log --oneline --graph --all --decorate
ds = diff --staged
ca = commit --amend --no-edit
undo = reset --soft HEAD~1
pub = push -u origin HEADAdd one without editing the file: git config --global alias.st "status -sb"; remove it with git config --global --unset alias.st. Use --local for one repository.
Gotchas
Avoid these; each loses work or rewrites shared history.
| Gotcha | Fix |
|---|---|
git pull creates surprise merge commits. | git config --global pull.ff only (or pull.rebase true). |
reset --hard, restore ., and clean -fd discard work with no undo. | git stash -u first; preview with clean -nd. |
push --force overwrites a teammate’s push. | Use --force-with-lease. |
git branch -d refuses a squash-merged branch. | Confirm it is merged, then -D. |
Aliases starting with ! run from the repo root. | Use absolute paths or git rev-parse --show-toplevel. |