Git cheat sheet

Status: đźź© COMPLETE Last updated: 2026-06-21 Plain-English tagline: Daily-use Git commands grouped by intent. For the why, read Git basics.


Setup (once per machine)

git config --global user.name "George"
git config --global user.email "you@example.com"
git config --global init.defaultBranch main
git config --global core.autocrlf true            # Windows
git config --global pull.rebase false             # use merge for pulls (default)
git config --global core.editor "code --wait"     # VS Code as Git editor

See what changed

git status                       # what's modified, staged, untracked
git diff                         # unstaged changes (vs working dir)
git diff --staged                # staged but uncommitted changes
git diff main feature/x          # difference between two branches
git diff HEAD~1                  # what changed since the previous commit
git log --oneline -10            # last 10 commits, one line each
git log --graph --oneline --all  # full history as ASCII graph
git blame <file>                 # who changed each line of a file
git show <hash>                  # everything about one commit

Stage and commit

git add <file>                                   # stage one file
git add .                                        # stage everything in current folder
git restore --staged <file>                      # unstage (move back to working dir)
git commit -m "Add dark mode toggle"             # commit with a one-line message
git commit -m "Add X" -m "Longer explanation."   # two -m flags = title + body
git commit --amend -m "Better message"           # rewrite the last commit (local only)
git commit --no-verify -m "..."                  # skip pre-commit hooks (use sparingly)

Branches

git branch                              # list local branches
git branch -a                           # include remote branches
git switch main                         # switch to existing branch
git switch -c feature/dark-mode         # create AND switch
git branch -m new-name                  # rename current branch
git branch -d feature/old               # delete (must be merged)
git branch -D feature/old               # force-delete (even if unmerged)
git push origin --delete feature/old    # delete on the remote

Sync with the remote

git fetch                               # download remote changes, don't apply
git pull                                # fetch + merge in one step
git pull --rebase                       # fetch + rebase instead of merge
git push                                # push current branch
git push -u origin feature/x            # first push: set upstream
git push --force-with-lease             # force push, but refuse if remote moved
git push origin --delete feature/x      # delete the remote branch

Merge and rebase

git merge feature/x                     # merge feature/x INTO current branch
git merge --abort                       # back out of a failed merge
git rebase main                         # replay current branch onto main's tip
git rebase --continue                   # after fixing a conflict during rebase
git rebase --abort                      # back out of a rebase
git rebase -i HEAD~5                    # interactive: squash, reorder, drop, reword

Undo

git restore <file>                      # discard unstaged changes to a file
git reset HEAD~1                        # uncommit last; keep changes (unstaged)
git reset --soft HEAD~1                 # uncommit last; keep changes (staged)
git reset --hard HEAD~1                 # uncommit last; THROW AWAY changes
git revert <hash>                       # NEW commit that undoes <hash> (safe for pushed)
git reflog                              # see history of where HEAD has been
git reset --hard <hash-from-reflog>     # recover from "I lost work"

Stash (set aside uncommitted work)

git stash                               # tuck away uncommitted changes
git stash list                          # see what's stashed
git stash pop                           # apply most recent stash + remove
git stash apply stash@{2}               # apply a specific stash without removing
git stash drop stash@{0}                # delete a specific stash
git stash clear                         # delete all stashes

Remotes

git remote -v                                              # list remotes
git remote add origin https://github.com/u/r.git           # add a remote
git remote set-url origin git@github.com:u/r.git           # change a remote URL
git remote remove origin                                   # remove

Clone / fresh start

git clone https://github.com/u/r.git                       # full clone (HTTPS)
git clone git@github.com:u/r.git                           # via SSH
git clone --depth 1 https://github.com/u/r.git             # shallow clone (faster)
git clone -b feature/x https://github.com/u/r.git          # clone a specific branch

Common workflows

A fresh feature, start to merge

git switch main
git pull
git switch -c feature/dark-mode
# ... work ...
git add lib/theme.ts components/Navbar.tsx
git commit -m "Add dark mode toggle"
git push -u origin feature/dark-mode
# (open PR via GitHub UI or `gh pr create`)
# (after PR is merged)
git switch main
git pull
git branch -d feature/dark-mode

”I broke something — get me back"

git reflog                              # find a recent good commit
git reset --hard <hash>                 # snap back

"I committed to the wrong branch"

git branch feature/x                    # create the branch you meant
git reset --hard HEAD~1                 # move current branch back one
git switch feature/x                    # your work is now on feature/x

"I want a clean linear history before opening a PR”

git rebase -i HEAD~5                    # squash/reorder commits
git push --force-with-lease             # update the remote

Common gotchas

  • .env* files in Git history are leaked even if you delete them later. Add to .gitignore BEFORE the first commit.
  • git push --force overwrites teammates’ work. Use --force-with-lease instead.
  • git reset --hard discards uncommitted changes permanently. Stash first if uncertain.
  • git add . can stage secret files you didn’t mean to commit. Always git status before committing.
  • git checkout is overloaded — switches branches AND discards file changes. Prefer git switch and git restore for clarity.
  • Detached HEAD lets commits get lost. If git checkout <hash> warns you, create a branch before committing: git switch -c rescue-branch.
  • git commit -a skips staging review. Convenient but bypasses the “review what’s in this commit” benefit.
  • Windows line endings (CRLF) vs Unix (LF). Use git config core.autocrlf true on Windows to avoid spurious “whole file changed” diffs.

See also


Sources