C.W.K.
Stream
Lesson 05 of 05 · published

reflog and clean: Emergency Tools

~22 min · reflog, clean, recovery

Level 0Untracked Rookie
0 XP0/47 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

reflog and clean are the bottom-of-the-toolbox tools

Two commands you should never need every day, but should know cold for the day you do. git reflog is Git's local memory of every move HEAD has made — every commit, reset, rebase, switch — for the last 90 days by default. It is how you find work you "lost." git clean removes untracked files from the working tree, the answer to "what is all this junk after a build?" and "I want a truly fresh checkout." Both are local-only; both can save you from disaster or cause one if used carelessly.

The reflog story usually goes: panic moment, "I just ran git reset --hard and lost a day of work." Calm response: git reflog. The output is a numbered list of every recent HEAD movement. HEAD@{0} is the current state, HEAD@{1} is one move ago, and so on. Find the entry that looks like the commit you lost, then anchor it: git switch -c rescue HEAD@{3} or git reset --hard HEAD@{3}. Crisis averted.

Reflog has individual logs per ref, not just HEAD. git reflog show feature/x tracks moves of that branch specifically. git reflog --date=relative shows times like "2 hours ago" instead of full timestamps. The 90-day default is configurable but usually fine — once entries fall off, the underlying commits become candidates for garbage collection and may be unrecoverable.

git clean deletes untracked files. Default refuses to do anything; you must pass -n (dry run) or -f (force). Combined with -d for directories and -x for ignored-but-still-on-disk files, it can wipe the working tree to a state matching git ls-files. Use git clean -ndx first, always, to see what would be deleted. Use git clean -fdx only after reading the dry-run output and confirming you really want it gone — there is no recovery for files Git was not tracking.

Code

Find lost work via reflog·bash
# After a confused reset, rebase, or branch delete:
git reflog --date=relative -n 30

# Output shows things like:
# abc1234 HEAD@{0} 5 minutes ago: reset: moving to HEAD~3
# def5678 HEAD@{1} 1 hour ago:    commit: feature/x final
# 12345ab HEAD@{2} 2 hours ago:   pull: Fast-forward

# Restore lost tip onto a rescue branch:
git switch -c rescue HEAD@{1}
# Or move current branch back:
git reset --hard HEAD@{1}

# Per-branch reflog:
git reflog show feature/x
Clean — always dry-run first·bash
# DRY RUN — list what would be deleted:
git clean -nd                  # untracked files + dirs
git clean -ndx                 # also include ignored files (build artifacts)

# Actually delete (after reviewing the dry run):
git clean -fd                  # delete untracked files + dirs
git clean -fdx                 # also delete ignored files

# Interactive — pick what to delete:
git clean -i

# DANGER — this can blow away build outputs, .env files,
# anything Git was not tracking. There is no Git-side undo.

External links

Exercise

Engineer a recoverable disaster: make a commit, then git reset --hard HEAD~1 to throw it away. Run git reflog, identify the lost commit, and restore it onto a new branch with git switch -c rescue HEAD@{1}. Verify with git log. Separately, in a repo with build artifacts, run git clean -ndx and read the list. Decide whether you would actually run the destructive form on this repo and write down why or why not.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.