ReadbackLesson 10In progress
2 steps · 30 minutes · one terminal

UNDO EVERYTHING

An agent has just hard-reset away three commits, or amended something you needed, or deleted a branch. Almost nothing in git is ever destroyed — it stops being pointed at, which is a completely different thing. Here is where it goes, and how to get it back.

What you already know

Retrieval · lessons 01 and 03

Two from memory. Between them they contain the entire recovery model — everything after this is applying them.

Answer before you move on

A commit that no branch, tag or HEAD can reach. What is its status?

Answer before you move on

Which trees does git reset --hard overwrite?

The reflog is the undo history

Claim + proof · git reflog

Every time HEAD moves — a commit, a checkout, a merge, a rebase, a reset — git appends a line to a log recording where it was and where it went. That log is the reflog, it is local to your repository, and it is the single most valuable file in it (Pro Git §7.7).

Here is a four-commit repository, and an agent that resets three of them away.

Executed, output verbatimDisaster 1
$ git log --oneline
$ git reset --hard HEAD~3
$ git log --oneline
db1af17 Add jitter
65c09b3 Add exponential backoff
20b4aa1 Add a timeout
d1ae31c Add the API client

HEAD is now at d1ae31c Add the API client

d1ae31c Add the API client

Three commits, gone from the log. This is the moment people describe as “losing work”.

Executed, output verbatim
$ git reflog
d1af17e HEAD@{0}: reset: moving to HEAD~3
db1af17 HEAD@{1}: commit: Add jitter
65c09b3 HEAD@{2}: commit: Add exponential backoff
20b4aa1 HEAD@{3}: commit: Add a timeout
d1ae31c HEAD@{4}: commit (initial): Add the API client

Every position HEAD has held, newest first, each with the operation that put it there. The three “lost” commits are on lines 1 through 3.

The whole of recovery, in one sentence

HEAD@{1} means where HEAD was one move ago. So git reset --hard HEAD@{1} undoes the last thing that moved HEAD — a reset, a rebase, a merge, a bad checkout — whatever it was.

Executed, output verbatim
$ git reset --hard 'HEAD@{1}'
$ git log --oneline
HEAD is now at db1af17 Add jitter

db1af17 Add jitter
65c09b3 Add exponential backoff
20b4aa1 Add a timeout
d1ae31c Add the API client

One command. All three commits are back, with their original hashes.

ORIG_HEAD, and when it is not enough

Lesson 05 used git reset --hard ORIG_HEAD, which is the same recovery with a friendlier name. The difference matters: ORIG_HEAD holds only the most recent operation’s starting point and is overwritten by the next one. The reflog holds all of them. When an agent has done three things since the mistake, ORIG_HEAD is already gone and the reflog is not.

The first thing to run, always

git reflog. Before diagnosing, before panicking, before asking the agent what it did — the reflog already knows. Reading it costs nothing and it is often the whole answer.

3 of 5 steps remain

Rewrites and deletions

You have read the first 2 steps in full — a claim and the verification that settles it. The rest of this lesson, and the 9 lessons after it, open when subscriptions do. Nothing that is free today will be taken away then.

Read the free reference
Subscriptions open soon
the free preview stays