@@ -7,6 +7,25 @@ description: "MANDATORY: Use instead of `git rebase -i` for squashing - unified
77
88** Purpose** : Safely squash multiple commits into one with automatic backup, verification, and cleanup.
99
10+ ## Parallel Initial Investigation
11+
12+ ** OPTIMIZATION: Run initial git commands in parallel to reduce round-trips.**
13+
14+ Before starting any squash workflow, gather information concurrently:
15+
16+ ``` bash
17+ # Run these commands in parallel (use & and wait)
18+ git rev-parse HEAD &
19+ git status --porcelain &
20+ git log --oneline < base> ..HEAD &
21+ git diff --stat < base> ..HEAD &
22+ wait
23+
24+ # All results now available for workflow selection
25+ ```
26+
27+ This reduces the initial investigation from 4+ sequential commands to a single parallel batch.
28+
1029## Safety Pattern: Backup-Verify-Cleanup
1130
1231** ALWAYS follow this pattern:**
3150fi
3251```
3352
53+ ## Planning Commit Pattern Detection
54+
55+ ** Detect common "feature + planning STATE.md update" pattern.**
56+
57+ Before squashing, check if the commit sequence follows this pattern:
58+ 1 . Implementation commit(s): ` feature: ` , ` bugfix: ` , ` refactor: ` , etc.
59+ 2 . Final commit(s): ` planning: ` or ` config: ` with only ` .claude/cat/issues/ ` changes
60+
61+ ** Detection logic:**
62+ ``` bash
63+ # Get the last commit's type and files
64+ LAST_COMMIT=$( git log -1 --format=" %s" HEAD)
65+ LAST_FILES=$( git diff-tree --no-commit-id --name-only -r HEAD)
66+
67+ # Check if last commit is planning-only
68+ if [[ " $LAST_COMMIT " =~ ^planning: ]] && \
69+ [[ " $LAST_FILES " =~ \. claude/cat/issues/ ]] && \
70+ ! echo " $LAST_FILES " | grep -qv " \.claude/cat/" ; then
71+ echo " PATTERN DETECTED: Final commit is planning-only STATE.md update"
72+ # This pattern indicates STATE.md should be preserved in squash
73+ fi
74+ ```
75+
76+ ** When pattern detected:**
77+ - Extract final STATE.md content before squash
78+ - After squash, ensure STATE.md reflects final state (not intermediate)
79+ - Include planning changes in implementation commit per M076
80+
3481## Quick Workflow (Commits at Branch Tip Only)
3582
3683** Use ONLY when squashing the most recent commits on a branch.**
@@ -106,6 +153,38 @@ rm /tmp/squash-editor.sh /tmp/msg-editor.sh
106153
107154## Critical Rules
108155
156+ ### Automatic STATE.md Preservation
157+
158+ ** CRITICAL: Preserve final STATE.md state when squashing planning commits.**
159+
160+ When squashing commits that include STATE.md updates:
161+
162+ 1 . ** Before squash:** Record the final STATE.md content
163+ ``` bash
164+ # Store final state before squash
165+ TASK_STATE=" .claude/cat/issues/v*/v*.*/*/STATE.md"
166+ git show HEAD:$TASK_STATE > /tmp/final-state.md 2> /dev/null || true
167+ ```
168+
169+ 2 . ** After squash:** Verify STATE.md wasn't reverted to intermediate state
170+ ``` bash
171+ # Check if STATE.md was affected
172+ if [[ -f /tmp/final-state.md ]]; then
173+ # Compare current vs final
174+ if ! diff -q " $TASK_STATE " /tmp/final-state.md > /dev/null 2>&1 ; then
175+ echo " ⚠️ STATE.md reverted to intermediate state - restoring final state"
176+ cp /tmp/final-state.md " $TASK_STATE "
177+ git add " $TASK_STATE "
178+ git commit --amend --no-edit
179+ fi
180+ fi
181+ ```
182+
183+ ** Why this matters:**
184+ - Squashing can revert STATE.md to earlier commit's version
185+ - Final state (status: completed, progress: 100%) must be preserved
186+ - Per M076: STATE.md belongs in same commit as implementation
187+
109188### Use Correct Workflow for Commit Position
110189
111190``` bash
@@ -182,6 +261,34 @@ git rebase -i <base-commit>
182261# pick ghi789 Other commit (unchanged)
183262```
184263
264+ ### Conflict Pre-Computation for Non-Adjacent Commits
265+
266+ ** Before attempting to squash non-adjacent commits, analyze potential conflicts:**
267+
268+ ``` bash
269+ # Identify files modified by multiple commits in the range
270+ echo " Conflict risk analysis:"
271+ git diff --name-only < base> ..HEAD | while read file; do
272+ commits=$( git log --oneline < base> ..HEAD -- " $file " | wc -l)
273+ if [[ $commits -gt 1 ]]; then
274+ echo " ⚠️ $file : modified by $commits commits"
275+ fi
276+ done
277+
278+ # Check for same-line modifications (highest risk)
279+ for file in $( git diff --name-only < base> ..HEAD) ; do
280+ git log -p < base> ..HEAD -- " $file " | grep -E " ^@@" | sort | uniq -d && \
281+ echo " 🔴 $file : same lines modified by multiple commits - HIGH RISK"
282+ done
283+ ```
284+
285+ ** Risk Levels:**
286+ | Risk | Pattern | Recommendation |
287+ | ------| ---------| ----------------|
288+ | LOW | Different files per commit | Safe to squash |
289+ | MEDIUM | Same file, different lines | Usually safe |
290+ | HIGH | Same file, same lines | Manual resolution likely needed |
291+
185292## Error Recovery
186293
187294``` bash
0 commit comments