【Git 学习笔记_23】Git 实用冷门操作技巧(二)——妙用 git bisect 与 git blame 进行代码调试

文章目录

    • 11.3 用 git bisect 进行调试
    • 11.4 使用 git blame 命令

本节所在位置:

  • 活用 git stash(上)
  • 保存并应用 stash(上)
  • 用 git bisect 进行调试(二)✔️
  • 使用 git blame 命令(二)✔️
  • 设置彩色命令行界面
  • 自动补全
  • 让 Bash 自带状态信息
  • 更多别名
  • 交互式新增提交
  • 用 Git 的图形界面交互式新增
  • 忽略文件
  • 展示与清理忽略文件

11.3 用 git bisect 进行调试

实际工作中经常遇到类似“究竟是哪次提交引入的某个 Bug”的问题,而底层应用二分算法的 git bisect 命令是该类问题的绝佳工具,尤其适用于在较长的提交历史记录中快速锁定引入 bug 具体 commit。二分查找法(binary search method)或二分法(bisection method),是一种在有序数组中查找目标位置的搜索方法。算法会在每一步与数组的中间值进行比较,如果匹配成功则返回该位置;否则,根据比较结果,选择中间值的右侧或左侧的子数组继续搜索,直至找到目标位置。在 Git 中,历史提交记录对应一组可供测试的值数组,若程序能在某个 commit 编译成功则为目标位置。二分查找的算法复杂度为 O(log n)

本节演示如何从一个提交了 23 次的带 bug 分支利用 git bisect 命令定位该 bug 的全过程(假设带 bug 提交的 SHA-183c22a39955ec10ac1a2a5e7e69fe7ca354129af):

# init repo
$ git clone https://github.com/PacktPublishing/Git-Version-Control-Cookbook-Second-Edition_tips_and_tricks.git bugHunting
$ cd bugHunting
$ git checkout bug_hunting

bug 位于 map.txt 文件第 38 行:

file with a bug

接下来是找到检测该 bug 的方法来测试不同版本。比如编译代码,执行测试等等。这里简化为定位代码中是否存在 oo 字样的行,编写测试脚本 test.sh 如下:(注:该测试脚本只适用于 Linux 环境下)

$ echo "! grep -q oo map.txt " > ../test.sh
$ chmod +x ../test.sh

为了避免测试脚本不受项目签出、编译等影响,最好将测试脚本放到 git 库外面。

小提示

经实测,测试脚本 test.sh 第一行末尾须加一个空格,否则脚本只能在 Linux 环境运行成功,而 Windows 下,Windows 的换行符号会与文件名 test.sh 连在一起,从而导致目标文件定位失败。

接下来开始测试:

$ git bisect start

将当前版本标记为【bad】:

# mark current commit as bad
$ git bisect bad

将上一个正常版本标记为【good】:

# mark the last known good commit (master HEAD) as good
$ git bisect good master
Bisecting: 12 revisions left to test after this (roughly 4 steps)
[7fb98059857aa0361cf14329d027573afd5a17b2] Build map part 10

启动第一轮排查:

# 1st round
$ ../test.sh; test $? -eq 0 && git bisect good || git bisect bad
Bisecting: 6 revisions left to test after this (roughly 3 steps)
[de6b768ceebd451591ee41ff4708ca889bafd3f2] Build map part 15

根据提示,启动第二轮排查:

# 2nd round
$ ../test.sh; test $? -eq 0 && git bisect good || git bisect bad
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[865ff6f8a62d61e4a59f7bc1b2478aa6c71c345a] Build map part 13

再启动第三、四轮:

# 3rd round
$ ../test.sh; test $? -eq 0 && git bisect good || git bisect bad
Bisecting: 0 revisions left to test after this (roughly 1 step)
[27952d82d1f9067948b37e39b9bc4d0e6d846567] Build map part 14
# 4th round
$ ../test.sh; test $? -eq 0 && git bisect good || git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[83076f97e8312f8d59976c6373c897aef284c26d] Bugs...

此时,剩余步骤提示为 0,来到最后一轮排查:

# 5th round
$ ../test.sh; test $? -eq 0 && git bisect good || git bisect bad
83076f97e8312f8d59976c6373c897aef284c26d is the first bad commit
commit 83076f97e8312f8d59976c6373c897aef284c26d
Author: HAL 9000 <aske.olsson@switch-gears.dk>
Date:   Tue May 13 09:53:45 2014 +0200Bugs...map.txt | 6 +++---1 file changed, 3 insertions(+), 3 deletions(-)

