원클릭으로
cleanup-history
Analyze branch commits, identify fixup candidates, rebase with autosquash, and post a PR comment explaining the cleanup.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Analyze branch commits, identify fixup candidates, rebase with autosquash, and post a PR comment explaining the cleanup.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | cleanup-history |
| description | Analyze branch commits, identify fixup candidates, rebase with autosquash, and post a PR comment explaining the cleanup. |
Clean up the commit history on the current branch before merging. Analyzes all commits since divergence from main, identifies which ones should be fixup commits folded into earlier commits, rebases with autosquash, force-pushes, and posts a PR comment documenting the cleanup.
This project uses a fork-based workflow. Contributors push to their fork (origin) and open PRs against the upstream repository (upstream). When running commands:
upstream/main if the upstream remote exists, otherwise origin/mainorigin (the contributor's fork)git remote | grep -q upstream && BASE=upstream/main || BASE=origin/main
git fetch $(echo $BASE | cut -d/ -f1)
If $ARGUMENTS contains a PR number, use that. Otherwise, detect from the current branch:
BRANCH=$(git branch --show-current)
gh pr list --head "$BRANCH" --json number,title,url --limit 1
If no PR is found, the skill can still clean up the history — just skip the PR comment step at the end.
git log --oneline HEAD..$BASE | wc -l # commits behind
If the branch is behind the base (commits behind > 0), STOP. Inform the user that the branch needs to be rebased onto the latest base first and instruct them to run /rebase-pr before re-running /cleanup-history. This keeps the rebase and the history cleanup as separate operations with distinct force-pushes and compare links.
# List all commits on the branch
git log --oneline $BASE..HEAD
# Show what each commit touches
git log --oneline --stat $BASE..HEAD
# Show full commit messages for context
git log --format="%H %s%n%n%b%n---" $BASE..HEAD
For each commit on the branch, classify it as either a standalone commit or a fixup candidate.
A commit is a fixup candidate if it:
For each fixup candidate, determine which earlier commit it should fold into by:
A commit stays standalone if it:
Show the user a clear before/after view:
## Current History (oldest first)
1. abc1234 feat: add widget component
2. def5678 feat: redesign widget layout
3. ghi9012 fix: address review feedback
4. jkl3456 fix: remove dead imports
## Proposed Cleanup
Standalone commits (will remain):
1. abc1234 feat: add widget component
2. def5678 feat: redesign widget layout
Fixup targets:
ghi9012 "fix: address review feedback" → fixup into abc1234 "feat: add widget component"
jkl3456 "fix: remove dead imports" → fixup into abc1234 "feat: add widget component"
## Resulting History
1. abc1234 feat: add widget component (absorbs ghi9012, jkl3456)
2. def5678 feat: redesign widget layout
Ask the user for explicit approval before proceeding. The user may want to adjust the plan — e.g., reassign a fixup to a different target, keep a commit standalone, or split things differently.
Before any mutation, create a backup branch from the current branch tip and push it to origin so the state is always recoverable:
BACKUP_BRANCH="backup/cleanup-$(git branch --show-current)-$(date +%Y%m%d-%H%M%S)"
ORIGINAL_TIP=$(git rev-parse HEAD)
git branch "$BACKUP_BRANCH" "$ORIGINAL_TIP"
git push origin "$BACKUP_BRANCH"
Inform the user that the backup was created and pushed. This makes the operation fully reversible — if anything goes wrong, the original history can be restored from the backup branch.
Build the rebase todo list by reordering commits so each fixup immediately follows its target, then marking fixup commits with fixup:
# Write the desired todo list to a script
# Use GIT_SEQUENCE_EDITOR to apply it non-interactively
GIT_SEQUENCE_EDITOR='bash /tmp/rebase-editor.sh' git rebase -i $BASE
Implementation approach:
GIT_SEQUENCE_EDITOR='bash /path/to/script.sh' to apply it non-interactivelyThe reordering must:
pick to fixup for fixup commitsIf conflicts occur:
git rebase --abortAfter successful rebase:
# Show the new history
git log --oneline $BASE..HEAD
# Verify no code changes — diff the branch-modified files between old and new HEAD
git diff HEAD $ORIGINAL_TIP -- <list of files the branch modifies>
The diff of branch-modified files must be empty. If it differs, stop and alert the user.
Force-push with lease and capture the before/after SHAs:
PUSH_OUTPUT=$(git push --force-with-lease 2>&1)
echo "$PUSH_OUTPUT"
# Parse old and new remote SHAs from push output
OLD_SHORT=$(echo "$PUSH_OUTPUT" | grep -oP '^\+?\s*\K[0-9a-f]+(?=\.\.\.)' | head -1)
NEW_SHORT=$(echo "$PUSH_OUTPUT" | grep -oP '\.\.\.(\K[0-9a-f]+)' | head -1)
CLEANUP_OLD_SHA=$(git rev-parse "$OLD_SHORT")
CLEANUP_NEW_SHA=$(git rev-parse "$NEW_SHORT")
Construct the comparison link:
https://github.com/{upstream-owner}/{repo}/compare/{CLEANUP_OLD_SHA}..{CLEANUP_NEW_SHA}
Use the upstream repo (where the PR lives) for the comparison URL, not the fork. SHAs must be full 40-character hashes.
Since the fixup folding only rewrites history without changing code, this compare link should show no file changes — confirming the cleanup was history-only.
If a PR was identified in Phase 1, draft a comment explaining the cleanup.
The comment should:
Template:
Cleaned up the commit history by [folding fixup commits](<cleanup-compare-link>) before merge (history-only, no code changes).
**Before** (<N> commits):
- <sha> <message>
- <sha> <message>
- ...
**After** (<M> commits):
- <sha> <message>
- <sha> <message>
<Brief explanation of what was folded into what>
Original branch state preserved at [`<backup-branch>`](<link-to-backup-branch-on-origin>) in case recovery is needed.
Show the draft comment to the user for approval before posting. Display the raw markdown in a code block so the user sees exactly what will be posted.
After approval:
gh pr comment <PR#> --body "<approved-comment>"
After everything is confirmed working:
git branch -D "$BACKUP_BRANCH"git push origin --delete "$BACKUP_BRANCH"--force-with-leaseAdd an SSH public key to a remote server's authorized_keys file
Save working documents to .context/ with proper frontmatter
Rebase a contributor's PR onto latest main. Fetches the PR, creates a backup branch on origin, sets up a worktree, analyzes divergence, rebases, and force-pushes back to the contributor's fork. Use when a PR needs to be brought up to date with main.
Merge source branch (default main) to production, create a CalVer release, and generate release content (GitHub release notes, Discord announcement, blog post)
Create a well-structured GitHub issue from a conversation or description
Link or unlink a local library for testing in a consumer project. Handles build, npm install from path, and cleanup. Default action is "link". Use "unlink" to reverse.