Why we built pull-pal

2 min read
open sourcedeveloper toolsgit

Every team I've been on has lost an afternoon to the same boring mistake. Someone pushes a branch that's behind the remote, or ships a change the tests would have caught, and the next hour disappears into untangling it. It's never dramatic. It's small, it's avoidable, and it keeps happening.

At some point a friend and I got tired of it and built pull-pal: a tiny CLI that sits in front of git push and refuses to let stale or broken code leave your machine.

What it actually does

pull-pal wraps the push. Before anything hits the remote, it fetches and checks whether your branch is behind the remote default branch, rebases if it is, then finds your project's test suite and runs it. If the tests fail, the push is blocked.

Run pull-pal setup once in a repo and it installs a pre-push hook, so every push goes through the same checks whether it comes from your terminal, your IDE, or a Git GUI.

npm install -g pull-pal   # or pip install pull-pal
 
pull-pal setup
 
git push
# behind origin/main? it rebases first.
# tests failing? the push never leaves your machine.

That's the whole product. No dashboard, no accounts, no telemetry. Everything runs locally.

Zero-config on purpose

The part I care most about is what it doesn't ask of you. There's no config file. pull-pal looks at your project and figures out how to run your tests on its own: npm test or bun test for Node, cargo test for Rust, go test ./... for Go, pytest for Python, and so on through Maven, Gradle, Make, and RSpec.

And when it can't find a test runner? It warns you and lets the push through. That was a deliberate choice. A safety tool that blocks pushes on a guess would get uninstalled within a week. The same thinking is behind the escape hatches: --no-rebase and --no-tests exist because sometimes you know better than the tool, and it should get out of your way when you do.

The lesson I keep relearning

There's a pattern here that shows up in most of my favorite tools: they earn their place by being quiet. pull-pal says nothing on the hundreds of pushes where everything is fine. It only speaks up at the exact moment you were about to make the mistake, and then it's loud enough to stop you.

A tool that's supposed to remove friction shouldn't add a config file you have to babysit, and it shouldn't need a tab open in your browser. It should just sit there, mostly invisible, catching the afternoon you were about to lose.