Git Cheat Sheet

The Git commands developers actually use daily, organized by workflow — branching, rebasing, undoing mistakes, and recovery — with real examples and a searchable quick reference.

runs locally on your browser. Your data never leaves your device.
13 sections
50+ commands
Searchable quick reference
100% offline

Setup & Config

The four commands you run once per machine, before Git will let you commit anything.

git init

Turns the current directory into a Git repository by creating a hidden .git folder. Run it once, in the project's root.

git clone <url>

Copies an existing remote repository — history, branches, and all — into a new folder on your machine, and automatically wires up 'origin' as its remote.

git config --global user.name "Your Name"
Essential

Sets the name attached to every commit you make on this machine. Without this (and user.email), Git refuses to commit.

git config --global user.email "you@example.com"
Essential

Sets the email attached to every commit. Use the same address as your GitHub/GitLab account if you want commits linked to your profile.

git config --global init.defaultBranch main
Handy

Git still defaults new repos to 'master' unless you set this. Run it once and every future git init uses 'main' instead.

Three levels of config
--system (every user on the machine), --global (every repo for you), and --local (this repo only — the default when you omit a flag) stack in that order, with local always winning. A work laptop with a different commit email per client is the classic reason to set user.email locally in specific repos instead of globally.

Everyday Basics

The status → add → commit loop you'll run dozens of times a day.

git status
Essential

Shows what's changed, what's staged, and what's untracked. Run this before every add and every commit — it's the single habit that prevents the most 'oops' commits.

git add <file>
Essential

Stages a file so it will be included in the next commit. git add . stages everything changed in the current directory — convenient, but easy to accidentally include files you didn't mean to.

git add -p
Handy

Walks through your changes hunk by hunk, letting you stage part of a file instead of all of it. The right tool when one file has both a real fix and an unrelated debug print you don't want to commit.

Stage this hunk [y,n,q,a,d,s,e,?]? y Stage this hunk [y,n,q,a,d,s,e,?]? n

git commit -m "message"
Essential

Records everything currently staged as a new, permanent point in history.

git commit -am "message"
Handy

Stages every already-tracked, modified file and commits in one step. Skips git add — but it will not pick up brand-new (untracked) files, which is a common source of 'why isn't my new file in the commit?'

git diff

Shows exactly what changed in your working directory, line by line, since the last commit — the unstaged version.

git diff --staged
Handy

Same idea, but shows only what's staged — i.e. exactly what git commit would record if you ran it right now. Run this instead of git diff right before committing.

git log --oneline --graph --all

A compact, one-line-per-commit view of history across every branch, with ASCII branch lines — the fastest way to see how branches relate to each other at a glance.

git add . is a habit worth breaking
It stages everything in the directory — including that stray console.log, a half-finished experiment, or a .env file that isn't in .gitignore yet. git status first, git add -p for anything you're not 100% sure about.

Branching & Merging

Branches are just movable pointers to commits — cheap to create, cheap to throw away.

git branch

Lists local branches, with an asterisk next to the one you're currently on.

git switch -c feature-x
Essential

Creates a new branch called feature-x from your current commit and switches to it immediately. The modern, purpose-built replacement for git checkout -b feature-x.

git switch main
Essential

Switches to an already-existing branch. On Git older than 2.23, use git checkout main instead — same effect, older syntax.

git switch -
Handy

Jumps back to whichever branch you were on before your last switch — the Git equivalent of cd - in a shell.

git merge feature-x

Merges feature-x into your current branch. If your branch hasn't diverged, Git does a 'fast-forward' (just moves the pointer); otherwise it creates a new merge commit tying both histories together.

git branch -d feature-x

Deletes a local branch — but only if it's already fully merged somewhere, as a safety check.

git branch -D feature-x
Advanced

Force-deletes a branch regardless of merge status. Capital -D skips the safety check — make sure you actually meant to throw that work away.

git branch -m old-name new-name
Handy

Renames a branch. If you've already pushed the old name, you'll also need to push the new one and delete the old remote branch.

