git reflog is your safety net: a local log of every move HEAD has made.
When a reset or rebase loses commits, reflog still knows the old SHAs so you can get them back.
What it does
git reflog shows the history of where HEAD (and other refs) have pointed, including states no longer reachable from any branch. It is local-only and not pushed.
Common usage
Terminal
git reflog
git reflog show main
# recover a lost commit:
git reset --hard HEAD@{2}
git checkout -b rescue <sha-from-reflog>
Options
Item
What it does
show <ref>
Show the reflog for a specific ref
HEAD@{n}
The state of HEAD n moves ago
expire
Prune old reflog entries
--date=iso
Show absolute timestamps
Common errors in CI
CI checkouts are usually fresh clones with little or no reflog, so reflog-based recovery is a local-developer tool, not a CI one. Note that git gc and reflog expiry (default 90 days) eventually drop unreachable entries.
Using this in CI
CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.
.github/workflows/ci.yml
- uses:actions/checkout@v4with:fetch-depth:0 # history, tags, and git describe all need this- run:|git rev-parse --is-shallow-repository # expect falsegit rev-parse --abbrev-ref HEAD # prints HEAD when detached
Frequently asked questions
git reflog: Usage, Options & Common CI Errors?
When a reset or rebase loses commits, reflog still knows the old SHAs so you can get them back.
What it does?
git reflog shows the history of where HEAD (and other refs) have pointed, including states no longer reachable from any branch. It is local-only and not pushed.
Common errors in CI?
CI checkouts are usually fresh clones with little or no reflog, so reflog-based recovery is a local-developer tool, not a CI one. Note that git gc and reflog expiry (default 90 days) eventually drop unreachable entries.