squashing-history

star 40

Squashes all commits on the repo's default branch (main, falling back to master) to a single conventional-commit "chore: initial commit" with backup branch, integrity verification, and user confirmation before force push. Use when cleaning history or preparing for fresh start.

SocketDev By SocketDev schedule Updated 6/7/2026

name: squashing-history description: Squashes all commits on the repo's default branch (main, falling back to master) to a single conventional-commit "chore: initial commit" with backup branch, integrity verification, and user confirmation before force push. Use when cleaning history or preparing for fresh start. user-invocable: true allowed-tools: AskUserQuestion, Bash(node:), Bash(git:) model: claude-haiku-4-5 context: fork

squashing-history

Squash all commits on the default branch to a single commit while preserving code integrity. This is the low-level squash-to-one-commit primitive; refreshing-history layers dep-refresh + a signed commit on top of the same engine.

The commit message is chore: initial commit — a Conventional Commits header, so it clears commit-message-format-guard. The collapse + the push are both history-rewriting operations that no-revert-guard gates; the runner sets an inline SQUASH_HISTORY=1 sentinel limited to exactly those two commands (the same opt-in-per-command shape as the cascade's FLEET_SYNC=1).

Run

node .claude/skills/fleet/squashing-history/run.mts /path/to/<repo>

The runner walks 8 phases end-to-end in a sibling worktree; the primary checkout is never touched. See run.mts for the implementation (the shared squashSingleCommit() engine lives there and is reused by refreshing-history).

# Phase What it does
1 Pre-flight Resolve default branch (main → master fallback); fetch; capture orig HEAD + count.
2 Worktree Add chore/squash worktree at <repo>-squash tracking origin/$BASE.
3 Backup Push $ORIG_HEAD to refs/heads/backup-YYYYMMDD-HHMMSS before any destructive op.
4 Squash Soft-reset to the root commit, then amend it; verify commit count == 1.
5 Integrity Diff against $ORIG_HEAD (ignoring submodules) must be empty (HARD exit otherwise).
6 Push Lease-push the single commit to $BASE under the sentinel.
7 Cleanup Remove worktree + delete the temp branch.
8 Report Print new SHA + backup ref name + recovery one-liner.

Why the runner is shaped the way it is

  • Amend the root, don't re-commit: a soft-reset to the root commit followed by a fresh commit leaves two commits (the original root plus the new one). Amending the root is what collapses to one.
  • Integrity is a HARD exit: the post-squash tree must be byte-identical to the pre-squash backup. A non-empty diff means the squash altered content — that is corruption, so the runner exits before the push can happen.
  • Lease, not bare force: the push uses --force-with-lease, which aborts if the remote moved since the last fetch, so a racing push is never clobbered.

When invoking interactively, show the summary (original count, backup ref, integrity status) and ask for explicit confirmation via AskUserQuestion before the push.

See reference.md for retry loops and edge-case handling.

Staying at one commit after a cascade

Once a repo is a single chore: initial commit, the wheelhouse cascade keeps it that way: sync-scaffolding detects the lone-initial-commit shape (isSingleInitialCommit in scripts/repo/sync-scaffolding/commit.mts) and amends the cascade into that commit (git commit --amend --no-edit) rather than stacking a chore(wheelhouse): cascade … on top. So a squashed repo doesn't drift back to multi-commit between manual squashes — no re-squash needed after routine cascades.

Install via CLI
npx skills add https://github.com/SocketDev/socket-registry --skill squashing-history
Repository Details
star Stars 40
call_split Forks 2
navigation Branch main
article Path SKILL.md
More from Creator