Skip to content

Instantly share code, notes, and snippets.

@rafaelcaricio
Last active December 4, 2019 15:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rafaelcaricio/b30f0e46759b74ad101d to your computer and use it in GitHub Desktop.
Save rafaelcaricio/b30f0e46759b74ad101d to your computer and use it in GitHub Desktop.
Using git bisect

Using git bisect

Git provides a simple way to find out where some code was modified or removed from your codebase. You can use git bisect for that and the processes can be completely automated.

As example I will try to find out when the method send_email_notification was removed from the file app/models/person.rb. So you have to create a automated bash file, or other kind of script, that should return 0 when the method is found and 1 otherwise. So git can run this script for each commit until it returns 1, which means that the method was removed in that commit. There's the script we gonna use:

if [[ `cat app/models/person.rb | grep send_email_notification` ]]; then
  exit 0
fi
exit 1

Then all you need to do is run those commands:

$ git bisect start
$ git bisect good [bad hash]
$ git bisect bad [good hash]

Where [bad hash] is the latest hash commit in your codebase and [good hash] is any past commit where you can find the method you want.

Then you can run the automated script and it will start the bisect search in your local repository.

$ git bisect run sh find_method.sh

You should see an output similar to:

running sh find_method.sh
Bisecting: 751 revisions left to test after this (roughly 10 steps)
[90ace1aadf1e03d7ed5e0e12d26ffacd11c2397d] Rename Save Your to Other
running sh find_method.sh
Bisecting: 375 revisions left to test after this (roughly 9 steps)
[58758680d07a8b84b8d62c2d037031497195acab] Fix issue with application_presenter
running sh find_method.sh
Bisecting: 191 revisions left to test after this (roughly 8 steps)
[228a55b5857136f1d9855d9082b46ed3848bb756] Add record updater
running sh find_method.sh
Bisecting: 96 revisions left to test after this (roughly 7 steps)
[2213a2331482f8402cfb6c6505dc8ceda9425ea3] Merge branch 'production'
running sh find_method.sh
Bisecting: 46 revisions left to test after this (roughly 6 steps)
[7fabb880e32a8676fbd48449d369032cd870a713] Merge branch 'master' into production
running sh find_method.sh
Bisecting: 23 revisions left to test after this (roughly 5 steps)
[83b9c114865efbe5b7b721a751b9d23fd7bf3663] Change label text
running sh find_method.sh
Bisecting: 11 revisions left to test after this (roughly 4 steps)
[79de4e6e9dddc6d170d86e846de76d010d48a8ac] Disable editing
running sh find_method.sh
Bisecting: 5 revisions left to test after this (roughly 3 steps)
[e206a78f4d28906c289b7f0c2f5381f4db8acf59] Fix specs
running sh find_method.sh
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[85a1e64f0c8a98247bd554536faf74e2e2810845] Re emails
running sh find_method.sh
Bisecting: 0 revisions left to test after this (roughly 1 step)
[8d657bbb6e0ba3c8359bc1a0732b85b13730b85e] Update
running sh find_method.sh
85a1e64f0c8a98247bd554536faf74e2e2810845 is the first bad commit
commit 85a1e64f0c8a98247bd554536faf74e2e2810845
Author: Nice co-Worker <someone@lunarlogic.io>
Date:   Fri May 30 09:51:35 2014 +0200

    Remove emails

:040000 040000 719522207350492054014134834b5387c7bfe6cc ce001f507a346c112d9fc4c5b0493901e9c90bd5 M	app
:040000 040000 afa6a4e53c822e1a35c1aa2f521b3d033e70b312 65890f8ae4b088fc88acf722cba8df9269561e06 M	config
:040000 040000 2f711c3b3f869d34594a9058867707eb2559ae34 43d8fbf8a2570fae4a2d23b057980b9512971686 M	spec
bisect run success

So from this output we can see that our method send_email_notification was removed from app/models/person.rb in the commit 85a1e64f0c8a98247bd554536faf74e2e2810845.

It was an simple example using grep command. But if you want to find out when a bug was introduced, you simple tell git to run an specific spec from your codebase. The rspec command already returns the appropriate value when it fails.

@chriscool
Copy link

You might want to try "git log -S" first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment