Git Commands Cheatsheet

The git commands developers actually use, with patterns and recovery recipes.

By Λ · Updated May 18, 2026

I have written this list four times in my notes over the years. This is the consolidated version: the commands I actually use, grouped by what you are trying to do.

Daily basics

Status and history

git status                    # what changed
git log --oneline -20         # last 20 commits
git log --graph --oneline -20 # with branch graph
git diff                      # unstaged changes
git diff --staged             # staged changes

Make a commit

git add .                       # stage everything
git add -p                      # stage interactively (preferred)
git commit -m "message"
git commit --amend              # change the most recent commit
git commit --amend --no-edit    # add staged changes to last commit, keep message

Branches

git branch                          # list branches
git switch main                     # check out main
git switch -c feature/x             # create + check out
git branch -d feature/x             # delete merged branch
git branch -D feature/x             # FORCE delete unmerged branch
git merge --ff-only origin/main     # fast-forward only (safe pull pattern)

Sync with remote

git fetch
git pull --rebase                   # safer than plain pull
git push
git push -u origin feature/x        # first push of a new branch

Inspecting things

git show HEAD                       # last commit
git show abc123                     # specific commit
git show abc123:path/to/file.js     # file at a specific commit
git blame path/to/file.js           # who wrote each line
git log --follow path/to/file.js    # history including renames
git log --all --source -- file.js   # find which branch added a file

Rebase and merge

Update feature branch with latest main

git switch feature/x
git fetch origin
git rebase origin/main
# resolve conflicts...
git rebase --continue
git push --force-with-lease  # NEVER plain --force on shared branches

--force-with-lease refuses to overwrite if someone else pushed in the meantime. Always use this instead of --force.

Interactive rebase (squash, reword, drop commits)

git rebase -i HEAD~5         # last 5 commits
# In the editor, change "pick" to:
#   reword - keep commit, change message
#   squash - combine with previous
#   fixup  - combine with previous, discard message
#   drop   - delete commit

Merge a feature branch

git switch main
git merge --no-ff feature/x          # always create merge commit (preserves history)
git push

Stash (temporary save)

git stash                       # save uncommitted changes
git stash -u                    # include untracked files
git stash list                  # see stashes
git stash pop                   # apply + remove most recent
git stash apply stash@{2}       # apply specific stash, keep it

Recovery

Oh no, I lost a commit

git reflog                      # see EVERY HEAD pointer change
git checkout abc123             # restore by hash
# or
git reset --hard abc123         # destructive but works

As long as you have not run git gc, commits survive in the reflog for 90 days.

Undo a commit (keep changes)

git reset --soft HEAD^         # uncommit but keep staged
git reset HEAD^                # uncommit, keep changes unstaged

Throw away local changes (destructive)

git checkout -- file.js        # discard one file
git restore file.js            # same, modern syntax
git reset --hard HEAD          # discard ALL uncommitted changes

No undo for these. Make sure you do not need the changes first.

Revert a pushed commit safely

git revert abc123              # creates new commit that undoes abc123
git push

Use revert on shared branches. Never reset --hard on something others have pulled.

Finding things

Find which commit introduced a bug

git bisect start
git bisect bad                  # current commit is bad
git bisect good v1.0            # this old version was good
# git will checkout commits between them
# at each, test and run:
git bisect good                 # or git bisect bad
# eventually: "abc123 is the first bad commit"
git bisect reset                # return to where you started

Search history

git log -S "stringToFind"       # commits that added/removed the string
git log --grep="bug"            # commits whose message matches
git log --author="Alice"        # by author

Working with remotes

git remote -v                          # list remotes
git remote add upstream <url>          # add another remote
git fetch upstream
git push origin --delete old-branch    # delete remote branch
git ls-remote --heads origin           # list remote branches without fetching

Tags and releases

git tag v1.0.0
git tag -a v1.0.0 -m "Release notes"     # annotated tag (preferred for releases)
git push origin v1.0.0
git push --tags                           # push all tags
git tag -d v1.0.0                         # delete local tag
git push origin --delete v1.0.0           # delete remote tag

Cherry-pick (pull commits from another branch)

git cherry-pick abc123                 # one commit
git cherry-pick abc123..def456         # range
git cherry-pick --abort                # if conflicts and you give up

Useful aliases

# Add to ~/.gitconfig:
[alias]
  st = status
  co = checkout
  br = branch
  ci = commit
  unstage = reset HEAD --
  last = log -1 HEAD
  visual = log --graph --pretty=format:'%C(yellow)%h%Creset -%C(red)%d%Creset %s %C(cyan)(%cr)%Creset' --abbrev-commit
  amend = commit --amend --no-edit
  undo = reset HEAD~1 --mixed
  force = push --force-with-lease

Last updated