Once you know commits, branches, merges, and remotes, the next step is learning the tools that save time during debugging, recovery, and automation. Advanced Git commands are not used every hour, but when you need them, they can be incredibly valuable.
In this lesson, you will meet six high-impact concepts:
cherry-pickbisectreflogTip: Advanced Git is less about memorizing every option and more about recognizing which tool fits the situation.
git cherry-pick copies the change introduced by an existing commit and applies it to your current branch.
This is useful when you want one specific fix without merging a whole branch.
Example:
git switch release/1.2
git cherry-pick a1b2c3dA common real-world use case is backporting a bug fix from main to an older release branch.
Use cherry-pick when:
Be careful not to overuse it, because duplicated commits across branches can make history harder to follow.
git bisect helps you find which commit introduced a bug by performing a binary search through history.
Start the process:
git bisect start
git bisect bad
git bisect good v1.0.0Git checks out a midpoint commit. You test it and tell Git whether that commit is good or bad.
git bisect goodor:
git bisect badGit keeps narrowing the range until it identifies the likely offending commit.
If a problem appeared somewhere in the last 100 commits, bisect can reduce manual hunting dramatically.
git reflog records where HEAD and branch references have pointed over time. It is a lifesaver when you accidentally lose track of commits after reset, rebase, or checkout operations.
Run:
git reflogYou may see entries like:
a1b2c3d HEAD@{0}: reset: moving to HEAD~1
d4e5f6g HEAD@{1}: commit: Add deployment notesIf you hard-reset by mistake, reflog can help you recover:
git reset --hard d4e5f6gNote: Reflog tracks your local reference movement. It is one of the best recovery tools for âI think I lost my commitâ moments.
A submodule lets one Git repository include another repository at a specific commit.
Example use cases:
Add a submodule:
git submodule add https://github.com/example/shared-lib.git libs/shared-libClone a project with submodules:
git clone --recurse-submodules https://github.com/example/platform.gitSubmodules are powerful, but they add complexity because the parent repo tracks a pointer to a specific child repo commit rather than copying its full contents into normal history.
Git hooks are scripts that run automatically at certain lifecycle events. They live in .git/hooks for a repository.
Common examples:
pre-commit: run formatting or tests before a commit completescommit-msg: validate commit message formatpre-push: run checks before pushingA simple pre-commit hook might run:
npm testHooks can improve quality by catching issues early, but local hooks are not always shared automatically unless your team uses a dedicated hook management approach.
Aliases let you define short names for longer Git commands.
Create a useful alias for a compact log view:
git config --global alias.lg "log --oneline --graph --decorate --all"Now run:
git lgAnother popular alias:
git config --global alias.st statusThen:
git stAliases reduce typing and make frequent commands easier to remember.
Here is a practical scenario:
git bisect helps find the bad commitgit revert or a hotfix commit to fix itcherry-pick the fix into a release branchgit reflog helps recover the lost commitpre-push hook prevents future broken pushesThese tools are different, but together they make teams more resilient.
cherry-pick whenbisect whenreflog whenAdvanced Git is about control and recovery. cherry-pick moves specific changes, bisect finds the commit that broke something, and reflog helps recover from history mistakes. Submodules, hooks, and aliases extend Git into larger workflows and better habits.
You do not need these commands every day, but learning them now makes you much more confident when the simple path stops being enough.
Scenario: A bug fix already exists on main, and you need the same single commit on release/1.2 without merging the whole branch.
Question: Which advanced Git tool from the tutorial is designed for that?
<MCQExercise
exercise={{
id: 'git-advanced-q1',
title: 'Exercise 1: Backporting one fix',
description: 'Choose the command meant for applying one specific existing commit to another branch.',
options: [
{ id: 'a', text: 'git bisect' },
{ id: 'b', text: 'git reflog' },
{ id: 'c', text: 'git cherry-pick' },
{ id: 'd', text: 'git submodule add' },
],
correctId: 'c',
explanation: 'The tutorial introduced git cherry-pick as the tool for copying the change from a specific commit onto your current branch. That is a classic backporting workflow when you want one fix but not the rest of the source branch.',
wrongExplanations: {
a: 'bisect finds the commit that introduced a bug. It does not copy a chosen fix onto another branch.',
b: 'reflog helps recover local reference history after mistakes, not transfer a commit across branches.',
d: 'Submodule commands manage nested repositories, which is unrelated to backporting a hotfix commit.',
},
}}
/>
Scenario: A regression appeared sometime in the last 100 commits, but nobody knows which one caused it.
Question: Which tool from the lesson is built to narrow that search efficiently?
<MCQExercise
exercise={{
id: 'git-advanced-q2',
title: 'Exercise 2: Finding the bad commit quickly',
description: 'Pick the advanced Git workflow that uses a binary search through history.',
options: [
{ id: 'a', text: 'git hook pre-push' },
{ id: 'b', text: 'git bisect' },
{ id: 'c', text: 'git tag -a' },
{ id: 'd', text: 'git branch -vv' },
],
correctId: 'b',
explanation: 'The lesson explained that git bisect performs a binary-search style investigation through history. By marking commits good or bad, Git quickly narrows a large range down to the likely offending commit.',
wrongExplanations: {
a: 'Hooks automate checks at lifecycle events, but they do not search history for regressions.',
c: 'Tags mark important commits but do not help identify which commit introduced a bug.',
d: 'Branch details show tracking information, not regression origins.',
},
}}
/>
Scenario: You ran a hard reset and think you lost a useful commit from yesterday.
Question: Which advanced Git feature from the tutorial gives you the best chance to find and recover it?
<MCQExercise exercise={{ id: 'git-advanced-q3', title: 'Exercise 3: Recovering after a mistake', description: 'Choose the recovery tool that records where HEAD and branch references pointed locally.', options: [ { id: 'a', text: 'Aliases, because they rename the lost commit back into existence.' }, { id: 'b', text: 'Submodules, because nested repositories keep backup copies of every branch.' }, { id: 'c', text: 'Hooks, because a pre-commit hook stores deleted commits automatically.' }, { id: 'd', text: 'Reflog, because it tracks local reference movements and can reveal the old commit ID.' }, ], correctId: 'd', explanation: 'The tutorial called reflog a lifesaver for situations where a reset, rebase, or checkout made a commit seem lost. Because reflog records local reference movements, it can often show the old commit so you can reset or branch back to it.', wrongExplanations: { a: 'Aliases shorten commands, but they do not preserve or recover history.', b: 'Submodules track another repository at a specific commit. They are not a safety net for local history mistakes.', c: 'Hooks can automate checks, but they do not act as a built-in lost-commit recovery log.', }, }} />
By binary search through history. You tell it a commit where the bug exists (git bisect bad) and one where it does not (git bisect good), and it checks out the midpoint for you to test, narrowing by half each round, around ten steps for a thousand commits. Mark each as good or bad and it names the first bad commit. git bisect run ./test.sh automates it entirely when you have a script that exits non-zero on failure, which turns an afternoon of guessing into a couple of minutes.
The reflog records every position HEAD has held in your local repository, including states no branch points at any more. That makes it the recovery tool for a bad reset --hard, a rebase that went wrong, a deleted branch, or a commit you amended away: git reflog lists the history, then git reset --hard HEAD@{5} or git switch -c recovered <sha> brings it back. Entries last about 90 days by default. It is local only, which is why committing is the real safety net.
Rebase replays a whole series of commits onto a new base; cherry-pick applies one or a few chosen commits. Under the surface they do much the same work, rebase is essentially a scripted sequence of cherry-picks, so the choice is about scope. Rebase for "move my branch on top of the latest main", cherry-pick for "I need just that one fix over here".
git blame <file> annotates every line with the commit, author and date that last changed it, and git blame -L 40,60 <file> limits it to a range. When blame only shows a formatting commit, git blame -w --ignore-rev <sha> skips whitespace changes and a specified reformat. For searching by content rather than location, git log -S "functionName" finds commits where the number of occurrences of that string changed, which is the fastest way to locate when something was added or deleted.
Three, in this order. git reflog, because it turns most disasters into inconveniences and takes five minutes to understand. git bisect, because nothing else finds a regression in a long history nearly as fast. And git log -S, because "when did this string appear" is a question you ask constantly. Cherry-pick and interactive rebase are valuable but situational, and submodules are best avoided until you have a specific need for them.
Automate checks at commit and push time with Git hooks: where they live, why they never reach your team, client versus server hooks, --no-verify and Husky.
Compare GitFlow, GitHub Flow and trunk-based development honestly, see which suits which team, why long-lived branches hurt and how feature flags help.
Configure Git once and stop fighting it: .gitconfig scopes, per-directory identities with includeIf, handy aliases and the defaults worth changing.