Git #
Day-to-day commands plus the intermediate moves: rebase, reset, stash, reflog.
Configuration #
One-time identity, plus aliases that pay for themselves. --global writes to ~/.gitconfig; omit it for repo-local settings.
git config --global user.name "Anguished Turtle"
git config --global user.email you@example.com
git config --global init.defaultBranch main
git config --global pull.rebase true # rebase, don't merge, on pull
git config --global alias.lg "log --oneline --graph --decorate --all"
Branching & merging #
Modern Git uses switch / restore instead of the overloaded checkout.
git switch -c feature/login # create and switch (= checkout -b)
git switch main # move back
git branch -d feature/login # delete a merged branch (-D forces)
git merge feature/login # fast-forward when possible
git merge --no-ff feature/login # always record a merge commit
A fast-forward just advances the branch pointer; --no-ff keeps an explicit merge commit so the feature's history stays grouped.
Staging & committing #
git add -p # stage hunk-by-hunk, interactively
git commit -m "Add login form"
git commit --amend # rewrite the last commit
git commit --fixup <sha> # queue a fix to autosquash later
git restore --staged file.txt # unstage but keep the edit
Tip:
git add -pis the fastest way to split messy work into clean, reviewable commits: accept (y), skip (n), or split (s) each hunk.
Rebasing & rewriting history #
git rebase main # replay your branch on top of main
git rebase -i HEAD~5 # squash / reorder / edit the last 5
git rebase --autosquash -i main # fold fixup! commits in automatically
git rebase --abort # bail out, restore pre-rebase state
Golden rule: never rebase commits you've already pushed and shared, since it rewrites their SHAs and forces everyone else to reconcile.
Undoing things #
Pick by what you want to keep:
| Goal | Command |
|---|---|
| Discard a working-tree change | git restore file |
| Unstage, keep the change | git restore --staged file |
| Undo last commit, keep changes staged | git reset --soft HEAD~1 |
| Undo last commit, keep changes unstaged | git reset HEAD~1 |
| Throw away the commit and the changes | git reset --hard HEAD~1 |
| New commit that inverts an old one | git revert <sha> |
Safety net:
git refloglists every position HEAD has held, sogit reset --hard <sha>can recover a "deleted" commit.
Stashing & inspecting #
git stash push -m "wip: half-done refactor"
git stash list
git stash pop # reapply and drop the latest stash
git log --oneline --graph --all
git diff main...feature # what feature added since it forked
git blame -L 10,20 app.py # who last touched lines 10-20
git bisect start # binary-search history for a bad commit
Remotes & tracking #
git remote -v # list configured remotes
git fetch origin # download refs without merging
git pull --ff-only # update only if no divergence (safe)
git push -u origin feature/login # push and set upstream tracking
git push --force-with-lease # safer force: refuses if remote moved
--force-with-leaseis the rebase-friendly force push: it overwrites the remote branch only when nobody else has pushed since you last fetched.
Tags & releases #
git tag -a v1.2.0 -m "Release 1.2.0" # annotated tag (recommended)
git tag # list tags
git push origin v1.2.0 # tags don't ride along with commits
git push --tags # push every local tag
Cherry-pick & worktrees #
git cherry-pick <sha> # replay one commit onto HEAD
git worktree add ../hotfix main # check out a branch in a sibling dir
git worktree list # show all linked working trees
A worktree checks out another branch in its own folder, sharing one .git, so you can build or test it without stashing or re-cloning.