| name | git-recovery |
| description | Safety practices and recovery techniques for Git. Covers reflog usage, reset vs revert strategies, recovering lost commits, undoing mistakes, and preventing data loss. Helps AI agents safely navigate Git operations and recover from errors. |
Git Safety and Recovery
Purpose: This skill teaches AI agents to work safely with Git and recover from common mistakes without losing work.
Core Principles
- Git Rarely Deletes - Almost everything is recoverable via reflog
- Understand Before Destroying - Know what
--hard, --force do
- Backup Before Risky Operations - Use stash or branches
- Revert, Don't Reset - For shared branches
Understanding Git's Safety Net
The Reflog (Your Safety Net)
What is reflog?
Git's reflog records every HEAD movement. It's your "undo history" for Git operations.
git reflog
abc123 HEAD@{0}: commit: feat(auth): add login
def456 HEAD@{1}: checkout: moving from main to feature
ghi789 HEAD@{2}: pull: fast-forward
jkl012 HEAD@{3}: reset: moving to HEAD~1
mno345 HEAD@{4}: commit: fix(bug): temporary fix
How long does reflog keep data?
- Default: 90 days for reachable commits
- 30 days for unreachable commits
- Configurable via
gc.reflogExpire
What Can Be Recovered?
- Deleted branches (if deleted recently)
- Reset commits (within 90 days)
- Amended commits (original still in reflog)
- Rebased commits (original still in reflog)
- Dropped stashes (if recent)
- Unstaged changes that were never committed
- Untracked files that were never added
- Commits older than gc.reflogExpire
- Files explicitly removed with git clean -f
Common Mistakes and Fixes
Mistake 1: Accidentally Deleted Branch
git branch -D feature/important-work
git reflog | grep "important-work"
git switch -c feature/important-work abc123
git branch feature/important-work abc123
git switch feature/important-work
Mistake 2: Reset Too Far
git reset --hard HEAD~3
git reflog
git reset --hard def456
git reset --hard HEAD@{1}
Mistake 3: Committed to Wrong Branch
git switch main
git add src/feature.js
git commit -m "feat(feature): add new feature"
git switch -c feature/new-feature
git switch main
git reset --hard HEAD~1
Mistake 4: Amended Wrong Commit
git commit --amend -m "New message"
git reflog
git reset --hard def456
Mistake 5: Rebased and Lost Commits
git rebase -i HEAD~5
git rebase --abort
git reflog
git reset --hard def456
Mistake 6: Force Pushed Wrong Branch
git push --force origin main
git reflog
git reset --hard <correct-commit>
git push --force-with-lease origin main
git push --force origin main
git fetch origin
git log origin/main@{1}
Mistake 7: Accidentally Removed Staged Changes
git restore --staged src/important.js
git restore src/important.js
git diff src/important.js
git stash push src/important.js
Reset vs Revert vs Restore
Decision Tree
What do you want to undo?
├─ Local changes not committed yet
│ └─> git restore <file>
│
├─ Staging area (unstage)
│ └─> git restore --staged <file>
│
├─ Last commit (not pushed)
│ ├─ Keep changes in working directory
│ │ └─> git reset --soft HEAD~1
│ │
│ └─ Discard changes completely
│ └─> git reset --hard HEAD~1
│
└─ Commit already pushed
└─> git revert <commit> (creates new commit)
Git Reset (For Local Changes)
git reset --soft HEAD~1
git reset HEAD~1
git reset --mixed HEAD~1
git reset --hard HEAD~1
Reset Examples
git reset --soft HEAD~1
git reset HEAD~1
git reset --hard HEAD~1
git reset --soft abc123
git log HEAD~3..HEAD
git diff HEAD~3
Git Revert (For Shared Branches)
git revert abc123
Revert Examples
git revert abc123
git revert abc123 --no-edit
git revert abc123 def456 ghi789
git revert HEAD~3..HEAD
git revert -m 1 abc123
Comparison Table
| Command | Changes History? | Safe for Shared? | Recoverable? | Use Case |
|---|
git restore | No | Yes | No (working dir changes lost) | Undo local file changes |
git reset --soft | Yes | No | Yes (via reflog) | Undo commit, keep changes staged |
git reset --mixed | Yes | No | Yes (via reflog) | Undo commit, keep changes unstaged |
git reset --hard | Yes | No | Yes (via reflog) | Undo commit, discard changes |
git revert | No | Yes | N/A (creates new commit) | Undo commit on shared branch |
Recovery Workflows
Workflow 1: Find and Recover Lost Commit
git reflog | grep -i "search term"
git reflog
git show abc123
git switch -c recovered-work abc123
git cherry-pick abc123
git reset --hard abc123
Workflow 2: Recover Deleted Branch
git reflog | grep "branch-name"
git reflog | grep "checkout"
git switch -c branch-name abc123
git log
Workflow 3: Undo Bad Merge
git reset --hard HEAD~1
git revert -m 1 HEAD
git merge --abort
Workflow 4: Recover from Bad Rebase
git rebase --abort
git reflog
git reset --hard def456
Workflow 5: Recover Dropped Stash
git reflog | grep stash
git switch -c recovered-stash abc123
git stash apply abc123
git stash apply abc123
Preventive Measures
Before Risky Operations
git switch -c backup-before-rebase
git switch feature-branch
git branch -d backup-before-rebase
git stash push -m "Backup before risky operation"
git stash drop
git stash pop
git tag backup-$(date +%Y%m%d-%H%M%S)
git tag -d backup-20240115-143000
Configure Safety Settings
git config --global alias.yolo '!echo "Are you sure? Use git reset --hard if certain"'
git config --global gc.reflogExpire 180
git config --global gc.reflogExpireUnreachable 60
git config --global alias.pushf 'push --force-with-lease'
git config --global clean.requireForce true
Pre-operation Checklist
Before running destructive commands:
Advanced Recovery
Recover Specific Files from History
git restore --source=abc123 src/important.js
git log --all --full-history -- src/deleted-file.js
git restore --source=abc123 src/deleted-file.js
git show stash@{0}:src/file.js > src/file.js
Recover from git clean
git clean -fd
git clean -nfd
git clean -fd
Recover from Rewritten History
git reflog
git log --all --oneline
git push --force-with-lease origin main
git fetch origin
git merge origin/main
git push
git cherry-pick abc123 def456
git push
Common Dangerous Commands
Commands to Use Carefully
git reset --hard <commit>
git clean -fd
git push --force
git rebase -i
git branch -D <branch>
Safe Alternatives
git stash
git push --force-with-lease
git clean -nfd
git stash push -u
git branch -d
git merge --no-ff <branch>
git reset --soft HEAD~3
git restore --staged .
Quick Reference
Recovery Commands
git reflog
git reflog show <branch>
git switch -c <branch> <commit-hash>
git reset --soft HEAD~1
git reset --hard HEAD~1
git reflog
git revert <commit>
git reset --hard HEAD~1
git revert -m 1 HEAD
git log --all --full-history -- <file>
git restore --source=<commit> <file>
git reflog | grep stash
git stash apply <stash-hash>
Summary
Key Principles:
- Git rarely deletes - Reflog keeps 90 days of history
- Backup before risky operations - Branch, tag, or stash
- Use revert for shared branches - Never reset public history
- Check before destroying - Dry runs, diffs, logs
- Force-with-lease, not force - Prevents accidental overwrites
Essential Commands:
git reflog
git reset --soft HEAD~1
git reset --hard <commit>
git revert <commit>
git switch -c name <hash>
Remember: Almost every mistake is recoverable. Stay calm, check reflog, and understand what each command does before running it.