git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* git-rev-list: "--bisect" flag
@ 2005-06-18  6:31 Linus Torvalds
  2005-06-19  0:18 ` Jon Seymour
  0 siblings, 1 reply; 19+ messages in thread
From: Linus Torvalds @ 2005-06-18  6:31 UTC (permalink / raw)
  To: Git Mailing List


Ok, I just added a feature to "git-rev-list" that I hereby nominate to be
the coolest feature ever, namely the "--bisect" flag, which basically
tries to split the list of revisions in two, and prints out just the "most
middle" commit.

The idea is that you want to do binary-search for a bug, but since the git
history isn't a nice linear thing, you don't know where the hell the
mid-point is between two commits, and even if you _do_ know where it is,
it gets even more complicated when you have 3 points (on different
branches) that are known good, and one point that is known bad.

Now, assuming you have three known-good points, and one known bad point, 
the way to get all commits in between is

	git-rev-list bad ^good1 ^good2 ^good3

and with the new flag you can now trivially get an estimate for what the 
mid-point is in this list. So you just do

	git-rev-list --bisect bad ^good1 ^good2 ^good3

and you now have the point to test. If testing shows that mid-way-point 
was bad, you just continue with that as a "new bad":

	git-rev-list --bisect new-bad ^good1 ^good2 ^good3

but if it shows that that point was still good, you instead just add it to 
the list of uninteresting commits, and do

	git-rev-list --bisect bad ^good1 ^good2 ^good3 ^new-good

instead. Every iteration you basically cut down the number of commits by 
half - you're bisecting the set, and binary-searching for the first bad 
commit.

Note that git also makes resetting to the test-point be really trivial: 
you just do

	git-read-tree -m -u <prev-point> <test-point>

where "prev-point" was your previous state (ie usually "HEAD" the first 
time, but the previous test-point otherwise), and "test-point" is the new 
point you want to test.

I haven't scripted this, but it should basically be pretty easy to add a
couple of simple scripts to make it very easy to do the binary search be
totally automated, assuming just a simple "mark test as failed/good"  
interface. Even without the scripting, it shouldn't be that hard to do
entirely by hand.

The idea being that if you notice that something doesn't work (usually in 
HEAD), but you know it used to work in the previous release, you just 
start the whole thing going with

	# set up initial state
	cat .git/HEAD > .git/BAD
	cat .git/HEAD > .git/CURRENT
	echo "^v2.6.12" > .git/GOOD

and then you just do something like:

	# iterate
	git-rev-list --bisect BAD $(cat .git/BAD) > .git/HALFWAY
	if [ ! -s .git/HALFWAY ]; then
		echo FOUND IT:
		cat .git/CURRENT
		exit 1
	fi
	git-read-tree -m -u CURRENT HALFWAY
	cat .git/HALFWAY > .git/CURRENT

	make ..


	# if good
	echo '^'$(cat .git/CURENT) >> .git/GOOD
	.. iterate ..

	# if bad
	cat .git/CURRENT > .git/BAD
	.. iterate ..

until it says "FOUND IT".

(The above is untested, but the --bisect behaviour itself I tested, and it 
seems to do the right thing).

NOTE! I'm not convinced I actually find a particularly good place to split 
at, but I think my stupid "halfway point" decision is good enough in 
practice. So it might not really be a real binary search, but I think it 
comes pretty close to it unless you have some really odd cases.

			Linus

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2005-06-20 14:32 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-06-18  6:31 git-rev-list: "--bisect" flag Linus Torvalds
2005-06-19  0:18 ` Jon Seymour
2005-06-19  3:38   ` Jan Harkes
2005-06-19  4:07     ` Jon Seymour
2005-06-19  3:43   ` Linus Torvalds
2005-06-19  5:03     ` Linus Torvalds
2005-06-19  5:05       ` David Lang
2005-06-19  5:30         ` Linus Torvalds
2005-06-19 10:15       ` Jon Seymour
2005-06-19 14:41         ` Jon Seymour
2005-06-19 17:20           ` Linus Torvalds
2005-06-19 17:36             ` Ingo Molnar
2005-06-19 19:01               ` Linus Torvalds
2005-06-19 19:55             ` Jon Seymour
2005-06-20  3:09               ` Linus Torvalds
2005-06-20  3:27                 ` Jon Seymour
2005-06-20  3:30                   ` Jon Seymour
2005-06-20 10:29                     ` Jon Seymour
2005-06-20 14:37                       ` Jon Seymour

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).