68

如果尝试从存储库根目录以外的任何位置运行任何 git-bisect 命令,则会被告知:

您需要从工作树的顶层运行此命令。

这是为什么?我知道没有其他 git 命令有这个要求,而且我看不出 bisect 应该是特殊的明显原因。手册页也没有提到这个限制。

这真的不是什么大不了的事。我主要只是好奇。

4

3 回答 3

65

查看项目中的一些提交,我看到了 Marcel M. Cary 的一个 (marcel@oak.homeunix.org)

他在提交中说(它恰好是关于 git-pull 但我认为它是相关的)

“git pull”失败是因为 POSIX shell 有一个与 getcwd() 不同的当前工作目录的概念。shell 将此路径存储在 PWD 中。因此,"cd ../" 在 shell 脚本中的解释与在 C 程序中的 chdir("../") 不同。shell 通过从 PWD 中剥离最后一个文本路径组件来解释“../”,而 C chdir() 遵循文件系统当前目录中的“..”链接。当 PWD 是符号链接时,这些是不同的目的地。因此,Git 的 C 命令会找到正确的顶级工作树,而 shell 脚本则找不到。

https://github.com/git/git/commit/08fc0608657ee91bc85276667804c36a93138c7d

所以我想说部分原因是因为 git-bisect 是一个 shell 脚本,它不能被信任自己找到顶层(当涉及符号链接时)。

于 2012-09-22T08:04:42.907 回答
11

平分过程需要检查项目的不同版本。如果特定修订不包含当前文件夹,则当前文件夹将被删除。

在这种情况下,您的 shell 最终可能会位于不再位于文件系统上的文件夹中!然后 Git 将无法找到顶层的.git文件夹,因此如果没有干预,对分过程将无法继续。

一个示范:

$ git rev-parse --show-toplevel
/path/to/project
$ mkdir tmp
$ cd tmp
$ rmdir ../tmp
$ git rev-parse --show-toplevel
fatal: Unable to read current working directory: No such file or directory

当然,同样的问题可能会在执行时发生git checkout,并且可以在事后轻松修复,例如cd ..(willoller 解释了为什么它在 shell 中有效,但在 git 中无效)。

但是由于二等分是一个过程,因此在开始之前避免这种情况是有意义的,特别是如果我们想使用自动化,例如git bisect run.

于 2016-08-15T02:06:27.617 回答
6

因此,Git 的 C 命令会找到正确的顶级工作树,而 shell 脚本则找不到。

好吧,随着 Git 2.21(2019 年 2 月),git bisect它继续从 shell 脚本过渡到 C。

请参阅Pranit Bauva ( ) 的提交 06f5608 、提交450ebb7提交 129a6cf提交 4fbdbd5提交 e3b1e3b提交 0f30233提交 5e82c3d pranitbauva1997 2019 年 1 月 2 日
帮助者:Ramsay Jones ( jeffhostetler)Stephan Beyer ( sbeyer)
(由Junio C Hamano 合并 -- gitster--09a9c1f 提交中,2019 年 2 月 7 日)

bisect--helper:bisect_start部分在 C 中的 shell 函数

在 C 中部分地重新实现bisect_startshell 函数并添加 bisect-start子命令以git bisect--helper从 git-bisect.sh 调用它。

这尚未完成,但该迁移的副作用是能够git bisect从子文件夹执行。


