Skip to main content
Advanced Git Commands
CHAPTER 09 Advanced

Git Reflog and Recovery Techniques

Updated: May 15, 2026
25 min read

# CHAPTER 9

Git Reflog and Recovery Techniques

1. Introduction

In standard software, when you delete a file, it is gone. If you delete a database row, it vanishes. Git defies this logic. In Git, commits are almost immortal. They are mathematically woven into the internal object database (Chapter 2) and are incredibly difficult to permanently destroy. Even if you aggressively rewrite history with a hard reset or a botched interactive rebase, the commits still exist in the hidden .git/objects folder. The only challenge is finding their SHA-1 hash so you can reattach them to a branch. In this chapter, we will master the Git Reflog (Reference Log), the ultimate forensic tool for hunting down "deleted" commits and resurrecting lost timelines.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Define the operational mechanism of the Reference Log (Reflog).
  • Understand the syntax of Reflog output (e.g., HEAD@{0}).
  • Use git reflog to trace the historical movements of the HEAD pointer.
  • Recover a deleted branch.
  • Differentiate between the HEAD reflog and specific branch reflogs.

3. Beginner-to-Advanced Explanations

The Illusion of Deletion: When you type git branch -d feature-branch, you feel like you just deleted code. As we learned in Chapter 2, a branch is just a 41-byte text file containing a hash. Deleting the branch deletes the *pointer*, not the commits. The commits are now floating in the void of the database, unattached. These are called "Dangling Commits."

The Reflog (The Ledger): The Reflog is a highly secure, local ledger that records every single time the tip of a branch (HEAD) moves.

  • Did you commit? Logged.
  • Did you switch branches? Logged.
  • Did you execute a hard reset? Logged.
  • Did you rebase? Logged.

If you can find the hash of the floating commit in the reflog ledger, you can instantly create a new branch pointing to that hash, completely resurrecting the "deleted" code.

4. Reading the Reflog

Type git reflog in your terminal. You will see an output like this:
text
123
3a9d1b2 HEAD@{0}: checkout: moving from feature to main
8f4b2c1 HEAD@{1}: commit: Add advanced filtering algorithm
7c2e9d3 HEAD@{2}: reset: moving to HEAD~1

How to read it:

  • Hash (8f4b2c1): The cryptographic ID of the commit.
  • Index (HEAD@{1}): Where HEAD was 1 action ago. (HEAD@{0} is where you are right now).
  • Action (commit:): What specific Git command caused the pointer to move.

5. Mini Project: Restore Deleted Branch History

Let's simulate a manager accidentally deleting a massive feature branch.

Step-by-Step Walkthrough:

  1. 1. Create a repository: mkdir reflog-demo && cd reflog-demo && git init
  1. 2. Create base: echo "V1" > index.html && git add . && git commit -m "V1"
  1. 3. Create a massive feature: git checkout -b feature-massive
  1. 4. Write code: echo "Massive Code" > massive.js && git add . && git commit -m "Add Massive Feature"
  1. 5. The Mistake: Switch to main and force-delete the branch!

bash
123456789101112131415
   git checkout main
   git branch -D feature-massive
   ```
6. Run `git branch`. The feature is gone. Run `git log`. The "Massive Feature" commit is invisible.
7. **The Forensics:** Run `git reflog`.
8. Look down the list for the action that says `commit: Add Massive Feature`. Copy the hash next to it (e.g., `b6c7d8e`).
9. **The Resurrection:** Create a brand new branch, but command Git to point it directly at that floating hash!
   ```bash
   git checkout -b recovered-massive b6c7d8e
   ```
10. Run `ls`. `massive.js` is back! Run `git log`. The commit is back! You have successfully recovered a deleted branch.

### 6. Time-Based Recovery
The Reflog allows you to travel back in time based on the clock, not just the index.
If you know your repository was perfect exactly two days ago before you started a chaotic rebase, you can view the state of the branch from exactly 48 hours ago.

bash git checkout main@{2.days.ago}

12345
This puts you in a Detached HEAD state looking at the past, allowing you to branch off from a known stable point in time.

### 7. Branch-Specific Reflogs
By default, `git reflog` shows the movements of `HEAD` (where your global cursor was). But Git also maintains a separate ledger for *every single branch*.
If you want to see exactly how the `develop` branch evolved over time, ignoring all your switching to other branches:

bash git reflog show develop ``

8. Best Practices

  • Garbage Collection: Do not rely on the Reflog for permanent archiving. Git automatically runs a background process called Garbage Collection (git gc) every 30 to 90 days. git gc actively hunts down unreferenced "Dangling Commits" and permanently deletes them from the hard drive to save disk space. If you need to recover something, do it within a few weeks.

9. Common Mistakes

  • Assuming the Reflog is Synced to GitHub: We covered this in Chapter 9 of the Merge course, but it bears repeating: The Reflog is strictly local. If your laptop falls into a volcano, your Reflog is destroyed. If a coworker deletes a commit on their laptop, you cannot use your Reflog to find it.

10. Exercises

  1. 1. Explain the architectural difference between a Commit and a Branch, and why deleting a branch does not instantly delete the code associated with it.
  1. 2. What is a "Dangling Commit" in the Git object database?

11. FAQs

Q: Can I manually run the garbage collector if I want to permanently delete a 5GB file from a deleted branch right now? A: Yes. You can force Git to clean the database immediately by expiring the reflog and running the collector:
git reflog expire --expire=now --all && git gc --prune=now --aggressive *(Warning: This is highly destructive and permanently deletes all unreferenced floating objects instantly).*

12. Summary

In Chapter 9, we unlocked the highest level of repository forensics. We proved that Git's architecture inherently resists data loss, treating branches merely as transient labels pointing to immutable, hidden objects. By mastering the
git reflog`, we learned how to read the hidden ledger of historical actions, trace the movements of the HEAD pointer, and resurrect floating, unreferenced commits. Armed with this knowledge, we can confidently navigate destructive rebases and accidental resets, knowing we possess the tools to recover virtually any lost timeline.

13. Next Chapter Recommendation

We know how to find lost commits. But how do we find out *who* wrote a specific line of code that broke the server? Proceed to Chapter 10: Advanced Git Diff and Log Analysis.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·