Git for Engineers cheat sheet
84 commands from every lesson of Git for Engineers — Level by Level, on one page.
Set up once
git config --global user.name "Your Name" | Name recorded in your commits |
git config --global user.email you@example.com | Email recorded in your commits |
git config --global init.defaultBranch main | New repositories start on main |
git config --global pull.rebase true | git pull rebases instead of creating merge commits |
git config --list --show-origin | Every setting and the file it comes from |
Look inside
git init / git clone <url> | Start a repository / copy an existing one |
git log --oneline --graph --all | The commit graph with every branch |
git cat-file -p HEAD | The raw commit object: tree, parent, author, message |
git cat-file -p HEAD^{tree} | The snapshot (tree) that commit points to |
git rev-parse HEAD | The full SHA of the current commit |
cat .git/HEAD | Where HEAD points (usually a branch) |
See changes
git status -sb | Short status with the current branch |
git diff | Unstaged changes |
git diff --staged | What the next commit will contain |
git diff main...feature | What a branch changed since it split from main |
Stage and commit
git add -p | Stage change by change (interactive hunks) |
git commit -m "fix(api): return 404 for unknown order" | Commit with a message |
git commit --amend | Fix the last commit (only if not pushed yet) |
git restore --staged <file> | Unstage a file |
Read history
git log --oneline -20 | Last 20 commits, one line each |
git log -p -- path/to/file | Every change to one file, with diffs |
git log -S "max_connections" | Commits that added or removed a string |
git blame -L 40,60 app.py | Who last changed lines 40–60, and in which commit |
git show <sha> | One commit: message and diff |
Branches
git switch -c feature/login | Create a branch and switch to it |
git switch main | Go back to main |
git branch -vv | Local branches with their upstream and last commit |
git branch -d feature/login | Delete a merged branch (-D forces) |
Combine
git merge --ff-only feature/login | Merge only if it's a fast-forward |
git merge --no-ff feature/login | Always create a merge commit |
git rebase main | Replay the current branch's commits on top of main |
git rebase -i HEAD~4 | Reorder, squash or reword the last 4 commits |
Conflicts
git status | Lists conflicted files |
git diff --name-only --diff-filter=U | Only the conflicted files |
git add <file> && git merge --continue | Mark resolved and finish a merge |
git rebase --continue / --abort | Continue or cancel a rebase |
git merge --abort | Cancel a merge and go back |
Remotes
git remote -v | Where fetch and push go |
git remote add upstream <url> | Add the original repository when working from a fork |
git fetch --all --prune | Download all remote updates, drop deleted branches |
git pull --rebase | Fetch and replay your local commits on top |
git push -u origin feature/x | Push a new branch and set its upstream |
git push --force-with-lease | Overwrite your own rewritten branch safely |
Authentication
ssh-keygen -t ed25519 -C you@example.com | Create an SSH key for the Git server |
ssh -T git@github.com | Test SSH authentication |
git config --global credential.helper cache | Cache HTTPS credentials in memory for a while |
Tags and releases
git tag -a v1.4.0 -m "Release 1.4.0" | Annotated release tag |
git push origin v1.4.0 | Publish one tag (git push --tags publishes all) |
git describe --tags | Nearest tag and commits since it, e.g. v1.4.0-3-g3f1c9a0 |
git log v1.3.0..v1.4.0 --oneline | What changed between two releases |
Release branches and hotfixes
git switch -c release/1.4 v1.4.0 | Start a release branch from a tag |
git cherry-pick -x <sha> | Copy a fix onto another branch, recording where it came from |
git branch --contains <sha> | Which branches already include a commit? |
Undo, by situation
git restore <file> | Discard unstaged changes in a file |
git restore --staged <file> | Unstage, keep the changes |
git reset --soft HEAD~1 | Undo the last commit, keep its changes staged |
git reset --hard origin/main | Throw away local commits and changes, match the remote |
git revert <sha> | New commit that undoes <sha> (safe on shared branches) |
git revert -m 1 <merge-sha> | Revert a merge commit |
Park, move, find
git stash push -m "wip login" | Park uncommitted work |
git stash list / git stash pop | See / restore parked work |
git cherry-pick <sha> | Copy one commit onto the current branch |
git reflog | Everywhere HEAD has been, including 'lost' commits |
git branch rescue <sha> | Give a lost commit a branch again |
git bisect start; git bisect bad; git bisect good v1.3.0 | Binary-search for the commit that broke something |
Hooks and scanning
pip install pre-commit && pre-commit install | Enable the hooks in .pre-commit-config.yaml for this clone |
pre-commit run --all-files | Run every hook on the whole repository |
gitleaks detect --source . --verbose | Scan the repository history for secrets |
gitleaks protect --staged | Scan only what you're about to commit |
Signing
git config --global gpg.format ssh | Sign commits with an SSH key |
git config --global user.signingkey ~/.ssh/id_ed25519.pub | Which key signs |
git config --global commit.gpgsign true | Sign every commit |
git log --show-signature -1 | Check the signature on the last commit |
History clean-up
git filter-repo --path secrets.env --invert-paths | Remove a file from all history (after rotating the secret) |
Faster clones
git clone --depth 1 <url> | Only the latest commit (CI builds) |
git clone --filter=blob:none <url> | Partial clone: file contents fetched on demand |
git sparse-checkout set apps/payments charts/ | Only these folders in the working tree |
git lfs track "*.iso" | Store large binaries outside normal Git objects |
git count-objects -vH | How big the repository really is |
Fix common errors
git pull --rebase && git push | Push rejected (non-fast-forward): integrate first |
git switch -c rescue | In detached HEAD with new commits: keep them on a branch |
ssh -vT git@github.com | Debug SSH authentication step by step |
git config --global core.autocrlf input | Normalise line endings on commit (Linux/macOS) |
git submodule update --init --recursive | Fetch submodules after cloning |