Guide · Git · about 5 minutes

Git cheatsheet: commands by task

Every Git command from the Git basics track, grouped by the job you're trying to do, with which undo to use, what Git's most common errors mean, and how to get out of trouble. Each row links to the lesson that explains it.

Last checked October 2026

How to use this page

Find the job you're trying to do, and copy the command. Words in capitals, like FILE, NAME or COMMIT, are yours to replace. COMMIT can be a commit ID from git log --oneline, like 88be1c0, or a position, like HEAD~1 (one commit before where you are). Every row links to the lesson that explains it. Use the print button at the top to keep a copy next to you.

Two habits that make every command here easier:

  • Run git status before and after anything. It tells you which branch you're on, what's changed, and usually what to do next.
  • Read the whole message. When Git refuses, the fix is almost always printed right there, often in brackets.

When Git says no

Start here when a command fails. Find the line Git printed, and it tells you where you are.

Git saysIt meansDo thisLesson
Your local changes ... would be overwritten by checkoutYou have unsaved changes that switching branches would destroyCommit them, or set them aside with git stash, switch, then git stash pop when you're back6
CONFLICT (content): Merge conflict in FILEBoth branches changed the same lines, and Git won't guess which winsEdit the file, delete the <<<<<<<, ======= and >>>>>>> lines, then git add FILE and git commit --no-edit. Or back out with git merge --abort4, 6
! [rejected] main -> main (fetch first)GitHub has commits you don't have yetgit pull, then git push again5
Need to specify how to reconcile divergent branchesBoth you and GitHub have new commits, and Git wants to know how to combine themgit pull --no-rebase --no-edit, or set it once with git config --global pull.rebase false5
the branch 'NAME' is not fully mergedGit can't prove the branch's commits are on your branch. After a squash merge, they're there but look differentCheck its changes are really on main, then git branch -D NAME4
You are in 'detached HEAD' stateYou're looking at an old commit, not a branch. Nothing is brokenJust looking: git switch main. Made commits to keep: git switch -c NAME first6
you are leaving 1 commit behindYou left detached HEAD with a commit no branch points togit branch NAME COMMIT, with the ID from the warning6

Which undo do you need?

The answer depends on one question: has it been committed, and has anyone else seen that commit? Rewrite only what nobody else has seen. Once it's pushed, revert.

Where the change isToRunLesson
Not committed yetThrow away a change in a file (gone for good)git restore FILE3
Not committed yetUnstage a file, but keep the changegit restore --staged FILE3
Committed, not pushedFix the last commit's message, or add a forgotten filegit add FILE, then git commit --amend -m "MESSAGE"3
Committed, not pushedUndo the last commit, keep its changes in your filesgit reset HEAD~13
Committed, not pushedUndo the last two commits and their changesgit reset --hard HEAD~23
Committed and pushedUndo a commit with a new commitgit revert --no-edit COMMIT3
AnywhereFind where you were before a resetgit reflog -33
AnywhereUndo a reset you regretgit reset --hard 'HEAD@{1}'3

Setting up, once

ToRunLesson
Check Git is installedgit --version1
Set your name for commitsgit config --global user.name "Your Name"1
Set your email for commitsgit config --global user.email "you@example.com"1
Name new repositories' first branch maingit config --global init.defaultBranch main1
Make git pull merge, not rebasegit config --global pull.rebase false5
See all your settingsgit config --global --list1
Sign the GitHub command line ingh auth login5

Saving your work

A change goes from your folder, to the staging area (what goes in the next commit), to a commit.

ToRunLesson
Start a repository in this foldergit init2
See what's changed and what's stagedgit status2
The same, one line per filegit status --short2
See the changes you haven't stagedgit diff2
Stage one filegit add FILE2
Stage everything (check git status first)git add .2
Commit what's stagedgit commit -m "MESSAGE"2
Stage every tracked file you changed, and commitgit commit -am "MESSAGE"3
Stop tracking a file, but keep it on diskgit rm --cached FILE, then add it to .gitignore2
Keep files out of GitList them in a file called .gitignore, like .env or *.log2

A good commit message finishes the sentence "This commit will...": Add a to-do list, not stuff or fixed it.

Reading the history

ToRunLesson
List commits, one line eachgit log --oneline2
Only the last fewgit log --oneline -33
See branches joining, as a drawinggit log --oneline --graph -54
What the last commit changedgit show2
Which files a commit changedgit show --stat COMMIT3
Everywhere HEAD has been, even after a resetgit reflog3
Look at an old version of everythinggit checkout COMMIT, then git switch main to come back6

Branches

ToRunLesson
List branches (* marks the one you're on)git branch4
Make a branch and switch to itgit switch -c NAME4
Switch to a branchgit switch NAME4
Make a branch, but stay where you aregit branch NAME6
Bring a branch's work into the one you're ongit merge NAME4
Cancel a merge that went wronggit merge --abort6
Delete a merged branch (safe: refuses if it isn't merged)git branch -d NAME4
Delete a branch anywaygit branch -D NAME4

GitHub and pull requests

ToRunLesson
Put this repository on GitHubgh repo create NAME --private --source=. --remote=origin --push5
Download a repository, with its full historygh repo clone NAME5
See where this repository pushes togit remote -v5
Push a new branch, the first timegit push -u origin NAME5
Push, after thatgit push5
Bring in GitHub's new commitsgit pull5
Check GitHub without changing anythinggit fetch, then git status5
Clear records of branches deleted on GitHubgit fetch --prune5
See your laptop's record of GitHub's branchesgit branch -r5
Open a pull requestgh pr create --fill --base main5
Open it in the browsergh pr view --web5
Squash and merge it, and delete the branchgh pr merge --squash --delete-branch5

The whole loop, for every change: git switch main and git pull, then git switch -c NAME, commit, git push -u origin NAME, gh pr create, merge, and back to git switch main and git pull.

Merge methodWhat lands on mainGood for
Merge commitEvery commit from the branch, plus a commit joining themKeeping the full history of how a change was built
SquashOne new commit with all the branch's changesA clean history: one commit per pull request
RebaseThe branch's commits, copied onto the end of mainA straight line that keeps every commit

Getting out of trouble

ToRunLesson
Set unfinished work asidegit stash6
The same, including new files Git isn't tracking yetgit stash -u6
Bring the work backgit stash pop6
See everything you've set asidegit stash list6
Throw away the latest stashgit stash drop6
Committed on main by mistake (not pushed): move it to a branchgit branch NAME, then git reset --hard HEAD~1. Branch first, then reset6
Keep commits made in detached HEADgit switch -c NAME6
Rescue a commit you left behindgit branch NAME COMMIT6

If you commit a secret, like a password or API key:

  1. Treat it as leaked, and change it. Make a new one and turn the old one off. This is the step that actually protects you.
  2. Not pushed yet? Take it out of the file, add the file to .gitignore, and git commit --amend.
  3. Already pushed? Removing it from history takes tools like git filter-repo, and rewrites shared history. That's why step 1 comes first.

Lessons 2, 3 and 6 cover each step.