Git Advanced: History, Workflows and Automation
Hooks, CI and Recovery
In this lesson you will
- Use a Git hook to check work before a commit
- Describe what continuous integration does and read a simple workflow file
- Respond correctly when a secret is committed
Introduction
Good teams do not rely on people remembering to run tests. They automate. Git offers hooks on your computer, and platforms offer continuous integration (CI) on the server. This lesson also covers the worst case: leaking a secret.
Git hooks
A hook is a script that Git runs at certain moments. Hooks live in .git/hooks/ and must be executable. A common one is pre-commit, which runs before each commit and can block it.
Terminal
#!/bin/sh
# .git/hooks/pre-commit
if git diff --cached | grep -q "console.log"; then
echo "Remove console.log before committing."
exit 1
fiA non-zero exit code stops the commit. Other hooks include commit-msg (check a message format) and pre-push (run tests before pushing).
Hooks in .git/hooks are not shared when others clone the repository. Teams share them using tools that install hooks for everyone, such as Husky for JavaScript or pre-commit for Python. A skipped hook (--no-verify) is a bypass, so hooks help but are not security. The server-side checks are the real gatekeeper.
Quick quiz
What happens if a pre-commit hook exits with a non-zero status?
Continuous integration
CI runs your tests and checks automatically on a server whenever code is pushed or a pull request opens. Problems are found in minutes, and the results show on the pull request.
On GitHub, CI is done with GitHub Actions. A workflow is a YAML file in .github/workflows/:
YAML
name: Tests
on:
pull_request:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm testReading it: it runs on pull requests and pushes to main, checks out the code, installs Node, installs dependencies and runs the tests. Combine it with branch protection that requires this job to pass. Pin action versions and keep secrets in the platform's secrets store, never in the file.
Signing commits
Anyone can set user.name to someone else's name. Signed commits prove who made them, using a GPG or SSH key. Platforms show a "Verified" badge. Teams that need strong provenance enforce it.
Recovery: a secret was committed
If you commit a password, API key or token:
- Revoke or rotate it immediately. Treat it as stolen. This is the most important step, because the secret may already have been copied from the history.
- Remove it from the current code, and store it in an environment variable or secrets manager.
- If you must remove it from history, use a dedicated tool such as
git filter-repoor BFG Repo-Cleaner, then force push and ask collaborators to re-clone. Deleting the file in a new commit is not enough. - Add the file to
.gitignore, and consider a secret scanner in CI.
Other big problems
- Huge files slow repositories. Use Git LFS for large binaries, and avoid committing build output.
- Detached HEAD means you are on a commit, not a branch. Create a branch with
git switch -c new-branchto keep your work. - Lost work: try
git reflogfirst.
Try it yourself
Write a pre-commit hook that blocks commits containing the word "TODO-REMOVE". Then write a GitHub Actions workflow file that runs your project's tests on every pull request.
Summary
- Hooks run scripts on your machine, but CI on the server is the real safety check.
- Workflow files describe what to run, and branch protection can require them to pass.
- If a secret leaks, rotate it first, then clean the history.
Lesson complete
+20 XP
Nice work. Keep going while it is fresh.
Sources and further reading