← ClaudeAtlas

squash-merge-content-preservation-vs-ancestor-checklisted

Use when verifying that an upstream commit (e.g., a colleague's work, a feature-branch commit) is preserved in a target branch after a propagation PR has merged — and the verification script uses `git merge-base --is-ancestor <upstream-sha> <target-branch>`. If the merge mode was **squash**, that ancestor check ALWAYS returns non-zero even when content is preserved verbatim, because squash collapses every commit into a single new SHA on the target. Apply this skill when: (1) preservation audit for a recently-merged propagation PR returns "MISSING" or non-zero exit on `git merge-base --is-ancestor`, (2) handoff prompt mixes `is-ancestor` AND content checks without specifying merge mode, (3) you need to gate a merge on "did colleague's signature work survive". The correct probe depends on merge mode — fast-forward / no-ff preserves lineage; squash does not.
wan-huiyan/agent-traffic-control · ★ 2 · Code & Development · score 79
Install: claude install-skill wan-huiyan/agent-traffic-control
# Squash Merge Content Preservation vs Ancestor Check ## Problem Your verification script says: ```bash git merge-base --is-ancestor 0b6303e76 origin/main && echo "OK" || echo "MISSING" # Prints: MISSING ``` … but `wc -l <signature-file>` returns the expected line counts and `grep -c <signature-string>` returns ≥ the expected ref count. The exit code from `is-ancestor` is non-zero **even though every byte of the upstream work is preserved on the target branch**. The "MISSING" verdict is wrong. Root cause: a squash merge collapses every commit on the source branch into a **single new commit** on the target. The original SHAs (including the upstream commit you're checking) never appear in the target's history. `is-ancestor` returns "false" because the SHA truly isn't an ancestor of the merge commit — but the SHA's *content* is preserved verbatim inside the squash commit. This trap fires whenever: - A handoff prompt or skill mixes ancestor-based checks with content-based checks for the same preservation claim - The handoff was written before the merge mode was decided - The verification template assumed fast-forward / no-ff (which preserves lineage) but the actual merge used squash ## Context / Trigger Conditions You're in the right place if **all** of these are true: - A propagation-style PR (`branch-A → branch-B`, often 20+ commits ahead) has recently merged - The verification step instructs you to check `git merge-base --is-ancestor <upstream-sha> <target-br