Git is one of those tools where you can get by with about 15 commands for years — and then one day you accidentally rebase your main branch and suddenly wish you'd learned a few more. This cheatsheet is the "few more" without the panic attack.
Here's the thing nobody tells you early on: git is really just a directed acyclic graph of snapshots. Every commit is a snapshot, every branch is a pointer, and HEAD is just a sticky note saying "you are here." Once that clicks, everything else — rebasing, cherry-picking, resetting — stops feeling like dark magic and starts feeling like moving sticky notes around.
We've organized this by workflow rather than alphabetically, because nobody thinks "I need a command that starts with R." You think "I need to undo that last commit" or "I need to grab my coworker's branch." Start with Basic Workflow if you're just getting your feet wet, then branch out (pun very much intended) as you get comfortable. The Stash and Reset sections will save your bacon at least once a week.
One golden rule: commit early, commit often. Small commits are easy to review, easy to revert, and easy to understand six months from now when you're reading git log and wondering what past-you was thinking.
Basic Workflow
git init
Create a new repository in the current directorygit clone <url>
Download a repository and its entire historygit status
Show changed, staged, and untracked filesgit add <file>
Stage a specific file for the next commitgit add .
Stage all changes in the current directorygit commit -m "<msg>"
Commit staged changes with a messagegit push
Upload local commits to the remotegit pull
Fetch and merge remote changes into your branch
Branching
git branch
List all local branchesgit branch -a
List local and remote branchesgit branch <name>
Create a new branch (but stay on current one)git switch <name>
Switch to an existing branchgit switch -c <name>
Create a new branch and switch to itgit branch -d <name>
Delete a branch (safe — blocks if unmerged)git branch -D <name>
Force-delete a branch, even if unmergedgit branch -m <new>
Rename the current branch
Merging & Rebasing
git merge <branch>
Merge a branch into your current branchgit merge --no-ff <branch>
Merge with a merge commit, even if fast-forward is possiblegit rebase <branch>
Replay your commits on top of another branchgit rebase --abort
Cancel an in-progress rebase and restore original stategit rebase --continue
Continue rebasing after resolving conflictsgit merge --abort
Cancel an in-progress mergegit cherry-pick <hash>
Apply a single commit from another branch
Stash
git stash
Temporarily shelve all uncommitted changesgit stash -u
Stash including untracked filesgit stash pop
Restore the most recent stash and remove itgit stash apply
Restore the most recent stash but keep it in the listgit stash list
Show all stashed changesetsgit stash drop
Delete the most recent stashgit stash drop stash@{n}
Delete a specific stash by index
Log & Diff
git log
Show commit history for the current branchgit log --oneline
Compact one-line-per-commit historygit log --graph --oneline
Show branch history as an ASCII graphgit diff
Show unstaged changes vs last commitgit diff --staged
Show staged changes vs last commitgit diff <branch1> <branch2>
Compare two branchesgit show <hash>
Show the changes in a specific commitgit log -p <file>
Show the full change history of a file
Reset & Revert
git reset <file>
Unstage a file but keep the changesgit reset HEAD~1
Undo last commit, keep changes stagedgit reset --soft HEAD~1
Undo last commit, keep changes staged (explicit)git reset --hard HEAD~1
Undo last commit and discard all changes permanentlygit revert <hash>
Create a new commit that undoes a previous commitgit checkout -- <file>
Discard unstaged changes to a specific filegit restore <file>
Discard unstaged changes (modern syntax)git restore --staged <file>
Unstage a file (modern syntax)
Remotes
git remote -v
List all remotes with their URLsgit remote add <name> <url>
Add a new remote repositorygit fetch
Download remote changes without merginggit fetch --prune
Fetch and remove stale remote-tracking branchesgit pull --rebase
Pull remote changes and rebase your work on topgit push -u origin <branch>
Push a branch and set it to track the remotegit push origin --delete <branch>
Delete a remote branch
Tags
git tag <name>
Create a lightweight tag at the current commitgit tag -a <name> -m "<msg>"
Create an annotated tag with a messagegit push --tags
Push all local tags to the remotegit tag -d <name>
Delete a local taggit push origin --delete <tag>
Delete a remote tag
Use git switch and git restore instead of git checkout. The checkout command does too many things — switch handles branches, restore handles files. Clearer intent, fewer mistakes.
Run git pull --rebase instead of plain git pull to keep your history linear. Better yet, set it as the default: git config --global pull.rebase true.
Made a typo in your last commit message? git commit --amend -m "fixed message" rewrites it. Just don't amend commits you've already pushed — that rewrites history your teammates might depend on.
Use git stash -u instead of plain git stash. The -u flag includes untracked files, which is almost always what you want. Without it, new files you haven't added yet get left behind.
The git reflog is your time machine. Even after a bad reset --hard, your commits aren't truly gone for about 30 days. Run git reflog, find the hash you want, and git reset --hard <hash> to recover.
Before a big merge or rebase, create a "safety branch" with git branch backup-before-merge. If everything goes sideways, you can always get back to where you started. Cheap insurance.
Use git log --oneline --graph --all to visualize your entire branch topology in the terminal. It's the fastest way to understand what's going on in a repo with multiple active branches.