How could I use git bisect to find the first GOOD commit?

匿名 (未验证) 提交于 2019-12-03 02:16:02

问题:

I have the following problem:

  • the version at master works fine
  • the version of the last tag before master (say last) has a bug
  • a colleague needs a patch for his last revision for that certain bug

Okay. Let's ask our friend git bisect for the revision that fixed the bug:

git bisect start git bisect bad last git bisect good master 

But that's not going to work:

Some good revs are not ancestor of the bad rev.
git bisect cannot work properly in this case.
Maybe you mistake good and bad revs?

Any hints to overcome this? Did I miss something in the docs?

回答1:

As of git 2.7, you can use the arguments --term-old and --term-new.

For instance, you can identify a problem-fixing commit thus:

git bisect start --term-new=fixed --term-old=unfixed git bisect fixed master git bisect unfixed $some-old-sha1 

As you test, say git bisect fixed or git bisect unfixed as appropriate.

Old answer, for versions of git prior to 2.7

Instead of temporarily training yourself to think that bad means good and good means bad, why not create some aliases?

In ~/.gitconfig add the following:

[alias]         bisect-fixed = bisect bad         bisect-unfixed = bisect good 

You can start identifying a problem-fixing commit thus:

$ git bisect start $ git bisect-fixed master $ git bisect-unfixed $some-old-sha1 

As you test, say git bisect-fixed or git bisect-unfixed as appropriate.



回答2:

I would just "cheat" git and swap meanings of good <=> bad.

In other words, consider "bad" as something that does not exhibit the problem so this is not the "good" version to base your patch on.

Good and bad are pretty subjective concepts anyway, right? :)

git bisect start git bisect good last git bisect bad master 


回答3:

If you're using git bisect run like I have been doing with Perl's prove command (which runs automatic tests) you have no chance just to swap good and bad. The success of the tests will be reported as exit code.

I have found a valid Bash syntax to negate the exit code of the program run by git bisect run:

git bisect start git bisect bad HEAD                 # last revision known to PASS the tests git bisect good $LAST_FAIL_REVISION # last revision known to FAIL the tests git bisect run bash -c "! prove" 

This gave me the first revision to pass the tests run by prove.



回答4:

Git aliases are a good idea, however the terms fixed and unfixed have the same issue than good and bad: you cannot have them be compatible with both regressions and progressions. It's easy to find words which work either way: simply pick them up from the original binary search terminology which is neutral in nature with no preconception of what is good or bad. For instance:

git config --global alias.bisect-high 'bisect bad' git config --global alias.bisect-low  'bisect good' 

With neutral terms like these you can always type: git bisect-high (or git bisect-upper, or git-bisect max,... your choice!) whether you're looking for a regression or a fix.

Too bad the git bisect developers could not simply re-use any of the existing terms. The user interface is not git's concern generally speaking: http://stevebennett.me/2012/02/24/10-things-i-hate-about-git/



回答5:

Git now lets you use old and new without first defining them. You have to call git bisect start without commits as further arguments, then properly start the bisection by calling

git bisect old <rev> git bisect new <rev> 

https://git-scm.com/docs/git-bisect#_alternate_terms

This essentially is what @MarcH was suggesting should be implemented.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!