🎯

git-recovery

🎯Skill

from daleseo/git-skills

VibeIndex|
What it does

Recovers lost Git commits, branches, and work using reflog, helping AI agents safely undo mistakes and prevent data loss.

πŸ“¦

Part of

daleseo/git-skills(4 items)

git-recovery

Installation

Quick InstallInstall with npx
npx skills add yourusername/git-skills
git cloneClone repository
git clone https://github.com/yourusername/git-skills.git
πŸ“– Extracted from docs: daleseo/git-skills
3Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

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.

Overview

# 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

  1. Git Rarely Deletes - Almost everything is recoverable via reflog
  2. Understand Before Destroying - Know what --hard, --force do
  3. Backup Before Risky Operations - Use stash or branches
  4. 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.

```bash

# βœ“ View reflog

git reflog

# Output shows every commit, checkout, reset, rebase, etc:

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?

```bash

# βœ“ CAN RECOVER:

  • 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)

# βœ— CANNOT RECOVER:

  • 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

```bash

# βœ— MISTAKE: Deleted wrong branch

git branch -D feature/important-work

# Deleted branch feature/important-work (was abc123).

# βœ“ FIX: Recover from reflog

git reflog | grep "important-work"

# abc123 HEAD@{5}: commit: Last commit on important-work

# Recreate branch at that commit

git switch -c feature/important-work abc123

# Or use branch -C to force create

git branch feature/important-work abc123

git switch feature/important-work

```

Mistake 2: Reset Too Far

```bash

# βœ— MISTAKE: Reset and lost commits

git reset --hard HEAD~3

# Now 3 commits are "gone"

# βœ“ FIX: Find commits in reflog

git reflog

# abc123 HEAD@{0}: reset: moving to HEAD~3

# def456 HEAD@{1}: commit: feat(auth): important feature ← Want this!

# Reset back to before the mistake

git reset --hard def456

# Or

git reset --hard HEAD@{1}

```

Mistake 3: Committed to Wrong Branch

```bash

# βœ— MISTAKE: Committed to main instead of feature branch

git switch main

git add src/feature.js

git commit -m "feat(feature): add new feature"

# Oops! This should be on feature branch

# βœ“ FIX: Move commit to correct branch

# Create feature branch (includes the commit)

git switch -c feature/new-feature

# Go back to main and remove the commit

git switch main

git reset --hard HEAD~1

# Now:

# - feature/new-feature has the commit

# - main is back to previous state

```

Mistake 4: Amended Wrong Commit

```bash

# βœ— MISTAKE: Amended commit that shouldn't be changed

git commit --amend -m "New message"

# Oops! Original commit was important

# βœ“ FIX: Find original commit in reflog

git reflog

# abc123 HEAD@{0}: commit (amend): New message

# def456 HEAD@{1}: commit: Original message ← Want this!

# Reset to original commit

git reset --hard def456

```

Mistake 5: Rebased and Lost Commits

```bash

# βœ— MISTAKE: Rebase went wrong, some commits disappeared

git rebase -i HEAD~5

# Accidentally dropped important commits

# βœ“ FIX: Abort or recover from reflog

# If still in rebase:

git rebase --abort

# If rebase already finished:

git reflog

# Find "rebase (start)" entry

# abc123 HEAD@{10}: rebase (start): checkout main

# def456 HEAD@{11}: commit: Important commit ← Before rebase started

# Reset to before rebase

git reset --hard def456

```

Mistake 6: Force Pushed Wrong Branch

```bash

# βœ— MISTAKE: Force pushed and overwrote remote commits

git push --force origin main

# Overwrote teammate's commits!

# βœ“ FIX: Depends on situation

# If you still have local copy of correct state:

git reflog

git reset --hard

git push --force-with-lease origin main

# If you don't have it, ask teammate to push their version:

# Teammate runs:

git push --force origin main

# Or restore from remote reflog (if server keeps it):

git fetch origin

git log origin/main@{1} # One state ago

```

Mistake 7: Accidentally Removed Staged Changes

```bash

# βœ— MISTAKE: Used git restore --staged and lost work

git restore --staged src/important.js

git restore src/important.js # Oops! Lost changes

# βœ“ PREVENTION: Check before restoring

git diff src/important.js # See what will be lost

git stash push src/important.js # Safer alternative

# βœ— CANNOT FIX: Unstaged changes cannot be recovered

# Prevention is key!

```

Reset vs Revert vs Restore

Decision Tree

```

What do you want to undo?

β”œβ”€ Local changes not committed yet

β”‚ └─> git restore

β”‚

β”œβ”€ Staging area (unstage)

β”‚ └─> git restore --staged

β”‚

β”œβ”€ 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 (creates new commit)

```

Git Reset (For Local Changes)

```bash

# Three modes of reset:

# 1. --soft: Move HEAD, keep staged and working directory

git reset --soft HEAD~1

# Use case: Undo commit, keep all changes staged

# Safe: Yes (changes preserved)

# 2. --mixed (default): Move HEAD, unstage, keep working directory

git reset HEAD~1

# OR

git reset --mixed HEAD~1

# Use case: Undo commit, keep changes but unstaged

# Safe: Yes (changes preserved in working directory)

# 3. --hard: Move HEAD, discard staged and working directory

git reset --hard HEAD~1

# Use case: Completely undo commit and discard changes

# Safe: NO (changes lost, but recoverable from reflog)

```

Reset Examples

```bash

# βœ“ SAFE: Undo last commit, keep changes

git reset --soft HEAD~1

# Now changes are staged, ready to re-commit differently

# βœ“ SAFE: Undo last commit, unstage changes

git reset HEAD~1

# Now changes are in working directory, unstaged

# βœ— DESTRUCTIVE: Undo commit and discard all changes

git reset --hard HEAD~1

# Changes are "gone" (but recoverable from reflog)

# βœ“ SAFE: Reset to specific commit

git reset --soft abc123

# All commits after abc123 are undone, changes staged

# βœ“ VISUAL: See what would be reset

git log HEAD~3..HEAD # Shows commits that would be undone

git diff HEAD~3 # Shows changes that would be affected

```

Git Revert (For Shared Branches)

```bash

# βœ“ SAFE: Undo commit on shared branch

git revert abc123

# Creates NEW commit that undoes changes:

# * Revert "feat(auth): add OAuth" ← New commit

# * feat(auth): add OAuth ← Original commit

# * Previous commit

# Why use revert instead of reset?

# - Doesn't rewrite history

# - Safe for shared branches

# - Preserves audit trail

```

Revert Examples

```bash

# βœ“ Revert single commit

git revert abc123

# Opens editor for revert commit message

# βœ“ Revert without opening editor

git revert abc123 --no-edit

# βœ“ Revert multiple commits

git revert abc123 def456 ghi789

# βœ“ Revert range of commits

git revert HEAD~3..HEAD

# βœ“ Revert merge commit

git revert -m 1 abc123

# -m 1 means keep first parent (usually main)

```

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

```bash

# 1. Search reflog for lost commit

git reflog | grep -i "search term"

# OR view all reflog

git reflog

# 2. Examine commit content

git show abc123

# 3. Recover options:

# Option A: Create new branch at that commit

git switch -c recovered-work abc123

# Option B: Cherry-pick the commit

git cherry-pick abc123

# Option C: Reset current branch to that commit

git reset --hard abc123

```

Workflow 2: Recover Deleted Branch

```bash

# 1. Find branch in reflog

git reflog | grep "branch-name"

# OR

git reflog | grep "checkout"

# 2. Find last commit on that branch

# abc123 HEAD@{5}: commit: Last commit on branch-name

# 3. Recreate branch

git switch -c branch-name abc123

# 4. Verify

git log

```

Workflow 3: Undo Bad Merge

```bash

# Just merged, but it was wrong

# βœ“ OPTION 1: Reset (if not pushed)

git reset --hard HEAD~1

# βœ“ OPTION 2: Revert (if already pushed)

git revert -m 1 HEAD

# -m 1 keeps the main branch parent

# βœ“ OPTION 3: Abort (if still in merge)

git merge --abort

```

Workflow 4: Recover from Bad Rebase

```bash

# Rebase went wrong

# βœ“ OPTION 1: Abort (if still in rebase)

git rebase --abort

# βœ“ OPTION 2: Recover from reflog (if already finished)

git reflog

# Find entry before rebase started:

# abc123 HEAD@{10}: checkout: moving from feature to main

# def456 HEAD@{11}: commit: Last commit before rebase

git reset --hard def456

```

Workflow 5: Recover Dropped Stash

```bash

# Accidentally dropped stash

# 1. Find stash in reflog

git reflog | grep stash

# abc123 WIP on main: Previous stash

# def456 index on main: Another stash

# 2. Create branch from stash commit

git switch -c recovered-stash abc123

# 3. Apply the stash

git stash apply abc123

# OR directly apply from reflog

git stash apply abc123

```

Preventive Measures

Before Risky Operations

```bash

# βœ“ BACKUP 1: Create safety branch

git switch -c backup-before-rebase

git switch feature-branch

# Do risky operation

# If successful, delete backup:

git branch -d backup-before-rebase

# βœ“ BACKUP 2: Use stash

git stash push -m "Backup before risky operation"

# Do risky operation

# If successful:

git stash drop

# If failed:

git stash pop

# βœ“ BACKUP 3: Tag current state

git tag backup-$(date +%Y%m%d-%H%M%S)

# Do risky operation

# If successful:

git tag -d backup-20240115-143000

```

Configure Safety Settings

```bash

# βœ“ Require confirmation for destructive operations

git config --global alias.yolo '!echo "Are you sure? Use git reset --hard if certain"'

# βœ“ Increase reflog retention

git config --global gc.reflogExpire 180 # 180 days instead of 90

git config --global gc.reflogExpireUnreachable 60 # 60 days instead of 30

# βœ“ Always use --force-with-lease

git config --global alias.pushf 'push --force-with-lease'

# βœ“ Protect against accidental git clean

git config --global clean.requireForce true

```

Pre-operation Checklist

Before running destructive commands:

  • [ ] Do I have a backup? (branch, tag, or stash)
  • [ ] Is this branch pushed to remote? (additional backup)
  • [ ] Have I verified what will be changed? (git diff, git log)
  • [ ] Do I understand what this command does?
  • [ ] Can I recover using reflog if something goes wrong?

Advanced Recovery

Recover Specific Files from History

```bash

# βœ“ Restore file from specific commit

git restore --source=abc123 src/important.js

# βœ“ Restore file from before it was deleted

git log --all --full-history -- src/deleted-file.js

# Find commit where it existed

git restore --source=abc123 src/deleted-file.js

# βœ“ Restore file from stash

git show stash@{0}:src/file.js > src/file.js

```

Recover from git clean

```bash

# βœ— PROBLEM: Ran git clean and deleted untracked files

git clean -fd

# Deleted important-file.js (untracked)

# βœ“ LIMITED RECOVERY OPTIONS:

# Option 1: Check editor auto-save

# Many editors keep unsaved file backups

# Option 2: Check OS trash/recycle bin

# Some Git GUIs move files to trash instead of deleting

# Option 3: File recovery tools

# Use OS-level file recovery (PhotoRec, TestDisk, etc.)

# βœ— PREVENTION: Always use -n first

git clean -nfd # -n = dry run, shows what would be deleted

# Review output

git clean -fd # Actually delete

```

Recover from Rewritten History

```bash

# Someone force-pushed and rewrote history

# βœ“ Find old commits in local reflog

git reflog

git log --all --oneline

# βœ“ Recovery options:

# Option 1: Push your version (if yours is correct)

git push --force-with-lease origin main

# Option 2: Merge both versions

git fetch origin

git merge origin/main

# Resolve conflicts

git push

# Option 3: Cherry-pick missing commits

git cherry-pick abc123 def456

git push

```

Common Dangerous Commands

Commands to Use Carefully

```bash

# βœ— DANGEROUS: Can lose work

git reset --hard

# Discards all changes in working directory

# Prevention: git stash first

git clean -fd

# Deletes untracked files permanently

# Prevention: git clean -nfd first (dry run)

git push --force

# Overwrites remote, can lose others' work

# Prevention: Use --force-with-lease instead

git rebase -i

# Can drop/edit commits, complex conflicts

# Prevention: Create backup branch first

git branch -D

# Deletes branch even if not merged

# Prevention: Use -d first (safer), recover from reflog if needed

```

Safe Alternatives

```bash

# βœ“ SAFER ALTERNATIVES:

# Instead of: git reset --hard

git stash # Or git stash push -u to include untracked

# Instead of: git push --force

git push --force-with-lease

# Instead of: git clean -fd

git clean -nfd # Dry run first

git stash push -u # Stash untracked files

# Instead of: git branch -D

git branch -d # Refuses if not merged

git merge --no-ff # Merge first, then delete

# Instead of: git reset --hard HEAD~3

git reset --soft HEAD~3 # Keep changes

git restore --staged . # Unstage if needed

```

Quick Reference

Recovery Commands

```bash

# View reflog

git reflog

git reflog show

# Recover deleted branch

git switch -c

# Undo last commit (keep changes)

git reset --soft HEAD~1

# Undo last commit (discard changes)

git reset --hard HEAD~1

git reflog # Can still recover

# Revert commit (safe for shared branches)

git revert

# Recover from bad merge

git reset --hard HEAD~1 # If not pushed

git revert -m 1 HEAD # If pushed

# Find deleted file

git log --all --full-history --

git restore --source=

# Recover dropped stash

git reflog | grep stash

git stash apply

```

Summary

Key Principles:

  1. Git rarely deletes - Reflog keeps 90 days of history
  2. Backup before risky operations - Branch, tag, or stash
  3. Use revert for shared branches - Never reset public history
  4. Check before destroying - Dry runs, diffs, logs
  5. Force-with-lease, not force - Prevents accidental overwrites

Essential Commands:

```bash

git reflog # Your safety net

git reset --soft HEAD~1 # Undo commit, keep changes

git reset --hard # Dangerous! Backup first

git revert # Safe undo for shared branches

git switch -c name # Recover deleted branch

```

Remember: Almost every mistake is recoverable. Stay calm, check reflog, and understand what each command does before running it.