Navigating and rescuing Git history at an advanced level: taking a specific commit with git cherry-pick, recovering deleted commits or branches through git reflog, and finding the commit that caused a bug with git bisect.

In episode 16 we learned to rewrite history with interactive rebase. In episode 17 we learn to read and rescue history: taking one commit from another branch with git cherry-pick, recovering seemingly lost commits through git reflog, and automatically finding the commit that caused a bug with git bisect.
These abilities are life-savers in the real world. Have you ever accidentally deleted a branch that contained a week of work? Or had a bug appear "suddenly" with no one knowing which commit it started from? This episode answers both — while reaffirming one important fact: Git almost never deletes data permanently.
Sometimes you only need a single commit from a branch — not the whole branch. Example: the hotfix fix: perbaiki bug login lives on the feature/auth branch, but main also needs that fix right now.
git switch main
git cherry-pick a1b2c3dgit cherry-pick copies the changes of a commit to the active branch as a new commit with a new SHA — the original commit on the other branch stays intact. It is a shortcut for spreading an important fix without merging the entire branch.
If the copied changes clash with files on the target branch, Git stops and shows conflict markers (remember episode 7). Resolve them like a normal merge conflict, then continue:
git add resolusi.txt
git cherry-pick --continueIf you want to cancel everything: git cherry-pick --abort.
git log only shows the history of commits. git reflog shows the history of HEAD movement — every event in the repository: checkout, commit, reset, amend, merge, even rebase:
a1b2c3d HEAD@{0}: checkout: moving from feature-x to main
e4f5g6h HEAD@{1}: commit: fix: perbaiki validasi login
i7j8k9l HEAD@{2}: commit: feat: tambah halaman dashboard
f1f2f3f HEAD@{3}: reset: moving to f1f2f3f
c9c8c7c HEAD@{4}: rebase: finishedEach line records the destination commit SHA, the HEAD position at that time, and the action that triggered it. This is why a reset commit or a deleted branch can still be found: their traces remain stored in the reflog.
| Command | Answers the Question |
|---|---|
git log | Which commits exist in this history? |
git reflog | How did HEAD move to reach its current position? |
git show <sha> | What did this commit change? |
Tip
The reflog is by default kept for around 90 days before being cleaned up by garbage collection. If you lose a commit, do not panic and do not wait — check the reflog as soon as possible.
The most common example: git branch -D feature-x turns out to have deleted a week of work. Stay calm, the commit is still alive in the reflog. Find its SHA, then recreate the branch:
git reflog
git switch -c feature-x a1b2c3dTo move the active branch back to an old commit:
git branch -f main a1b2c3d
git switch mainWarning
Never use git reset --hard <sha> on an already-pushed branch to "turn back time" — it would break other people's remote history. Reflog and reset --hard are only for local history that has not been shared.
A bug appears and no one knows since when. git bisect finds it with binary search: it marks half of the history, checks whether the bug is there, then narrows down until one suspect commit remains.
git bisect start
git bisect bad HEAD
git bisect good v1.0.0Git then checks out a commit in the middle. You test: if the bug is still present, mark git bisect bad; if clean, mark git bisect good. Every answer halves the candidates. A few steps later one commit remains — that is the culprit.
For bugs that can be tested automatically, let Git run the loop itself:
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
git bisect run bun run testOr use a custom script cek-bug.sh that exits with code 0 (good) or non-zero (bad):
#!/bin/sh
./jalankan_aplikasi
if grep -q "BUG" log.txt; then
exit 1
else
exit 0
fiWhen done, return HEAD to its position:
git bisect resetTip
Combine the three for a complete rescue flow: bisect finds the culprit commit, cherry-pick spreads its fix to other branches, and reflog rescues anything that was already deleted.
The points to take with you:
git cherry-pick <hash> copies one commit's changes to the active branch as a new commit.git reflog records every HEAD movement — the emergency path to find commits that were reset, amended, or deleted.git switch -c <name> <sha> from the reflog.git bisect finds the bug-causing commit with binary search; git bisect run <script> does it automatically.History can now be tidied up and navigated. Time to talk scale: how to combine many repositories into one project. In the next episode 18 we cover Git Submodules & Subtrees for managing multi-repository dependencies. See you in episode 18!