| name | git-safe |
| 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: git safe, 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 Safe
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.
git rev-parse --abbrev-ref HEAD
git rev-parse --short HEAD
git log --oneline --decorate main
git tag -l
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
git branch backup/pre-rewrite-$(date +%Y%m%d-%H%M%S) HEAD
git tag -l --format='%(contents)' {tag} > /tmp/{tag}-message.txt
Phase 5: EXECUTE
Pattern A: Amend Content in Historical Commit
cp {file} /tmp/cleaned-file
git stash
GIT_SEQUENCE_EDITOR="sed -i '' 's/^pick {short_sha}/edit {short_sha}/'" git rebase -i {parent_sha}
cp /tmp/cleaned-file {file}
git add {file}
git commit --amend --no-edit
git rebase --continue
Pattern B: Squash N Commits into 1
GIT_SEQUENCE_EDITOR="sed -i '' '2,{N}s/^pick/squash/'" git rebase -i --root
GIT_SEQUENCE_EDITOR="sed -i '' '2,{N}s/^pick/squash/'" git rebase -i {parent_sha}
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
GIT_SEQUENCE_EDITOR="sed -i '' 's/^pick {short_sha}/edit {short_sha}/'" git rebase -i {parent_sha}
git commit --amend -m "{new_message}"
git rebase --continue
Pattern D: Delete Branches
git branch -D {branch1} {branch2}
git push origin --delete {branch1} {branch2}
Phase 6: UPDATE TAGS
After any rebase, commit hashes change. Tags must be recreated.
git log --oneline -{N} main
git tag -d {tag1} {tag2}
git tag -a {tag} {new_sha} -F /tmp/{tag}-message.txt
git tag -a {tag} {new_sha} -m "{message}"
Phase 7: FORCE PUSH
git push origin :refs/tags/{tag1} :refs/tags/{tag2}
git push --force-with-lease origin {branch}
git push origin {tag1} {tag2}
Phase 8: VERIFY
git log --oneline --decorate -{N} main
git rev-list --count main
git tag -l | sort -V
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-lease prevents 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)