Git has hundreds of commands; you use about ten of them daily. Here are those ten, plus how to get out of trouble.

A day’s shape

  git switch main && git pull --rebase     # get current
git switch -c feat/login-rate-limit      # branch off
# ... work ...
git add -p                               # stage hunk by hunk, reviewing as you go
git commit -m "Limit login attempts to five per minute"
git push -u origin feat/login-rate-limit
  

git add -p walks you through each hunk and asks whether to include it. It prevents most stray-print-statement accidents on its own.

Commands you’ll use

GoalCommand
Terse statusgit status -sb
See changesgit diff, or git diff --staged for staged ones
One-line loggit log --oneline --graph --decorate -20
Switch branchgit switch <branch>
New branchgit switch -c <branch>
Set work asidegit stash, restore with git stash pop
Take one commitgit cherry-pick <hash>
Prune remote branchesgit fetch --prune

Commit messages

Settling on a format makes history far easier to read later. A widely used convention:

  feat: limit login attempts to five per minute
fix: return 401 instead of 500 for expired tokens
refactor: move auth middleware into auth/
docs: add a rollback step to the deploy runbook
test: cover token refresh failure
chore: update dependencies
  

Keep the subject under 50 characters and in the imperative. If you need a body, leave a blank line and explain why. The diff already says what.

Undoing things

SituationCommand
Fix the last commit messagegit commit --amend
Undo the last commit, keep changesgit reset --soft HEAD~1
Unstage onlygit restore --staged <file>
Throw away file changesgit restore <file>
Revert an already-pushed commitgit revert <hash>
Rewind a branch wholesalegit reset --hard <hash> (careful)
Find a lost commitgit reflog, then git reset --hard <hash>

git reflog is the last safety net. Even commits destroyed by reset --hard are usually still there (90 days by default).

The rule is revert for pushed commits, reset for local ones only. Rewriting shared history breaks everyone else’s clone.

Rebase and merge

  # replay your branch on top of the latest main (linear history)
git switch feat/login
git fetch origin
git rebase origin/main

# on a conflict, fix the files then
git add <file>
git rebase --continue

# to give up
git rebase --abort
  

To tidy commits before pushing, use an interactive rebase.

  git rebase -i origin/main
# change pick to squash (s) to fold a commit into the one above it
  

Settings worth having

  git config --global pull.rebase true          # no merge commits on pull
git config --global push.autoSetupRemote true # -u becomes unnecessary
git config --global init.defaultBranch main
git config --global rerere.enabled true       # remember conflict resolutions
git config --global fetch.prune true
  

Next

To handle PRs and issues without a browser → GitHub CLI

Last updated 19 Aug 2026, 00:00 UTC. history