为什么必须从工作树的顶级目录运行git-bisect?

Par*_*tes 54 git git-bisect

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

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

这是为什么?我知道没有其他git命令有这个要求,我认为没有明显的理由,bisect应该是特殊的.手册页也没有提到这个限制.

这真的不是什么大不了的事.我大多只是好奇.

wil*_*ler 54

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

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

"git pull"失败,因为POSIX shell具有与getcwd()不同的当前工作目录的概念.shell将此路径存储在PWD中.因此,"c ... .."可以在shell脚本中以不同于C程序中的chdir("../")的方式进行解释.shell通过基本上剥离PWD中的最后一个文本路径组件来解释"../",而C chdir()跟随文件系统上当前目录中的".."链接.当PWD是符号链接时,这些是不同的目的地.因此,Git的C命令找到正确的顶级工作树,而shell脚本则找不到.

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

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

  • 我希望有更好的理由,但这不是你的错.非常感谢你做了一些研究. (3认同)

joe*_*dle 8

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

在这种情况下,你的shell最终可能会坐在不再在文件系统上的文件夹中!然后Git将无法找到toplevel的.git文件夹,因此bisect进程无法在没有干预的情况下继续.

示范:

$ 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
Run Code Online (Sandbox Code Playgroud)

当然,这样做时会出现同样的问题git checkout,并且可以在事后很容易修复,例如cd ..(willoller解释了为什么在shell中工作但在git中不工作).

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


Von*_*onC 5

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

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

请参阅Pranit Bauva ( ) 的commit 06f5608commit 450ebb7commit 129a6cfcommit 4fbdbd5commit e3b1e3bcommit 0f30233commit 5e82c3d(2019 年 1 月 2 日。 帮助者:拉姆齐·琼斯 ( )斯蒂芬·拜尔 ( )(由Junio C Hamano合并-- --commit 09a9c1f,2019 年 2 月 7 日)pranitbauva1997
jeffhostetlersbeyer
gitster

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

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

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


Git 2.23 进一步改进了到 C 的转换。
请参阅Johannes Schindelin ( ) 的提交 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--helper: bisect_resetshell function in C", 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 ( ) 的commit 6c69f22commit 9ec598ecommit 45b6370commit cdd4dc2commit e8e3ce6commit ce58b5dcommit 7613ec5(2020 年 2 月 17 日。 请参阅Miriam Rubio (``) 的commit 680e8a0commit b8e3b2fcommit 16538bf(2020 年 2 月 17 日。 请参阅提交 bfacfce提交 292731c(2020 年 2 月 17 日)由Tanushree Tumane ( )(由Junio C Hamano合并-- --pranitbauva1997

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 ( ) 的commit 4d9005f(2020 年 5 月 20 日(由Junio C Hamano合并-- --63e50b8 提交中,2020 年 6 月9日)carenas
gitster

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

签约人:Carlo Marcelo Arenas Belón
认可人:Christian Couder

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

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


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

请参阅Christian Couder ( ) 的commit 73c6de0 (25 Sep 2020 )(由Junio C Hamano合并-- --2020 年 10 月 4 日提交 03a0182 中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"
Run Code Online (Sandbox Code Playgroud)

进入:

+      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);
Run Code Online (Sandbox Code Playgroud)

如果无效的“ arg” when"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 日。 见提交c7a7f48(2020年9月24日),以及提交7b4de74提交3027676提交ef5aef5(2020年8月28日)由仪Rubio的((由Junio C Hamano合并-- --提交 f4cc68c 中,2020 年 10 月 4 日)pranitbauva1997
mirucam
gitster

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

导师:Lars Sch