DevOps
Git
Refs & Reflogs

Git Refs & Reflogs

Git is essentially a map of pointers to commit objects. Understanding how Git stores these pointers and how it records their movements is the key to mastering "History Recovery" and professional repository forensics.


1. What are Refs?

Refs (References) are simple text files stored in the .git/refs/ directory. They contain the 40-character SHA-1 hash of a commit.

The File Structure

If you look inside a .git folder, you will see:

  • .git/refs/heads/: Contains local branch pointers (e.g., main, dev).
  • .git/refs/tags/: Contains your project tags (e.g., v1.0).
  • .git/refs/remotes/: Contains pointers to the last known state of your remote branches.

[!NOTE] HEAD is a special reference that points to the branch or commit you currently have checked out.


2. The Ultimate Safety Net: Reflogs

While git log shows you the history of the commits in your project, git reflog shows you the local history of where your HEAD and branch pointers have been.

Why use Reflogs?

Reflogs protect you from local mistakes. They record every time you:

  • Switch branches.
  • Create a commit.
  • Reset your history.
  • Merge or Rebase.
  • Stash work.

Core Command

To view your recent activity:

git reflog

3. How to Recover "Lost" Commits

Imagine you accidentally performed a git reset --hard HEAD~5 and lost 5 commits. They are no longer in git log, but they ARE in the reflog.

The Recovery Workflow

  1. Find the ID: Run git reflog and find the hash before the reset (e.g., HEAD@{1}).
  2. Restore:
    # Option A: Move your current branch back to that state
    git reset --hard HEAD@{1}
     
    # Option B: Create a new branch from that "lost" commit
    git checkout -b recovered-work HEAD@{1}

4. Maintenance & Expiration

Reflogs are local only. They are not pushed to the server. By default, Git keeps reflog entries for:

  • 90 days for reachable commits.
  • 30 days for unreachable (dangling) commits.

To manually clear entries (rarely needed):

  • git reflog expire --expire=now --all: Expire all old entries.
  • git reflog delete <entry>: Delete a specific entry.

[!TIP] Reflog is Local Forensics Because reflogs are local, you cannot use them to recover a teammate's mistake. They are your personal safety net for your direct interactions with the repository.