Git Squash
Pre-flight Checks
Before merging, validate the environment:
-
Determine source branch — use the argument if provided (/git-squash feature/my-branch ), otherwise use the current branch.
-
Verify not on main — if the source branch is main , abort with an error.
-
Check for uncommitted changes — run git status --porcelain . If there are uncommitted changes, abort and suggest committing or stashing first.
-
Verify branch exists — confirm the source branch exists locally (git rev-parse --verify <branch> ).
-
Verify divergence from main — run git log main..<branch> --oneline . If empty, abort — nothing to merge.
Switch to Main
git checkout main
If a remote origin exists, pull latest:
git pull --ff-only
If --ff-only fails, abort — main has diverged and needs manual resolution.
Squash Merge
git merge --squash <branch>
If the merge produces conflicts:
-
Abort immediately: git merge --abort
-
Switch back to the source branch: git checkout <branch>
-
Suggest the user rebase first: Merge conflicts detected. Run
git rebase mainon your branch to resolve conflicts, then retry. -
Stop — do not proceed.
Delegate to git-commit
After a successful squash merge, invoke /git-commit to handle the commit. This delegates the full 7-step workflow:
-
Sensitive File Guard
-
Auto-stage tracked changes
-
Multi-concern analysis
-
Commit message generation (Conventional Commits with inferred type/scope)
-
Heredoc commit with Co-Authored-By trailer
-
Hook failure handling
Do not write commit messages directly — always delegate.
Post-merge Verification
After the commit succeeds:
git log --oneline -5 git status git diff
Confirm: clean working tree, squash commit visible at HEAD, no leftover staged changes.
Cleanup
Delete local branch
First, try safe delete:
git branch -d <branch>
If -d fails because git doesn't recognise the squash merge (expected — squash merges don't preserve commit ancestry), verify there is zero diff between main and the branch:
git diff main <branch>
If the diff is empty (content fully merged), force-delete is safe:
git branch -D <branch>
If there IS a diff, do not delete — something was lost in the squash. Investigate before proceeding.
Delete remote branch (if exists)
Check if a remote tracking branch exists:
git ls-remote --heads origin <branch>
If it exists:
git push origin --delete <branch>
Rules
-
Proceed without confirmation — pre-flight checks are the safety gate. Do not ask the user to approve before merging.
-
Only merge into main — never squash-merge into other branches.
-
Always use --squash — never fast-forward or regular merge.
-
Always delegate the commit to /git-commit — never write commit messages directly.
-
Abort on merge conflicts — never auto-resolve.
-
Never force-push (--force , --force-with-lease ).
-
Prefer git branch -d — use -D only after verifying zero diff between main and the branch (squash merges don't preserve ancestry, so -d will fail even when content is fully merged).
-
If any step fails, stop and report the error — do not continue the workflow.
Quick Reference
-
Pre-flight: verify branch, check uncommitted changes, confirm divergence from main.
-
Switch to main, pull latest with --ff-only .
-
git merge --squash <branch> — abort on conflicts, suggest rebase.
-
Delegate commit to /git-commit (Sensitive File Guard, Conventional Commits, heredoc).
-
Verify: git log , git status , git diff .
-
Cleanup: git branch -d (fall back to -D after verifying zero diff), git push origin --delete (if remote exists).