如果在代码库的根目录之外的任何位置尝试运行git-bisect命令,会收到以下提示:
您需要从工作树的顶层运行此命令。
为什么会这样呢?我不知道其他任何一个git命令有这种要求,也没有明显的原因表明bisect应该特殊对待。手册中也没有提及这个限制。
这其实并不是什么大问题。我只是好奇。
如果在代码库的根目录之外的任何位置尝试运行git-bisect命令,会收到以下提示:
您需要从工作树的顶层运行此命令。
为什么会这样呢?我不知道其他任何一个git命令有这种要求,也没有明显的原因表明bisect应该特殊对待。手册中也没有提及这个限制。
这其实并不是什么大问题。我只是好奇。
在查看项目的一些提交时,我发现有一条由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 脚本,不能自行找到顶级目录(当涉及到符号链接时)。
二分过程需要检查您项目的不同版本。如果特定版本不包含当前文件夹,则当前文件夹将被删除。
在这种情况下,你的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
。
git bisect
正在从Shell脚本向C语言过渡。
请查看 提交 06f5608, 提交 450ebb7, 提交 129a6cf, 提交 4fbdbd5, 提交 e3b1e3b, 提交 0f30233, 提交 5e82c3d (2019年1月2日) 由 Pranit Bauva (pranitbauva1997
) 提交。
协助者: Ramsay Jones (jeffhostetler
), 和 Stephan Beyer (sbeyer
)。
(由Junio C Hamano -- gitster
--于提交 09a9c1f中合并,2019年2月7日)
bisect-helper:
bisect_start
shell函数部分使用C重新实现
将
bisect_start
shell函数部分使用C重新实现,并向git bisect--helper
添加bisect-start
子命令,以便从git-bisect.sh中调用它。这还没有完成,但此迁移的一个副作用将是能够从子文件夹执行
git bisect
。
Git 2.23进一步改进了C语言转换。
请参见提交7877ac3(2019年5月21日),作者为Johannes Schindelin (dscho
)。
(由Junio C Hamano -- gitster
--于提交5b476dc中合并,2019年6月17日)
从 Git 2.25 (2020年第一季度) 开始,bisect_reset
得到了修复的好处。
请参见 提交 51a0a4e (由 Tanushree Tumane (tanushree27
) 于 2019年12月09日提交)
(由 Junio C Hamano -- gitster
-- 合并于 提交 4bfc9cc,2019年12月25日)
在5e82c3dd22a("C语言中的
bisect--helper
: 避免使用后释放导师:Johannes Schindelin
导师:Christian Couder
签名:Tanushree Tumane
签名:Miriam Rubio
bisect_reset
shell函数",2019-01-02,Git v2.21.0-rc0 -- 合并)中,git bisect reset
子命令被移植到了C中。git checkout
失败时,向用户报告了一个错误消息(could not check out original HEAD
)。
但是,该错误消息已经使用了刚发布的strbuf
,因此需要对它进行修改:先使用它,然后再释放它。
git bisect--helper
" 的基础机制正在重构为更易于重用的部分。
请查看由Pranit Bauva (pranitbauva1997
)于2020年2月17日提交的提交6c69f22, 提交9ec598e, 提交45b6370, 提交cdd4dc2, 提交e8e3ce6, 提交ce58b5d, 提交7613ec5。
请查看由Miriam Rubio (``)于2020年2月17日提交的提交680e8a0, 提交b8e3b2f, 提交16538bf。
请查看由Tanushree Tumane (tanushree27
)于2020年2月17日提交的提交bfacfce, 提交292731c。
(合并自Junio C Hamano -- gitster
--在提交25063e2,2020年3月5日)
bisect--helper
: 引入新的decide_next()
函数Mentored-by: Christian Couder
Signed-off-by: Tanushree Tumane
Signed-off-by: Miriam Rubio
让我们将
bisect_next_check()
代码重构为一个新的decide_next()
辅助函数。这将移除一些
goto
语句,并使代码更简单、更清晰、更容易理解。
在 Git 2.28(2020 年第三季度)之前,解析 "git bisect start
" 命令行的代码在验证参数方面比较宽松。
请参见 commit 4d9005f(2020 年 5 月 20 日),作者为 Carlo Marcelo Arenas Belón (carenas
)。
(由 Junio C Hamano -- gitster
-- 合并至 commit 63e50b8,于 2020 年 6 月 9 日)
bisect--helper
:避免在start --term-*
中出现语法错误导致段错误签名作者:Carlo Marcelo Arenas Belón
经过确认:Christian Couder
06f5608c14 ("
bisect--helper
:bisect_start
shell function partially 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 bisect start X Y
(man)”中,当X和Y不是有效的提交对象名称时,应该将X和Y作为路径规范处理,但实际未能这样做。
请查看由Christian Couder (chriscool
)于2020年9月25日提交的提交73c6de0。
(在2020年10月4日被Junio C Hamano -- gitster
--合并到提交03a0182中)
bisect
: 开始时不要使用无效的 oid 作为 rev签名作者: Christian Couder
签名作者: Johannes Schindelin
In 06f5608c14 ("
bisect--helper
:bisect_start
shell function partially in C", 2019-01-02, Git v2.21.0-rc0 -- merge), we changed the following shell code:
- 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"
into:
+ 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);
In case of an invalid "
arg
" when"has_double_dash"
is false, the old code would "break" out of the argument loop.In the new C code though,
oid_to_hex(&oid)
is unconditonally appended to "revs
". This is wrong first because "oid
" is junk asget_oid(commit_id, &oid)
failed, and second because it doesn't break out of the argument loop.Not breaking out of the argument loop means that "
arg
" is then not treated as a path restriction (which is wrong).
在Git 2.29(2020年第四季度)中,用C重写“git bisect
”(man)脚本的工作正在继续。
查看 提交 517ecb3,提交 09535f0(2020年9月24日)由Pranit Bauva (pranitbauva1997
)。
查看 提交 c7a7f48(2020年9月24日),以及提交 7b4de74, 提交 3027676, 提交 ef5aef5 (2020年8月28日)由Miriam Rubio (mirucam
)。
(由Junio C Hamano -- gitster
--合并于提交 f4cc68c,2020年10月4日)
bisect--helper
:在C语言中重新实现bisect_next
和bisect_auto_next
shell函数指导者:Lars Schneider
指导者:Christian Couder
指导者:Johannes Schindelin
签署者:Pranit Bauva
签署者:Tanushree Tumane
签署者:Miriam Rubio
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脚本版本的一个bug。
使用--bisect-next
和--bisect-auto-next
子命令是将shell函数移植到C的临时措施,以便使用现有的测试套件。随着更多的函数被移植,--bisect-auto-next
子命令将被淘汰,并将由其他方法调用。
git bisect
"(man)。
请参阅 提交 b0f6494, 提交 5c517fe, 提交 9b437b0, 提交 27257bc, 提交 04774b4, 提交 e439607, 提交 88ad372 (2020年10月15日) ,作者为 Pranit Bauva (pranitbauva1997)
。
(由Junio C Hamano -- gitster
--合并于提交 cfdc70b,2020年11月9日)
bisect--helper
:在C中重新实现bisect_state
和bisect_head
shell函数
导师:Lars Schneider
导师:Christian Couder
导师:Johannes Schindelin
签名:Pranit Bauva
签名:Tanushree Tumane
签名:Miriam Rubio
审核:Johannes Schindelin
在C中重新实现bisect_state()
shell函数,并在git-bisect--helper
中添加一个子命令--bisect-state
,以从git-bisect.sh
调用它们。
随着Git 2.31 (2021年第一季度)的到来:对C语言中"git bisect
"(man)的重写进行了逐步处理。
请查看由Pranit Bauva (pranitbauva1997
)于2021年2月3日提交的提交97b8294, 提交e4c7b33, 提交9feea34, 提交b7a6f16, 提交68efed8, 提交2b1fd94, 提交97d5ba6。
(由Junio C Hamano -- gitster
--合并于2021年2月17日的提交0871fb9)
bisect--helper
: 废除 --bisect-write
子命令
指导者: Lars Schneider
指导者: Christian Couder
指导者: Johannes Schindelin
签署者: Pranit Bauva
签署者: Tanushree Tumane
签署者: Miriam Rubio
--bisect-write
子命令不再从 git-bisect.sh shell 脚本中使用。
而是直接从 C 实现中调用函数 bisect_write()
。
"git bisect
"(man) 在 2.30 时间框架内的重新实现更多地使用了 C 语言,但不能很好地接受带有注释的标签作为好/坏的终点。
这个回归错误已在 Git 2.31.1 (Q1 2021) 中得到修正。
请看 提交 7730f85 (2021年3月16日) ,作者是Jeff King (peff
)。
(由Junio C Hamano -- gitster
--在提交 35381b1中合并,2021年3月19日)
bisect
: 将带注释的标签转换为提交
署名:Jeff King
This patch fixes a bug where 'git-bisect
'(man) doesnt handle receiving annotated tags as "git bisect
" good <tag>
, etc.
It's a regression in 27257bc ("bisect--helper
: reimplement bisect_state
& bisect_head
shell functions in C", 2020-10-15, Git v2.30.0-rc0 -- merge listed in batch #4).
The original shell code called:
sha=$(git rev-parse --verify "$rev^{commit}") ||
die "$(eval_gettext "Bad rev input: \$rev")"
which will peel the input to a commit (or complain if that's not possible).
But the C code just calls get_oid()
, which will yield the oid of the tag.
The fix is to peel to a commit.
The error message here is a little non-idiomatic for Git (since it starts with a capital).
新错误信息:
Bad rev input (not a commit): xxxx
警告:在使用自定义单词来代替new/old时, "git bisect skip
"(man) 在Git 2.31中无法正常工作,但已在Git 2.32(2021年第二季度)中得到修复。
请参见 提交记录4cd66e7 (2021年4月29日),作者为Ramsay Jones(ramsay-jones
)。
该提交已被Junio C Hamano(gitster
)合并至提交记录8ca4771,时间为2021年5月11日。
bisect--helper
:在“bisect skip
”命令中使用BISECT_TERMS
报告者:Trygve Aaberge
签署者:Bagas Sanjaya
签署者:Ramsay Jones
作为 shell-to-C 转换的一部分,提交 e4c7b33 ("bisect--helper
: 在 C 中重新实现 bisect_skip
shell 函数",2021-02-03,Git v2.31.0-rc0 -- 合并 列在 批次 #9 中) 时,忘记读取新的 'bisect skip
' 命令实现期间的 'terms' 文件(.git/BISECT_TERMS
)。因此,'bisect skip
' 命令将使用默认的“bad”/“good”术语。如果二分术语已设置为非默认值(例如通过 'bisect start
' 命令),则'bisect skip
' 命令将失败。为了解决这个问题,在 'bisect--helper
' 的 '--bisect-skip
' 命令实现中插入对 get_terms()
函数的调用,该函数从该文件中读取非默认术语(如果设置)。另外,添加一个测试以防止潜在的未来回归。
在 Git 2.33(2021 年第三季度), "git bisect
"(man) 仅为了在检出下一个要测试的版本后漂亮地打印提交标题,而生成了 git show-branch
(man);现已使用 C 重写。
请查看 提交记录 1fcc40c (2021年7月28日) 和 提交记录 ffcb4e9 (2021年7月27日),作者为 Junio C Hamano (gitster
)。
(已合并至 提交记录 ae2d05d,由 Junio C Hamano -- gitster
-- 完成,日期为2021年8月24日)
bisect
: 不必运行show-branch命令来显示当前提交记录
在脚本化的 "git bisect
"(man) 版本中,我们使用 "git show-branch
"(man) 来描述 bisect 日志中的单个提交,并在检出下一个要测试的版本后向交互用户提供信息。当重写编写 bisect 日志条目的帮助函数时,以前使用 "git show-branch
" 的用法已经丢失,该帮助函数在 0f30233 ("bisect--helper
: bisect_write
shell function in C", 2019-01-02, Git v2.21.0-rc0 -- merge) 中被改写为 C 语言。
但是自从 0871984 (bisect:make "git bisect
" use new --next-all
bisect-helper function, 2009-05-09, Git v1.6.4-rc0 -- merge) 开始使用了忠实的 C 重写之后,我们一直保留了后者(即向交互用户提供信息)。该重写是在 ef24c7c (bisect--helper
: add "--next-exit
" to output bisect results, 2009-04-19, Git v1.6.4-rc0 -- merge) 中添加的 (bisect--helper
: add "--next-exit
" to output bisect results, 2009-04-19)。
使用我们的 helper pretty.c
::format_commit_message() 显示 "[<full hex>] <subject>
" 很简单,而生成 show-branch 则是一种过度操作。让我们减少一个外部进程。