CS Fundamentals's Linux, Git & Tooling covers what a commit, a branch, and the object graph actually are underneath these commands. This page assumes add/commit/push/pull are already muscle memory and covers the commands that actually save you once something's gone wrong or history needs reshaping.
Interactive rebase
The tool for cleaning up commit history before it's shared — squashing, reordering, rewording, or dropping commits.
git rebase -i HEAD~5 # interactively rebase the last 5 commitsgit rebase -i main # rebase the current branch onto main, interactively
In the editor that opens, each commit line takes a verb: pick (keep as-is), reword (keep, edit message), edit (pause here to amend), squash/fixup (merge into the previous commit), drop (remove).
git rebase --continue # after resolving a conflict or finishing an `edit` stopgit rebase --abort # bail out, return to the pre-rebase stategit rebase --skip # skip the current commit entirely
Bisect: finding which commit broke something
Binary search over history for the commit that introduced a bug.
git bisect startgit bisect bad # current commit is brokengit bisect good v1.2.0 # this earlier tag/commit was known good# git checks out a midpoint commit -- test it, then:git bisect good # or `git bisect bad`, repeat until it narrows to one commitgit bisect reset # done -- return to the original HEAD
Reflog: recovering "lost" commits
git log only shows reachable history. reflog shows everywhere HEAD has pointed, including commits a reset --hard or a bad rebase seemed to delete — they're still there until garbage collected.
git reflog # every HEAD movement in this repo, most recent firstgit reset --hard HEAD@{2} # jump back to what HEAD pointed to 2 moves agogit checkout <sha-from-reflog> # inspect a "lost" commit directlygit branch recovered-work <sha> # turn it back into a real branch
Worktree: multiple branches checked out at once
Avoids the stash-switch-stash dance when you need to work on two branches simultaneously without two full clones.
git worktree add ../hotfix hotfix-branch # new working directory, existing branchgit worktree add ../new-feature -b feature/x # new working directory AND new branchgit worktree list # show all active worktreesgit worktree remove ../hotfix # clean up when done
Cherry-pick and stash
git cherry-pick <sha> # apply one specific commit onto the current branchgit cherry-pick <sha1>..<sha2> # apply a range of commitsgit cherry-pick --continue # after resolving a conflict mid-cherry-pickgit stash # shelve uncommitted changes, working dir goes cleangit stash -u # also stash untracked filesgit stash list # see all stashesgit stash pop # reapply the most recent stash and drop itgit stash apply stash@{1} # reapply a specific stash, keep it in the listgit stash drop stash@{1} # delete a stash without applying it
Diagnosing and diffing
git log --oneline --graph --all # compact, visual branch historygit log -p -- path/to/file # full diff for every commit touching a filegit log -S"searchTerm" # commits that added/removed a string (the "pickaxe")git blame path/to/file # who last touched each line, and in which commitgit diff HEAD~3 # working tree vs. 3 commits agogit diff branch-a..branch-b # what changed between two branches