Merge vs. rebase, in one sentence
Merge preserves exactly what happened, including a merge commit that says "these two histories joined here"; rebase rewrites your branch's commits as if they'd been written on top of the latest main all along, producing a straight line with no merge commit. Neither is universally "correct" — merge is honest, rebase is tidy.
Resolving a merge conflict
Git leaves conflict markers in the file: everything between <<<<<<< HEAD and ======= is your side, everything down to >>>>>>> feature-x is theirs. Edit the file to keep what you want, delete all three marker lines, then git add the file and git commit (or git rebase --continue if the conflict came from a rebase) to finish.

Working With Remotes

Where your local history meets everyone else's.

git remote -v

Lists every remote Git knows about and the URLs it fetches from / pushes to. Almost every repo has exactly one, named 'origin'.

git remote add origin <url>

Registers a remote named origin — needed if you ran git init locally instead of git clone, and now want to connect it to GitHub/GitLab/etc.

git fetch origin
Essential

Downloads new commits and branches from the remote into your local copy — but does not touch your working files or current branch. Always safe to run.

git pull
Essential

Shorthand for git fetch followed immediately by git merge — brings your current branch up to date with its upstream, creating a merge commit if you'd diverged.

git pull --rebase
Handy

Same idea, but replays your local commits on top of the fetched ones instead of merging — keeps history linear instead of accumulating small 'merge branch main' commits on a branch only you use.

git push origin feature-x
Essential

Uploads your local feature-x branch and its commits to the remote.

git push -u origin feature-x
Handy

Pushes and remembers the link between your local branch and origin/feature-x, so every future push or pull on this branch can drop the branch name entirely.

Tip
Set git config --global pull.rebase true once and every future git pull behaves like git pull --rebase automatically, without needing the flag every time.

Rewriting History

Commits aren't as permanent as they look — as long as nobody else has built on top of them yet.

git commit --amend
Essential

Replaces your most recent commit with a new one — opens your editor to change the message, and includes whatever's currently staged as additional changes.

git commit --amend --no-edit
Handy

Same as above, but keeps the existing commit message — useful for 'oops, forgot to stage this file' right after committing.

git rebase main

Replays every commit on your current branch, one by one, on top of main's latest commit — as if you'd branched off just now instead of days ago.

git rebase -i HEAD~3
Advanced

Opens an editable to-do list of your last 3 commits, letting you reorder, reword, squash together, or drop them entirely before continuing.

pick a1b2c3d Add login form squash e4f5g6h Fix typo in login form reword h7i8j9k Add password validation

git cherry-pick <sha>
Advanced

Applies one specific commit from anywhere in the repo onto your current branch — handy for pulling a single hotfix out of a branch without merging the whole thing.

git reset --soft HEAD~1
Handy

Moves your branch pointer back one commit but leaves all its changes staged, ready to re-commit — use when the code was right but the commit itself wasn't (bad message, should've been split up).

git reset --hard HEAD~1
Advanced

Moves your branch pointer back one commit and throws away its changes completely, in both the index and your working files. There is no undo dialog — see the Undoing Mistakes section if you didn't mean it.

git revert <sha>
Essential

Creates a brand-new commit that applies the exact opposite of a previous commit, leaving all existing history untouched. The correct way to 'undo' something that's already been pushed and possibly pulled by others.

The one rule of rebasing
Never rebase (or amend, or force-push over) commits that other people have already pulled. Rebasing rewrites commit hashes — everyone who has the old ones now has a history that's diverged from yours, and their next pull turns into a conflict-riddled mess. Rebase freely on branches only you use; on shared branches, use git revert instead.
Auto-squash your fixups
git commit --fixup <sha> creates a commit tagged as a fix for an earlier one. Follow it with git rebase -i --autosquash <sha>~1 and Git automatically reorders and marks it to squash into the right place — no manually dragging lines around in the interactive rebase editor.

Undoing Mistakes

The commands for the moment right after you realize you shouldn't have done that.

git restore <file>
Essential

Discards uncommitted changes to a file, reverting it to how it looked at the last commit. The modern replacement for git checkout -- <file>.

git restore --staged <file>
Handy

Unstages a file — moves it back to 'modified, not staged' — without touching its actual contents. What you want when git add caught more than you meant it to.

git reflog
Advanced

Shows a chronological log of every position HEAD has ever pointed to on this machine, including commits a reset --hard or a rebase seemingly 'deleted.' Those commits are still there until Git eventually garbage-collects them.

