Parent: #54
Problem
When /vit:complete-milestone finishes, the git history retains the full messy tree of all phase branches, merge commits, plan branches, sync merges, and planning artifacts. For example, v1.1 produced 50+ commits with a complex merge graph between ba0a3cb (v1.0) and 657f7cf (v1.1 tag):
* 657f7cf - docs: add v1.1 milestone handoff (tag: v1.1)
* f3826c5 - chore: complete v1.1 milestone
* fe3a8d8 - docs: update documentation and changelog for v1.1
... 40+ commits with merge octopus ...
| * merge: plan 02-05 into phase 02
| |\
| | * merge: sync phase branch into plan 02-04
|/| |
... etc ...
* ba0a3cb - feat: v1.0 GitHub Sync & Agents Extension (tag: v1.0)
Expected: After milestone completion, the entire milestone's work should be squashed into a single commit on top of the previous milestone tag, producing a clean linear history:
* <squash> - feat: v1.1 Documentation & Developer Portal (tag: v1.1)
* ba0a3cb - feat: v1.0 GitHub Sync & Agents Extension (tag: v1.0)
Changes
Update .claude/commands/vit/complete-milestone.md
Add a git cleanup step after all milestone completion tasks (archiving, changelog, tagging) but before the final push:
# 1. Identify the base commit (previous milestone tag or first commit)
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || git rev-list --max-parents=0 HEAD)
BASE_COMMIT=$(git rev-parse "$PREV_TAG")
# 2. Squash all milestone work into one commit
MILESTONE_NAME=$(grep "^Current focus:" .planning/PROJECT.md | sed 's/.*: //')
git reset --soft "$BASE_COMMIT"
git commit -m "feat: ${MILESTONE} ${MILESTONE_NAME}
Squashed ${COMMIT_COUNT} commits from milestone ${MILESTONE}.
Phases completed:
$(grep "| ${MILESTONE}/" .planning/STATE.md | awk -F'|' '{print "- " $2 ": " $3}')
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>"
# 3. Re-apply the milestone tag to the squashed commit
git tag -f "${MILESTONE}" HEAD
# 4. Clean up remote branches for completed phases
PHASE_BRANCHES=$(grep "| ${MILESTONE}/" .planning/STATE.md | grep -o 'feature/[^ |]*')
PLAN_BRANCHES=$(grep "| ${MILESTONE}/" .planning/STATE.md | grep -o 'feature/v[^ |,]*' | sort -u)
for BRANCH in $PHASE_BRANCHES $PLAN_BRANCHES; do
git branch -D "$BRANCH" 2>/dev/null || true
git push origin --delete "$BRANCH" 2>/dev/null || true
done
# 5. Clean up worktrees
git worktree prune 2>/dev/null
# 6. Force push the squashed milestone branch and tag
git push origin "$MILESTONE_BRANCH" --force-with-lease
git push origin "refs/tags/${MILESTONE}" --force
Safety considerations
- Use
--force-with-lease for the push (not --force)
- Only squash AFTER the tag is created and all completion steps are done
- Delete remote phase/plan branches that are fully merged
- Prune orphaned worktrees
- The squash commit message should list all phases completed
Also update .claude/vit/workflows/complete-milestone.md
Add a squash_and_clean step in the workflow reference documenting this behavior.
Files
.claude/commands/vit/complete-milestone.md
.claude/vit/workflows/complete-milestone.md (if exists)
Parent: #54
Problem
When
/vit:complete-milestonefinishes, the git history retains the full messy tree of all phase branches, merge commits, plan branches, sync merges, and planning artifacts. For example, v1.1 produced 50+ commits with a complex merge graph betweenba0a3cb(v1.0) and657f7cf(v1.1 tag):Expected: After milestone completion, the entire milestone's work should be squashed into a single commit on top of the previous milestone tag, producing a clean linear history:
Changes
Update
.claude/commands/vit/complete-milestone.mdAdd a git cleanup step after all milestone completion tasks (archiving, changelog, tagging) but before the final push:
Safety considerations
--force-with-leasefor the push (not--force)Also update
.claude/vit/workflows/complete-milestone.mdAdd a
squash_and_cleanstep in the workflow reference documenting this behavior.Files
.claude/commands/vit/complete-milestone.md.claude/vit/workflows/complete-milestone.md(if exists)