squash-commits

Squash all commits on the current branch into a single commit with a coherent, synthesized commit message. Use when you want to clean up branch history before merging — combines multiple small commits (WIP, fixes, iterations) into one meaningful commit. Trigger keywords: squash commits, combine commits, consolidate commits, clean branch history, collapse commits.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "squash-commits" with this command: npx skills add bkowshik/agent-skills/bkowshik-agent-skills-squash-commits

Squash Commits

Combine all commits on the current branch into a single commit with a meaningful, synthesized commit message. This cleans up branch history before merging so reviewers see one clear commit instead of dozens of WIP saves.

How it works

The helper script at {{SKILL_DIR}}/scripts/squash.sh handles git operations (pre-flight checks, base branch detection, backup, soft-reset). You handle the commit message synthesis and user interaction.

Workflow

Step 1: Gather information

Run the helper script in dry-run mode to collect commit data without modifying anything:

{{SKILL_DIR}}/scripts/squash.sh --dry-run

The output contains:

  • BASE_BRANCH — the detected base branch
  • COMMIT_COUNT — number of commits to squash
  • HAS_MERGE_COMMITS — whether merge commits are present
  • HAS_UPSTREAM — whether the branch has been pushed
  • COMMITS section — each commit (short hash + message)
  • COMMIT MESSAGES section — full message body of each commit
  • TRAILERS section — deduplicated Co-authored-by and Signed-off-by trailers

If the script exits with an error, relay the error message to the user and stop. Common errors: dirty working tree, detached HEAD, only one commit ahead.

Step 2: Synthesize the commit message

Read all the commit messages from the dry-run output. Your job is to understand the overall intent of the changes and write a single, coherent commit message — not a mechanical list or concatenation of the originals.

Good synthesis means:

  • Capture what the combined changes accomplish as a whole
  • Remove noise (WIP, fixup, typo fixes, "oops") that doesn't add meaning
  • Use the same voice and style as the project's existing commits
  • Keep it concise — a short summary line, optionally followed by a body
  • Do NOT add your own name, Co-Authored-By trailer, or any other attribution identifying you as an AI tool to the commit message. The commit message should contain only the synthesized summary and human-authored trailers.

If the TRAILERS section contains any trailers, append them at the end of the commit message (after a blank line). These carry attribution and compliance information that should not be dropped.

Step 3: Show the preview

Present the user with a clear preview before any changes are made. Because squashing rewrites history, showing exactly what will happen reduces mistakes and builds confidence. Display:

  • Base branch: the detected base branch name and merge-base commit
  • Commits to squash: count and list (short hash + original message for each)
  • Proposed message: the full synthesized commit message you wrote
  • Force-push needed: yes/no based on whether the branch has been pushed
  • Merge commits warning: if merge commits are present, warn that squashing will flatten them

Then ask the user to confirm or decline. If they decline, stop — no changes are made.

Step 4: Handle pushed branches

If HAS_UPSTREAM=true, the branch has been pushed to a remote. After squashing, the user will need to force-push (git push --force-with-lease) because the branch history has been rewritten. Mention this in the preview so the user is aware before confirming the squash. The actual force-push confirmation happens in Step 6 after the squash completes.

Step 5: Execute the squash

Run the helper script in execute mode (without --dry-run):

{{SKILL_DIR}}/scripts/squash.sh

This creates a backup ref and runs git reset --soft to the merge-base. All changes remain staged.

Then create the commit with the synthesized message:

git commit -m "<synthesized message with trailers>"

Step 6: Confirm success and handle force-push

After the commit, show the user:

  • The new single commit (run git log --oneline -1)
  • The backup ref location (from the script output)
  • The recovery command: git reset --hard <backup-ref>

If HAS_UPSTREAM=false, the squash is complete — no further action needed.

If HAS_UPSTREAM=true, the branch was pushed before squashing and the remote history now diverges. Offer to force-push:

  1. Warn that collaborators who have pulled this branch will see diverged history after the force-push.

  2. Ask the user to confirm whether they want to force-push now.

  3. If the user confirms, run:

    git push --force-with-lease
    
    • If the push succeeds, show the output and confirm the remote branch is updated.
    • If the push fails, show the full error output. Reassure the user that the local squash commit is intact and the backup ref is still available for recovery. Provide the manual command for retry: git push --force-with-lease
  4. If the user declines, skip pushing and show the manual command as a reference: git push --force-with-lease