a1b2c3d HEAD@{0}: reset: moving to HEAD~1 e4f5g6h HEAD@{1}: commit: Add password validation h7i8j9k HEAD@{2}: commit: Add login form

git reset --hard HEAD@{1}
Advanced

Once you've found the lost commit's position in git reflog, this snaps your branch straight back to it, undoing an accidental reset or rebase.

git stash
Essential

Shelves all uncommitted changes (staged and unstaged) into a temporary slot and gives you a clean working directory — for when you need to switch branches right now but aren't ready to commit.

git stash pop
Handy

Reapplies the most recently stashed changes to your working directory and removes them from the stash list. Use git stash apply instead if you want to keep the stash around as a backup.

git clean -nfd
Advanced

Dry-runs a cleanup of untracked files and directories — prints exactly what would be deleted without deleting anything. Drop the -n (leaving just -fd) only once you've read that list and are sure.

Tip
Reflog entries aren't kept forever — Git's garbage collector eventually clears unreachable ones (90 days for reachable history, 30 for unreachable, by default). Long enough to save you almost every time, not long enough to treat as permanent storage.
git clean has no reflog safety net
Unlike commits, files deleted by git clean were never tracked by Git in the first place — there's no reflog entry to recover them from. Always run the -n dry-run version first.

Inspecting & Searching

For when you need to know who, when, or which commit — not just what.

git log -p -- <file>

Shows the complete commit history of a single file, including the full diff at every change — the file's biography.

git blame <file>
Handy

Annotates every line of a file with the commit and author who last changed it. The starting point for 'why is this line here' archaeology.

git show <sha>

Displays one commit's full metadata (author, date, message) plus the diff it introduced.

git grep "pattern"
Handy

Searches every tracked file in the repo for a string or regex — faster than a filesystem-wide grep since it only looks at what's checked into Git.

git bisect start
Advanced

Begins a binary search through history for the exact commit that introduced a bug. Mark a known-bad commit and a known-good one, and Git checks out the midpoint for you to test — repeat until it narrows down to a single commit.

git bisect start git bisect bad # current commit is broken git bisect good v1.2.0 # this tag was fine # ...test each checkout, then: git bisect good # or: git bisect bad git bisect reset # when done, return to normal

Automate a bisect
If you have a script or test command that exits non-zero on failure, run git bisect run ./test.sh right after git bisect good and Git will check out and test every candidate commit itself — no manual testing loop required.

Tags & Releases

Named, (usually) permanent bookmarks — what most projects use to mark a release.

git tag -a v1.0.0 -m "First stable release"
Handy

Creates an annotated tag — stores its own author, date, and message, and is what git describe and most release tooling expect. Use this over a lightweight tag for anything you'll actually ship.

git tag v1.0.0

Creates a lightweight tag — just a named pointer to a commit, with no extra metadata. Fine for quick personal bookmarks, not ideal for public releases.

git push origin v1.0.0
Essential

Tags aren't pushed automatically with git push — you have to push them explicitly, one at a time, or all at once with --tags below.

git push origin --tags
Handy

Pushes every local tag that isn't already on the remote, in one command.

git tag -d v1.0.0

Deletes a tag locally only. Pair with the next command if it's already been pushed.

git push origin --delete v1.0.0
Advanced

Deletes a tag from the remote. Deleting a tag doesn't delete the commit it pointed to — just the bookmark.

Aliases & Productivity

Small, one-time setup that pays for itself within a week.

git config --global alias.st "status -s"
Handy

Creates git st as a shorthand for a compact status. Once set, aliases work exactly like built-in commands.

git config --global alias.co switch

Creates git co as a shorthand for git switch — a habit carried over from the git checkout era that still saves keystrokes.

git config --global alias.lg "log --oneline --graph --all --decorate"
Handy

Turns the long visual-history command from the Basics section into a two-letter git lg.

git config --global alias.undo "reset HEAD~1 --soft"
Handy

A one-word safety net for the single most common 'wait, undo that commit' moment — see the Rewriting History section for what --soft actually preserves.

git config --global core.excludesfile ~/.gitignore_global
Advanced

Points Git at a personal, machine-wide .gitignore for editor files, OS clutter (.DS_Store, Thumbs.db), and other things that have nothing to do with any specific project — so you never have to add them to a project's own .gitignore.

