Unnamed Skill
Rewrites git history safely with dry-run-first workflow. Supports commit amending, squashing, rewording, tag updates, and force pushing. Always proposes plan before execution. Triggers on keywords: rewrite history, squash commits, amend commit, fix commit, update tags, rebase history, clean history, fix tag
$ Instalar
git clone https://github.com/MatiasComercio/agentic-config /tmp/agentic-config && cp -r /tmp/agentic-config/core/skills/git-rewrite-history ~/.claude/skills/agentic-config// tip: Run this command in your terminal to install the skill
name: git-rewrite-history description: Rewrites git history safely with dry-run-first workflow. Supports commit amending, squashing, rewording, tag updates, and force pushing. Always proposes plan before execution. Triggers on keywords: rewrite history, squash commits, amend commit, fix commit, update tags, rebase history, clean history, fix tag project-agnostic: true allowed-tools:
- Bash
- Read
- Edit
- Write
Git Rewrite History
Safely rewrite git history with mandatory dry-run planning and user confirmation.
Critical Rules
- ALWAYS DRY RUN FIRST - Propose plan, never execute without approval
- ALWAYS WAIT FOR CONFIRMATION - User must explicitly approve before destructive operations
- ALWAYS CREATE BACKUP - Backup branch before any rebase/amend
- ALWAYS SAVE TAG MESSAGES - Preserve tag annotations before deletion
Supported Operations
| Operation | Use Case |
|---|---|
| Amend Content | Change files in historical commits |
| Squash Commits | Combine multiple commits into one |
| Reword Message | Change commit message text |
| Update Tags | Move tags to new commits after rebase |
| Delete Branches | Remove local and remote branches |
| Force Push | Push rewritten history to remote |
Workflow
Phase 1: ANALYZE
Gather current state before proposing changes.
# Current branch and HEAD
git rev-parse --abbrev-ref HEAD
git rev-parse --short HEAD
# Commit history
git log --oneline --decorate main
# All tags
git tag -l
# All branches
git branch -a -v
Phase 2: PLAN (DRY RUN)
OUTPUT FORMAT:
## DRY RUN - PROPOSED PLAN
### Current State
- Branch: {branch}
- HEAD: {sha}
- Commits: {count}
- Tags: {list}
### Operations
1. {operation description}
2. {operation description}
...
### Commands to Execute
{numbered list of exact commands}
### Risk Assessment
| Risk | Impact | Mitigation |
|------|--------|------------|
### Affected
- Commits: {list}
- Tags: {list}
- Remote: {yes/no force push required}
**Awaiting approval to proceed.**
Phase 3: CONFIRM
STOP AND WAIT for user to respond with approval (e.g., "OK", "proceed", "yes").
Phase 4: BACKUP
# Create backup branch
git branch backup/pre-rewrite-$(date +%Y%m%d-%H%M%S) HEAD
# Save tag messages to temp files
git tag -l --format='%(contents)' {tag} > /tmp/{tag}-message.txt
Phase 5: EXECUTE
Pattern A: Amend Content in Historical Commit
# Save cleaned file
cp {file} /tmp/cleaned-file
# Stash if needed
git stash
# Start interactive rebase (mark target as "edit")
GIT_SEQUENCE_EDITOR="sed -i '' 's/^pick {short_sha}/edit {short_sha}/'" git rebase -i {parent_sha}
# Apply changes when stopped
cp /tmp/cleaned-file {file}
git add {file}
git commit --amend --no-edit
# Continue
git rebase --continue
Pattern B: Squash N Commits into 1
# For commits 2-N, change "pick" to "squash"
GIT_SEQUENCE_EDITOR="sed -i '' '2,{N}s/^pick/squash/'" git rebase -i --root
# OR for non-root:
GIT_SEQUENCE_EDITOR="sed -i '' '2,{N}s/^pick/squash/'" git rebase -i {parent_sha}
# When prompted for message, use edit mode:
GIT_SEQUENCE_EDITOR="sed -i '' '1s/^pick/edit/'" git rebase -i --root
git commit --amend -m "{new_message}"
git rebase --continue
Pattern C: Reword Commit Message
# Mark commit for edit
GIT_SEQUENCE_EDITOR="sed -i '' 's/^pick {short_sha}/edit {short_sha}/'" git rebase -i {parent_sha}
# Amend message
git commit --amend -m "{new_message}"
# Continue
git rebase --continue
Pattern D: Delete Branches
# Local branches
git branch -D {branch1} {branch2}
# Remote branches
git push origin --delete {branch1} {branch2}
Phase 6: UPDATE TAGS
After any rebase, commit hashes change. Tags must be recreated.
# Get new commit hashes
git log --oneline -{N} main
# Delete old tags (local)
git tag -d {tag1} {tag2}
# Recreate tags on new commits
git tag -a {tag} {new_sha} -F /tmp/{tag}-message.txt
# OR with inline message:
git tag -a {tag} {new_sha} -m "{message}"
Phase 7: FORCE PUSH
# Delete remote tags first
git push origin :refs/tags/{tag1} :refs/tags/{tag2}
# Force push branch
git push --force-with-lease origin {branch}
# Push new tags
git push origin {tag1} {tag2}
Phase 8: VERIFY
# Final history
git log --oneline --decorate -{N} main
# Commit count
git rev-list --count main
# Tags
git tag -l | sort -V
# Remote sync
git status
Output Format
After completion, report:
## Complete
### Final State
{commit} (tag: {tag}) {message}
{commit} (tag: {tag}) {message}
...
### Summary
| Metric | Before | After |
|--------|--------|-------|
| Commits | {N} | {M} |
| Tags | {list} | {list} |
### Verification
| Check | Result |
|-------|--------|
| Commit count | {N} |
| Tags exist | {list} |
| Remote synced | Yes/No |
Safety Notes
--force-with-leaseprevents overwriting others' work- Backup branches preserve original state for rollback
- Tag messages saved to /tmp allow recreation with original annotations
- Reflog preserves history locally (expires after 90 days by default)
Repository
