I prepared a small Laravel playground with a shipping price bug and a deliberately long commit history to demonstrate automated regression hunting with Pest and git bisect.
The endpoint should charge €5.90 for a domestic parcel weighing up to and including one kilogram. At exactly 1000 grams, it returns €9.90. That gives us a specific behaviour to put into a Pest feature test: call the shipping quote route with weight_grams: 1000 and assert that price_cents is 590.
Once that test reproduces the failure, it can also drive the search through Git history. In the playground, 06bc68c5 is a known good revision:
git bisect start git bisect bad git bisect good 06bc68c5 git bisect run php artisan test --filter=ShippingQuote Git checks out candidate revisions and runs the test, narrowing the range according to the result. The search identifies a refactor to a match expression:
return match (true) { $weightGrams < 1000 => 590, $weightGrams <= 5000 => 990, default => 1590, }; The first condition used to be <= 1000. Changing it to < 1000 sends a parcel weighing exactly one kilogram into the next price band.
For this example, the new test stays untracked so it remains available as Git moves between revisions. Once the search finishes, git bisect reset returns to the original checkout.
The practical caveat is that the test must run reliably across the history being searched. A dependency or application boot failure could otherwise classify a revision as bad for an unrelated reason. For revisions that cannot be tested, a wrapper script can return 125 to tell Git to skip them, as described in the Git documentation (https://git-scm.com/docs/git-bisect#_bisect_run).
I wrote up the full walkthrough on my blog (https://www.maiobarbero.dev/articles/find-laravel-bug-pest-git-bisect/), and the playground repository (https://github.com/maiobarbero/laravel-pest-bisect) is available if you want to try the search yourself.
[link] [留言]