Git 2.23 进一步改进了对 C 的转换。
参见Johannes Schindelin ( ) 的commit 7877ac3(2019 年 5 月 21 日(由Junio C Hamano 合并——提交 5b476dc中,2019 年 6 月 17 日)dscho
gitster


使用 Git 2.25(2020 年第一季度),bisect_reset受益于修复。

请参阅Tanushree Tumane ( ) 的提交 51a0a4e(2019 年 12 月 9 日(由Junio C Hamano 合并——提交 4bfc9cc中,2019 年 12 月 25 日)tanushree27
gitster

bisect--helper: 避免使用后释放

指导人:Johannes Schindelin
指导人:Christian Couder
签字人:Tanushree Tumane
签字人:Miriam Rubio

5e82c3dd22a(“ bisect--helperbisect_resetC中的shell函数”,2019-01-02,Git v2.21.0-rc0 --merge 中,将[git bisect](https://git-scm.com/docs/git-bisect) reset子命令移植到C
中,调用git checkout失败时,报错(could not check out original HEAD)给用户。

但是,此错误消息使用的strbuf是刚刚发布的。
让我们切换一下:首先使用它,然后释放它。


Git 2.26(2020 年第一季度)继续如此,其中“ git bisect--helper”的底层机制被重构为更易于重用的部分。

请参阅Pranit Bauva () 的提交 6c69f22 、提交9ec598e提交 45b6370提交 cdd4dc2提交 e8e3ce6提交 ce58b5d提交 7613ec5 pranitbauva1997 2020 年 2 月 17 日
请参阅Miriam Rubio (``)的提交 680e8a0提交 b8e3b2f提交 16538bf(2020 年 2 月 17 日) 。 请参阅提交 bfacfce提交 292731c(2020 年 2 月 17 日),作者Tanushree Tumane ( )(由Junio C Hamano 合并 -- --
tanushree27
gitster提交 25063e2,2020年 3 月 5 日)

例如:

bisect--helper: 引入新decide_next()功能

指导人:Christian Couder
签字人:Tanushree Tumane
签字人:Miriam Rubio

让我们将代码重构bisect_next_check()为一个新的decide_next()辅助函数。

这删除了一些goto语句,使代码更简单、更清晰、更容易理解。


在 Git 2.28(2020 年第三季度)之前,解析“ git bisect start”命令行的代码在验证参数时很松懈。

请参阅Carlo Marcelo Arenas Belón ( ) 的提交 4d9005f(2020 年 5 月 20 日(由Junio C Hamano 合并 -- --commit 63e50b8中,2020 年 6 月 9 日)carenas
gitster

bisect--helper: 避免语法错误的段错误start --term-*

签字人:Carlo Marcelo Arenas Belón
签字人:Christian Couder

06f5608c14 (" bisect--helper: bisect_startshell function partial in C", 2019-01-02, Git v2.21.0-rc0 -- merge[ ) 为git bisect start添加了一个松散的解析器,](https://git-scm.com/docs/git-bisect)这可能导致在自定义 start 的语法错误调用下出现段错误条款。

检测命令行中是否有足够的参数用于--term-{old,good,new,bad}和中止,如果没有,原始实现将显示相同的语法错误。


在 Git 2.29(2020 年第四季度)之前," ( man ),当 X 和 Y 不是有效的提交对象名称时,应该将 X 和 Y 作为路径规范,但没有。git bisect start X Y

请参阅Christian Couder ( ) 的commit 73c6de0(2020 年 9 月 25 日(由Junio C Hamano 合并 -- --提交 03a0182中,2020 年 10 月 4 日)chriscool
gitster

bisect: 启动时不要使用无效的 oid 作为 rev

签字人:Christian Couder
签字人:Johannes Schindelin

06f5608c14 (" bisect--helper: bisect_startshell function partial in C", 2019-01-02, Git v2.21.0-rc0 -- merge ) 中,我们更改了以下 shell 代码:

-      rev=$(git rev-parse -q --verify "$arg^{commit}") || {
-              test $has_double_dash -eq 1 &&
-              die "$(eval_gettext "'\$arg' does not appear to be a valid revision")"
-              break
-      }
-      revs="$revs $rev"

进入:

+      char *commit_id = xstrfmt("%s^{commit}", arg);
+      if (get_oid(commit_id, &oid) && has_double_dash)
+              die(_("'%s' does not appear to be a valid "
+                    "revision"), arg);
+
+      string_list_append(&revs, oid_to_hex(&oid));
+      free(commit_id);

如果无效的“ arg”当"has_double_dash"为假时,旧代码将“中断”出参数循环。

但是,在新的 C 代码中,oid_to_hex(&oid)无条件地附加到“ revs”。这首先是错误的,因为“ oid”是get_oid(commit_id, &oid)失败的垃圾,其次是因为它没有跳出参数循环。

不打破参数循环意味着“ arg”不被视为路径限制(这是错误的)。


在 Git 2.29(2020 年第四季度)中,继续用 C 重写“ git bisectman脚本。

请参阅Pranit Bauva ( ) 的提交 517ecb3提交 09535f0(2020 年 9 月 24 日。 请参阅Miriam Rubio ( ) 的 commit c7a7f48 ( 2020 年 9 月 24 日)和commit 7b4de74commit 3027676commit ef5aef5(2020 年 8 月 28 日(由Junio C Hamano 合并 -- --提交 f4cc68c中,2020 年 10 月 4 日)pranitbauva1997
mirucam
gitster

bisect--helper: 在 C 中重新实现bisect_nextbisect_auto_nextshell 函数

指导人:Lars Schneider
指导人:Christian Couder
指导人:Johannes Schindelin
签字人:Pranit Bauva
签字人:Tanushree Tumane
签字人:Miriam Rubio

在 C 中重新实现bisect_next()bisect_auto_next()shell 函数,并将子命令添加到[git](https://github.com/git/git/blob/517ecb3161daa4503f7638489fd44177b3659913/Documentation/git-.txt)<sup>([man](https://git-scm.com/docs/git-))</sup> bisect--helper以从 git-bisect.sh 调用它们。

bisect_auto_next()函数返回一个枚举bisect_error类型,因为整个[git bisect](https://github.com/git/git/blob/517ecb3161daa4503f7638489fd44177b3659913/Documentation/git-bisect.txt)<sup>([man](https://git-scm.com/docs/git-bisect))</sup> 可以在退出时出现错误代码bisect_next()

失败时返回错误bisect_next(),修复 shell 脚本版本的错误。

使用--bisect-nextand--bisect-auto-next子命令是将 shell 函数移植到 C 以使用现有测试套件的临时措施。随着更多的功能被移植,--bisect-auto-next子命令将被淘汰并被其他一些方法调用。


在 Git 2.30(2021 年第一季度)中,C 中的“ git bisectman重写仍在继续。

请参阅Pranit Bauva () 的提交 b0f6494 、提交5c517fe提交 9b437b0提交 27257bc提交 04774b4提交 e439607提交 88ad372 pranitbauva1997 2020 年 10 月 15 日
(由Junio C Hamano 合并gitster——提交 cfdc70b中,2020 年 11 月 9 日)

bisect--helper: 在 C 中重新实现bisect_state& bisect_headshell 函数

指导人:Lars Schneider
指导人:Christian Couder
指导人:Johannes Schindelin
签字人:Pranit Bauva
签字人:Tanushree Tumane
签字人:Miriam Rubio
审核人:Johannes Schindelin

在 C 中重新实现bisect_state()shell 函数,并添加一个子命令--bisect-stategit-bisect--helper调用它们git-bisect.sh


使用 Git 2.31(2021 年第一季度):继续用 C 语言重写“ git bisectman

请参阅Pranit Bauva () 的提交 97b8294 、提交e4c7b33提交 9feea34提交 b7a6f16提交 68efed8提交 2b1fd94提交 97d5ba6 pranitbauva1997 2021 年 2 月 3 日
(由Junio C Hamano 合并 -- gitster--0871fb9 提交中,2021 年 2 月 17 日)

bisect--helper: 退休--bisect-write子命令

指导人:Lars Schneider
指导人:Christian Couder
指导人:Johannes Schindelin
签字人:Pranit Bauva
签字人:Tanushree Tumane
签字人:Miriam Rubio

--bisect-writegit-bisect.sh shell 脚本中不再使用该子命令。
相反,该函数bisect_write()是直接从 C 实现中调用的。


" git bisect" ( man )在 2.30 时间范围内用 C 重新实现了更多,并没有将带注释的标签作为好/坏端点。
此回归已在 Git 2.31.1(2021 年第一季度)中得到纠正。

请参阅Jeff King ( ) 的提交 7730f85(2021 年 3 月 16 日(由Junio C Hamano 合并 -- --提交 35381b1中,2021 年 3 月 19 日)peff
gitster

bisect: 将注释标签剥离到提交

签字人:杰夫·金

此补丁修复了一个错误,其中 ' git-bisect' ( man )不处理接收带注释的标签为 " git bisect" 好<tag>等。
这是27257bc中的回归(" bisect--helper: reimplement bisect_state& bisect_headshell functions in C", 2020-10-15, Git v2.30.0- rc0 -合并在批次 #4中列出)。

原来的shell代码叫做:

sha=$(git rev-parse --verify "$rev^{commit}") ||
        die "$(eval_gettext "Bad rev input: \$rev")"

这会将输入剥离到提交(如果不可能,则抱怨)。
但是 C 代码只是调用get_oid(),这将产生标签的 oid。

解决方法是剥离提交。
这里的错误消息对于 Git 来说有点不习惯(因为它以大写字母开头)。

新的错误信息:

Bad rev input (not a commit): xxxx

警告:当自定义词用于新/旧时, “ git bisect skipman)在 Git 2.31 中不起作用,已在 Git 2.32(2021 年第二季度)中更正。

请参阅Ramsay Jones ( ) 的提交 4cd66e7(2021 年 4 月 29 日(由Junio C Hamano 合并 -- --提交 8ca4771中,2021 年 5 月 11 日)ramsay-jones
gitster

bisect--helper:BISECT_TERMS在 ' bisect skip' 命令中使用

报告人:Trygve Aaberge
签字人:Bagas Sanjaya
签字人:Ramsay Jones

提交e4c7b33 (" bisect--helper: reimplement bisect_skipshell function in C", 2021-02-03, Git v2.31.0-rc0 -- merge在批处理 #9中列出),作为 shell 到 C 转换的一部分,忘记阅读 '.git/BISECT_TERMS在新的 ' bisect skip' 命令执行期间的条款'文件 ( )。
因此,“ bisect skip”命令将使用默认的“坏”/“好”术语。
如果二等分项已设置为非默认值(例如通过“ bisect start”命令),则“ bisect skip”命令将失败。

为了纠正这个问题,我们在 ' ' 的 ' ' 命令实现中插入对该函数的调用,该get_terms()函数从该文件中读取非默认项(如果已设置)。--bisect-skipbisect--helper

此外,添加一个测试以防止潜在的未来回归。


在 Git 2.33(2021 年第三季度)中,“ git bisectman生成man只是为了在签出要测试的下一个版本后漂亮地打印提交的标题;这已用 C 重写。git show-branch

请参阅Junio C Hamano ( ) 的提交1fcc40c ( 2021 年 7 月 28 日)和提交 ffcb4e9(2021 年 7 月 27 日(由Junio C Hamano 合并 -- --提交 ae2d05d中,2021 年 8 月 24 日)gitster
gitster

bisect: 不要仅仅为了显示当前提交而运行 show-branch

在 " " ( man ) 的脚本版本中git bisect我们使用" " git show-branch( man )描述 bisect 日志中的单个提交,并在签出要测试的下一个版本后向交互式用户描述。

git show-branch当写入 bisect 日志条目的辅助函数在 C 中的0f30233(“ bisect--helperbisect_writeC 中的 shell 函数”,2019 年 1 月 2 日,Git v2.21.0-rc0 -- merge)处重写时,以前的“”用法就丢失了

但是我们从0871984 ( bisect: make , 2009-05-09, Git v1.6.4-rc0 -- merge ) (bisect: make " git bisect" use new --next-allbisect-helper function, 2009-05-09) 开始就一直保留后者使用在ef24c7c ( bisect--helper: add , 2009-04-19, Git v1.6.4-rc0 -- merge ) ( bisect--helper: add " --next-exit" to output bisect results, 2009-04-19) 中引入的忠实 C 重写。

使用我们的帮助器::format_commit_message()显示 " [<full hex>] <subject>" 非常简单,而生成 show-branch 是一种过度杀伤力。 让我们失去一个外部进程。pretty.c

于 2019-03-03T20:59:10.233 回答