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 git reset or git checkout 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:
-
git status
-
Check current working directory state and branch
-
git reflog
-
View history of HEAD movements (critical for finding lost commits)
-
git branch -a
-
List all branches including remotes
-
git log --oneline -10
-
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:
-
commit:
-
A commit was made (potential recovery target)
-
checkout:
-
A branch switch occurred (may indicate where commits were left behind)
-
reset:
-
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:
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:
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:
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):
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: git status 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: 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
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:
git log --oneline -5
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:
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:
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:
git reflog | head -20
Decision Framework
When recovering lost work, choose the approach based on these factors:
Situation Recommended Approach
Single commit, want full history git merge
Single commit, want linear history git cherry-pick
Multiple related commits git merge the most recent (includes ancestors)
Multiple unrelated commits git cherry-pick each one
Uncertain about recovery Create branch first, then merge
Need to completely move branch git reset (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 git checkout <commit> without creating a branch