Specifying a different base branch

If the script cannot auto-detect the base branch (none of main, master, develop exist), it will exit with an error asking you to specify one. Ask the user which branch to use, then re-run with:

{{SKILL_DIR}}/scripts/squash.sh --dry-run --base-branch <name>

And for execution:

{{SKILL_DIR}}/scripts/squash.sh --base-branch <name>

Always confirm the detected base branch in the preview so the user can correct it before proceeding.

Example: branch off develop

If a user is on feature/login branched off develop:

{{SKILL_DIR}}/scripts/squash.sh --dry-run --base-branch develop

The script finds the merge-base between develop and HEAD, lists only the commits on feature/login, and the rest of the workflow proceeds identically.

Edge cases

  • Dirty working tree: The script refuses to run. Tell the user to commit or stash their changes first — a reset with uncommitted changes can lose work.
  • Detached HEAD: The script refuses. Tell the user that squashing requires being on a branch.
  • Single commit ahead: The script reports nothing to squash. Inform the user and stop.
  • Merge commits in history: The script detects and reports them. Warn the user that squashing will flatten merge commits into a single linear commit. Ask for confirmation before proceeding.
  • Already pushed: Covered in Steps 4 and 6. Step 4 mentions the force-push requirement in the preview. Step 6 asks the user to confirm and executes git push --force-with-lease on confirmation. If the push fails, the error is shown with reassurance that the local squash is intact.
  • Diverged base (base branch has new commits since the branch was created): The soft-reset approach handles this correctly by design. It only affects the branch's own commits — the merge-base stays the same regardless of new commits on the base branch. No rebase is performed.

Example

A developer has a branch feature/add-search with 4 commits off main. The branch has been pushed to the remote. Some commits were made with an AI coding tool that added its own Co-Authored-By trailer:

abc1234 WIP: search endpoint skeleton
def5678 Add query parsing and validation
ghi9012 Fix typo in search query parser
jkl3456 Add pagination to search results

Co-authored-by: Alice <alice@example.com>
Co-authored-by: Claude <noreply@anthropic.com>

The helper script automatically filters out known LLM/bot trailers, so only the human trailer (Alice) appears in the TRAILERS section of the dry-run output.

Running the skill:

  1. {{SKILL_DIR}}/scripts/squash.sh --dry-run shows 4 commits, base branch main, no merge commits, has upstream.

  2. You synthesize: "Add search endpoint with query parsing, validation, and paginated results"

  3. Preview shown to user:

    Base branch: main (merge-base: 789abcd)
    Commits to squash: 4
      abc1234 WIP: search endpoint skeleton
      def5678 Add query parsing and validation
      ghi9012 Fix typo in search query parser
      jkl3456 Add pagination to search results
    
    Proposed message:
      Add search endpoint with query parsing, validation, and paginated results
    
      Co-authored-by: Alice <alice@example.com>
    
    Force-push needed: Yes (branch has been pushed)
    
  4. User confirms the squash.

  5. {{SKILL_DIR}}/scripts/squash.sh creates backup at refs/backup/squash-commits/feature/add-search and soft-resets to merge-base.

  6. git commit -m "Add search endpoint with query parsing, validation, and paginated results\n\nCo-authored-by: Alice <alice@example.com>" creates the single commit.

  7. Result shown: 1 commit ahead of main, backup ref available for recovery.

  8. Since the branch was pushed, ask the user to confirm force-push. User confirms, git push --force-with-lease runs, remote branch is updated.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

learning-log

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

vercel-composition-patterns

React composition patterns that scale. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or designing reusable APIs. Triggers on tasks involving compound components, render props, context providers, or component architecture. Includes React 19 API changes.

Repository Source
86.2K23Kvercel
Automation

vercel-react-native-skills

React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.

Repository Source
60.5K23Kvercel
Automation

supabase-postgres-best-practices

Postgres performance optimization and best practices from Supabase. Use this skill when writing, reviewing, or optimizing Postgres queries, schema designs, or database configurations.

Repository Source
35.2K1.6Ksupabase