--- description: Find the commit that introduced a regression using git bisect run with a verified check script argument-hint: ["check command"] [bad-ref] --- Arguments: $ARGUMENTS Parse: first argument is GOOD. A quoted string is the CHECK command. Another ref after it is BAD (default `HEAD`). If GOOD is missing, ask. If CHECK is missing, ask how the regression shows up and propose the narrowest command that fails on it. ## 1. Preconditions - `git status --porcelain`: if not clean, tell the user and ask whether to `git stash push -u -m bisect-autostash`. Do not stash without a yes. - Record the current branch with `git rev-parse --abbrev-ref HEAD` to return to later. - Confirm GOOD is an ancestor of BAD: `git merge-base --is-ancestor GOOD BAD`. ## 2. Write the check script Create `.git/bisect-check.sh` (inside `.git` so checkouts do not modify it) and `chmod +x` it: ```sh #!/bin/sh # Exit 0 = good, 1-124/126-127 = bad, 125 = skip (cannot test this commit) set -u # Install dependencies only when needed. Adapt to the project, e.g.: # npm ci --silent || exit 125 # uv sync --quiet || exit 125 # composer install -q || exit 125 # Build step if required: # npm run build --silent || exit 125 status=$? [ "$status" -eq 0 ] && exit 0 exit 1 ``` Rules for the script: - Use exit 125 for failures unrelated to the bug (dependency install or build errors), so git skips those commits. - Keep the check narrow and deterministic: one test file or one command. If the bug is flaky, run the check several times and treat any failure as bad, and say so. - Avoid network-dependent checks where possible. ## 3. Verify the check separates good from bad - `git checkout --quiet GOOD && .git/bisect-check.sh; echo $?` -> must be 0. - `git checkout --quiet BAD && .git/bisect-check.sh; echo $?` -> must be non-zero and not 125. - Return to the original branch. If either result is wrong, stop and fix the check with the user. Do not bisect with an unverified check. ## 4. Bisect ``` git bisect start BAD GOOD git bisect run .git/bisect-check.sh git bisect log ``` Then always run `git bisect reset`, even if something failed. Restore the stash if you created one (`git stash pop`), and confirm the original branch is checked out. ## 5. Explain - `git show --stat ` and read the diff. - Identify the specific hunk most likely responsible and explain the mechanism. - If bisect reported several candidates because of skipped commits, list them all. ``` Range: GOOD..BAD ( commits), steps, skipped First bad commit: (, ) Likely cause: (`file:line`) Check used: ``` Offer to write a fix and a regression test. Delete `.git/bisect-check.sh` when done unless the user wants to keep it.