Advanced Git

You can commit, branch, merge and push. Then a branch turns up with a commit called wip in it, a test that passed last month fails, or a teammate asks who changed a line and why. The basics do not cover those.
This series is for people who finished the first Git series, Commit to Success, or who already know what a branch and a remote are. Some lessons also use stash and commit --amend, which that series teaches.
The promise is small. By the end, you can reshape a branch before anyone reviews it, track down a bad commit, and work with big repositories and shared hooks without guessing.
Every lesson has a practice terminal where you type the real commands, and a few questions or a challenge at the end. The commands and the output on the page were run in a scratch repository with Git 2.45.2 before they were printed.
Try two moves first
Two small labs run right here. Nothing is sent anywhere and nothing is saved, and neither one touches a real repository.
Rebase Bench
Set an action for six toy commits, move them around, and see the history that git rebase -i would leave.
With JavaScript on, this becomes a list you can edit. Without it, here is one example. This todo list picks two commits, squashes one into the commit before it, and fixes up another:
pick 53efffd wip
pick 0b044f0 Add search box
squash 60bc230 fix typo
pick b77d7a4 Add search results
fixup 6a7b3ea Fix typo in search box
pick 7f3690c Update README
Six commits go in and four come out. Squash keeps both messages, so "fix typo" joins "Add search box". Fixup throws its message away, so "Fix typo in search box" disappears.
e86450a Update README
8edddc0 Add search results
c9846f6 Add search box
also: fix typo
53efffd wip
6718b5b Start project
Bisect Hunt
One of sixteen commits broke something, so test commits to narrow it down, or let git bisect choose and just answer good or bad.
With JavaScript on, this is a row of sixteen commits with a hidden bad one. Without it, here is a worked example where commit 11 is the bad one:
- Test commit 8: good. The bad commit is later, so commits 9 to 16 are left.
- Test commit 12: bad. It is this one or earlier, so commits 9 to 12 are left.
- Test commit 10: good. Commits 11 and 12 are left.
- Test commit 11: bad. That is the first bad commit.
Found it in 4 steps (best possible: 4). Each test cuts the range in half, which is why sixteen commits never need more than four.
Pick a lesson by goal
| I want to… | Read |
|---|---|
| Tidy my commits before anyone reviews them | Interactive Rebase, Done Properly |
| Find the commit that broke something | Find the Commit That Broke It |
| Find who changed a line, or when a word appeared | Dig Through History |
| Work with a huge repository without downloading all of it | Big Repositories, Shallow, Partial and Sparse |
| Run checks before a commit is created | Hooks You Will Actually Use |
| Make Git faster to type and safer by default | Make Git Yours |
| Remove a secret I committed, in the right order | You Committed a Secret |
If you are not sure where to start, start with the first one.
- Interactive Rebase, Done Properly.Tidy a branch before review with git rebase -i. Squash, reword and fixup commits, fold in a late fix, and recover from a bad rebase.
- Find the Commit That Broke It.Find the exact commit that introduced a bug with git bisect, first by hand and then by handing the job to a script.
- Dig Through History.Find who changed a line, when a string appeared or vanished, and how a function changed, using git blame, log -S and log -L.
- Big Repositories, Shallow, Partial and Sparse.Clone a large repository with only its latest commit, without file contents, or with only the folders you use, and know what each costs.
- Hooks You Will Actually Use.Write a pre-commit and a commit-msg hook that run on Windows, share them with the team, and know what a hook can never enforce.
- Make Git Yours.Find where each Git setting comes from, turn on six defaults that each stop one annoyance, and write aliases that do not hide danger.
- You Committed a Secret: What to Do, in Order.A key is already pushed in a commit. Revoke it first, then remove it from history with git filter-repo and get your team onto the new history.