skills/git-squash/SKILL.md
This skill should be used when the user asks to squash a feature branch's commits into one and rebase onto the base branch. Trigger phrases include "squash commits", "squash branch", "flatten branch history", "prepare a clean PR commit".
npx skillsauth add paulrberg/dot-agents 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:
chorerefs/remotes/origin/HEADgit remote show originmain, master, trunkStart by confirming that history can be rewritten safely. 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.
Soft-reset to the merge-base. This keeps the branch's net changes staged while removing the intermediate commits from history. If the staged diff is empty after the reset, restore the original head and stop with an error, because there is no net change to commit.
git reset --soft "$merge_base"
git diff --cached --quiet
git reset --soft "$original_head"
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
chore: squash <branch> net changes unless the user explicitly provided --subject.content-media
Summarize or transcribe URLs, YouTube/videos, podcasts, articles, transcripts, PDFs, and local files.
tools
Use Obscura — a Rust headless browser with a Chrome DevTools Protocol server — for fast page fetches, JS execution, scraping, and CDP automation. Drop-in CDP replacement for Chrome with Puppeteer or Playwright. Trigger on requests to "open a page", "fetch a URL with JS", "scrape a site", "render this page", "automate browser via CDP", or any task where Chrome would be too heavy. Also use when the user mentions stealth fingerprinting, tracker blocking, `navigator.webdriver` masking, or evading basic bot detection.
tools
Use the Notion CLI (`ntn`) to interact with the Notion API, manage workers, and upload files. Use when the user asks to "call the Notion API", "deploy a worker", "upload a file to Notion", "create a page", "query a database", or any task involving the `ntn` command.
data-ai
This skill should be used when the user asks to "open CoinGecko historical data", "show historical price on date X", "open coingecko historical page", or wants to view the CoinGecko historical-data page for a coin around a given date in their default browser.