Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何调试大型git提交?_Git_Debugging - Fatal编程技术网

如何调试大型git提交?

如何调试大型git提交?,git,debugging,Git,Debugging,好的,情况是这样的: 几年前,我们对代码库中的多个文件进行了多次更改,并同时提交了所有更改。在这些变化的某个地方隐藏着一个bug。使用git-bisect,我很快就能追踪到罪犯的犯罪行为,但该犯罪行为中的大量变化让我的热情有所下降 找到一个错误的提交是git bisect的一件轻而易举的事情,但是一旦找到了,什么是跟踪使它变得繁荣的单个更改的最佳方法呢?逐个将受影响的文件还原到其以前的版本?您始终可以创建一个提交分支,然后从那里开始进行对分 另外,请记住,git-bisect只是缩小导致问题的更

好的,情况是这样的:

几年前,我们对代码库中的多个文件进行了多次更改,并同时提交了所有更改。在这些变化的某个地方隐藏着一个bug。使用git-bisect,我很快就能追踪到罪犯的犯罪行为,但该犯罪行为中的大量变化让我的热情有所下降


找到一个错误的提交是git bisect的一件轻而易举的事情,但是一旦找到了,什么是跟踪使它变得繁荣的单个更改的最佳方法呢?逐个将受影响的文件还原到其以前的版本?

您始终可以创建一个提交分支,然后从那里开始进行对分


另外,请记住,
git-bisect
只是缩小导致问题的更改范围的工具。这并不能免除您必须分析问题、查找错误并提出修复方案的责任。

除非您非常了解在大型提交中发生的所有更改,否则这可能会非常乏味

通常,非常大(错误的大)提交涉及许多不同的更改。您需要做的是从概念上隔离所有这些更改,并重写不同的提交

我建议根据以下4个标准对变更进行细分:

[新增]涉及与单独识别的技术级功能相关的所有代码(与可能涉及多个技术级功能的用户级功能相反)

[RFG]任何行为不变的变化。保留执行的行为和API(接口)

[CHG]实施任何表示规范/要求变更的内容

[修复]任何可能改变行为以使其符合编码背后意图的更改

那么,git-wise就是您需要做的:

  git checkout <bad commit SHA1> -b CULPRIT
这将撤消提交,就像提交中的所有更改都作为未老化更改的补丁应用于上一次提交一样。然后使用

  git add --patch
您可以更改这些更改的子集。请不要犹豫使用[s]plit选项逐行单独选择更改。有时,您无法避免使用一个版本来手动选择所需的更改。在我上面建议的新的、RFG、CHG、FIX方案中,当多个提交被分解时重新进行,并根据需要重写多个提交

注意:

  • 暂存未编译的新提交
  • 暂存一个新的提交,该提交会产生“微不足道”的运行时错误(例如segfault)
  • sub提交需要组合以使其工作
…因为我们的目标是让对分有效。此外,确保您的新提交与git diff的旧提交相同。新的头提交将针对罪魁祸首,以确保您没有引入进一步的更改


一开始这是一种痛苦,需要大量的练习,但一旦你做到这一点,你将成为一个调试神,受到整个团队的崇拜,然后可以以NEW、CHG、RFG和FIX的形式传播小提交的福音。

因为坏提交中只有少数文件,我选择了一种有点幼稚的方式。根据公认的答案,这就是我最终所做的:

1) 准备提交的未老化版本:

git checkout <bad commit SHA1> -b CULPRIT
git reset HEAD^ --mixed
4) 如果错误仍然没有显示:

git stash pop
5) 重复步骤2、3和4,直到错误出现,这意味着之前暂存的文件是罪魁祸首

由于罪魁祸首文件中有几个不相关的更改,我选择继续消除过程,但这次是在代码行(或“大块”)级别:

6) 在罪魁祸首文件中放置单个代码块:

add --patch <culprit filename>
add--patch
7) 重复第3步和第4步,直到错误出现,这意味着之前上演的帅哥就是罪魁祸首


我想我本可以更优雅地完成这项工作,并使用git对分,但由于在错误提交中只有7个受影响的文件,我决定手动进行消除。一旦发现了错误代码,我就删除了本地的罪魁祸首分支。

正如您已经指出的,源代码管理无法为您做更多的事情。你真的只是问“如何调试我的代码?”而没有告诉我们代码,甚至没有告诉我们你用哪种语言编写?这是一个很好的例子,说明了为什么提交应该是小的、原子的、带有明确提交消息的操作。@Gareth:不,我不是问如何调试代码,所以这里的实际代码是不相关的。我在寻求进一步缩小错误提交范围的最佳方法,方法是像git bisect那样消除好的更改。我认为下面给出的答案很好地说明了源代码管理实际上可以做得更多。@JohanFredrikVaren:您可以使用Delta()创建一个最小的失败补丁。您需要测试应用补丁是否能让您在提交之前通过一些测试,但现在发现的bug仍然失败。最小化该修补程序将指向错误的更改。谢谢。我尝试了“将提交拆分为较小的提交”解决方案,但在其中的某个地方迷失了方向。像我这样的Git noobs真的需要为他们解释清楚。@JohanFredrikVaren有很多关于拆分Git提交的教程,其中一些教程非常详细地解释了这些步骤,只需谷歌一下就可以了。我只是简单地链接到一个看起来很匹配的。
git stash --keep-index
git stash pop
add --patch <culprit filename>