From b24a3596b5fd3cb60b1326ad084eac789637e631 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Tue, 16 Jun 2026 12:42:08 +0200 Subject: [PATCH] fix(config): post-checkout does nothing on same-HEAD instead of export --stage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refines 34ffcda86. The export --stage approach preserved the mutation but did more than the bug needs: it eagerly stages changelog rows mid-checkout (surprising in git status), and those staged rows can leak onto the wrong branch when a later switch rebuilds by replaying the working-tree changelog. Minimal fix: on a branch *creation* / no-op checkout (prev-HEAD == new-HEAD) the working tree is unchanged, so pql.db already holds the committed state plus any uncommitted mutation — just skip the whole block (do nothing). The mutation stays in pql.db untouched and the next commit's pre-commit hook flushes it normally. Only a real branch *switch* (prev != new) rebuilds. No git-index side effects, no leak. Verified: same-HEAD invocation preserves an uncommitted status mutation and stages nothing. (Credit: pql-clide's review of the upstream feature request.) Co-Authored-By: Claude Opus 4.8 (1M context) --- .config/hooks/post-checkout | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/.config/hooks/post-checkout b/.config/hooks/post-checkout index 41593f932..a637ad9c6 100755 --- a/.config/hooks/post-checkout +++ b/.config/hooks/post-checkout @@ -6,19 +6,16 @@ # in sync with the changelog. File-level checkouts ($3 == 0) are skipped. # Args: . # -# 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 - if [ "$1" = "$2" ]; then - pql plan export --stage >/dev/null 2>&1 || true - else - pql plan rebuild >/dev/null 2>&1 || true - fi +# Only a real branch *switch* (prev-HEAD != new-HEAD) loads a different changelog +# and needs a rebuild. On a branch *creation* (`git checkout -b`) or no-op checkout +# (prev == new) the working-tree content is unchanged, so pql.db already holds the +# committed state AND any uncommitted ticket mutation set just before the branch was +# cut (e.g. a just-activated in_progress status) — so do NOTHING. A rebuild there +# would drop that mutation; the next commit's pre-commit hook flushes it normally. +# Doing nothing (rather than an eager `export --stage`) also avoids staging changelog +# rows mid-checkout — those could otherwise leak onto the wrong branch when a later +# switch rebuilds by replaying the working-tree changelog. +if [ "${3:-0}" = "1" ] && [ "$1" != "$2" ] && command -v pql >/dev/null 2>&1; then + pql plan rebuild >/dev/null 2>&1 || true pql decisions sync >/dev/null 2>&1 || true fi