Pro trick
List every alias you've set with git config --get-regexp alias. Worth running after a fresh machine setup to confirm your dotfiles actually carried over.

Quick Reference

Already know Git — just need the exact syntax? Search instead of scrolling.

git init

Initialize a new repository in the current directory

git clone <url>

Copy a remote repository to your machine

git config --global user.name "Name"

Set the name attached to your commits

git config --global user.email "you@example.com"

Set the email attached to your commits

git config --global init.defaultBranch main

Set the default branch name for new repos

git status

Show changed, staged, and untracked files

git add <file>

Stage a file's changes for the next commit

git add -p

Interactively stage specific hunks instead of whole files

git commit -m "message"

Record staged changes as a new commit

git commit -am "message"

Stage all tracked changes and commit in one step

git diff

Show unstaged changes against the last commit

git diff --staged

Show staged changes not yet committed

git log --oneline --graph --all

Compact visual history across all branches

git branch

List local branches

git switch -c feature-x

Create and switch to a new branch

git switch main

Switch to an existing branch

git switch -

Switch back to the previously checked-out branch

git merge feature-x

Merge feature-x into the current branch

git branch -d feature-x

Delete a branch already merged in

git branch -D feature-x

Force-delete a branch, merged or not

git branch -m old new

Rename a branch

git remote -v

List configured remotes and their URLs

git remote add origin <url>

Add a new remote named origin

git fetch origin

Download remote changes without merging them

git pull

Fetch and merge the current branch's upstream

git pull --rebase

Fetch and replay local commits on top instead of merging

git push origin feature-x

Push a branch to the remote

git push -u origin feature-x

Push and set the upstream tracking branch

git commit --amend

Edit the most recent commit's message or contents

git rebase main

Replay the current branch's commits on top of main

git rebase -i HEAD~3

Interactively edit, squash, or reorder the last 3 commits

git cherry-pick <sha>

Apply one specific commit onto the current branch

git reset --soft HEAD~1

Undo the last commit, keep its changes staged

git reset --hard HEAD~1

Undo the last commit and discard its changes entirely

git revert <sha>

Create a new commit that undoes a previous one

git restore <file>

Discard uncommitted changes to a file

git restore --staged <file>

Unstage a file without discarding its changes

git reflog

Show every place HEAD has pointed, including "lost" commits

git stash

Temporarily shelve uncommitted changes

git stash pop

Reapply and remove the most recent stash

git clean -nfd

Preview which untracked files/directories would be deleted

git log -p -- <file>

Show the full diff history of one file

git blame <file>

Show who last changed each line and in which commit

git bisect start

Begin a binary search for the commit that introduced a bug

git show <sha>

Show a single commit's metadata and diff

git grep "pattern"

Search tracked files for a string, fast

git tag -a v1.0.0 -m "message"

Create an annotated tag

git push origin v1.0.0

Push a single tag to the remote

git push origin --tags

Push all local tags to the remote

git config --global alias.st "status -s"

Create a custom shorthand command

git push --force-with-lease

Force-push, but refuse if someone else pushed first

51 of 51 commands

Common Use Cases

Real situations, not just isolated commands — the sequence that actually gets you out of each one.

You committed straight to main instead of a feature branch

Save the work on a proper branch, then rewind main to where it was:

  1. git branch feature-x
  2. git reset --hard origin/main
  3. git switch feature-x

You need to undo the last commit but keep the changes

A soft reset un-commits without touching your files:

  1. git reset --soft HEAD~1
  2. // edit, re-stage, re-commit

You already pushed a commit that needs to go

Don't reset shared history — add a commit that undoes it instead:

  1. git revert <sha>
  2. git push

Your last 3 commits are messy "wip" commits before opening a PR

Squash them into one clean commit with an interactive rebase:

  1. git rebase -i HEAD~3
  2. // mark the last two 'squash', save

You started coding on the wrong branch, nothing committed yet

Shelve the work, switch, then bring it back:

  1. git stash
  2. git switch correct-branch
  3. git stash pop

You deleted a branch and immediately regretted it

Find its last commit in the reflog, then re-create the branch there:

  1. git reflog
  2. git branch recovered-branch <sha>

Debugging & Troubleshooting

The exact errors Git prints, decoded — and what to type in response.

fatal: not a git repository (or any of the parent directories): .git

