前言
介绍了 git bisect 命令的使用,通过二分查找法快速定位出现问题的提交点。今日前端早读课文章由 @jrainlau 投稿分享。
云原生构建:https://cnb.cool/
正文从这开始~~
今天偶然看到了一篇文章 Debugging Till Dawn: How Git Bisect Saved My Demo,既惊讶于 Git 竟然提供了一个如此强大的工具用于 debug,也对自己的孤陋寡闻感到羞愧。
【第3269期】不知道bug 躲在哪个commit 吗?来试试Git bisect 吧!
只要是有项目经验的人,一定会遇到过一个问题:项目运行情况之前明明都是好的,怎么突然就坏了?为了找到原因,除了实时 debug 以外,更流行的做法是把代码不停回滚,直到回滚到出问题之前的那次提交。
但是随着项目规模不断变大,很有可能在发现问题时,已经过去了无数次提交了。那么这个时候该如何快速准确地找到引发问题的那次提交呢?git bisect 提供了一个非常实用的解法。
顾名思义,该命令是使用二分查找的方式来找到出问题的提交的。假设我们有一个仓库,直到目前为止它一共经历过 7 次提交,而在最后一次提交后,我们才 “惊讶地” 发现它出错了!这个时候我们就要设法找到到底是什么时候引入的错误。
为了简单起见,这个仓库只有一个 README.md 文件,对于 “正确” 的情况,README.md 的内容里应该有且只有单词 “good”。如果什么时候出现了单词 “bad”,就证明它出错了。
# README.md
good
good
good
bad
good
good
good
现在我们拥有了三个已知条件:
第一次提交的时候,项目是好的,当时的标记为 1.0.0;
最后一次提交的时候,项目是坏的,此时的标记为 HEAD;
通过项目的 README.md 文件中是否存在 “bad” 字符串来判断好坏。
接下来,我们就可以使用 git bisect 指令,来快速找到出问题的那次提交了!
首先,在项目根目录中执行以下指令,把前两个已知条件添加进去:
注意,下面的示例代码中,
“>”
后的内容为输入指令并回车后的系统输出。
git bisect start
> 状态:正在等待好的和坏的提交
git bisect bad HEAD
> 状态:正在等待好的提交,已知坏的提交
git bisect good v1.0.0
> 二分查找中:在此之后,还剩 2 个版本待测试 (大概 2 步)
> [0abea12555d76d1cf57500198d1ff011ae0ae4f9] 1.0.3
此时,二分查找已经启动,查找的指针落到了第 4 次提交(v1.0.3)当中。这时候我们看下在第四次的提交中,README.md 都有哪些内容:
cat README.md
>
good
good
good
bad%
可以看到,在这一次提交(v1.0.3)中,项目仍然是坏的,那么我们就可以更新已知条件的第二条了:
【第2934期】利用好 git bisect 这把利器,帮助你快速定位疑难 bug
最后一次提交的时候,项目是坏的,此时的标记为 HEAD;
第四次提交的时候,项目是坏的,此时的标记为 v1.0.3;
git bisect bad v1.0.3
> 二分查找中:在此之后,还剩 0 个版本待测试 (大概 1 步)
> [af369bdbffad4496cff3bf520793cc6b5cfe62e6] 1.0.2
此时二分查找的指针来到了第三次提交(v1.0.2)里,看看此时的 README.md:
cat README.md
>
good
good
good%
可以看到,此时的项目是好的,所以我们可以更新第一条已知条件了:
第一次提交的时候,项目是好的,当时的标记为 1.0.0;
第三次提交的时候,项目是好的,此时的标记为 v1.0.2
所以我们只需要把更新后的条件输入到 git bisect,它就能告诉我们答案了:
git bisect good v1.0.2
>
0abea12555d76d1cf57500198d1ff011ae0ae4f9 is the first bad commit
commit 0abea12555d76d1cf57500198d1ff011ae0ae4f9
Author: jrainliu <jrainliu@tencent.com>
Date: Fri Oct 25 10:27:02 2024 +0800
1.0.3
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
哦,原来出现问题的提交就是标记为 v1.0.3 的那一次!这时候我们已经找到了有问题的提交记录,这时候只需要输入
git bisect reset
即可结束二分查找了。
这种通过肉眼判断项目代码是否出错的方式,实在是太不优雅。好在 git bisect 是支持执行脚本指令的。还是以上面这个示例项目为例,我们只需要写一个简单的 bash 脚本,判断 README.md 的内容是否包含单词”bad“,并通过” 结束码 “就可以自动让 git bisect 告诉我们最终的答案了。
关于所谓的结束码,约定返回 0 为” 正常退出 “,返回非 0 为” 异常退出 “。
# test.sh
#!/usr/bin/env bash
# Check if README.md contains the word "bad"
if grep -q "bad" README.md; then
echo "README.md contains the word 'bad'"
exit 1
else
echo "README.md does not contain the word 'bad'"
exit 0
fi
准备好脚本后,步骤和之前一样,先输入已知的” 好提交 “和” 坏提交 “的标记,然后让 git bisect 自己去执行 test.sh 即可:
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
git bisect run ./test.sh
类似递归的原理,当 test.sh 的退出码为 0 时,会自动缩小二分查找的范围,直到退出码为非 0。
>
正在执行 './test.sh'
README.md contains the word 'bad'
二分查找中:在此之后,还剩 0 个版本待测试 (大概 1 步)
[af369bdbffad4496cff3bf520793cc6b5cfe62e6] 1.0.2
正在执行 './test.sh'
README.md does not contain the word 'bad'
0abea12555d76d1cf57500198d1ff011ae0ae4f9 is the first bad commit
commit 0abea12555d76d1cf57500198d1ff011ae0ae4f9
Author: jrainliu <jrainliu@tencent.com>
Date: Fri Oct 25 10:27:02 2024 +0800
1.0.3
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
二分查找找到了第一个坏的提交
在体会到 git bisect 的强大以后,更能意识到” 代码可测试性” 的重要。如果只靠肉眼 debug,即使是二分查找法也难以提升效率,最终还是得靠完善的测试脚本,通过程序自动化地完成项目好坏的判断,这才是值得我们真正思考和关心的内容。
Debugging Till Dawn: How Git Bisect Saved My Demo:https://www.mikebuss.com/posts/debugging-till-dawn
关于本文
作者:@jrainlau
原文:https://cnb.cool/jrainlau/blog/-/issues/1
这期前端早读课
对你有帮助,帮” 赞 “一下,
期待下一期,帮” 在看” 一下 。