Searching: grep, log, blame, bisect

Finding code, and finding when and why it changed · 7 min

In one breath

git grep searches the code as it is now. git log -S searches history ("which commit added this?"). git blame says who last changed each line and in which commit. git bisect finds the commit that broke something by binary search.

git grep: search the code

git grep "CharacterCarriedWeaponMap"
git grep -n "UPROPERTY" -- "*.h"         # -n line numbers, only headers
git grep -i "startupdata"                # -i ignore case

Searching history

QuestionCommand
Which commit added or removed this text?git log -S "CharacterCarriedWeaponMap" --oneline
What happened to this file?git log --oneline -- Source/WadOfGore/Public/WarriorGameplayTags.h
Commits whose message mentions somethinggit log --grep "equip" --oneline
Who last changed each line, in which commit?git blame path/to/file.cpp
What did a commit change?git show fa176d1

blame is badly named. It's for finding context, not culprits: "this line came from commit X; read X's message to learn why it's like this." Rider and Visual Studio show it inline ("annotate").

git bisect: which commit broke it?

The axe worked a week ago and doesn't now, and there are 30 commits in between. Bisect does a binary search:

git bisect start
git bisect bad              # the current commit is broken
git bisect good 5960ce1     # this older one worked
# git checks out a commit halfway between. Build, test, then tell it:
git bisect good             # or: git bisect bad
# ...repeat. About 5 steps for 30 commits. Then:
git bisect reset            # back to where you were

Halving each time means 1,000 commits take about 10 tests. This is why small commits that each compile matter: bisect lands on a small commit that clearly shows the cause.

Quiz yourself

git grep vs searching the folder with a normal search tool, on an Unreal project?

git grep only searches tracked files, so it skips Binaries, Intermediate and other ignored build output. Much faster, and less noise.

Which command finds the commit that added a particular line of code?

git log -S "the text" (the "pickaxe"). git blame also shows the last commit to touch each current line.

What is git blame really for?

Finding the commit (and its message) behind a line, to understand why it's written that way.

How does git bisect find a bad commit, and roughly how many tests for 1,000 commits?

Binary search: test the midpoint, mark good or bad, halve the range. About 10 tests.

Why do small commits that each compile make bisect useful?

Bisect needs to build and test each stop, and it lands on one commit. A small commit points straight at the cause; a huge one doesn't.