You're running a Git command outside of any Git repository. Either cd into the project folder, or if this is meant to be a brand-new project, run git init first.

Please tell me who you are. Run git config --global user.email ...

Git won't let a commit happen with no identity attached. Run the two commands from the Setup section — user.name and user.email — once, and every future commit picks them up automatically.

error: failed to push some refs (fetch first / non-fast-forward)

The remote has commits you don't have locally — usually because someone else pushed first. Pull (or fetch + rebase) to bring your branch up to date, resolve any conflicts, then push again.

git pull --rebase
fatal: refusing to merge unrelated histories

You're trying to merge or pull from a repository that shares no common commit with yours — often when a local git init'd project is connected to a remote that already has its own initial commit (like a README created on GitHub).

git pull origin main --allow-unrelated-histories
You are in 'detached HEAD' state

You checked out a specific commit or tag instead of a branch, so new commits wouldn't belong to any branch and could get lost. If you want to keep working from here, create a branch right now; if you were just looking around, switch back to a real branch.

git switch -c save-my-work
CONFLICT (content): Merge conflict in <file>

Two branches changed the same lines. Open the file, resolve the <<<<<<< / ======= / >>>>>>> markers by hand (see the callout in Branching & Merging), stage the file, then finish the merge or rebase.

git add <file> && git commit
A secret or credential got committed and pushed

Deleting it in a new commit is not enough — it's still sitting in history and in anyone's clone. Rotate/revoke the credential immediately, treat it as compromised, then use a history-rewriting tool (git filter-repo, or the BFG Repo-Cleaner) to strip it from every commit before force-pushing.

Things to Remember

If you forget everything else on this page, keep these.

  • Commit early and often — small commits are easier to revert, bisect, and review than one giant one.
  • git pull is fetch + merge under the hood; prefer --rebase on branches only you use to avoid noisy merge-bubble commits.
  • Never rewrite history (rebase, amend, force-push) on commits others have already pulled — use git revert on shared branches instead.
  • reset moves history backward; revert adds a new commit on top. Use reset locally, revert once something's already shared.
  • Nothing is truly gone the moment you reset --hard or rebase — git reflog is your safety net for about 90 days.
  • git status before git add, git diff --staged before git commit — a five-second habit that catches most accidental commits.
  • Prefer git switch and git restore for day-to-day work; git checkout still works but does too many unrelated things at once.
  • When you do need to force-push, use --force-with-lease — it refuses if someone else pushed in the meantime, plain --force doesn't.
  • A handful of aliases (st, co, lg) save more keystrokes over a year than any GUI shortcut ever will.

Common Use Cases

Recall the exact flags for an interactive rebase before cleaning up a feature branch's commit history
Figure out whether to reach for reflog, revert, or reset --hard after a mistake — before you make it worse
Look up the safe way to force-push, rename a branch, or resolve a detached HEAD mid-terminal-session
Search the quick-reference table for a command's exact syntax instead of digging through git --help output

About Git Cheat Sheet

Git's own command-line help is technically complete and practically useless the first fifty times you read it — "git reset [<mode>] [<commit>]" tells you the syntax, not when you'd reach for --soft over --hard, or why your coworker's advice to "just force push" made things worse. Most cheat sheets make the same mistake: an alphabetized wall of commands with no sense of when you'd actually use each one, copied from documentation that was already copied from documentation.

This one is organized the way you actually learn Git — starting from the commands you'll type in the first five minutes of any project (status, add, commit, log), through the ones that come up once you're collaborating (branching, remotes, merge conflicts), and finally into the commands that only matter once something has already gone wrong (reflog, cherry-pick, interactive rebase, detached HEAD recovery). Each command includes a plain-English explanation of what it actually does to your repository, not just what flags it accepts.

Every section calls out the mistakes that trip people up specifically — force-pushing over a shared branch, confusing git reset with git revert, losing commits that reflog can still save, rebasing a branch other people have already pulled. There's a searchable quick-reference table for the moment you already know what you're looking for and just need the exact syntax, plus a troubleshooting section decoded from the actual error messages Git prints (not a paraphrase of them).

Like every tool on AllCoreKit, this page runs entirely in your browser — the quick-reference search filters instantly as you type using nothing but local JavaScript, and nothing about what you search for or read is ever sent anywhere or logged.

Frequently Asked Questions