The Code Oracle
git blame, git bisect, git cherry-pick
Introduction
In the depths of the Citadel of Knowledge, the Master Archivist leads you through a corridor you had never noticed. Behind a heavy oak door reinforced with black iron, a circular room opens before you. At its center, an ancient mirror floats in the air, surrounded by luminous runes. Scrolls are piled on shelves that seem to disappear into the darkness.
"Apprentice, you have proven your mastery of the fundamentals. It is time to reveal to you the ancient arts of divination. Do you see this mirror? It is the Code Oracle. Through it, you will be able to travel back in time to find the origin of a corruption, identify who wrote each line of a scroll, and even surgically transplant a fragment from one chronicle to another. These three arts are formidable in the hands of an experienced Archivist."
The art of divination: git blame
The Oracle's first skill is divination: knowing who wrote each line of a file, and when.
git blame <file> This command displays each line of the file with:
- The commit hash that last modified it
- The author's name
- The date of the modification
- The line number
- The content of the line
Example output:
a1b2c3d4 (Aldric the Scribe 2024-01-15 09:00:00 +0100 1) Creature Registry
e5f6g7h8 (Elara the Wise 2024-02-05 16:30:00 +0100 2) Last updated: year 1024 Blame on a range of lines
You don't always need to see the entire file. To examine only lines 10 to 20:
git blame -L 10,20 <file> You can also use other formats:
git blame -L 10,+5 <file> # 5 lines starting from line 10 When to use git blame? When you come across a strange line of code and want to know who wrote it, when, and most importantly in which commit - so you can read the commit message and understand the context.
The binary search: git bisect
The Oracle's second art is the binary search through history. Imagine: your program was working 10 commits ago, but it's broken now. The bug was introduced somewhere within those 10 commits. You could test them one by one... or let the Oracle cut the history in half at each step.
That's the principle of git bisect: a binary search through Git's history.
How does it work?
- Start the search:
git bisect start - Mark the current version as broken:
git bisect bad - Mark a commit where everything worked:
git bisect good <commit> - Git automatically places you in the middle of the history. You test, then tell Git whether this version is good or bad:
git bisect good # if it works here git bisect bad # if it's broken here - Git cuts in half again. You test again. And so on, until you find the exact commit that introduced the bug.
- End the search and return to your normal branch:
git bisect reset
The surgery: git cherry-pick
The Oracle's third art is surgical transplantation. Sometimes, you need to apply a single specific commit from one branch to another, without merging the entire branch.
git cherry-pick <commit-hash> This command takes the changes from a specific commit and replays them on your current branch, creating a new commit with the same changes (but a different hash).
When to use cherry-pick?
- Urgent hotfix: a fix was made on a development branch, but you need to apply it immediately to
mainwithout waiting for the full merge. - Porting a change: a feature developed on one branch also needs to be applied to another maintenance branch.
- Recovering an isolated commit: you want a specific commit from an experimental branch, not the entire branch.
Cherry-pick and conflicts
Like a merge, a cherry-pick can cause conflicts if the commit's changes contradict the current state of your branch.
In that case, Git stops and asks you to resolve the conflict manually:
- Open the conflicting file
- Resolve the conflict markers (
<<<<<<<,=======,>>>>>>>) - Mark as resolved and continue:
git add <file> git cherry-pick --continue
To abort a cherry-pick in progress:
git cherry-pick --abort git cherry-pick creates a new commit with a different hash. This means that if you later merge the source branch, the same change will exist twice (two different commits, same modifications). Use cherry-pick judiciously - for specific cases, not as your default merging method.
Practical exercise - The Code Oracle
An ancient archive of the kingdom has been corrupted. A bug has crept into the Spellbook - somewhere in the history, a magic formula has been sabotaged. The Oracle will help you trace the origin of the corruption, identify the culprit, and surgically apply a fix.
Step 1 - Retrieve the archive
git clone archive.bundle the-code-oracle
cd the-code-oracle Step 2 - Examine with blame
Start by examining the Spellbook:
git blame grimoire.txt Observe who modified each line and when. Then examine a specific section:
git blame -L 15,25 grimoire.txt git blame shows you the commit hash responsible for each line. You can then use git show <hash> to see the full commit details.
Step 3 - Find the bug with bisect
The spellbook contains an error: a formula has been corrupted (the line contains the word CORRUPTED). This error was not present in the first commit. Use git bisect to find the exact commit:
git bisect start
git bisect bad # the current version contains the bug
git bisect good <first-commit> # the very first commit was good Replace <first-commit> with the hash of the first commit (visible with git log --oneline).
At each step, check if the word CORRUPTED appears in grimoire.txt:
grep CORRUPTED grimoire.txt - If the word appears:
git bisect bad - If the word doesn't appear:
git bisect good
Continue until Git identifies the guilty commit. Note the hash, then finish:
git bisect reset Step 4 - Apply the fix with cherry-pick
Good news: an Archivist has already prepared a fix on the fix branch. Since the repository was cloned from a bundle, this branch is remote - we reference it with the origin/ prefix. Check which commit is on it:
git log --oneline origin/fix The latest commit on that branch contains the fix. Apply it to main with cherry-pick:
git cherry-pick <fix-commit-hash> Verify that the spellbook no longer contains the word CORRUPTED:
grep CORRUPTED grimoire.txt If the cherry-pick causes a conflict, don't panic! Open the file, resolve the conflict manually by keeping the corrected version, then do git add grimoire.txt and git cherry-pick --continue.
Step 5 - Verify
Run the verification script to validate your quest:
Bash (Linux / macOS / Git Bash on Windows):
bash verifier.sh PowerShell (Windows):
.\verifier.ps1 The script checks:
- You are in a Git repository
- You used git bisect (trace in the reflog)
- You used git cherry-pick (trace in the reflog)
- The spellbook no longer contains the word
CORRUPTED
Command summary
| Command | Description |
|---|---|
git blame <file> | See who modified each line and when |
git blame -L 10,20 <file> | Blame on a specific range of lines |
git bisect start | Start a binary search through history |
git bisect bad | Mark the current version as broken |
git bisect good <commit> | Mark a commit as working |
git bisect reset | End the search and return to normal |
git cherry-pick <commit> | Apply a specific commit to the current branch |
git cherry-pick --abort | Abort a cherry-pick in progress |
The Master Archivist watches the Oracle's mirror, where the reflection of the corrected history shimmers softly.