After this lesson, you will be able to: Recover lost work and surgically manipulate history with cherry-pick, reflog, bisect, and submodules, the advanced Git commands that turn 'I lost everything' into a two-minute fix.
Most engineers know add, commit, push, and merge. The commands that make you the person teammates come to when Git goes wrong are cherry-pick, reflog, bisect, and submodules. None are magic once you understand the object model from the internals lesson. This lesson is the safety net that means you never actually lose work.
When you need exactly one commit from another branch, not a whole merge.
# You fixed a bug on a feature branch, but it's needed on main NOW,# before the feature is ready to merge.git log feature/new-checkout # find the commit hash of the fixgit checkout maingit cherry-pick a1b2c3d # apply just that one commit to main# Pick a range (exclusive of the first):git cherry-pick a1b2c3d..e4f5g6h# If it conflicts, resolve, then:git cherry-pick --continue# or bail out:git cherry-pick --abort
Git records every move of HEAD for ~90 days. A 'lost' commit is almost never actually gone.
# You did a hard reset and panicked: your commits 'disappeared'.git reflog# Output, most recent first:# e4f5g6h HEAD@{0}: reset: moving to HEAD~3# a1b2c3d HEAD@{1}: commit: the work you thought you lost# ...# Get it back: point a branch at the commit reflog shows.git branch recovered a1b2c3d# or jump back directly:git reset --hard HEAD@{1}# This is why 'I lost my work in Git' is almost always recoverable.# As long as you committed it once, reflog can find it.
A test passes on an old commit and fails now. bisect finds the exact breaking commit in log2(n) steps.
git bisect startgit bisect bad # current commit is brokengit bisect good v1.4.0 # this old tag worked# Git checks out a commit halfway between. You test it, then tell Git:git bisect good # this one is fine -> search newer half# orgit bisect bad # this one is broken -> search older half# Repeat ~log2(commits) times. Git prints the first bad commit.git bisect reset # return to where you started# Automate it: bisect runs your test script on each step.git bisect run npm test
A submodule pins another Git repository at a specific commit inside your repo. `git submodule add <url> path/` adds it; `git submodule update --init --recursive` pulls the pinned versions after a clone. They are useful for vendoring a shared library you also develop, but they are famously easy to get wrong (a clone without `--recursive` gives empty submodule folders). In 2025 most teams reach for a package registry or a monorepo instead. Know submodules exist, recognize them when you see a `.gitmodules` file, and prefer alternatives for new work.
Assuming a hard reset destroyed work. Check `git reflog` first; it is almost always recoverable. cherry-picking a commit that depends on earlier commits, then wondering why it conflicts. Pick the whole dependent range or rebase instead. Running bisect manually when a one-line test exists. `git bisect run <cmd>` automates the whole search. Cloning a repo with submodules and forgetting `--recursive`, then debugging 'missing files' that are just un-initialized submodules. Using submodules where a versioned package would be simpler.
Pick the most efficient approach.
Sign in and purchase access to unlock this lesson.