
git-squash
by cowwoc
AI Agents that land on their feet
SKILL.md
name: git-squash description: Safely squash multiple commits into one with automatic backup and verification
Git Squash Skill
Purpose: Safely squash multiple commits into one with automatic backup, verification, and cleanup.
Safety Pattern: Backup-Verify-Cleanup
ALWAYS follow this pattern:
- Create timestamped backup branch
- Execute the squash
- Verify immediately - no changes lost or added
- Cleanup backup only after verification passes
Workflow Selection
CRITICAL: Choose workflow based on commit position.
# Check if commits are at tip of branch
LAST_COMMIT="<last-commit-to-squash>"
BRANCH_TIP=$(git rev-parse HEAD)
if [ "$(git rev-parse $LAST_COMMIT)" = "$BRANCH_TIP" ]; then
echo "Commits at tip → Use Quick Workflow (soft reset)"
else
echo "Commits in middle of history → Use Interactive Rebase Workflow"
fi
Quick Workflow (Commits at Branch Tip Only)
Use ONLY when squashing the most recent commits on a branch.
# 1. Verify commits are at tip
git log --oneline -1 # Should show <last-commit-to-squash>
# 2. Create backup
BACKUP="backup-before-squash-$(date +%Y%m%d-%H%M%S)"
git branch "$BACKUP"
# 3. Verify clean working directory
git status --porcelain # Must be empty
# 4. Soft reset to base (parent of first commit to squash)
git reset --soft <base-commit>
# 5. Verify no changes lost
git diff --stat "$BACKUP" # Must be empty
# 6. Create squashed commit (see git-commit skill for message guidance)
git commit -m "Unified message describing what code does"
# 7. Verify result
git diff "$BACKUP" # Must be empty
git rev-list --count <base-commit>..HEAD # Must be 1
# 8. Cleanup backup
git branch -D "$BACKUP"
Interactive Rebase Workflow (Commits in Middle of History)
Use when commits to squash have other commits after them.
# 1. Create backup of current branch
BACKUP="backup-before-squash-$(date +%Y%m%d-%H%M%S)"
git branch "$BACKUP"
# 2. Create sequence editor script
FIRST_COMMIT="<first-commit-to-squash>" # Keep this one, squash others into it
COMMITS_TO_SQUASH="<second-commit> <third-commit> ..." # These get squashed
cat > /tmp/squash-editor.sh << EOF
#!/bin/bash
$(for c in $COMMITS_TO_SQUASH; do echo "sed -i 's/^pick $c/squash $c/' \"\$1\""; done)
EOF
chmod +x /tmp/squash-editor.sh
# 3. Create commit message editor script
cat > /tmp/msg-editor.sh << 'EOF'
#!/bin/bash
cat > "$1" << 'MSG'
<your unified commit message here>
MSG
EOF
chmod +x /tmp/msg-editor.sh
# 4. Run interactive rebase
BASE_COMMIT="<parent-of-first-commit>"
GIT_SEQUENCE_EDITOR=/tmp/squash-editor.sh EDITOR=/tmp/msg-editor.sh git rebase -i $BASE_COMMIT
# 5. Verify no changes lost
git diff "$BACKUP" # Must be empty
# 6. Cleanup
git branch -D "$BACKUP"
rm /tmp/squash-editor.sh /tmp/msg-editor.sh
Critical Rules
Use Correct Workflow for Commit Position
# WRONG - Using soft reset workflow for mid-history commits
git checkout <mid-history-commit>
git reset --soft <base>
git branch -f main HEAD # LOSES all commits after the squash range!
# CORRECT - Use interactive rebase for mid-history commits
GIT_SEQUENCE_EDITOR=... git rebase -i <base> # Preserves all commits
Position HEAD First (Quick Workflow Only)
# WRONG - HEAD beyond squash range
git reset --soft <base> # Squashes ALL commits to current HEAD!
# CORRECT - Checkout last commit first
git checkout <last-commit>
git reset --soft <base> # Squashes only intended range
Write Meaningful Commit Messages with Task ID
# WRONG - Concatenated messages, no Task ID
feature(auth): add login
feature(auth): add validation
bugfix(auth): fix typo
# CORRECT - Unified message with Task ID footer
feature: add login form with validation
- Email/password form with client-side validation
- Server-side validation with descriptive messages
Task ID: v2.1-implement-user-auth
MANDATORY: Include Task ID: v{major}.{minor}-{task-name} as the last line.
See git-commit skill for detailed message guidance.
Verify Immediately After Commit
# Check no changes lost
git diff "$BACKUP" # Empty = success
# Check commit count
git rev-list --count <base>..HEAD # Should be 1
Squash vs Fixup
| Command | Message Behavior | When to Use |
|---|---|---|
squash | Combines all messages | Different features being combined |
fixup | Discards secondary messages | Trivial fixes (typos, forgotten files) |
When in doubt, use squash - you can edit the combined message.
Non-Adjacent Commits
For commits separated by others, use interactive rebase:
git rebase -i <base-commit>
# In editor: Move commits to be adjacent, mark with 'squash'
# Example:
# pick abc123 Target commit
# squash def456 Commit to combine (MOVED here)
# pick ghi789 Other commit (unchanged)
Error Recovery
# If anything goes wrong:
git reset --hard $BACKUP
# Or check reflog:
git reflog
git reset --hard HEAD@{N}
Success Criteria
- Backup created before squash
- HEAD positioned at correct last commit
- No changes lost (diff with backup is empty)
- Single commit created with all changes
- Meaningful commit message (not "squashed commits")
- Backup removed after verification
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
1ヶ月以内に更新
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon

