You pull, start the app, and get Cannot find module 'zod'. You reinstall. Now it is relation "invoice_lines" does not exist. You migrate. Then a crash because STRIPE_WEBHOOK_SECRET is undefined, since someone added it to .env.example and your .env never got it.
The pulled code was fine every time. Your environment fell behind: git updates the files that describe it (lockfiles, migrations, .env.example, Dockerfiles, .nvmrc), but not the installed packages, database, .env or containers they describe.
The checklist
After a pull, merge or checkout, diff the old HEAD against the new one and look for:
| Changed | Run |
|---|---|
package-lock.json, yarn.lock, pnpm-lock.yaml
|
npm ci, yarn install --frozen-lockfile, pnpm install --frozen-lockfile
|
poetry.lock, uv.lock, requirements*.txt
|
poetry install, uv sync, pip install -r ...
|
New files in migrations/, db/migrate/, alembic/versions/
|
your framework's migrate command |
New keys in .env.example
|
add them to .env
|
Dockerfile, compose.yml
|
docker compose up -d --build |
.nvmrc, .tool-versions
|
switch versions |
.gitmodules, .terraform.lock.hcl
|
git submodule update --init --recursive, terraform init
|
Two details save time. Use npm ci, not npm install, after someone else changed the lockfile: it installs exactly what the lockfile says. And a package.json change that only touches scripts needs no reinstall at all.
Why hooks do not cover it
A post-merge hook can reinstall for you, but hooks are not cloned (every developer installs them by hand), post-merge does not fire on checkout, and they run commands without asking.
Let the editor build the list
I built AfterPull, a free VS Code extension that watches HEAD in every repo in your workspace. When it moves, it diffs old vs new and shows AfterPull: 3 things to do after this pull, with a panel of chores: dependencies in twelve package managers, new migrations, missing .env keys (one click appends them, existing keys untouched), container rebuilds, toolchain changes, submodules and Terraform. It is monorepo-aware and each command runs in its own folder.
Nothing runs on its own: each command starts as a visible task after your click, and "Run all" lists every command first. Your own commits are skipped. No network, no telemetry.
code --install-extension jaytankdev.afterpull
Source (MIT): github.com/jay-tank/afterpull
Full write-up (the full checklist, why hooks leak, prior art, limitations, FAQ): Your app broke after git pull? The after-pull checklist every team forgets
Top comments (0)