如何使用git bisect?
我读过一些文章说, git bisect
真棒,但我不是母语,我不明白为什么它真棒。
你可以请示例代码示例什么是如此惊人的呢? 这是否像svn blame
?
git bisect
背后的想法是在历史中执行二分search以find特定的回归。 想象一下,你有以下的发展历史:
... --- 0 --- 1 --- 2 --- 3 --- 4* --- 5 --- current
你知道你的程序在current
修订版本中工作不正常,并且正在修订版本0
。 所以这个回归可能是在当前提交的1
中的一个中引入的。
您可以尝试检查每个提交,构build它,检查回归是否存在。 如果有大量的提交,这可能需要很长时间。 这是一个线性search。 我们可以做一个二进制search做得更好。 这是git bisect
命令的作用。 在每一步,它都会尝试减less可能坏一半的版本的数量。
你会使用这样的命令:
$ git stash save $ git bisect start $ git bisect bad $ git bisect good 0 Bisecting: 2 revisions left to test after this (roughly 2 steps) [< ... sha ... >] 3
在这个命令之后, git
会检出一个提交。 在我们的例子中,这将是提交3
。 你需要build立你的程序,并检查回归是否存在。 你还需要告诉git
这个修订版本的状态,如果回归是存在的,那么git bisect bad
,或者如果git bisect good
没有关联, git bisect good
。
假设回归是在提交4
中引入的。 然后在这个版本中不存在回归,我们把它告诉git
。
$ make $ make test ... ... ... $ git bisect good Bisecting: 0 revisions left to test after this (roughly 1 step) [< ... sha ... >] 5
然后它将检出另一个提交。 4
或5
(因为只有两个提交)。 我们假设它select了5
。 build立之后,我们testing程序,看看回归是否存在。 然后我们把它告诉git
:
$ make $ make test ... ... ... $ git bisect bad Bisecting: 0 revisions left to test after this (roughly 0 steps) [< ... sha ... >] 4
我们testing最后的修订, 4
。 而且由于它是引入了回归的那个,我们把它告诉git
:
$ make $ make test ... ... ... $ git bisect bad < ... sha ... > is the first bad commit < ... commit message ... >
在这种简单的情况下,我们只需要testing3个版本( 3
)而不是4( 4
)。 这是一个小小的胜利,但这是因为我们的历史是如此之小。 如果search范围是N提交,我们应该期望testing1 + log2 N提交与git bisect
而不是大致N / 2提交与线性search。
一旦你find了引入回归的提交,你可以研究它来find问题。 一旦完成,你可以使用git bisect reset
来在使用git bisect
命令之前把所有的东西都恢复到原来的状态。
如果你有一个自动化的testing脚本 ,退出状态0,如果testing正常,你可以自动find对bisect run
的错误:
git bisect start # Tell Git that the current commit is bad. git bisect bad git checkout HEAD~9 ./test # If the above test passed, tell Git that the current commit is good. # Immediately check out to `bad~5`, the middle commit. git bisect good # Automatically check out to the first failing rev. git bisect run ./test # Check out to master and end the bisect operation. git bisect reset
其他有用的操作 :
留在对分之后的第一个失败的提交,而不是回到master
:
git bisect reset HEAD
start
+初始bad
, good
:
git bisect start HEAD HEAD~10
是相同的:
git bisect start git bisect bad git bisect good HEAD~9
看看到目前为止已经testing过的东西(通过手动的bad
或run
):
git bisect log
示例输出:
git bisect log git bisect start # bad: [00b9fcdbe7e7d2579f212b51342f4d605e53253d] 9 git bisect bad 00b9fcdbe7e7d2579f212b51342f4d605e53253d # good: [db7ec3d602db2d994fe981c0da55b7b85ca62566] 0 git bisect good db7ec3d602db2d994fe981c0da55b7b85ca62566 # good: [2461cd8ce8d3d1367ddb036c8f715c7b896397a5] 4 git bisect good 2461cd8ce8d3d1367ddb036c8f715c7b896397a5 # good: [8fbab5a3b44fd469a2da3830dac5c4c1358a87a0] 6 git bisect good 8fbab5a3b44fd469a2da3830dac5c4c1358a87a0 # bad: [dd2c05e71c246f9bcbd2fbe81deabf826c54be23] 8 git bisect bad dd2c05e71c246f9bcbd2fbe81deabf826c54be23 # bad: [c536b1b7242d5fcf92cd87e9a534bedb1c0c9c05] 7 git bisect bad c536b1b7242d5fcf92cd87e9a534bedb1c0c9c05 # first bad commit: [c536b1b7242d5fcf92cd87e9a534bedb1c0c9c0
考虑这个testing回购,如果你想玩弄命令。
TL; DR
开始:
$ git bisect start $ git bisect bad $ git bisect good <goodcommit>
Bisecting: X revisions left to test after this (roughly Y steps)
重复:
问题依然存在?
- 是的:
$ git bisect bad
- 不:
$ git bisect good
结果:
<abcdef> is the first bad commit
完成时:
git bisect reset
只是补充一点:
我们可以指定一个文件名或path来git bisect start
,以防我们知道这个bug来自特定的文件。 例如,假设我们知道引起回归的变化在com / workingDir目录下,那么我们可以运行git bisect start com/workingDir
这意味着只有改变了这个目录内容的提交会被检查,这样做事情更快。
另外,如果很难判断一个特定的提交是好还是坏,你可以运行git bisect skip
,这会忽略它。 鉴于有足够的其他提交,git bisect将使用另一个缩小search范围。
$ git bisect ..
基本上是一个用于debugging的Git工具 。 'Git Bisect'通过完成上次(已知)工作提交之前的提交进行debugging。 它使用二进制search来通过所有这些提交,以达到引入回归/错误的那个。
$ git bisect start
#开始对分
$ git bisect bad
#说明当前提交(v1.5)具有回归/设置“不好”的一点
$ git bisect good v1.0
#提到它最后一个良好的工作提交(没有回归)
这个提到'坏'和'好'点将帮助git bisect (二进制search)select中间元素(提交v1.3)。 如果回退是在v1.3提交的,你会把它设置为新的“坏”点,即( 好 – > v1.0和坏 – > v1.3 )
$ git bisect bad
或者类似的,如果提交v1.3是无bug的,你会把它设置为新的“好点”即(*好 – > v1.3和坏 – > v1.6)。
$ git bisect good