LearnAI ToolsCareerPractice BuildsPlayDevelopmentContact
Lesson 1615 min read

Recovering from Mistakes: reflog, cherry-pick and More

Rescue “lost” commits with git reflog, recover deleted branches, copy commits between branches with git cherry-pick, find bugs with git bisect, and build habits that prevent disasters.

On this page 11 sections

Introduction

Sooner or later you will run a command and think “I have just lost my work”. A hard reset to the wrong commit, a branch deleted with -D, a rebase gone wrong. The good news: once something has been committed, Git almost never truly deletes it straight away. This lesson shows how to get it back.

What You Will Learn
  • How git reflog records everywhere HEAD has been.
  • How to undo a hard reset and restore a deleted branch.
  • How to copy a single commit to another branch with git cherry-pick.
  • How git bisect finds the commit that introduced a bug.

The Reflog: Git’s Safety Net

The reflog (reference log) is a private diary of every place HEAD has pointed to in your repository: every commit, checkout, reset, merge and rebase. It exists only on your computer and keeps entries for at least 30 days for commits that are no longer on any branch (90 days by default for the rest). Here is where Priya’s portfolio stands:

git log --oneline -3
Output

Click Run to see what this code prints.

Undoing a Hard Reset

Meaning to drop one commit, she types HEAD~2 instead of HEAD~1:

git reset --hard HEAD~2
Output

Click Run to see what this code prints.

git log --oneline -3
Output

Click Run to see what this code prints.

Her two latest commits have vanished from the branch. But the reflog remembers where HEAD was:

git reflog -3
Output

Click Run to see what this code prints.

Read it top to bottom, newest first. HEAD@{0} is the reset she just did. HEAD@{1} is where she was immediately before it — her latest commit, “Limit page width and improve spacing”. (Entries like “reset: moving to HEAD” come from earlier git stash commands, which use a reset internally.) Resetting back to that entry restores everything:

git reset --hard HEAD@{1}
Output

Click Run to see what this code prints.

git log --oneline -3
Output

Click Run to see what this code prints.

What the Reflog Cannot Save

The reflog only remembers commits. Edits that were never committed — wiped by git restore or git reset --hard — are gone for good. That is the strongest argument for committing small and often.

Recovering a Deleted Branch

Priya tries a heading animation on an experimental branch, commits it, returns to main and force-deletes the branch:

git switch -c experiment/animations
# ...create animations.css...
git add animations.css
git commit -m "Add fade-in animation for heading"
git switch main
git branch -D experiment/animations
Output

Click Run to see what this code prints.

Git even printed the commit the branch pointed to: was 7ae3a04. If that message has scrolled away, the reflog has it too:

git reflog -3
Output

Click Run to see what this code prints.

A branch is only a label, so recreating it is one command — point a new label at that commit:

git branch experiment/animations 7ae3a04
git branch
Output

Click Run to see what this code prints.

Mini Challenge · Fix the Command

You ran git reset --hard HEAD~3 by mistake and lost three commits. git reflog shows HEAD@{1} is where you were before. How do you get the commits back?

Choose one answer

Copying a Commit with cherry-pick

Priya decides the animation is good after all, but she does not want the whole experiment branch — just that one commit. git cherry-pick copies a commit onto the current branch as a new commit:

git cherry-pick experiment/animations
Output

Click Run to see what this code prints.

git log --oneline -2
Output

Click Run to see what this code prints.

A branch name picks its latest commit; you can also give any commit ID, or several IDs at once. Cherry-pick is ideal for bringing one specific fix into a release branch. For whole features, merge instead — cherry-picking many commits creates duplicates with different IDs that are confusing later.

Finding a Bug with git bisect

Something broke, and you do not know which of the last fifty commits did it. git bisect performs a binary search through history: you mark one bad commit and one good commit, and Git checks out the commit halfway between. You test it and say good or bad; Git halves the range again. Fifty commits take only about six tests.

git bisect start
git bisect bad # the current commit has the bug
git bisect good v1.0.0 # this release did not
# Git checks out a commit in the middle. Test it, then run one of:
git bisect good
git bisect bad
# ...repeat until Git names the first bad commit, then:
git bisect reset

If you have an automated test that detects the bug, git bisect run <test-command> runs the whole search for you.

Habits That Prevent Disasters

  • Commit small and often — anything committed can be recovered.
  • Run git status before any command that discards work (restore, reset --hard, clean).
  • Push your branches regularly, so a lost laptop never means lost work.
  • Never rewrite shared history: revert instead of reset, and no force pushes to main.
  • Keep secrets out of commits with .gitignore, and rotate anything that leaks.
  • Store large binary files such as videos with Git LFS (Large File Storage), not as regular commits.
  • Before trying anything risky, create a safety branch: git branch backup-before-rebase.
Mini Challenge · Put It in Order

You think you lost commits. Put the recovery steps in order.

  1. Create a branch there or reset to it
  2. Check the result with git log
  3. Find the entry from just before the mistake
  4. Stop and do not run more destructive commands
  5. Run git reflog to see where HEAD has been

Common Mistakes

Avoid These Mistakes
  • Panicking and running more commands, which pushes the right reflog entry further down the list.
  • Deleting and re-cloning a repository to “fix” it, losing local commits that were never pushed.
  • Cherry-picking a long series of commits instead of merging the branch.
  • Forgetting git bisect reset at the end, leaving the repository on an old commit.

Frequently Asked Questions

No. The reflog is local to each repository on each computer. If you need to recover something that only existed on GitHub, a teammate’s clone or GitHub support may be your best option.

It means HEAD points directly to a commit instead of a branch — for example after checking out a tag, or during bisect. You can look around freely; if you make commits you want to keep, create a branch with git switch -c <name> before switching away.

Practise the workflow on real projects: put your own work on GitHub, open pull requests, and make a small open-source contribution. Then learn continuous integration, which runs automated checks on every pull request.

Key Takeaways

  • git reflog records every position of HEAD, so committed work can be found for weeks.
  • git reset --hard HEAD@{n} returns to an earlier reflog entry.
  • Recreate a deleted branch with git branch <name> <commit-id>.
  • git cherry-pick <commit> copies a single commit onto the current branch.
  • git bisect binary-searches history to find the commit that introduced a bug.

Summary

Congratulations — you have completed the Git & GitHub course. You can track changes, branch and merge, rebase safely, collaborate through pull requests, contribute to open source, mark releases, follow team workflows and recover from almost any mistake. Put it into practice with the projects on the course page, and make Git part of everything you build from now on.

Course Complete!

You have finished Git & GitHub. Practise the full workflow with the course projects, and keep every project you build on GitHub from now on.

Back to the Course