Git Cheatsheet

Undoing Changes

Use this Git reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Overview: Which Tool to Use

GoalCommand
Discard unstaged file changesgit restore <file>
Unstage a file (keep changes)git restore --staged <file>
Amend the last commitgit commit --amend
Undo last commit, keep changes stagedgit reset --soft HEAD~1
Undo last commit, keep changes unstagedgit reset --mixed HEAD~1
Undo last commit, discard changesgit reset --hard HEAD~1
Undo a commit safely (add a new revert commit)git revert <sha>
Recover a deleted commitgit reflog + git checkout <sha>

Restoring Working Tree Files

git restore <file>              # Discard unstaged changes in a file
git restore .                   # Discard all unstaged changes
git restore --staged <file>     # Unstage a file (working tree unchanged)
git restore --staged .          # Unstage everything
git restore --staged --worktree <file>  # Unstage AND discard changes
git restore --source=HEAD~2 <file>      # Restore file to its state at HEAD~2
git restore --source=<sha> <file>       # Restore file from a specific commit
git restore --source=<branch> <file>    # Restore file from another branch

git restore was introduced in Git 2.23 as a safer alternative to git checkout -- <file>. Older syntax: git checkout -- <file>.

Amending the Last Commit

git commit --amend              # Edit message and/or add staged changes
git commit --amend --no-edit    # Add staged changes without changing message
git commit --amend -m "new msg" # Replace the message entirely
git commit --amend --reset-author  # Update author to current config

Only amend commits that have NOT been pushed to a shared remote.

git reset

Moves HEAD (and optionally the branch pointer and index/working tree) to a different commit.

git reset --soft HEAD~1         # Move HEAD back 1; changes remain staged
git reset --mixed HEAD~1        # Move HEAD back 1; changes unstaged (default)
git reset --hard HEAD~1         # Move HEAD back 1; changes discarded permanently
git reset <sha>                 # Reset to a specific commit (--mixed by default)
git reset --hard <sha>          # Reset to a specific commit, discard all changes
git reset HEAD <file>           # Unstage a specific file (older syntax)
git reset --keep HEAD~1         # Like --hard but fails if local changes would be lost
git reset --merge HEAD~1        # Like --hard but preserves uncommitted merge changes

Reset Modes Comparison

ModeHEADIndex (Staging)Working Tree
--softMovedUnchangedUnchanged
--mixed (default)MovedResetUnchanged
--hardMovedResetReset

--hard is destructive. Recover with git reflog + git reset --hard <sha> if needed.

git revert

Creates a NEW commit that undoes the changes of a previous commit. Safe for shared/public branches.

git revert <sha>                # Revert a commit (opens editor for commit msg)
git revert <sha> --no-edit      # Revert without opening editor
git revert HEAD                 # Revert the latest commit
git revert HEAD~3..HEAD         # Revert the last 3 commits (newest-first)
git revert <sha1>..<sha2>       # Revert a range of commits
git revert -n <sha>             # Stage the revert changes but don't commit yet
git revert --continue           # Continue after resolving conflicts
git revert --abort              # Abort an in-progress revert
git revert --no-commit <sha>    # Same as -n

git revert is the correct tool for undoing changes on main/master or any shared branch — it preserves history.

Recovering with git reflog

reflog records every position HEAD has been at, even after resets and deletions:

git reflog                      # Show all recent HEAD movements
git reflog show <branch>        # Reflog for a specific branch
git reflog --relative-date      # Show times (e.g., "3 hours ago")
git reflog expire --expire=now --all  # Expire all reflog entries (cleanup)

Recovering a lost commit:

git reflog                      # Find the SHA of the lost commit
git checkout <sha>              # Inspect it (detached HEAD)
git switch -c recovery-branch   # Save it to a new branch
# Or restore directly:
git reset --hard <sha>          # Move current branch back to that commit

Cleaning Untracked Files

git clean -n                    # Dry run: show what would be removed
git clean -f                    # Remove untracked files (force required)
git clean -fd                   # Remove untracked files AND directories
git clean -fx                   # Remove untracked files including ignored ones
git clean -fX                   # Remove ONLY ignored files
git clean -i                    # Interactive mode

git clean -f is irreversible. Always run -n (dry run) first.

Removing a File from All Commits (History Rewriting)

# Using git filter-repo (recommended, install separately)
git filter-repo --path <file> --invert-paths

# Using BFG Repo Cleaner (Java tool)
bfg --delete-files <file>
bfg --replace-text passwords.txt

# After rewriting, force push ALL branches
git push --force --all

After these operations, all collaborators must re-clone or re-fetch. These change commit SHAs.

Undoing Specific Hunks

git checkout -p <file>          # Interactively discard specific hunks
git restore -p <file>           # Modern equivalent
git add -p <file>               # Interactively stage specific hunks
git reset -p HEAD <file>        # Interactively unstage specific hunks

Gotchas

git reset --hard and git clean -f are the two most dangerous everyday Git commands — both discard work without moving it to the trash.

git commit --amend rewrites the commit SHA. If already pushed, the remote will reject a normal push. Use --force-with-lease.

Reflog entries expire (default 90 days for reachable commits, 30 days for unreachable). Don't rely on it as a long-term backup.