Marcio Cunha

How to recover lost commits and branches in Git with reflog

Learn how to use Git reflog to rescue lost commits, revert disastrous merges, and save your code without data loss.

Marcio Cunha•5 min
Also available in:PortuguêsEspañol
Summary
  • The reflog acts as a black box that records all changes to the current pointer of your local repository.
  • Commits that appear deleted after an aggressive rebase or reset remain saved in hidden history for weeks.
  • Commands like git checkout combined with old hashes allow you to restore accidentally deleted branches.
  • Data recovery in Git depends on system garbage collection not having cleared orphan objects locally.
  • Mastering pointer tracking brings confidence to manipulate the terminal without fear of losing history.

What happens when you lose a commit in Git

Who hasn't felt a sinking stomach when running the wrong terminal command and watching hours of work vanish in seconds? In software development, typos or misuse of tools can feel like the end of the world, especially when entire branches disappear. In practice, this means you made a misstep manipulating your project's version history, whether through an aggressive reset or a botched rebase. The good news is that Git rarely deletes files permanently right away, keeping almost everything you do in a sort of hidden memory.

When working under pressure, it is common to try desperate solutions that end up making things worse, such as cloning the repository from scratch or overwriting files manually. Before panicking, remember that the version control system was designed to be resilient to human error. If you've been there, you know that recovering lost data requires calmness and the right knowledge of terminal internal tools. For those who need a comprehensive overview of data recovery in critical environments, it is worth checking out the guide on how to recover deleted files on Linux via terminal.

Understanding reflog and the Git black box

To understand how to save your day, we first need to demystify the concept of reflog. Simply put, the reflog is a chronological log of every time your branch pointers or main pointer (called HEAD) changed location on your computer. Every commit, checkout, or merge you perform creates a new line in this local logbook. Unlike the standard history you see with the git log command, the reflog even records actions that were discarded or isolated from the main development workflow.

This happens because Git works by saving snapshots of your code as objects in a local internal database. When you delete a branch, you aren't deleting the actual content of the commits, but only the friendly name that pointed to them. As long as these orphan objects are not cleaned up by the system's automatic maintenance process (known as garbage collection), they continue residing on your hard drive, waiting to be found. It is this silent persistence that allows you to retrace your steps after a catastrophic mistake.

Step-by-step to track and recover missing commits

When you realize an important commit has vanished from your working tree, the first step is to open the terminal in the project folder and check the logbook. The primary command for this mission is reflog, which lists recent movements of your current pointer directly. Let's run the query to identify the exact moment before the disaster and note the identification code of that safe point.

To list the detailed history of local movements, type the following command in your terminal:

git reflog

Running this command displays a table-like listing with hexadecimal codes on the left, such as a1b2c3d, followed by descriptions of executed actions. Look for the line showing the state of the code prior to the error, such as before a destructive git reset --hard command. Note the first characters of this hash code so we can use it to restore your work.

Rescuing accidentally deleted branches

Deleting a branch that still contained unmerged code is one of the most common scares in a developer's routine. Often we use the forced deletion command because we thought the task was already completed elsewhere. If this happened to you, the reflog remains your lifeline, as it remembers what the exact commit was at the top of that branch before its final removal from the visible list.

To bring the branch back to life from that safe point discovered in the logbook, we use the creation command pointing to the old hash. Run the command below in your terminal to recreate the lost branch:

git checkout -b my-recovered-branch a1b2c3d

In practice, this command tells Git to create a new branch called 'my-recovered-branch' exactly at the moment in history represented by the hash code you found. As soon as the command runs, all your files, changes, and history return intact to your working area. To ensure your development environment remains organized and agile, you can also optimize your routine by following productivity tips such as those seen in how to organize large PDF files on Linux via terminal.

Undoing disastrous merges without losing control

Another stressful situation occurs when we combine different codebases and the result is a massive conflict accompanied by unexpected application behavior. A poorly planned merge can pollute history and break the main build for the entire team. Instead of trying to manually fix dozens of corrupted files or full duplicate lines, the safest path is to return the pointer to the exact moment prior to the merge.

To revert the current state and return to the safety of before the merge, you can use a reset command directed to the previous hash recorded in the reflog. See the example command to clear the scenario:

git reset --hard HEAD@{1}

This instruction forces your working directory to return precisely to the position immediately preceding the last change recorded in your pointer. Remember that the 'hard' parameter discards unsaved modifications pending in your tree, so it should be used cautiously on files without backups. With these techniques in hand, the terminal stops being an uncertain environment and becomes a tool of total control over your code. To explore these architectural concepts further in production, see our related technical analysis on How to test optocouplers on board with a multimeter.

Final considerations on resilience and best practices

Learning to deal with the behind-the-scenes of version control transforms how we view errors in software development. The fear of breaking the repository often paralyzes beginner developers, preventing healthy experimentation in code. Understanding that reflog acts as an invisible safety net provides the necessary peace of mind to explore advanced commands and solve complex problems autonomously and quickly.

Maintaining the habit of checking hidden history when things go off-plan saves precious hours of rework and avoids the stress of rebuilding solutions from scratch. By combining knowledge of Git's inner workings with efficient terminal routines, you elevate your technical level and ensure project integrity regardless of the unexpected event.