Securing a Repo
Course 2, Chapter 9 introduced branch protection as the structural fix for force-push dangers. This chapter covers the full set of protection options properly, adds CODEOWNERS for automatically routing reviews to the right people, and covers signed commits — proving a commit genuinely came from who it claims to.
Branch Protection, the Complete Picture
Settings → Branches → Add branch protection rule, applied to main (or any branch worth protecting):
CODEOWNERS — Automatic Review Routing
A CODEOWNERS file (in the repo root, or .github/, or docs/) maps file paths to the people or teams responsible for them — GitHub automatically requests their review the moment a PR touches a matching path.
# Default owner for everything not matched below
* @philipo
# Database migrations need a specific reviewer every time
/migrations/ @philipo @db-team
# CI/CD configuration
/.github/workflows/ @philipo
Combined with branch protection's "require approval from Code Owners," this turns review routing from a manual, easily-forgotten step ("don't forget to tag someone on the migration!") into something GitHub enforces automatically.
Signed Commits — Proving Authorship
A commit's author name and email (set via git config back in Course 1, Chapter 1) are just text fields — trivially easy to set to anything, including someone else's identity. A signed commit adds a cryptographic signature, proving the commit was created by someone possessing a specific private key.
Setting up GPG signing
$ gpg --full-generate-key
$ # Find the key ID
$ gpg --list-secret-keys --keyid-format=long
$ # Tell git to use it, and sign every commit by default
$ git config --global user.signingkey YOUR_KEY_ID
$ git config --global commit.gpgsign true
$ # Add the public key to GitHub: Settings → SSH and GPG keys → New GPG key
From here, every commit gets signed automatically, and GitHub shows a verification badge on the commit:
SSH signing — a simpler alternative
Git also supports signing with the SSH key you may already have set up (Course 1, Chapter 5) — avoiding GPG entirely:
$ git config --global user.signingkey ~/.ssh/id_ed25519.pub
$ git config --global commit.gpgsign true
Command Reference
| Command | What it does |
|---|---|
| git config --global commit.gpgsign true | Signs every commit automatically going forward |
| git config --global user.signingkey <id> | Sets which key to sign with (GPG key ID or SSH public key path) |
| git commit -S -m "msg" | Signs a single commit explicitly (if not signing by default) |
| git log --show-signature | Shows signature verification status for recent commits |
Chapter 6 Quick Reference
- Branch protection (full set): require PR, require approvals (dismiss on new commits), require status checks, require conversation resolution, require signed commits, restrict pushers, include administrators
- "Include administrators" closes the most commonly forgotten loophole — no bypass for repo owners
- CODEOWNERS — maps file paths to required reviewers, automatically requested on matching PRs
- Signed commits — cryptographically prove WHO created a commit, via GPG or SSH key signing
- git config commit.gpgsign true — signs every future commit automatically
- A signature proves authorship, not code quality — complements review and protection, doesn't replace them
- Next chapter: large repos — Git LFS, shallow clones, sparse checkout, and monorepo strategies