Skip to content

Complete-milestone should squash milestone commits and clean git tree #71

Description

@LeVarez

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)

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions