Git Recovery and Fix Skill
This skill provides systematic approaches for diagnosing and recovering from common Git problems, particularly lost commits and detached HEAD situations.
When to Use This Skill
- Recovering commits that appear to be "lost" or missing
- Fixing detached HEAD states where work was committed but not on a branch
- Recovering from accidental or operations
- Restoring work after switching branches without committing
- Investigating what happened to missing changes in a repository
Diagnostic Approach
Initial Assessment
To diagnose a Git recovery situation, run these commands in parallel to understand the repository state:
- - Check current working directory state and branch
- - View history of HEAD movements (critical for finding lost commits)
- - List all branches including remotes
- - View recent commit history on current branch
Understanding Reflog Output
The reflog is the most important tool for recovery. It shows every position HEAD has been in, including:
- Commits made in detached HEAD state
- Positions before resets
- Branch switches and checkouts
Reflog entries follow the format:
<commit-hash> HEAD@{n}: <action>: <message>
Look for entries that indicate:
- - A commit was made (potential recovery target)
- - A branch switch occurred (may indicate where commits were left behind)
- - A reset was performed (commits after this point may need recovery)
Recovery Strategies
Strategy 1: Merge Lost Commit
When a commit exists in reflog but not on any branch:
bash
# First, ensure on the target branch
git checkout <target-branch>
# Merge the lost commit
git merge <commit-hash>
This preserves commit history and relationships.
Strategy 2: Cherry-pick Lost Commit
Alternative when merge is not desired or when only specific commits are needed:
bash
git checkout <target-branch>
git cherry-pick <commit-hash>
Use cherry-pick when:
- Only specific commits from a series are needed
- The commit history should appear linear
- Merge would bring in unwanted changes
Strategy 3: Create Recovery Branch
Before performing recovery operations, create a safety branch:
bash
# Create a branch at the lost commit for safety
git branch recovery-<descriptive-name> <commit-hash>
# Then proceed with merge or cherry-pick
git checkout <target-branch>
git merge recovery-<descriptive-name>
This provides a rollback point if recovery goes wrong.
Strategy 4: Reset to Lost Commit
When the current branch should be moved to a lost commit (use with caution):
bash
# Soft reset preserves changes in staging
git reset --soft <commit-hash>
# Mixed reset (default) preserves changes in working directory
git reset <commit-hash>
# Hard reset discards all changes (dangerous)
git reset --hard <commit-hash>
Conflict Resolution During Recovery
Handling Merge Conflicts
When merging a recovered commit causes conflicts:
- Identify conflicting files: shows files with conflicts
- Read the conflicting file to understand both versions
- Look for context clues: Commit messages often indicate intent (e.g., "Move to Stanford" suggests which version is correct)
- Edit to resolve: Remove conflict markers and keep correct content
- Verify resolution: Re-read the file to confirm all conflict markers are removed
- Complete the merge:
bash
git add <resolved-files>
git commit
Conflict Marker Format
<<<<<<< HEAD
Current branch content
=======
Incoming commit content
>>>>>>> <commit-hash>
Remove all three marker lines and keep the desired content.
Verification Steps
After any recovery operation, verify success:
-
Check all modified files: When a recovered commit modified multiple files, examine each one
bash
git show <commit-hash> --stat # See which files were modified
-
Verify file contents: Read files that were part of the recovery to confirm correct content
-
Check for remaining conflict markers: Search for
,
, or
in modified files
-
Review commit history:
-
Run tests if available: Execute any test suite to verify functionality
Common Pitfalls
Pitfall 1: Incomplete Conflict Resolution
Problem: Conflict markers left in files after supposedly resolving conflicts.
Prevention: Always re-read files after editing to confirm all markers are removed.
Pitfall 2: Ignoring Auto-merged Files
Problem: Focusing only on files with conflicts while ignoring auto-merged files that may have issues.
Prevention: Check
git show <commit-hash> --stat
to see all files modified by the recovered commit, and verify each one.
Pitfall 3: Not Creating a Safety Branch
Problem: Performing recovery operations without a rollback point.
Prevention: Before merging or resetting, note the current HEAD position or create a branch:
bash
git branch backup-before-recovery
Pitfall 4: Garbage Collection Risk
Problem: Commits in detached HEAD state can eventually be garbage collected if not referenced by a branch or tag.
Prevention: Create a branch at important commits promptly:
bash
git branch save-work <commit-hash>
Pitfall 5: Assuming Single Lost Commit
Problem: Only recovering the most recent lost commit when multiple commits may be orphaned.
Prevention: Examine the full reflog to identify all commits that may need recovery:
Decision Framework
When recovering lost work, choose the approach based on these factors:
| Situation | Recommended Approach |
|---|
| Single commit, want full history | |
| Single commit, want linear history | |
| Multiple related commits | the most recent (includes ancestors) |
| Multiple unrelated commits | each one |
| Uncertain about recovery | Create branch first, then merge |
| Need to completely move branch | (with caution) |
Post-Recovery Best Practices
After successful recovery:
- Document what happened: Understanding the cause prevents recurrence
- Check for similar issues: Other work may also be orphaned
- Consider workflow improvements: Detached HEAD often results from without creating a branch