Git Cheatsheet
Bookmark this one. The next time Git breaks, check here before you delete the folder and clone again.

Git Mistakes You Can Undo in One Command
You know the feeling. You ran a command, something broke, and now your terminal is staring at you. Your first instinct is to delete the folder and clone again. Maybe you've done it. I definitely have.
The thing is, Git almost never loses your work permanently. Every panic moment you've had in Git has a one-line fix. You just didn't know where to look.
This is that page. Bookmark it. The next time something breaks, come back here before you touch anything.
Quick Reference
Find your situation, get the fix, and then read the full section if you want to understand what's happening.
| Problem | Fix | When is it safe? |
|---|---|---|
| Typo in commit message | git commit --amend -m "fixed message" | Before push only |
| Added the wrong file to staging | git restore --staged <file> | Anytime |
| Undo last commit, keep the code | git reset --soft HEAD~1 | Before push only |
| Coded on the wrong branch | git switch -c <new-branch> | Before commit |
| Merge or rebase going wrong | git merge --abort or git rebase --abort | During the merge/rebase |
| Pushed a bad commit to shared branch | git revert <commit-hash> | Safe after push |
| Deleted the wrong branch | git branch <name> <commit-hash> | Anytime |
Ran reset --hard by mistake | git reset --hard HEAD@{1} | Anytime, run immediately |
| Committed a .env file | git rm --cached .env + update .gitignore | Urgent if already pushed |
| Forgot a file in the last commit | git commit --amend --no-edit | Before push only |
| Discard changes in one file | git restore <file> | Anytime (destructive) |
| Move work mid-task | git stash / git stash pop | Anytime |
| Need one commit from another branch | git cherry-pick <commit-hash> | Anytime |
| Squash or reword commits | git rebase -i HEAD~<n> | Before push only |
| Rename a branch | git branch -m <old> <new> | Anytime |
| Stuck in detached HEAD | git switch - or git switch <branch> | Anytime |
Before We Start: The Building Blocks
A few terms come up everywhere in this guide. If you know them, skip ahead.
- HEAD is a pointer to your current position in Git history. Usually it points to the tip of your current branch. When you make a commit, HEAD moves forward.
- HEAD~1 means "one commit before HEAD."
HEAD~2means two commits back. You'll see this in reset and rebase commands. HEAD@{1}means "where HEAD was before the last operation." It comes from the reflog, not the commit graph. This is how you undo a reset or a branch switch.- A commit hash is a 40-character string like
a3f2c91d8b...that uniquely identifies a commit. You don't need the full thing. The first 7 characters usually work. Get them withgit log --oneline. - Staging (or the index) is the holding area between your working files and a commit.
git addmoves changes into staging.git committakes whatever is staged and makes it a commit. - The reflog is Git's internal diary. Every time HEAD moves (commit, reset, checkout, rebase), Git writes it down. By default it keeps entries for 90 days, or 30 days for commits that are no longer on any branch. It's the safety net behind most "I thought I lost everything" moments.
1. Fixing a Commit
1.1 Typo in your commit message?
When: before push only. Risk: rewrites history.
# fix the last commit message
git commit --amend -m "fixed message"This replaces the last commit with a new one that has the updated message. The code inside the commit doesn't change at all.
⚠️ NOTE
This gives the commit a new hash. If you already pushed it to a shared branch and teammates pulled it, don't do this. It will cause conflicts for everyone.
1.2 Forgot a file in the last commit?
When: before push only. Risk: rewrites history.
git add forgotten-file.ts
git commit --amend --no-editStage the file first. Then --amend reopens the last commit and adds the staged file to it. --no-edit keeps the existing commit message, so you don't have to type anything.
1.3 Undo the last commit, keep the code?
When: before push only. Risk: safe (your code stays).
# undo the commit, keep the code
git reset --soft HEAD~1The commit disappears from history. Everything that was in it goes back to staged, ready for you to fix and commit again. Your actual files are untouched.
Use this when you committed too early, committed to the wrong branch, or want to split one commit into two.
1.4 The three modes of git reset
Since reset comes up a lot, here's what each mode does:
| Mode | Commit history | Staged changes | Working files |
|---|---|---|---|
--soft | Undone | Kept staged | Unchanged |
--mixed (default) | Undone | Unstaged | Unchanged |
--hard | Undone | Gone | Reset to that commit |
--soft is the safe one. --hard is the dangerous one. --mixed is the middle ground where your code stays but you have to re-stage everything.
2. Fixing Staging
2.1 Added the wrong file to staging?
When: anytime. Risk: safe.
# take it out of the next commit
git restore --staged secret.txtThis removes the file from staging. Your changes stay on disk exactly as they are. You just won't accidentally commit it.
💡 TIP
Needs Git 2.23 or newer. On older versions use git reset HEAD secret.txt.
2.2 Throw away changes in one file entirely?
When: anytime. Risk: destructive. The changes are gone.
git restore <file>This resets the file back to its state at the last commit. Whatever you changed is gone, and there's no undo for this one. Use it only when you're sure.
3. Fixing Branches
3.1 Coded on the wrong branch?
When: before committing, while changes are uncommitted. Risk: safe.
# move your work to a new branch
git switch -c feature-loginYour uncommitted changes come with you to the new branch. Nothing lost, nothing committed to main. This is the cleanest way to recover mid-work.
💡 TIP
On Git older than 2.23, use git checkout -b feature-login.
3.2 Need to move work mid-task without committing?
When: anytime. Risk: safe.
git stash
git switch <other-branch>
# do what you need to do
git switch -
git stash popgit stash saves your uncommitted changes to a temporary stack. git stash pop brings them back. Use it when you need to switch branches but you're not ready to commit yet.
By default git stash only stashes tracked files. If you have new untracked files you want included, use git stash -u.
3.3 Deleted the wrong branch?
When: anytime, as long as Git hasn't garbage-collected the commits. Risk: safe.
# swap in the hash Git printed on delete
git branch feature-login <commit-hash>When you delete a branch with git branch -d feature-login (or -D to force it), Git prints something like Deleted branch feature-login (was a3f2c91). Copy that hash and use it here to bring the branch back.
Lost the hash? git reflog has it. Look for the last line mentioning your branch name.
3.4 Need to rename a branch?
When: anytime. Risk: safe.
git branch -m old-branch-name new-branch-nameIf you're already on the branch you want to rename:
git branch -m new-nameIf you've already pushed the old branch, push the renamed one and delete the old one:
git push origin -u new-name
git push origin --delete old-branch-name3.5 Stuck in detached HEAD?
When: anytime. Risk: depends on what you do.
You end up in detached HEAD when you checkout a specific commit hash or tag instead of a branch. Git tells you: "HEAD detached at a3f2c91."
If you made commits in this state and want to keep them:
git switch -c recovery-branchThis creates a new branch from where you are, keeping all your commits.
If you just want to go back without keeping anything:
git switch -Or go to a specific branch:
git switch main4. Fixing Merges and Rebases
4.1 Merge going wrong?
When: during an active merge or rebase, before you resolve it. Risk: safe. Takes you back to before you started.
# back to before the merge
git merge --abort
# same idea for a rebase
git rebase --abortIf the conflicts are everywhere and you just want out, these take you back to the state before you ran git merge or git rebase. Clean slate.
⚠️ NOTE
These only work while the merge or rebase is in progress. Once you've committed the result, you need git revert instead.
4.2 Squash or reword old commits?
When: before push only. Risk: rewrites history.
git rebase -i HEAD~3This opens an interactive editor showing the last 3 commits. You can reorder them, squash them together, drop them, or reword the messages. Replace 3 with however many commits you want to work with.
In the editor, change pick to:
squash(ors) to merge a commit into the one above itreword(orr) to change the commit messagedrop(ord) to delete a commit entirely
5. Fixing a Pushed Mistake
5.1 Pushed a bad commit to a shared branch?
When: safe after push. The right fix when others may have pulled. Risk: safe (adds a new commit, no force push).
# swap in a real hash from git log --oneline
git revert <commit-hash>Instead of deleting the bad commit, git revert creates a new commit that undoes the changes in it. The history stays intact and your teammates don't need to do anything special.
Get the hash with git log --oneline. It looks like a3f2c91 bad commit message. The 7-character hash is enough.
5.2 Reverting a merge commit
Merge commits are a special case. You need the -m flag to tell Git which parent is the mainline:
git revert -m 1 <merge-commit-hash>-m 1 means "keep the first parent," which is usually the branch you merged into (main). git log --oneline shows you the merge commit hash.
5.3 Need to force push safely?
When: only when you have to rewrite pushed history (after amend, interactive rebase, etc.).
Risk: still rewrites history, but safer than --force.
git push --force-with-lease--force overwrites whatever is on the remote, even if someone else pushed after you. --force-with-lease checks first. If anyone pushed to the branch since you last fetched, it refuses and asks you to pull. Use this instead of --force whenever you have to force push.
5.4 Need one specific commit from another branch?
When: anytime. Risk: safe.
git cherry-pick <commit-hash>This takes one commit from anywhere in your history and applies it to your current branch. Useful when you fixed a bug on the wrong branch and need just that fix, without merging everything else.
Get the hash with git log --oneline <branch-name>.
6. Recovering Lost Work
6.1 Ran reset --hard by mistake?
When: anytime. Run it immediately, before anything else. Risk: recovers commits only. Uncommitted changes are gone for good.
# go back to where you were
git reset --hard HEAD@{1}HEAD@{1} is reflog notation for "where HEAD was one operation ago." This takes you back to before the reset happened.
⚠️ NOTE
This brings back commits. If the reset wiped uncommitted changes, those are gone for practical purposes, because Git has no normal command to get back work that was never committed. This is the one situation in Git where work is actually lost.
6.2 Using the reflog when you don't know the exact reference
If you need to look further back:
git reflogThis shows every position HEAD has been at, with entries like:
a3f2c91 HEAD@{0}: reset: moving to HEAD~1
f8b1a2c HEAD@{1}: commit: your old commit message
Find the entry you want to go back to, copy its hash, then:
git reset --hard <hash>Commits you reset away stay recoverable for about 30 days by default, so even old mistakes are often fixable.
7. Diagnosing What Went Wrong
Before you fix something, you need to know what happened. These three commands are your starting point.
7.1 git log --oneline
git log --onelineA compact history, one commit per line, hash on the left and message on the right. This is where you get the hashes for git revert and git cherry-pick.
7.2 git diff
git diff # changes not yet staged
git diff --staged # changes staged but not committed
git diff main..feature-login # difference between two branchesUse this to see exactly what changed before you commit or before you decide what to revert.
7.3 git blame
git blame <filename>Shows every line of a file annotated with the last commit that changed it and who made it. Useful for tracking down when and why something changed.
8. Secrets and Safety
8.1 Committed a .env file?
When: urgent if already pushed. Do this now. Risk: removing it from tracking is not enough if it was pushed.
# stop tracking it, keep the file
git rm --cached .env
echo ".env" >> .gitignore
git commit -m "stop tracking .env"git rm --cached removes the file from Git's tracking without deleting it from your machine. Adding it to .gitignore makes sure you don't add it again.
If you pushed it: the file is in your Git history. Anyone who clones the repo can find it in the commit log. Removing it from tracking only stops future commits from including it. The keys are already out there.
Rotate them. Today. Go to whatever service the keys belong to (AWS, Stripe, OpenAI, whatever), generate new keys and invalidate the old ones.
If you want to scrub the file from history, you need a tool like git filter-repo or BFG Repo Cleaner. That's a bigger operation and usually needs a force push, so only do it if the repo isn't shared yet or you've coordinated with everyone who has a clone.
9. Which Command Do I Use?
Something wrong with my last commit:
- Message wrong?
git commit --amend -m "new message"(before push) - Forgot a file?
git add file, thengit commit --amend --no-edit(before push) - Want to undo it entirely?
git reset --soft HEAD~1(before push)
Something wrong with staging:
- File shouldn't be staged?
git restore --staged <file> - File changes should be thrown away?
git restore <file>(destructive)
Something wrong with my branch:
- Coded on main?
git switch -c feature-branch - Need to work on two things at once?
git stash, switch, thengit stash pop - Deleted the wrong branch?
git branch <name> <hash>
Something wrong with a merge:
- Conflicts everywhere and I want out?
git merge --abort - Rebase going sideways?
git rebase --abort
Something was pushed and I need to undo it:
git revert <hash>. No force push needed, safe for shared branches.
I lost something and don't know how to get it back:
git reflogfirst. Find the hash of where you want to be, thengit reset --hard <hash>.
10. The One Rule That Prevents Most of This
Commit small and commit often.
A commit with 3 lines changed is easy to revert. A commit with 800 lines changed across 12 files is a nightmare to untangle. The smaller your commits, the easier every fix in this guide becomes.
And write commit messages that mean something. "fix bug" helps nobody. "fix null pointer in useAuth when token expires" helps everyone, including future you at 2am.
✅ TIP
When in doubt, run git reflog before anything else. Most "lost" work is still in there.

Imtiyaz Nandasaniya
I'm a full-stack developer from Ahmedabad. I post what I learn about code on Instagram as code.clash, in the simplest language I can.
Subscribe to code.clash.
I will email you when I publish a new post. No spam, and you can unsubscribe whenever.
Related Writing.

Free APIs Every Developer Should Know
A list of 25+ free APIs for learning, side projects and trying out ideas.

ReactJS Cheatsheet
JSX, components, hooks, state and performance tips, plus the newer React 18 features.

JavaScript Cheatsheet
Core JavaScript in one page: ES6 features, data types, functions, the event loop and DOM basics.
Comments (0)
Leave a Comment
No account needed. Anonymous comments are welcome.