Working Code
Example 1: Advanced git log searches
Set up a repository with some history:
git init
echo "v1" > app.py && git add app.py && git commit -m "feat: initial app"
echo "login" >> app.py && git add app.py && git commit -m "feat: add login feature"
echo "bug fix" >> app.py && git add app.py && git commit -m "fix: fix login bug"
echo "profile" >> app.py && git add app.py && git commit -m "feat: add profile page"
echo "style" >> app.py && git add app.py && git commit -m "style: format code"
Search by commit message:
git log --grep="feat" --oneline
Output:
e4f5g6h feat: add profile page
b2c3d4e feat: add login feature
a1b2c3d feat: initial app
Find commits that changed specific content:
# Commits where "login" was added or removed
git log -S "login" --oneline
Output:
c3d4e5f fix: fix login bug
b2c3d4e feat: add login feature
Example 2: Search by author
git log --author="John Doe" --oneline
# Date range
git log --after="2024-01-01" --before="2024-02-01" --oneline
# History of a specific file
git log --oneline app.py
Example 3: git blame
See who wrote each line and when:
git blame app.py
Output:
a1b2c3d (John Doe 2024-01-15 10:30:01 +0900 1) v1
b2c3d4e (John Doe 2024-01-15 10:31:00 +0900 2) login
c3d4e5f (Jane Kim 2024-01-16 09:00:00 +0900 3) bug fix
e4f5g6h (John Doe 2024-01-17 14:00:00 +0900 4) profile
Each line shows:
- Commit hash (first 8 characters)
- Author
- Date/time
- Line number
- Content
Try It Yourself
git log -S: tracking specific code changes
When you need to find "when was this code added?":
# Commits where "getUserById" was added or removed
git log -S "getUserById" --oneline
# Include the full diff
git log -S "getUserById" -p
# Regex search
git log -G "user.*[Bb]y[Ii]d" --oneline
git blame in depth
# Specific line range only (lines 10-20)
git blame -L 10,20 app.py
# Shorter hashes
git blame --abbrev=7 app.py
# Ignore whitespace changes
git blame -w app.py
Using blame results to explore history:
git blame app.py
# c3d4e5f (Jane Kim ...) 3) bug fix
# View that commit in detail
git show c3d4e5f
# View blame before that commit
git blame c3d4e5f~1 app.py
git cherry-pick: grabbing specific commits
Apply a specific commit from another branch to the current branch:
git checkout -b feature-a
echo "Feature A" >> app.py && git add app.py && git commit -m "feat: add feature A"
echo "Bug fix A" >> app.py && git add app.py && git commit -m "fix: fix feature A bug"
git checkout main
git log --oneline --all
Output:
f1g2h3i (feature-a) fix: fix feature A bug
e0f1g2h (feature-a) feat: add feature A
a1b2c3d (HEAD -> main) style: format code
...
Bring only the bug fix to main:
git cherry-pick f1g2h3i # Pick only the fix commit
git log --oneline
Output:
j0k1l2m (HEAD -> main) fix: fix feature A bug <- Copied with a new hash
a1b2c3d style: format code
Cherry-pick copies a commit. The original stays on its branch and the copy gets a new hash on the current branch.
Cherry-picking multiple commits:
# Pick 2 commits
git cherry-pick a1b2c3d e4f5g6h
# Pick a range (a exclusive, b inclusive)
git cherry-pick a1b2c3d..e4f5g6h
# Pick a range (a inclusive)
git cherry-pick a1b2c3d^..e4f5g6h
git bisect: finding the bug-introducing commit
"This feature broke at some point. Which commit caused it?"
# Start bisect
git bisect start
git bisect bad HEAD # Current state: has the bug
git bisect good a1b2c3d # This commit was working fine
# Git auto-checks out a middle commit
# Test and report the result
git bisect good # This commit works
# or
git bisect bad # This commit has the bug
# After a few rounds, Git pinpoints the guilty commit
# Return to normal
git bisect reset
"Why?" -- When you need history exploration
| Scenario | Tool |
| ------------------------------------------------- | ------------------- |
| "When was this feature added?" | git log -S "code" |
| "Who wrote this line?" | git blame |
| "When did this bug start?" | git bisect |
| "I need just that one commit from another branch" | git cherry-pick |
| "Show me only this person's commits" | git log --author |
Real-world debugging scenario
# 1. Bug found: a function behaves incorrectly
# 2. Find who last touched it with blame
git blame -L 45,60 src/auth.js
# 3. Inspect that commit
git show c3d4e5f
# 4. Compare before and after
git diff c3d4e5f~1 c3d4e5f
# 5. Narrow the range with bisect
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
Common Mistakes
Mistake 1: Not knowing how to handle cherry-pick conflicts
git cherry-pick f1g2h3i # Conflict occurs
# CONFLICT: ...
# Resolve the conflict, then
git add filename
git cherry-pick --continue
# Or abort
git cherry-pick --abort
Mistake 2: Confusing git log -S and --grep
# --grep: searches commit MESSAGES
git log --grep="login" # Commits with "login" in the message
# -S: searches code CHANGES
git log -S "login" # Commits where "login" was added/removed in the code
Mistake 3: Using blame to assign blame
The purpose of git blame is to understand code context, not to find someone to blame. Check the commit message and PR to understand why the code was written that way.
Deep Dive
Customizing git log --format
# Hash, author, date, message
git log --format="%h %an %ar %s"
# Colorized output
git log --format="%C(yellow)%h%C(reset) %C(blue)%an%C(reset) %s"
# Register as an alias
git config --global alias.lg "log --format='%C(yellow)%h%C(reset) %C(blue)%an%C(reset) %ar %s' --graph --all"
git lg
git shortlog: contributor summary
# Commit count by contributor
git shortlog -sn
# For a specific time period
git shortlog -sn --after="2024-01-01"
Output:
45 John Doe
23 Jane Kim
12 Bob Lee
Useful for open-source contributor lists or team activity summaries.
git stash vs cherry-pick vs patch
Ways to move code between branches:
# cherry-pick: copy a specific commit
git cherry-pick commit-hash
# patch: export changes as a file and apply
git format-patch -1 commit-hash
git am 0001-commit-message.patch
# Quick file copy
git show commit-hash:path/file.txt > copy.txt
- Create several commits and search for feat commits with
git log --grep="feat" --oneline. - Find commits that changed specific code with
git log -S "specific-code" --oneline. - Run
git blame filenameto see each line's author and commit. - Create a feature branch with 2 commits, then use
git cherry-pick commit-hashto bring just one to main. - Simulate
git bisect(create multiple commits, then alternate between good/bad to find the guilty commit).
Q1. What is the difference between git log -S "getUserById" and git log --grep="getUserById"?
- A)
-Ssearches authors,--grepsearches content - B)
-Sfinds commits where the text was added/removed in code,--grepsearches commit messages - C)
-Sis a fast search,--grepis an exact search - D) Both commands show the same result