由此锁定引入 Bug 的那次提交(版本标识为:83076f97e8312f8d59976c6373c897aef284c26d)。最后是状态重置:

# reset bisect, get SHA-1 (83076f9): 
$ git bisect reset
Previous HEAD position was 83076f9 Bugs...
Switched to branch 'bug_hunting'
Your branch is up to date with 'origin/bug_hunting'.
$ git show 83076f9
commit 83076f97e8312f8d59976c6373c897aef284c26d
Author: HAL 9000 <aske.olsson@switch-gears.dk>
Date:   Tue May 13 09:53:45 2014 +0200Bugs...diff --git a/map.txt b/map.txt
index 8a13f6b..1afeaaa 100644
--- a/map.txt
+++ b/map.txt
@@ -34,6 +34,6 @@ Australia:.-./     |.     :  :,/           '-._/     \_/                '       \
-           .'                         *: Brisbane
-        .-'                             ;
-        |                               |
+           .'        \__/             *: Brisbane
+        .-'          (oo)               ;
+        |           //||\\              |

演示过程的示意图如下:

git bisect result

注意:其实倒数第二轮时已经找到引入 bug 的版本了,但需要进一步确认 bug 是该版本自己产生的,还是其他版本传播到这里的,因此多运行了一轮。

发散

上述示例的一个弊端就是手动执行每一轮测试脚本,直到找出目标位置为止。若想让该过程自动进行,可以给 git 指定一个脚本(script),或 makefile,或一个测试脚本,使得二分查找自动进行。传入的脚本,会在命中目标时用返回一个为零状态(exit with a zero-status),或者在未命中时返回一个非零状态(a non-zero status):

# Automatic bisect
$ git bisect start HEAD master
Bisecting: 12 revisions left to test after this (roughly 4 steps)
[7fb98059857aa0361cf14329d027573afd5a17b2] Build map part 10
# pass the test script
$ git bisect run ../test.sh
running  '../test.sh'
Bisecting: 6 revisions left to test after this (roughly 3 steps)
[de6b768ceebd451591ee41ff4708ca889bafd3f2] Build map part 15
running  '../test.sh'
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[865ff6f8a62d61e4a59f7bc1b2478aa6c71c345a] Build map part 13
running  '../test.sh'
Bisecting: 0 revisions left to test after this (roughly 1 step)
[27952d82d1f9067948b37e39b9bc4d0e6d846567] Build map part 14
running  '../test.sh'
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[83076f97e8312f8d59976c6373c897aef284c26d] Bugs...
running  '../test.sh'
83076f97e8312f8d59976c6373c897aef284c26d is the first bad commit
commit 83076f97e8312f8d59976c6373c897aef284c26d
Author: HAL 9000 <aske.olsson@switch-gears.dk>
Date:   Tue May 13 09:53:45 2014 +0200Bugs...map.txt | 6 +++---1 file changed, 3 insertions(+), 3 deletions(-)
bisect found first bad commit
$ git bisect reset
Previous HEAD position was 83076f9 Bugs...
Switched to branch 'bug_hunting'
Your branch is up to date with 'origin/bug_hunting'.
$ git show 83076f9
# ... (omitted)

11.4 使用 git blame 命令

上一节的 git bisect 适用于只知道项目有 bug,但不知道 bug 在哪儿、是具体哪次提交引入的场景。如果知道了 bug 在代码中的位置,需要明确谁提交或改动的这行代码,就需要使用 git blame 命令。

继续以 Git-Version-Control-Cookbook-Second-Edition_tips_and_tricks 库为例:

$ git blame --date short -L 30,47 .\map.txt
7fb98059 (Dave Bowman      2014-05-13 30) Australia:
33016136 (Frank Poole      2014-05-13 31)
33016136 (Frank Poole      2014-05-13 32)                     _,__        .:
33016136 (Frank Poole      2014-05-13 33)             Darwin <*  /        | \
5a5f6ef7 (Frank Poole      2014-05-13 34)                .-./     |.     :  :,
5a5f6ef7 (Frank Poole      2014-05-13 35)               /           '-._/     \_
5a5f6ef7 (Frank Poole      2014-05-13 36)              /                '       \
83076f97 (HAL 9000         2014-05-13 37)            .'        \__/             *: Brisbane
83076f97 (HAL 9000         2014-05-13 38)         .-'          (oo)               ;
83076f97 (HAL 9000         2014-05-13 39)         |           //||\\              |
27952d82 (Dave Bowman      2014-05-13 40)         \                              /
27952d82 (Dave Bowman      2014-05-13 41)          |                            /
27952d82 (Dave Bowman      2014-05-13 42)    Perth  \*        __.--._          /
de6b768c (Heywood R. Floyd 2014-05-13 43)            \     _.'       \:.       |
de6b768c (Heywood R. Floyd 2014-05-13 44)            >__,-'             \_/*_.-'
de6b768c (Heywood R. Floyd 2014-05-13 45)                                  Melbourne
9b49c0f0 (Heywood R. Floyd 2014-05-13 46)         snd                     :--,
9b49c0f0 (Heywood R. Floyd 2014-05-13 47)                                  '/

