I did a fresh installation of Drupal 8 this morning and came across a bit of ugliness: an ugly grey border on the home page, caused by an empty div being inserted into the page:
My last fresh install of Drupal 8 was about a week ago and didn't have this problem. I didn't relish the idea of going through all of the commits since then one-by-one to figure out where this bug was introduced.
Enter the git bisect command! The git bisect
command works by performing a "binary" search between one state of the code and the other in order to find, by process of elimination, where a given problem was introduced. It's quick, it's easy, and by golly it just works!
Here's how to use git bisect
, step-by-step!
Step 1: Find a commit where things were working.
Have a look through the git log for a commit from around the time you know things were last working, such as https://git.drupalcode.org/project/drupal/-/commit/fd0a623f478e335794e09....
Confim that this commit actually works ok by switching your checkout to it instead:
(Tip: you only need to reference the first 5-6 characters of the commit hash; you don't need the entire thing... Git is smart and will figure it out!)
$ git checkout fd0a623f
Note: checking out 'fd0a623f'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at fd0a623 - Patch #1201024 by pillarsdotnet: drupal_realpath() should describe when it should be used.
Now refresh your Drupal 8 site in your browser . Yay! No more ugly border. So we know that this version of the code, at least, was working okay. Progress!
Step 2: Find a commit where things are not working.
(Tip: Normally, this will just be '8.x' or whatever branch you're working on where you found the problem, but since I want this tutorial to work even months or years from now, we'll go with this route.)
Next we need to know the current commit hash, where things are not working so good. That would be https://git.drupalcode.org/project/drupal/-/commit/256d85044583970a2d39e....
Confirm this by doing:
$ git checkout 256d85
Previous HEAD position was fd0a623... - Patch #1201024 by pillarsdotnet: drupal_realpath() should describe when it should be used.
HEAD is now at 256d850... Issue #1011614 by catch: Fixed Theme registry can grow too large for MySQL max_allowed_packet() and memcache default slab size.
...and refreshing the page again. That ugly border is back again. Ick!
Step 3 - N: Use git bisect to find the problem commit
Great. So we know where it was working, and we know where it isn't anymore. Time for some fun!
To begin, we need to start git bisect
and then give it the "known good" place, and the "known bad" place.
$ git bisect start
$ git bisect good fd0a623
$ git bisect bad 256d850
Bisecting: 28 revisions left to test after this (roughly 5 steps)
[68c0c8c6359961cbef832398c4ddab0fe2f17083] Issue #1238258 by kiamlaluno, izmeez: Change 'Track page visits' to 'Page visits'.
Git bisect looked at all of the commits between fd0a623 and 256d850, picked the middle one, and switched the current checkout to that instead.
Now, we need to figure out if the code in commit 68c0c8c has the same issue or not. Reload the page. Hey, the ugly border is gone again!
Tell Git about the good news, and it will start the next search, this time at the halfway point between commit 68c0c8c (new known good) and 256d850 (known bad):
$ git bisect good
Bisecting: 14 revisions left to test after this (roughly 4 steps)
[03b443e8f5043b6e8c3a743ad01a3db9d663ad3c] Issue #1123092 by michaellenahan, varunarora: Fixed user-profile.tpl.php doc has confusing/misleading first paragraph.
Refresh the page. Ewww. Border's back again. That's no good. However, we did manage to find a new "known bad" state. Let's tell Git about it so it can give us a new version to try:
$ git bisect bad
Bisecting: 6 revisions left to test after this (roughly 3 steps)
[e217c4ef1bf06ad75bf6124b9af520195f212001] Issue #1291458 by arithmetric: Fixed Database::getConnection mentions short-lived fixed bug and shouldn't.
You know the drill now. Reload. Border gone. Bisect good!
$ git bisect good
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[08b9bd41723a0a23687c59033c15d66c1840b4f3] Issue #918808 by moshe weitzman, Damien Tournoud, dww: Standardize block cache as a drupal_render() #cache.
Reload. Border's back. BAD!
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 1 step)
[9763ca906a6229125dfbe1b56956405457d55892] Issue #1290512 by droplet: Fixed Seven: remove duplicated css.
One last time, reload. Border's gone. GOOD!
$ git bisect good
08b9bd41723a0a23687c59033c15d66c1840b4f3 is the first bad commit
commit 08b9bd41723a0a23687c59033c15d66c1840b4f3
Author: Nathaniel
Date: Thu Sep 29 12:29:59 2011 +0900
Issue #918808 by moshe weitzman, Damien Tournoud, dww: Standardize block cache as a drupal_render() #cache.
:040000 040000 493cba4b1f84c0e907a37f5f4e40d3576bb84785 7763c1bb6f7e4e7b1296863b5df945f5b1760f67 M modules
BAM! By process of elimination, we've just found our problem commit! It was from pesky old issue #918808. Time to update the issue with a pointer to the bug it introduced (and vice-versa).
Step 4: Get back to a working state
Once you're all finished up, run these commands to end your git bisect session and get back to the normal 8.x branch:
$ git bisect reset
Previous HEAD position was 9763ca9... Issue #1290512 by droplet: Fixed Seven: remove duplicated css.
HEAD is now at 256d850... Issue #1011614 by catch: Fixed Theme registry can grow too large for MySQL max_allowed_packet() and memcache default slab size.
$ git checkout 8.x
Switched to branch '8.x'
Now you're back in business to review more 8.x patches! w00t!
Awww, yeah!
We've successfully deduced where a problem was introduced in about 3 minutes. Sifting through commit logs and trying to revert patches on an ad-hoc basis can take 10 times that or more. Let's say it together now, Git bisect rules!! :D
Comments
Git bisect rules!
Git bisect rules!
And if you dont want to do it manually
http://blog.boombatower.com/git-bisect-saves-the-day
thanks for providing that url
thanks for providing that url to us, looks very interesting to me. Me and my friends from the university talked about exactly that topic last week in Hamburg
Thanks!
Thanks for the great write-up! I've run into plenty of situations in which
git bisect
would have really come in handy, so I bet it's not long until I put this walkthrough to use!Thanks!
That is super useful. Thanks for writing it up!
(ephanypdx)
caring about the project history
git bisect is great. And it is another reason for caring about the project history (I mean the commit history in this context):
Those simple rules are generic but they have the side effect of making bisecting ever more effective.
Thanks,
Antonio
Bisect FTW
I'm a big fan of it, especially if it's a bug like this that isn't dependent on the database. I've used it combined with drush site-install to reset the site after each bisect, but it's always painful if you have to re-import a huge DB from a production site.
Well this all looks like
Well this all looks like dichotomy search? Am I right?
Thanks for the great write-up
Thanks for the great write-up! It looks very useful for me.