Advanced Git Concepts
From the quiz curriculum
Advanced Git Concepts
TL;DR
You've got the basics of Git down, now we'll explore powerful features like interactive rebasing, the reflog, and bisecting to refine your workflow. These tools help you clean up commit history, recover lost work, and pinpoint bugs efficiently. Mastering them will make you a much more effective Git user and team member.
1. The Mental Model
Think of Git's history as a series of connected snapshots. Advanced Git concepts give you superpowers to rewrite this history (locally!), see where you've been, and even search through it systematically. These aren't just tricks; they're essential tools for maintaining a clean, understandable project.
2. The Core Material
Interactive Rebase (git rebase -i)

Photo by RealToughCandy.com on Pexels
Interactive rebase is your best friend for cleaning up your local commit history before pushing to a shared remote. It lets you reorder, combine, edit, or delete commits. This results in a cleaner, more linear history that's easier for others to review.
The command git rebase -i <ref> (where <ref> can be a commit hash, branch name, or HEAD~N for the last N commits) opens an editor with a list of commits and commands.
git rebase -i HEAD~3
This will open an editor showing the last three commits (most recent at the top) and a list of commands like pick, reword, edit, squash, fixup, drop.
pick f7f3f2d "Add user authentication"
pick a1b2c3d "Fix login bug"
pick d4e5f6g "Update UI styles"
# Rebase 1a2b3c4..d4e5f6g onto 1a2b3c4 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) for each commit
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the object names specified as arguments)
#
# These lines can be reordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
You modify this file, save it, and exit your editor to apply the changes.
The Reflog (git reflog)

Photo by Digital Buggu on Pexels
The reflog (reference log) is a local safety net. It records almost every time your HEAD (what you're currently pointing to) or other branch tips change. If you accidentally reset, rebase, or discard commits, git reflog can show you where your branch was previously, allowing you to recover lost work.
git reflog
This will output a list like:
a1b2c3d HEAD@{0}: commit: Add new feature
f7f3f2d HEAD@{1}: rebase (finish): returning to refs/heads/main
c8d9e0f HEAD@{2}: rebase (start): checkout main
e0f1g2h HEAD@{3}: commit (initial): Initial commit
You can then use git reset --hard HEAD@{N} (where N is the reflog entry number) to jump back to a previous state.
Git Bisect (git bisect)

Photo by Kevin Ku on Pexels
git bisect helps you find the commit that introduced a bug. Instead of manually checking out commits one by one, Git performs a binary search through your commit history. You tell it if a commit is "good" or "bad", and it narrows down the range until it finds the culprit.
Here's the basic flow:
graph TD
A["Start: git bisect start"] --> B{"Current commit is good or bad?"}
B -- "Bug is present (bad)" --> C["git bisect bad"]
B -- "Bug is NOT present (good)" --> D["git bisect good"]
C --> E{"Midpoint calculated"}
D --> E
E --> F{"Is the bug pinpointed?"}
F -- "No" --> G["Checkout next midpoint"]
G --> B
F -- "Yes" --> H["Found bad commit!"]
H --> I["End: git bisect reset"]
Git Cherry-Pick (git cherry-pick)

Photo by Vlad Vasnetsov on Pexels
git cherry-pick <commit-hash> takes a single commit (or a range of commits) from one branch and applies it to your current HEAD. This is useful when you need to bring a specific fix or feature from another branch without merging the entire branch.
# While on 'main' branch
git cherry-pick abc1234 # Applies commit abc1234 to main
3. Worked Example
Let's say you're working on a feature branch my-feature and have made several small, messy commits. You want to clean them up before merging into main.
# On your 'my-feature' branch
git log --oneline
# Output:
# 0b1c2d3 (HEAD -> my-feature) Add final styling
# e4f5g6h Fix button alignment
# 7a8b9c0 Initial styles for header
# d1e2f3g Add header component
# a1b2c3d Initial feature setup
You want to combine 7a8b9c0 and e4f5g6h into 0b1c2d3 and maybe reword d1e2f3g. Let's rebase the last 5 commits (from a1b2c3d up to 0b1c2d3).
git rebase -i HEAD~5
This opens your editor with:
pick a1b2c3d Initial feature setup
pick d1e2f3g Add header component
pick 7a8b9c0 Initial styles for header
pick e4f5g6h Fix button alignment
pick 0b1c2d3 Add final styling
To achieve our goal:
1. Change pick d1e2f3g to reword d1e2f3g.
2. Change pick 7a8b9c0 to squash 7a8b9c0.
3. Change pick e4f5g6h to fixup e4f5g6h.
The file now looks like this:
pick a1b2c3d Initial feature setup
reword d1e2f3g Add header component
squash 7a8b9c0 Initial styles for header
fixup e4f5g6h Fix button alignment
pick 0b1c2d3 Add final styling
Save and close the editor. Git will then pause for you to reword the d1e2f3g commit message. After that, it will squash 7a8b9c0 and e4f5g6h into 0b1c2d3.
After exiting the editor for the reword, Git will continue and combine the commits.
Finally, your git log --oneline might look like:
git log --oneline
# Output:
# f8e9d0c (HEAD -> my-feature) Add feature styling and fixes
# b1c2d3e (renamed) Implement header component
# a1b2c3d Initial feature setup
You now have a much cleaner history!
4. Key Takeaways
- Interactive rebase (
rebase -i) lets you rewrite local commit history for a clean, linear, and understandable project history. - Use
squashorfixupin an interactive rebase to combine small, related commits into a single, meaningful one. - The
git reflogis your powerful local undo history; it tracks where yourHEADhas been, even if commits are no longer referenced by a branch. git bisectefficiently finds the specific commit that introduced a bug by performing a binary search, saving you manual effort.git cherry-pickis for selectively bringing specific commits from one branch to another without merging the entire branch.- These advanced tools are primarily for cleaning up local history before sharing; rewriting shared history can cause problems for collaborators.
Common Mistakes to Avoid:
- Rebasing public history: Never rebase commits that have already been pushed to a shared remote branch unless you understand the implications and coordinate with your team.
- Forgetting to git push --force-with-lease: After a rebase on a branch you've already pushed, you'll need to force push. Use --force-with-lease for a safer force push.
- Overusing git reset --hard: While powerful for recovery with reflog, git reset --hard discards uncommitted changes, so use it carefully.
- Not testing during git bisect: You need to accurately identify "good" or "bad" commits for bisect to work correctly. Don't guess.
- Cherry-picking too many commits: If you need most commits from another branch, a merge or full rebase might be more appropriate than many cherry-picks.
5. Now Try It
Create a new Git repository and make 5-7 small, unpolished commits. Experiment with git rebase -i HEAD~N to clean up your commit history. Try squashing two commits together, rewording one, and dropping another. After you've successfully cleaned it, use git reflog to see the history of your HEAD moving, and then try to git reset --hard back to the state before your rebase.
What to do:
1. git init && touch file1.txt && git add . && git commit -m "Initial commit"
2. Make 5-7 more commits, some small, some with typos in messages.
3. Use git rebase -i to clean up the last few commits: squash some, fixup others, reword one.
4. Verify your new, clean history with git log --oneline.
5. Run git reflog and identify the entry right
Frequently asked about Advanced Git Concepts
More from quiz
Get the full quiz curriculum
Clone the complete plan to your dashboard for unlimited AI-generated notes, practice quizzes, and a personalised revision schedule.
Create Free Account