skills/git-squash/SKILL.md
Squash a feature branch into one commit via soft reset to the merge base, ready for a clean PR.
npx skillsauth add paulrberg/agent-skills git-squashInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Squash the current PR branch into one commit based on net branch changes relative to the default branch. Do not create or invoke a helper script. Run the Git commands directly.
Parse $ARGUMENTS for optional flags:
--subject <line>: Override the generated commit subject line--base <branch>: Override default-branch auto-detectionDefaults:
Gather and report the branch, clean-tree state, base candidate, ahead count, merge base, remote tracking state, and commits that would be replaced before mutating history. Stop on the first failure.
git rev-parse --is-inside-work-treegit symbolic-ref --quiet --short HEADgit status --porcelaingit rev-parse --is-inside-work-tree
git symbolic-ref --quiet --short HEAD
git status --porcelain
If --base was provided, use that branch name directly. Otherwise, detect the default branch in this order:
refs/remotes/origin/HEADgit remote show originmain, master, trunkAfter the branch name is resolved, normalize it to a usable ref by preferring the local branch and falling back to
origin/<branch>. Stop if neither exists. Also stop if the current branch is the default branch, because the skill
should never squash the default branch into itself.
git symbolic-ref --quiet --short refs/remotes/origin/HEAD
git remote show origin
git show-ref --verify --quiet "refs/heads/$default_branch"
git show-ref --verify --quiet "refs/remotes/origin/$default_branch"
Compute the merge-base between HEAD and the resolved default ref. That merge-base is the point where the branch
diverged. Count how many commits are ahead of it. If the count is zero, there is nothing to squash.
merge_base="$(git merge-base HEAD "$default_ref")"
ahead_count="$(git rev-list --count "$merge_base..HEAD")"
original_head="$(git rev-parse HEAD)"
Inspect the commits that will be squashed before mutating history. Use them to understand intent and distinct workstreams, but treat the staged net diff as the source of truth for what survives.
git log --reverse --format='%H%x09%s' "$merge_base..HEAD"git show --stat --summary --format=fuller <commit>git log --format='%aN <%aE>' "$merge_base..HEAD" | sort -u to get the list,
then exclude the current user (git config user.name / git config user.email). Each remaining author becomes a
Co-authored-by trailerYou are not writing a changelog of every commit. You are deriving one accurate commit message for the final net change.
Record original_head immediately before mutation. Soft-reset to the merge-base; this keeps the branch's net changes
staged while removing the intermediate commits from history. Until the replacement commit succeeds, any failure must
restore HEAD and the index with git reset --soft "$original_head". Because preflight requires a clean tree, that
rollback returns the branch to its exact pre-squash commit and staged state without touching working-tree files.
original_head="$(git rev-parse HEAD)"
git reset --soft "$merge_base"
if git diff --cached --quiet; then
git reset --soft "$original_head"
exit 1
fi
Use --subject when provided. Otherwise, generate a conventional-commit subject by semantically analyzing:
"$merge_base..HEAD"git diff --cached when the summary is ambiguousInfer the commit type from the surviving change, not from the fact that a squash happened:
featfixrefactordocstestbuildcichore(deps)styleperfaichoreDo not default to chore unless the net change is actually maintenance work.
Subject requirements:
type(scope): description or type: descriptionfeat(streaming): add batch cancel support is acceptable, chore: squash branch changes is notBody requirements:
shortstat, name-status, or file inventories into the messageValidation requirements before committing:
Helpful commands:
git log --reverse --format='%H%x09%s' "$merge_base..HEAD"
git diff --cached --stat
git diff --cached
If co-authors were collected in step 4, append a blank line followed by one Co-authored-by: Name <email> trailer per
co-author at the end of the message. Do not add trailers for the current user.
Write the final message to a temporary file and commit with git commit -F.
After the commit succeeds:
git commit -F "$message_file"
git push --force-with-lease
development
Use when creating or substantially redesigning web interfaces, landing pages, dashboards, components, or other frontend UI where visual direction and implementation quality matter. Produces subject-specific art direction, accessible responsive code, and rendered visual verification.
development
Orchestrate one to five Sonnet subagents to implement an approved Claude Code plan.
tools
Open the CoinGecko historical-data page for a coin/date in Chromium via Chrome DevTools MCP.
tools
Orchestrate one to five Codex CLI agents to implement an approved Claude Code plan.