其中的 -L 表示限定考察代码的行数范围,格式为 -L <from>,<to> 。从反馈的结果可知,bug 出现在 map.txt 文件的第 37 至 39 行,由 HAL 首次引入该 bug,对应 SHA-183076f97,与 git bisect 结果一致。

此外,还可以指定 -M 参数,查看文件被重构或移动到某处的情况;指定 -C 参数,则可以展示目标文件从当前 commit 包含的文件中复制或移入相关代码的情况;指定 -CCC 则范围不仅限于当前 commit,可包含所有 commit

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/413391.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

零基础Opencv学习(三)

概述&#xff1a;主要目的是为了在图像中获取所需要的特征信息&#xff0c;比如直线或者圆等 一、标准霍夫变换 cv::Mat midImage, dstImage;/// 边缘检测 转化灰度图cv::Canny(image, midImage, 50, 200, 3);cv::cvtColor(midImage, dstImage, CV_GRAY2BGR);/// 进行霍夫线变…

浅谈SpringMvc的核心流程与组件

一、SpringMvc的核心流程 当发起请求时被前置的控制器(DispatcherServlet)拦截到请求&#xff0c;根据请求参数生成代理请求&#xff0c;找到请求对应的实际控制器&#xff0c;控制器处理请求&#xff0c;创建数据模型&#xff0c;访问数据库&#xff0c;将模型响应给中心控制…

ubuntu24下python3.9安装pytorch

安装gpu版pytorch 1.去官网查找命令 https://pytorch.org/get-started/previous-versions/由于我们安装的是CUDA12.1&#xff0c;所以我们选择12.1的进行安装 安装完成之后通过下面代码进行测试 >>> import torch >>> print(torch.cuda.is_available()) T…

Linux入门攻坚——30、sudo、vsftpd

su&#xff1a;Switch User&#xff0c;即切换用户 su [-l user] -c ‘COMMAND’ 如&#xff1a;su -l root -c ‘COMMAND’ 如果没有指定-l user&#xff0c;则默认是root sudo&#xff1a;可以让某个用户不需要拥有管理员的密码&#xff0c;而可以执行管理员的权限。 需…

raw.githubusercontent.com未能解析” 解决方案

1.操作场景 通过windows11 powershell 下载依赖包 2.报错信息如下 irm : 未能解析此远程名称: raw.githubusercontent.com 所在位置 行:1 字符: 27 & ([scriptblock]::Create((irm "https://win11debloat.raphi.re/"))) ~~~~~~~~~…

2 Python开发工具:PyCharm的安装和使用

本文是 Python 系列教程第 2 篇&#xff0c;完整系列请查看 Python 专栏。 1 安装 官网下载地址https://www.jetbrains.com.cn/pycharm/&#xff0c;文件比较大&#xff08;约861MB&#xff09;请耐心等待 双击exe安装 安装成功后会有一个30天的试用期。。。本来想放鸡火教程&…

Mybatis中的缓存

一&#xff0c;为什么要使用缓存 1&#xff0c;缓存的作用 缓存(cache&#xff09;的作用是为了减去数据库的压力&#xff0c;提高查询性能。 缓存实现的原理&#xff1a; 从数据库中查询出来的对象在使用完后不要销毁&#xff0c;而是存储在内存&#xff08;缓存&#xff09;…

智能指针(RAII)

智能指针&#xff08;RAII&#xff09; 一、内存泄漏1、介绍2、原因3、泄漏的内存类型分类 二、RAII1、介绍2、基本思想3、优点4、实现方式 三、unique_ptr1、介绍2、主要特性3、注意事项4、unique_ptr类5、示例代码6、运行结果7、简单实现 四、shared_ptr1、介绍2、主要特点3、…

单自由度无阻尼系统振动分析

