Git Reflog and Recovery: Your Safety Net for Destructive Operations
Master git reflog to recover lost commits, undo destructive operations, and understand Git's safety net. Learn recovery techniques for reset, rebase, and merge disasters.
Git Reflog and Recovery: Your Safety Net for Destructive Operations
When to Use / When Not to Use
Use Git Reflog When
- Accidental reset — You ran
git reset --hardand lost commits - Dropped stash — You accidentally dropped a stash with important work
- Failed rebase — A rebase went wrong and you need to go back
- Force push recovery — You force pushed the wrong branch and need the old state
- Orphaned commits — Commits exist but no branch points to them
- Understanding history — You want to see what operations were performed locally
Do Not Use Git Reflog When
- Shared history recovery — Reflog is local; it can’t recover commits never pushed
- Long-term backup — Reflog entries expire (default 90 days); it’s not a backup system
- Remote recovery — Reflog doesn’t exist on the remote; it’s a local-only feature
- Deleted repository — If the
.gitdirectory is gone, reflog is gone too
Core Concepts
Git reflog tracks HEAD movements and branch updates:
| Entry Type | Trigger | Example |
|---|---|---|
commit | Creating a new commit | commit: feat: add user authentication |
checkout | Switching branches | checkout: moving from main to feature/login |
reset | Running git reset | reset: moving to HEAD~3 |
rebase | Running git rebase | rebase: picking abc1234 |
merge | Running git merge | merge main: Fast-forward |
stash | Stash operations | stash: WIP on feature: abc1234 |
cherry-pick | Running git cherry-pick | cherry-pick: def5678 |
Each reflog entry has a reference: HEAD@{n} where n is how many operations ago. HEAD@{0} is the current state, HEAD@{1} is the previous state, and so on.
graph LR
A["HEAD@{0}: Current State"] --> B["HEAD@{1}: Previous Operation"]
B --> C["HEAD@{2}: Earlier Operation"]
C --> D["HEAD@{3}: Even Earlier"]
D --> E["HEAD@{n}: Oldest Tracked"]
Architecture and Flow Diagram
The reflog structure and recovery workflow:
graph TD
A[Local Operations] --> B[HEAD Reflog]
A --> C[Branch Reflog]
B --> D["refs/heads/main@{n}"]
B --> E["refs/heads/feature@{n}"]
C --> F[".git/logs/HEAD"]
C --> G[".git/logs/refs/heads/"]
D --> H{Need Recovery?}
E --> H
H -->|Yes| I[git reflog show]
I --> J[Find Target Commit]
J --> K[git reset/checkout/branch]
K --> L[Recovered State]
Step-by-Step Guide
Reference: 1. Viewing the Reflog
Reference: 4. Recovering a Dropped Stash
1. Viewing the Reflog
The basic reflog shows recent HEAD movements:
# Show HEAD reflog
git reflog
# Output example:
# abc1234 HEAD@{0}: commit: feat: add payment processing
# def5678 HEAD@{1}: commit: feat: add cart functionality
# ghi9012 HEAD@{2}: checkout: moving from main to feature/checkout
# jkl3456 HEAD@{3}: reset: moving to HEAD~2
# mno7890 HEAD@{4}: commit: feat: add product listing
# pqr1234 HEAD@{5}: clone: from https://github.com/org/project.git
# Show reflog for a specific branch
git reflog show main
# Show reflog with dates
git reflog --date=iso
# Show reflog with full commit hashes
git reflog --format='%H %gd %gs'
2. Essential Reflog Patterns
Key patterns for everyday reflog usage:
# Get only the last 10 entries
git reflog -10
# Show branch-specific reflog with relative times
git reflog show main --format='%gd %gs %cr' -10
# Find a specific operation by message
git reflog --format='%gd %gs' | grep -i "reset\|rebase"
# Show reflog for a specific time window
git reflog --since='2 days ago'
# Export reflog to JSON for scripting
git reflog --format='{"ref":"%gd","message":"%gs","time":"%cr"}' > reflog.json
3. Recovering from Accidental Reset
The most common disaster scenario:
# Scenario: You accidentally reset main back 5 commits
git reset --hard HEAD~5
# Oh no! Your work is gone... but not really
# Check the reflog
git reflog
# Find the commit you were at before the reset
# abc1234 HEAD@{1}: reset: moving to HEAD~5
# def5678 HEAD@{2}: commit: feat: add user profile
# Reset back to where you were
git reset --hard def5678
# Done! Your commits are back.
4. Recovering a Dropped Stash
Stashes are commits too, and they appear in the reflog:
# Scenario: You accidentally dropped an important stash
git stash drop stash@{0}
# Find the stash commit in the reflog
git reflog | grep stash
# Or search for the stash message
git reflog | grep "WIP on feature"
# The stash commit SHA appears in the reflog
# abc1234 HEAD@{15}: stash: WIP on feature/auth
# Recreate the stash from the commit
git stash apply abc1234
# Or create a branch from it
git branch recovered-stash abc1234
5. Recovering from a Failed Rebase
When a rebase goes wrong, reflog is your escape hatch:
# Scenario: Rebase created conflicts and messed up history
git rebase main
# Conflicts everywhere... you abort but things are still broken
# Check the reflog for the state before rebase
git reflog
# Find the pre-rebase state
# def5678 HEAD@{1}: rebase: picking abc1234
# ghi9012 HEAD@{2}: checkout: moving from feature to feature
# Reset to before the rebase started
git reset --hard ghi9012
# Start fresh with a better rebase strategy
git rebase -i main
6. Recovering Orphaned Commits
Commits that no branch points to can still be found:
# Find all unreachable commits
git fsck --lost-found --no-reflogs
# This creates .git/lost-found/commit/ with orphaned commits
ls .git/lost-found/commit/
# Examine each one
git show <commit-sha>
# Create a branch from the one you want
git branch recovered-feature <commit-sha>
7. Using Reflog with Dates
Time-based recovery when you don’t remember the commit:
# What did HEAD look like yesterday?
git reflog --date=iso | grep "yesterday"
# What was main pointing to 2 hours ago?
git reflog show main --date=relative | grep "2 hours ago"
# Checkout the state from a specific time
git checkout main@{2.hours.ago}
# Create a branch from that state
git branch recovery-point main@{2.hours.ago}
Production Failure Scenarios
| Scenario | What Happens | Mitigation |
|---|---|---|
| Reflog expired — Entry is older than 90 days | The commit may be garbage collected | Run recovery within 90 days; use git fsck for older commits |
Garbage collection ran — git gc pruned unreachable commits | Reflog entries exist but commits are gone | Disable aggressive gc; set gc.reflogExpireUnreachable to longer period |
| Remote force push — You force pushed and lost remote commits | Local reflog can’t help if you never had the commits | Require force push protection; use --force-with-lease instead of --force |
| Deleted .git directory — The entire repository is gone | Reflog lives in .git/logs/ — it’s gone too | Regular backups; never delete .git without archiving first |
| Reflog corruption — Reflog file is damaged | Entries may be unrecoverable | Reflog is append-only; corruption is rare but possible |
| Wrong commit recovery — You recover the wrong commit | You’re back to a different wrong state | Verify the commit content with git show before resetting |
Trade-off Analysis
| Aspect | Advantage | Disadvantage |
|---|---|---|
| Safety net | Catches almost all local mistakes | Local only; doesn’t help with remote issues |
| Time-based | Can recover by date/time | Entries expire (default 90/30 days) |
| Comprehensive | Tracks all HEAD movements | Can be overwhelming with hundreds of entries |
| No setup required | Enabled by default | Consumes disk space for log files |
| Branch-specific | Each branch has its own reflog | Only tracks branches you’ve checked out |
| Recovery flexibility | Can reset, checkout, or branch from any entry | Requires understanding of reflog references |
Implementation Snippets
Reflog Configuration
# ~/.gitconfig
[gc]
# Don't aggressively garbage collect
auto = 6000
autopacklimit = 50
[core]
# Keep reflog entries longer
logAllRefUpdates = true
# Per-repository settings
git config gc.reflogExpire 180.days.ago
git config gc.reflogExpireUnreachable 90.days.ago
Recovery Script
#!/bin/bash
# scripts/recovery-assistant.sh
# Interactive reflog recovery assistant
echo "=== Git Reflog Recovery Assistant ==="
echo ""
# Show recent reflog
echo "Recent operations:"
git reflog --date=iso --format='%C(auto)%h %gd %C(reset)%gs %C(blue)%cr' | head -20
echo ""
echo "Options:"
echo "1) Reset HEAD to a specific reflog entry"
echo "2) Create a branch from a reflog entry"
echo "3) Show details of a specific entry"
echo "4) Search reflog by message"
echo "5) Find lost stashes"
read -r choice
case $choice in
1)
echo "Enter reflog reference (e.g., HEAD@{3} or commit SHA):"
read -r ref
echo "This will reset HEAD to: $ref"
echo "Proceed? (y/n)"
read -r confirm
if [ "$confirm" = "y" ]; then
git reset --hard "$ref"
echo "Reset complete."
fi
;;
2)
echo "Enter reflog reference:"
read -r ref
echo "Branch name:"
read -r branch
git branch "$branch" "$ref"
echo "Branch '$branch' created from $ref"
;;
3)
echo "Enter reflog reference:"
read -r ref
git show "$ref"
;;
4)
echo "Search term:"
read -r term
git reflog --grep="$term"
;;
5)
echo "Lost stashes:"
git reflog | grep "stash"
;;
*)
echo "Invalid option"
;;
esac
Pre-Destructive Hook
#!/bin/bash
# scripts/safe-reset.sh
# Wrapper for git reset that creates a safety branch first
TARGET=${1:?Usage: safe-reset.sh <target>}
# Create a safety branch pointing to current HEAD
SAFETY_BRANCH="safety/$(date +%Y%m%d-%H%M%S)"
git branch "$SAFETY_BRANCH" HEAD
echo "Safety branch created: $SAFETY_BRANCH"
echo "Current HEAD: $(git rev-parse HEAD)"
echo ""
# Perform the reset
echo "Resetting to: $TARGET"
git reset --hard "$TARGET"
echo ""
echo "Reset complete."
echo "If something went wrong, recover with:"
echo " git reset --hard $SAFETY_BRANCH"
Reflog Diff Viewer
#!/bin/bash
# scripts/reflog-diff.sh
# Compare two reflog entries
ENTRY1=${1:?Usage: reflog-diff.sh <entry1> <entry2>}
ENTRY2=${2:?Second entry required}
echo "=== Comparing $ENTRY1 vs $ENTRY2 ==="
echo ""
git diff "${ENTRY1}...${ENTRY2}" --stat
echo ""
echo "Full diff:"
git diff "${ENTRY1}...${ENTRY2}"
Observability Checklist
- Logs: Not typically applicable — reflog is local
- Metrics: Track reflog size and entry count per repository
- Alerts: Alert when reflog entries approach expiration or when disk usage from logs exceeds threshold
- Dashboards: Display reflog health: entry count, oldest entry age, and disk space used
- Recovery tracking: Log recovery operations for post-incident analysis
Security and Compliance Notes
- Local only: Reflog never leaves your machine — it’s stored in
.git/logs/ - Sensitive data: Reflog may contain commit messages with sensitive information — audit reflog entries
- No remote sync: Reflog is not pushed to remotes; each developer has their own reflog
- Audit trail: Reflog provides a local audit trail of all operations, useful for forensic analysis
- Compliance: For regulated environments, reflog can help reconstruct developer actions during an incident
Security & Compliance Considerations
- Assuming Reflog is Forever — Reflog entries expire. Default is 90 days for reachable commits, 30 days for unreachable ones. Don’t rely on it as a backup.
- Ignoring Unreachable Commits — After
git gc --prune, unreachable commits are gone forever. Run recovery before garbage collection. - Confusing Reflog with Log —
git logshows commit history;git reflogshows local operations. They serve different purposes. - Not Verifying Before Reset — Resetting to the wrong reflog entry compounds the problem. Always
git showthe target first. - Force Push Without Lease — Using
--forceinstead of--force-with-leasecan overwrite others’ work without warning. - Deleting .git/logs — Manually cleaning
.git/logs/destroys your safety net. Let Git manage reflog expiration. - No Backup Strategy — Reflog is not a backup. Use remote branches, tags, or external backups for critical work.
Quick Recap Checklist
- Reflog tracks all HEAD movements locally
- Use
git reflogto view recent operations - Use
git reflog show <branch>for branch-specific history - Recover lost commits with
git reset --hard <reflog-entry> - Recover dropped stashes by finding them in reflog
- Use
git fsck --lost-foundfor orphaned commits - Reflog entries expire (default 90/30 days)
- Reflog is local-only; it doesn’t sync to remotes
- Create safety branches before destructive operations
- Never use reflog as a substitute for proper backups
Recovery Decision Tree
When you’ve lost work, follow this path:
flowchart TD
A[Lost work detected] --> B{Reflog available?}
B -->|Yes| C[Find target commit in reflog]
C --> D[Reset or branch from entry]
B -->|No| E{Refs still accessible?}
E -->|Yes| F[Use git fsck --lost-found]
E -->|No| G{Remote has commits?}
G -->|Yes| H[Fetch from remote]
G -->|No| I[Check backups]
I --> J{Lost work recovered?}
J -->|No| K[Accept loss, recreate]
J -->|Yes| L[Document incident]
D --> L
F --> L
H --> L
- Reflog available? →
git reflog— Find the commit SHA and reset/branch from it - Reflog expired? →
git fsck --lost-found— Check.git/lost-found/commit/for orphaned objects - Remote has it? →
git fetch origin— Check if the remote still has the old branch state - Backup exists? → Check your backup system, IDE local history, or time machine
- All else failed? → The work is gone. Accept the loss and recreate it.
Reflog Internals and Storage
Understanding how reflog works under the hood helps you reason about its behavior:
Reflog Storage Architecture
Where Reflog Data Lives
Reflog entries are stored as plain text files in the .git/logs/ directory:
- HEAD reflog:
.git/logs/HEAD - Branch reflogs:
.git/logs/refs/heads/<branch>
Each line follows the format:
<old_sha> <new_sha> <author> <timestamp> <operation_message>
Example entry:
0000000 abc1234 Geek Workbench <email> 1742000000 +0000 commit: feat: add payment processing
Reflog Entry Format
| Field | Description |
|---|---|
old_sha | Commit before the operation |
new_sha | Commit after the operation |
author | User who performed the operation |
timestamp | Unix timestamp of the operation |
message | Human-readable operation description |
Reflog Size Management
Reflog files grow over time. Monitor and manage them:
# Check reflog file sizes
ls -lh .git/logs/
# See entry count per reflog
wc -l .git/logs/HEAD
git reflog | wc -l
# Compact reflog (remove expired entries)
git reflog expire --expire=30.days.ago --all
Reflog Lifecycle
Reflog and Garbage Collection
Git’s garbage collector (git gc) removes unreachable objects, including reflog entries past their expiration:
# Reflog entries expire based on reachability
git config gc.reflogExpire 90.days.ago # Reachable commits
git config gc.reflogExpireUnreachable 30.days.ago # Orphaned commits
# Check gc configuration
git config --get gc.reflogExpire
git config --get gc.reflogExpireUnreachable
# Run gc manually (usually automatic)
git gc --prune=now
Reflog Across Clones
When you clone a repository, reflog is not transferred. Each developer has their own local reflog tracking their own operations. This design choice means:
- You cannot recover another developer’s dropped commits
- Remote force pushes cannot be undone via local reflog
- Each repository maintains independent reflog history
Extended Reflog Configuration
Expiration Configuration for Critical Repos
For repositories where recovery is critical, extend reflog retention:
# Extend to 180 days for reachable, 90 for unreachable
git config gc.reflogExpire 180.days.ago
git config gc.reflogExpireUnreachable 90.days.ago
# Or disable expiration for certain branches
git config gc.reflogExpireNever refs/heads/main
Reflog and Git Operations
Every Git operation that moves HEAD writes to reflog. The reflog acts as a chronological journal:
# Timeline of operations
git reflog --format="%h %gd %gs %cr"
# Find operation by time
git reflog --date=iso | grep "2026-03-31"
# Trace a specific commit through reflog
git reflog --all --format="%H %gd %gs" | grep <sha>
Understanding reflog internals helps you diagnose recovery failures and configure appropriate expiration policies for your workflow.
Recovery Checklist
- Act quickly — Reflog entries expire; garbage collection makes recovery impossible
- Don’t run
git gc— Garbage collection permanently removes unreachable objects - Check reflog first —
git reflogis the fastest recovery path - Verify before resetting —
git show <sha>to confirm it’s the right commit - Create safety branch —
git branch recovery-attempt HEADbefore any destructive operation - Check fsck — If reflog fails,
git fsck --lost-foundmay find orphaned commits - Check remote —
git fetch originand check remote branches for the lost state - Extend reflog — For critical repos, set
gc.reflogExpireto 180 days or more
Interview Questions
git log shows the commit history of the current branch — the ancestry chain of commits reachable from HEAD. It's a view of the project's evolution.
git reflog shows the history of local operations — every time HEAD moved, regardless of whether the commit is still reachable. It includes resets, checkouts, rebases, and stashes that don't appear in git log.
Think of it this way: git log is the project's history; git reflog is your personal history with the repository.
By default, reflog keeps entries for 90 days for commits reachable from any branch or tag, and 30 days for unreachable commits (orphaned commits not referenced by any branch).
These values are configurable via gc.reflogExpire and gc.reflogExpireUnreachable. You can extend them for critical repositories or shorten them to save disk space.
After expiration, entries are removed during garbage collection. Once garbage collected, the commits are truly gone unless you have a backup.
Only if you had the commits locally. Reflog is a local feature — it tracks operations on your machine. If you force pushed and lost commits that existed on the remote but you never had locally, reflog can't help.
If you did have the commits locally, check your reflog for the pre-force-push state and reset or create a branch from that entry. Then force push the recovered state.
To prevent this scenario, use --force-with-lease instead of --force. It checks that the remote hasn't changed since your last fetch, preventing accidental overwrites.
Interactive rebase rewrites history, but the original commits remain in the reflog:
- Run
git reflogto find the state before the rebase started - Look for the entry just before the rebase:
HEAD@{n}: rebase: picking ... - The entry before that is your pre-rebase state
- Create a branch from it:
git branch recovered HEAD@{n+1} - Compare the recovered branch with your current state to identify dropped commits
Alternatively, use git fsck --lost-found to find all unreachable commits and examine each one.
Reflog data lives in .git/logs/ as plain text files:
.git/logs/HEAD— Global HEAD movements.git/logs/refs/heads/<branch>— Per-branch reflogs
Each line follows the format: <old_sha> <new_sha> <author> <timestamp> <operation_message>
Because reflog is just text, you can read it with any editor, parse it with scripts, and even back it up manually.
The three reset modes differ in what they preserve:
--soft: Moves HEAD but keeps staging area and working directory unchanged. All changes remain staged and ready to commit.--mixed(default): Moves HEAD and resets staging area but keeps working directory. Unstages changes but doesn't discard them.--hard: Moves HEAD, resets staging, and discards all working directory changes. This is the dangerous one — data loss is permanent unless recovered via reflog.
All three modes are recorded in reflog, allowing recovery from any of them.
Reflog is stored in .git/logs/ which is not transferred during clone, fetch, or push. Each developer maintains their own independent reflog.
Implications:
- You cannot recover another developer's dropped commits
- Remote force-push losses cannot be undone via local reflog
- Team members can't see your reflog history
- Reflog must be present before data loss occurs — it's not a backup system
This is why teams use protected branches, force-push restrictions, and external backups for critical work.
Even after git stash drop <stash-ref>, the commit object remains until garbage collection:
- Find the stash commit in reflog:
git reflog | grep stash - Look for entries like
HEAD@{n}: stash: WIP on feature/... - Extract the commit SHA from the reflog entry
- Recover via
git stash apply <sha>or create a branch:git branch recovered <sha>
If reflog expired, try git fsck --lost-found and examine commits in .git/lost-found/commit/.
git fsck --lost-found finds commits that are reachable by no ref or branch — orphaned objects that would be garbage collected.
Usage:
- After reflog fails (expired entries)
- When you need to find commits that existed before a reset or rebase
- Before running
git gc --prune=nowto rescue important work
Found commits are written to .git/lost-found/commit/ with short SHA filenames. Examine each with git show <sha> to identify the one you need.
--force overwrites the remote branch unconditionally, destroying any commits that teammates pushed since your last fetch.
--force-with-lease adds a safety check: it verifies that the remote ref still matches your local tracking ref. If another developer pushed since your last fetch, the push fails with a warning.
Think of it as a lease — you're saying "I know my fetch is current, let me push." If someone else pushed, the lease is broken and the push is rejected.
Best practice: alias git push to always use --force-with-lease to prevent accidental overwrites.
Yes, branches are just pointers — deleting a branch doesn't destroy the commits:
- Check the branch reflog:
git reflog show <deleted-branch> - Find the last commit the branch pointed to
- Recreate the branch:
git branch <deleted-branch> <commit-sha>
If the branch was never checked out, it won't have its own reflog. In that case, use git reflog (HEAD reflog) to find operations that referenced the branch, or search through git fsck --lost-found.
Reflog entries have expiration dates. Git's garbage collector removes:
- Reflog entries older than
gc.reflogExpire(default 90 days) - Reflog entries for unreachable commits older than
gc.reflogExpireUnreachable(default 30 days)
When GC removes a reflog entry, the referenced commits become eligible for pruning. After GC runs, recovery may be impossible.
To protect important work, either recover before GC runs or configure longer expiration for critical repositories.
Git supports symbolic reflog references with time units:
HEAD@{yesterday}— HEAD position yesterdayHEAD@{2.days.ago}— Two days agomain@{last.week}— main branch from last weekHEAD@{3.months.ago}— Three months ago
Useful when you don't remember the commit SHA but know approximately when things were correct. Use with git checkout, git reset, or git branch.
List available time references: git reflog --date=iso
Several practices lead to problems:
- Assuming reflog is permanent — Entries expire after 90/30 days; it's not a backup
- Not verifying before resetting — Resetting to wrong entry compounds the problem
- Relying on reflog for shared work — It's local-only; can't help with remote issues
- Ignoring gc warnings — Garbage collection permanently removes unreachable objects
- Manually editing .git/logs/ — Can corrupt reflog and make recovery impossible
- Using reflog instead of proper workflow — Safer to create safety branches before destructive ops
Multiple layers of protection:
- Configure on remote: Disable force-push on main/develop or require PR reviews
- Use --force-with-lease: Configure as default in git config
- Create backup branches: Before risky operations, create safety branches
- Set longer reflog expiration: For critical repos, extend to 180+ days
- External backups: Regular pushes to mirrored repos for critical branches
On GitHub/GitLab: use branch protection rules to block force-push to protected branches.
Clone creates a fresh repository with no reflog history from the original. You get:
- The current branch heads (at the clone point)
- All commits reachable from those branches
- No operational history — your reflog starts empty
This is by design: reflog tracks local operations. The clone operation itself becomes the first reflog entry.
If you need shared history, consider using shallow clones with --depth carefully — they can make certain recovery scenarios harder.
Reflog provides a forensic record of repository operations:
- Export reflog:
git reflog --format='%H %gd %gs %cr' --all - Search for sensitive operations: Look for reset, rebase, branch deletion
- Correlate with commit content:
git show <sha>to see what changed - Track user activity: Parse the author field for team member operations
In regulated environments, reflog can help reconstruct developer actions during incident investigation. Store reflog exports periodically for long-term audit trails.
For shared branches, follow this safety checklist:
- Communicate: Alert team members that you'll be rewriting history
- Create backup:
git branch backup/<branch> HEAD - Verify target:
git show <target-commit>to confirm correct state - Use --force-with-lease: When pushing recovered state, use
--force-with-lease - Confirm after push: Team members should fetch and reset their local tracking branches
Consider using git revert instead of reset for shared branches — it creates new commits that don't rewrite history.
Reflog entries are created automatically by Git operations — you cannot manually add entries for past operations.
You can:
- Expire entries early:
git reflog expire --expire=now HEAD - Delete reflog: Remove
.git/logs/HEAD(dangerous!)
You cannot safely edit reflog entries — the format is append-only and modifications can corrupt the log. If you need to remove sensitive entries, remove the entire reflog file after the fact.
Monitor reflog to catch problems before data loss occurs:
# Check entry count and oldest entry git reflog | wc -l git reflog --date=iso | tail -5Alert if oldest entry > 60 days (threshold configurable)
OLDEST=$(git reflog —format=‘%at’ | tail -1) NOW=$(date +%s) DAYS=$(( (NOW - OLDEST) / 86400 )) if [ $DAYS -gt 60 ]; then echo “Reflog oldest entry is $DAYS days old”; fi
Monitor disk usage of reflog files
du -sh .git/logs/
Set up alerts in your CI/CD or monitoring system to notify when reflog entries approach expiration or disk usage exceeds thresholds.
Further Reading
- Git reflog documentation — Official Git documentation
- Git recovery guide — Reset and recovery techniques
- Git fsck documentation — Finding orphaned objects
- Force push safety — Using —force-with-lease
- Git garbage collection — Understanding gc and reflog expiration
Conclusion
The reflog is Git’s insurance policy — it records every movement of HEAD, even after destructive operations. When a reset goes wrong or a rebase explodes, the reflog is your first and best recovery tool.
Category
Related Posts
Git Bisect for Bug Hunting: Binary Search Through Commit History
Master git bisect to find the exact commit that introduced a bug using binary search. Automate bug hunting with scripts and handle complex scenarios.
Git Blame and Annotate: Line-by-Line Code Attribution
Master git blame for line-by-line code attribution, understanding code history, finding when code changed, and using blame effectively for code comprehension.
git log: Master Commit History Navigation and Filtering
Master git log formatting, filtering, searching history, and navigating commit history effectively for version control debugging and auditing.