fix(config): post-checkout preserves uncommitted pql mutations on branch creation

The post-checkout hook ran 'pql plan rebuild' (drop + replay changelog) on every
branch checkout, including 'git checkout -b'. That silently dropped any pql.db
ticket mutation not yet in the committed changelog — e.g. an in_progress status set
right before cutting a feature branch (hit this session: T-1039/T-1043 reverted to
backlog at branch creation).

Git has no pre-checkout/pre-worktree hook, so capture the changelog at post-checkout
instead: when prev-HEAD == new-HEAD (a branch *creation* — content unchanged, pql.db
already correct), run 'pql plan export --stage' (the same flush the pre-commit hook
does) instead of the destructive rebuild. Real branch *switches* (prev != new) still
rebuild to match the branch's changelog.

Verified: simulating a same-HEAD checkout with an uncommitted in_progress mutation now
preserves it (previously reverted).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-16 12:05:19 +02:00
co-authored by Claude Opus 4.8
parent a3c3929c4e
commit d2cbdc2431
+17 -4
View File
@@ -2,10 +2,23 @@
# Post-checkout hook. Folds in pql's planning logic (its .pql/hooks installer is
# dead under core.hooksPath=.config/hooks).
#
# On a branch checkout (third arg == 1), rebuild pql.db from the changelog so the
# local planning cache reflects the new branch's state. File-level checkouts
# ($3 == 0) are skipped. Args: <prev-HEAD> <new-HEAD> <branch-flag>.
# On a branch checkout (third arg == 1), keep the local planning cache (pql.db)
# in sync with the changelog. File-level checkouts ($3 == 0) are skipped.
# Args: <prev-HEAD> <new-HEAD> <branch-flag>.
#
# prev-HEAD == new-HEAD means the working-tree content did not change — a branch
# *creation* (`git checkout -b`) or a no-op checkout. pql.db is already correct
# for this content, so a `plan rebuild` here would only DROP uncommitted ticket
# mutations that have not reached the changelog yet (e.g. a just-activated
# in_progress status set right before the branch was cut). Instead, flush + stage
# them — the same changelog capture the pre-commit hook does — so the activation
# is durable across the checkout. A real branch *switch* (prev != new) loads a
# different changelog, so rebuild pql.db to match the branch we moved to.
if [ "${3:-0}" = "1" ] && command -v pql >/dev/null 2>&1; then
pql plan rebuild >/dev/null 2>&1 || true
if [ "$1" = "$2" ]; then
pql plan export --stage >/dev/null 2>&1 || true
else
pql plan rebuild >/dev/null 2>&1 || true
fi
pql decisions sync >/dev/null 2>&1 || true
fi