特别感谢&#xff1a;https://www.bilibili.com/video/BV114411y7ab/?p6&spm_id_frompageDriver&vd_sourceebe07816bf845358030fc92d23830b29 本文图片该系列视频 tips&#xff1a;关于特征方程与振动方程&#xff1a; 特征方程有助于我们理解和确定系统的固有频率和模…

C语言基础(二十)

链表是一种常见的数据结构&#xff0c;通常用来存储一系列元素&#xff0c;每个元素由一个节点来表示。在链表中&#xff0c;每个节点包含两部分&#xff1a;数据元素本身和指向下一个节点的指针。这种结构使得链表中的元素在内存中不是连续存储的&#xff0c;而是通过指针连接…

随笔九、SARADC按键程控测试

目录 1. 泰山派环境 2. 按键3分析 3. 编程测试 1. 泰山派环境 泰山派开发板上有3个按键 按键1是电源按键PWRON&#xff0c;实测按几下会导致开发板重启 按键2是复位按键RESET&#xff0c;按下立马复位重启 按键3是升级按键RECOVER&#xff0c;配合RESET按键可以使开发板进…

Unity编辑器扩展之Scene视图扩展

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity编辑器扩展之Scene视图扩展 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&#xff01; …

使用cJSON进行JSON文件读写

推荐cJSON下载地址&#xff1a; Git地址&#xff1a;https://github.com/arnoldlu/cJSON 可以尝试&#xff1a;sudo apt-get install libcjson-dev&#xff0c;笔者未使用该方式。 百度AI搜索程序&#xff0c;供参考&#xff0c;部分函数名称应以cJSON模块内定义为主 json文…

游泳耳机哪个牌子的好?四大口碑精品游泳耳机专业推荐!

在追求健康生活的同时&#xff0c;游泳成为了许多人选择的锻炼方式。它不仅能够帮助人们塑造身材&#xff0c;还能有效缓解压力。而在游泳过程中&#xff0c;音乐的陪伴无疑能让人更加享受这段时光。因此&#xff0c;一款适合游泳时使用的耳机&#xff0c;成为了游泳爱好者们不…

CSS学习笔记(01)flex布局

1、首先对父元素设置disiplay&#xff1a;felx&#xff0c; 其有6个属性 fex-direction:设置主轴的方向 justify-content:设置主轴上的子元素排列方式 flex-wrap:设置子元素是否换行 align-content:设置侧轴上的子元素的排列方式(多行) align-items:设置侧轴上的子元素排列方式…

前端性能优化:提升网站加载速度的五个关键技巧

聚沙成塔每天进步一点点 本文回顾 ⭐ 专栏简介前端性能优化&#xff1a;提升网站加载速度的五个关键技巧1. 引言2. 前端性能优化的五个关键技巧2.1 减少HTTP请求技巧说明实现示例 2.2 启用浏览器缓存技巧说明实现示例 2.3 使用内容分发网络&#xff08;CDN&#xff09;技巧说明…

8.27FLEX,BISON

RC ParseStage::handle_request(SQLStageEvent *sql_event) 这个意思是返回类型是RC&#xff0c;然后用到的函数来自 ParseStage&#xff0c;&#xff1a;&#xff1a;就是用来标识作用域的&#xff0c;函数名是handle_request&#xff0c;是ParseStage里的函数 FLEX BISON

一个浏览器插件如何月入12万美元:深入了解 GoFullPage

一个浏览器插件如何月入12万美元&#xff1a;深入了解 GoFullPage 前言 GoFullPage 这个插件的诞生&#xff0c;源于其创作者 Peter Coles 的一个简单想法&#xff1a;解决一个他在日常开发工作中遇到的痛点。早在 2012 年&#xff0c;Coles 发现许多现有的网页截图工具无法完…

x264 编码器 AArch64汇编系列:zigzag 扫描相关汇编函数

zigzag 在x264_zigzag_init函数中初始化具体的 zigzag 实现函数: 以scan_4x4为例 c 语言实现 4x4 变换块扫描:zigzag_scan_4x4_frame。#define ZIGZAG4_FRAME\ZIGDC( 0,

ssh远程连接服务

1、概述 一种安全访问远程服务器的协议&#xff0c;远程管理工具&#xff0c;通过加密方式管理连接&#xff0c;使服务器更安全。 2、加密算法 对称加密 发送密码前将密码数据加密成密文&#xff0c;然后发送出去 接收方收到密文后&#xff0c;使用同一个密钥将密文解密。…