Git Advanced: History, Workflows and Automation
Cherry-pick, Bisect and Reflog
In this lesson you will
- Apply one commit to another branch with cherry-pick
- Use git bisect to find a bug-causing commit
- Recover lost commits with the reflog
Introduction
Three tools solve problems that confuse many developers: getting one fix onto another branch, finding exactly when something broke, and recovering from "I just deleted my work".
Cherry-pick: copy one commit
Sometimes you need a single commit from another branch, for example a bug fix that must also go into a release branch.
Terminal
git switch release-1.0
git cherry-pick a1b2c3dGit applies the changes of that commit as a new commit on your current branch, with a new hash. If it conflicts, resolve, git add, then git cherry-pick --continue.
Use it sparingly. Copying commits creates duplicates in history, and many cherry-picks suggest your branching needs rethinking.
Quick quiz
What does git cherry-pick do?
Bisect: find the commit that broke it
Imagine the app worked last month and is broken now, with hundreds of commits in between. Bisect performs a binary search through history, so you test only a few commits.
Terminal
git bisect start
git bisect bad # the current commit is broken
git bisect good v1.2.0 # this old tag workedGit checks out a commit in the middle. You test it, then tell Git:
Terminal
git bisect good # or: git bisect badGit halves the range again and again. After about log2(N) steps, it names the first bad commit. For 1,000 commits, that is about 10 tests. When finished:
Terminal
git bisect resetYou can automate it with a script that exits 0 for good and non-zero for bad:
Terminal
git bisect run ./test.shThis works best when each commit builds and runs, which is another reason for clean history.
Reflog: the safety net
Git records every place HEAD has pointed. Even after a hard reset or a deleted branch, the commits usually remain for a while (often months), but are no longer reachable by name.
Terminal
git refloga1b2c3d HEAD@{0}: reset: moving to HEAD~3
e4f5a6b HEAD@{1}: commit: Add search featureTo get the lost work back, point a branch at it:
Terminal
git branch recovered e4f5a6bThe reflog is local to your computer. It is not sent to remotes. Unreachable commits are eventually removed by garbage collection.
Try it yourself
Create a repository with 8 commits where a bug appears in commit 5, with a small test script. Use git bisect run to find it. Then make a hard reset back a few commits and recover them with the reflog.
Summary
git cherry-pickcopies one commit onto the current branch.git bisectfinds the commit that introduced a bug with a binary search.git refloglists where HEAD has been, so lost commits can be recovered.
Lesson complete
+20 XP
Nice work. Keep going while it is fresh.
Sources and further reading