Squash Commits
Squash multiple commits into a single commit with GitHub PR squash merge style message.
Use Case
- •Clean up commits before PR merge
- •Combine multiple WIP commits into one
- •Maintain clean commit history
Arguments
| Argument | Description | Default |
|---|---|---|
| (none) | All commits from base branch | - |
<N> | Squash only last N commits | - |
Commit Message Format
Same format as GitHub PR squash merge:
text
<user-provided title> * <commit1 message> (oldest) * <commit2 message> * <commit3 message> (newest)
Process
- •Safety check: Prevent running on protected branches (main, master, develop)
- •Detect range:
- •No argument: Find merge base with
git merge-base origin/<base> HEAD - •Numeric argument: Use
HEAD~N
- •No argument: Find merge base with
- •Show commits: Display commits to squash (chronological order)
- •Get title: Ask user for commit title (using AskUserQuestion)
- •Build message: Generate title + commit list body
- •Execute squash:
git reset --soft <target> && git commit - •Done: Show push instructions (user pushes manually)
Execution Steps
- •
Get current branch with
git rev-parse --abbrev-ref HEAD - •
Check if protected branch (main, master, develop)
- •
Detect base branch (main or master)
- •
Determine squash target:
- •No argument:
git merge-base origin/<base> HEAD - •Argument N:
HEAD~N
- •No argument:
- •
Show commits with
git log --oneline --reverse <target>..HEAD(chronological) - •
Ask user for commit title (using AskUserQuestion)
- •
Build commit message:
text<title> * <commit1 subject> * <commit2 subject> ...
- •
Run
git reset --soft <target> - •
Run
git commitwith HEREDOC for message - •
Show completion message and push instructions
Safety Features
- •Protected branches: Never squash on main/master/develop
- •No auto-push: Only squash, user pushes manually
Examples
Squash all commits:
text
/stylish-git:squash -> Current branch: feature/add-button -> Base branch: main -> Commits to squash (3): 1. abc1234 feat: add button component 2. def5678 fix: button style 3. ghi9012 refactor: clean up -> Enter commit title: feat: add button component with styling -> Squashing... -> Squashed 3 commits -> Final commit message: +---------------------------------------- | feat: add button component with styling | | * feat: add button component | * fix: button style | * refactor: clean up +---------------------------------------- -> Run 'git push --force-with-lease' to update remote
Squash last N commits:
text
/stylish-git:squash 2 -> Current branch: feature/add-button -> Squashing last 2 commits -> Commits to squash (2): 1. def5678 fix: button style 2. ghi9012 refactor: clean up -> Enter commit title: fix: improve button styling -> Squashing... -> Squashed 2 commits -> Final commit message: +---------------------------------------- | fix: improve button styling | | * fix: button style | * refactor: clean up +---------------------------------------- -> Run 'git push --force-with-lease' to update remote
Protected branch error:
text
/stylish-git:squash -> Error: Cannot squash on protected branch 'main' -> Switch to a feature branch first
No commits error:
text
/stylish-git:squash -> No commits to squash -> Current branch has no commits ahead of main