IAd*_*ter 416 git git-bisect
我读过一些文章说这git bisect很棒,但我不是母语,我不明白为什么它很棒.
你能否在一些代码示例上展示一下它的惊人之处?它就像svn blame?
Syl*_*sne 610
背后的想法git bisect是在历史中执行二进制搜索以找到特定的回归.想象一下,您有以下开发历史:
... --- 0 --- 1 --- 2 --- 3 --- 4* --- 5 --- current
Run Code Online (Sandbox Code Playgroud)
您知道您的程序在current修订版中无法正常工作,并且它正在修订版中0.因此,回归中提交的一个可能的介绍1,2,3,4,5,current.
您可以尝试检查每个提交,构建它,检查是否存在回归.如果有大量提交,这可能需要很长时间.这是线性搜索.我们可以通过二进制搜索做得更好.这就是git bisect命令的作用.在每一步中,它都会尝试将可能坏的修订数量减少一半.
你将使用这样的命令:
$ 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
Run Code Online (Sandbox Code Playgroud)
执行此命令后,git将签出提交.在我们的例子中,它将被提交3.您需要构建程序,并检查是否存在回归.如果存在回归,或者不存在回归,您还需要告知git此修订的状态.git bisect badgit bisect good
我们假设回归是在提交中引入的4.然后在这个版本中没有回归,我们告诉它git.
$ make
$ make test
... ... ...
$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[< ... sha ... >] 5
Run Code Online (Sandbox Code Playgroud)
然后它将签出另一个提交.无论是4或5(如只有两个提交).我们假设它被选中了5.在构建之后,我们测试程序并看到回归存在.然后我们告诉它git:
$ make
$ make test
... ... ...
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[< ... sha ... >] 4
Run Code Online (Sandbox Code Playgroud)
我们测试了最后一次修订4.由于它是引入回归的那个,我们告诉它git:
$ make
$ make test
... ... ...
$ git bisect bad
< ... sha ... > is the first bad commit
< ... commit message ... >
Run Code Online (Sandbox Code Playgroud)
在这个简单的情况下,我们只需要测试3个版本(3,4,5),而不是4( ,1,2,).3 4这是一个小胜利,但这是因为我们的历史是如此之小.如果搜索范围是N次提交,我们应该期望git bisect用线性搜索测试1 + log2 N次提交而不是大约N/2次提交.
一旦找到引入回归的提交,您就可以研究它以找到问题.完成此操作后,您git bisect reset将在使用git bisect命令之前将所有内容重新置于原始状态.
Cir*_*四事件 146
git bisect run 自动平分如果您的自动./test脚本的退出状态为0,如果测试正常,您可以自动查找错误bisect run:
git checkout KNOWN_BAD_COMMIT
git bisect start
# Confirm that our test script is correct, and fails on the bad commit.
./test
# Should output != 0.
echo $?
# Tell Git that the current commit is bad.
git bisect bad
# Same for a known good commit in the past.
git checkout KNOWN_GOOD_COMMIT
./test
# Should output 0.
echo $?
# After this, git automatically checks out to the commit
# in the middle of KNOWN_BAD_COMMIT and KNOWN_GOOD_COMMIT.
git bisect good
# Bisect automatically all the way to the first bad or last good rev.
git bisect run ./test
# End the bisect operation and checkout to master again.
git bisect reset
Run Code Online (Sandbox Code Playgroud)
当然,假设如果测试脚本./test是git跟踪的,那么它在二分期间的某些早期提交中不会消失.
我发现很多时候你只需PATH要从树中复制树内脚本,并且可能玩类似变量,然后从那里运行它就可以逃脱.
当然,如果测试基础设施test依赖于旧提交,那么就没有解决方案,您将不得不手动完成任务,决定如何逐个测试提交.
在bisect之后保持第一次失败的提交而不是回到master:
git bisect reset HEAD
Run Code Online (Sandbox Code Playgroud)
start+初始bad和good一次性:
git bisect start KNOWN_BAD_COMMIT KNOWN_GOOD_COMMIT~
Run Code Online (Sandbox Code Playgroud)
是相同的:
git checkout KNOWN_BAD_COMMIT
git bisect start
git bisect bad
git bisect good KNOWN_GOOD_COMMIT
Run Code Online (Sandbox Code Playgroud)
查看到目前为止测试的内容(通过手册good和bad或run):
git bisect log
Run Code Online (Sandbox Code Playgroud)
样本输出:
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
Run Code Online (Sandbox Code Playgroud)
在git log上显示好的和坏的refs以获得更好的时间概念:
git log --decorate --pretty=fuller --simplify-by-decoration master
Run Code Online (Sandbox Code Playgroud)
这只显示具有相应引用的提交,这会减少噪声,但确实包括类型的自动生成的引用:
refs/bisect/good*
refs/bisect/bad*
Run Code Online (Sandbox Code Playgroud)
告诉我们哪些提交标记为好或坏.
如果你想玩这个命令,请考虑这个测试回购.
有时:
对于那些情况,例如假设失败总是在5秒内发生,如果我们懒得使测试更具体,我们可以使用timeout如下:
#!/usr/bin/env bash
timeout 5 test-command
if [ $? -eq 1 ]; then
exit 1
fi
Run Code Online (Sandbox Code Playgroud)
这可以在timeout退出124失败时test-command退出1.
git bisect run 退出状态有点挑剔:
任何高于127的东西都会导致二分失败,例如:
git bisect run failed:
exit code 134 from '../test -aa' is < 0 or >= 128
Run Code Online (Sandbox Code Playgroud)
特别是,C assert(0)导致a SIGABRT和退出状态134,非常烦人.
125是神奇的,并且可以跳过运行 git bisect skip
请参阅man git-bisect详细信息.
所以你可能想要使用类似的东西:
#!/usr/bin/env bash
set -eu
./build
status=0
./actual-test-command || status=$?
if [ "$status" -eq 125 ] || [ "$status" -gt 127 ]; then
status=1
fi
exit "$status"
Run Code Online (Sandbox Code Playgroud)
在git 2.16.1上测试过.
Geo*_*ale 113
$ git bisect start
$ git bisect bad
$ git bisect good <goodcommit>
Run Code Online (Sandbox Code Playgroud)
Bisecting: X revisions left to test after this (roughly Y steps)
问题仍然存在?
$ git bisect bad$ git bisect good<abcdef> is the first bad commit
Run Code Online (Sandbox Code Playgroud)
git bisect reset
Run Code Online (Sandbox Code Playgroud)
Nic*_*cks 38
只是补充一点:
我们可以指定文件名或路径 git bisect start,以防我们知道错误来自特定文件.例如,假设我们知道导致回归的更改位于com/workingDir目录中,然后我们可以运行.git bisect start com/workingDir这意味着只会检查更改此目录内容的提交,这会使事情变得更快.
此外,如果很难判断特定提交是好还是坏,您可以运行git bisect skip,这将忽略它.鉴于有足够的其他提交,git bisect将使用另一个来缩小搜索范围.
Nab*_*med 12
$ git bisect ..基本上是一个用于调试的Git工具.'Git Bisect'通过执行自上次(已知)工作提交以来的提交进行调试.它使用二进制搜索来完成所有这些提交,以获得引入回归/错误的提交.
$ git bisect start #Starting bisect
$ git bisect bad #声明当前提交(v1.5)具有回归/设置'坏'点
$ git bisect good v1.0 #提到它最后一次良好的工作提交(没有回归)
这提到'坏'和'好'点将有助于git bisect(二进制搜索)选择中间元素(commit v1.3).如果在commit v1.3中存在回归,则将其设置为新的"坏"点,即(Good - > v1.0和Bad - > v1.3)
$ git bisect bad
Run Code Online (Sandbox Code Playgroud)
或类似地,如果提交v1.3没有错误,你将它设置为新的'好点'即(*好 - > v1.3和坏 - > v1.6).
$ git bisect good
Run Code Online (Sandbox Code Playgroud)
注意:术语good和bad并不是您可以用于标记具有或不具有特定属性的提交的唯一术语。
Git 2.7(2015 年第四季度)引入了新git bisect选项。
git bisect start [--term-{old,good}=<term> --term-{new,bad}=<term>]
[--no-checkout] [<bad> [<good>...]] [--] [<paths>...]
Run Code Online (Sandbox Code Playgroud)
随着文档添加:
有时,您不是在寻找引入破坏的提交,而是在寻找导致其他“旧”状态和“新”状态之间发生变化的提交。
例如,您可能正在寻找引入特定修复程序的提交。
或者您可能正在寻找第一个提交,其中源代码文件名最终全部转换为您公司的命名标准。管他呢。在这种情况下,使用术语“好”和“坏”来指代“变更前的状态”和“变更后的状态”可能会非常混乱。
因此,您可以分别使用术语“
old”和“new”来代替“good”和“bad”。
(但请注意,您不能在单个会话中将“good”和“bad”与“old”和“new”混合使用。)在这种更一般的用法中,您提供
git bisect了一个new具有某些属性的 "old" 提交和一个没有该属性的 " " 提交。每次
git bisect检出提交时,您测试该提交是否具有以下属性:
如果具有,则将该提交标记为“new”;否则,将其标记为“old”。当二分完成后,
git bisect将报告哪个提交引入了该属性。
请参阅Matthieu Moy ( ) 的commit 06e6a74、commit 21b55e3、commit fe67687(2015 年 6 月 29 日)。
请参阅Antoine Delaite ( ) 的commit 21e5cfd(2015 年 6 月 29 日)。(由Junio C Hamano合并-- --在提交 22dd6eb,2015 年 10 月 5 日)moyCanardChouChinois
gitster
| 归档时间: |
|
| 查看次数: |
77223 次 |
| 最近记录: |