BackendBench
Coffee
Cheat sheet

Git cheat sheet by task

Find the command by what you want to do, with a note on whether it is safe, rewrites history or discards work.

Undo the last commit but keep the changes stagedrewrites history
git reset --soft HEAD~1
Moves the branch back one commit; your changes stay in the index, ready to commit again.
Undo the last commit and keep the changes unstagedrewrites history
git reset HEAD~1
Same, but the changes are left in the working tree (a mixed reset).
Throw away the last commit and its changesdiscards work
git reset --hard HEAD~1
Resets the branch and the files. The commit can still be recovered through the reflog for a while.
Change the last commit messagerewrites history
git commit --amend -m "new message"
Replaces the last commit. Do not do it after pushing unless you coordinate a force push.
Add a forgotten file to the last commitrewrites history
git add file && git commit --amend --no-edit
Folds the staged file into the previous commit and keeps its message.
Unstage a filesafe
git restore --staged file
Removes the file from the index but keeps your edits.
Discard local changes to a filediscards work
git restore file
Replaces the file with the committed version. Your edits are gone.
Create a branch and switch to itsafe
git switch -c feature/name
Replaces the older git checkout -b.
Switch back to the previous branchsafe
git switch -
Rename the current branchsafe
git branch -m new-name
Add -M to force. Update the remote with git push -u origin new-name and delete the old one.
Delete a merged local branchsafe
git branch -d name
-D forces deletion of an unmerged branch.
Delete a remote branchsafe
git push origin --delete name
Stash changes, then bring them backsafe
git stash push -u -m "wip" && git stash pop
-u includes untracked files. git stash list shows saved stashes.
Update your branch with the latest main (linear history)rewrites history
git fetch origin && git rebase origin/main
Replays your commits on top of main. Resolve conflicts, then git rebase --continue.
Update your branch with a merge insteadsafe
git fetch origin && git merge origin/main
Keeps history as it happened and adds a merge commit.
Squash the last 3 commits into onerewrites history
git rebase -i HEAD~3
In the editor mark the later commits as squash (or s).
Copy one commit onto the current branchsafe
git cherry-pick <sha>
Use -x to record the original commit in the message.
Undo a commit that is already pushedsafe
git revert <sha>
Creates a new commit that reverses the change, so shared history stays intact.
Force push safely after rewritingrewrites history
git push --force-with-lease
Refuses to overwrite remote commits you have not seen, unlike plain --force.
See a compact history graphsafe
git log --oneline --graph --decorate --all
See what you are about to commitsafe
git diff --staged
git diff alone shows unstaged changes.
See commits not pushed yetsafe
git log origin/main..HEAD --oneline
Replace origin/main with your upstream branch.
Find who last changed each linesafe
git blame -L 10,30 file
-w ignores whitespace changes, -C follows moved code.
Find the commit that introduced a bugsafe
git bisect start && git bisect bad && git bisect good <sha>
Git checks out commits halfway between; mark each good or bad until it names the culprit. Finish with git bisect reset.
Search the history for a stringsafe
git log -S"text" --oneline
Finds commits that added or removed that text.
Recover a "lost" commit or branchsafe
git reflog
Lists where HEAD has been. Create a branch at the entry you want: git branch rescue <sha>.
Stop tracking a file but keep it on disksafe
git rm --cached file
Then add it to .gitignore and commit.
Remove untracked files (preview first)discards work
git clean -n  then  git clean -fd
-n shows what would be deleted. -f -d actually removes files and folders.
Change the remote URLsafe
git remote set-url origin <url>
git remote -v shows the current ones.
Set the upstream for a new branchsafe
git push -u origin HEAD
After this, plain git push and git pull work.
Clone only recent historysafe
git clone --depth 1 <url>
A shallow clone is much faster for CI. Use git fetch --unshallow to get the rest.
Create an annotated tag and push itsafe
git tag -a v1.2.0 -m "Release 1.2.0" && git push origin v1.2.0
Initialise and update submodulessafe
git submodule update --init --recursive
Run after cloning a repository that has submodules.
Show a file as it was in another commitsafe
git show <sha>:path/to/file

Git by task

Most people use a dozen Git commands daily and look up the rest every time: how to undo the last commit without losing the work, how to unstage, how to clean up a branch before a pull request. Git's help pages are organised by command; when you are stuck you think in terms of what you want to do. This sheet is organised by task.

Each entry gives the command, a one-line explanation of what it does and a risk label so you know what you are about to do: safe (nothing is lost), rewrites history (fine for local commits, dangerous after pushing without coordination) or discards work (uncommitted changes cannot be recovered). Use the search box to filter, for example "undo", "branch" or "stash".

Three habits that prevent most disasters

Commands use the modern git switch and git restore introduced in Git 2.23 alongside the older checkout. Test unfamiliar commands in a scratch repository first. The page is static and works offline.

Frequently asked questions

What is the difference between git reset and git revert?

reset moves the branch pointer and rewrites history, which is fine for local commits. revert adds a new commit that undoes an earlier one, which is the right tool for commits that others may already have.

What is the difference between merge and rebase?

Merge joins two histories with a merge commit and keeps everything as it happened. Rebase replays your commits on top of another branch for a straight line, but creates new commits, so never rebase commits others have based work on.

I deleted a branch or lost a commit. Is it gone?

Usually not. git reflog records every position of HEAD for about 90 days by default; find the commit there and create a branch pointing to it.

Why use --force-with-lease?

A plain force push overwrites whatever is on the remote. With lease, Git first checks that the remote branch is where you last saw it and refuses otherwise, protecting a colleague's newer commits.

More tools you might need