如何调试大型git提交? [英] How do I debug a large git commit?

查看:156
本文介绍了如何调试大型git提交?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,这是这样的:



几年前,我们的代码库中的多个文件已经进行了多次更改,并且一次被提交。这些变化的某个地方隐藏了一个错误。使用git平分法,我​​很快就能够追查歹徒的承诺,但是这个承诺中的变化量让我不那么热心。



查找不好的提交是与git平分的微风,但一旦发现,什么是最好的方法来追踪一切变化,这一切都是繁荣?将受影响的文件逐个恢复到以前的版本?

解决方案

除非你非常了解所有这些,通常,一个非常大(不好的大)提交涉及许多不同的更改。



您需要做的是在概念上分离所有这些更改,并重写不同的提交。



我建议根据这4个条件分解更改:



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



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



[CHG]执行任何代表规范/要求更改的内容



[FIX]可能会改变行为以使其符合代码背后的意图的任何更改。



然后,git-wise这里是您需要做的:

  git checkout< bad commit SHA1> -b CULPRIT 

这将创建一个CULPRIT分支。我总是保留这个作为参考,因为您可能需要执行以下步骤的繁琐的迭代。作为旁注,保持部分参考文献有助于(作为分支或标签)。

  git reset HEAD ^ --mixed 

这将撤销提交,就像将提交中的所有更改应用为以前的提交。然后使用

  git add --patch 

您可以更改这些更改的一个子集。不要犹豫,使用[s] plit选项来逐行选择更改。有时,您无法避免使用版本来选择所需的更改。并且在新建,RFG,CHG,FIX方案中,根据您的需要,重新启动多个提交,并且根据需要重写尽可能多的提交。



注意: p>


  • 暂存不编译的新提交

  • 暂存一个产生微不足道的运行时错误的新提交(例如,segfault)

  • 子提交需要组合使事情工作



因为目标是使平分工作。此外,确保您的新提交与git的旧提交相同,新的HEAD提交重新启动CULPRIT,以确保您没有进行进一步的更改。



这是一个痛苦一开始需要很多的练习,但一旦你做得这么好,你将成为一个被整个团队崇拜的调试神,然后以新的,CHG,RFG的形式传播小小的福音, FIX。


Ok, here's the case:

A couple of years ago, multiple changes was made to multiple files in our codebase, and was committed all at once. Somewhere in those changes hides a bug. Using git bisect, I was quickly able to track down the culprit commit, but the amount of changes in that commit made me a little less enthusiastic.

Finding a bad commit is a breeze with git bisect, but once found, what is the best way to track down the single change that made it all go boom? Revert the affected files to their previous version, one by one?

解决方案

This can be pretty tedious unless you understand very well all the changes that occured within that large commit.

Typically a very large (bad large) commit involves many different changes. What you need to do is isolate all those changes conceptually and rewrite different commits.

I suggest breaking down changes according to these 4 criteria:

[NEW] involves all code related to a singly identified technical-level feature (as opposed to user-level which may involve more than one tech-level feature)

[RFG] any behavioral invariant changes. Preserves executed behavior and APIs (interfaces)

[CHG] implementation of anything that represents a change of specifications/requirements

[FIX] any changes that may change behavior to make it conformant to the intentions behind the codeing.

then, git-wise here is what you need to do:

  git checkout <bad commit SHA1> -b CULPRIT

this will create a "CULPRIT" branch. I always keep this one as a reference as you may need to perform many tedious itteration of the following steps. As a sidenote, keeping partial references along the way help (as branches or tags).

  git reset HEAD^ --mixed

this will undo the commit as if all the changes from the commit were applied as patch of unstaged changes to the previous commit. Then using

  git add --patch

you can change a subset of those changes. Do not hesitate to use the [s]plit option to singly pick the changes line by line. Sometimes, you can't avoid an edition to hand pick the changes you want. And restage as multiple commits broken down in the NEW,RFG,CHG,FIX scheme I suggest above and rewrite as many commits as you want.

Be mindful of:

  • staging a new commit that do not compile
  • staging a new commit that produce "trivial" runtime error (such as segfault for example)
  • sub commits that needs to be combined to make the thing work

...because the goal is to make bisect work. Furthermore, ensure your new commits are the same as the old commit by git diff the new HEAD commit againts CULPRIT to ensure you did not introduced further changes.

This is a pain at first and requires a lot of practice but once you become good enough at doing this, you will become a debugging god to be worshipped by your whole team and then can spread the gospel of small commits in the form of NEW,CHG,RFG and FIX.

这篇关于如何调试大型git提交?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