找出我们试图挑选的提交的依赖关系

时间:2017-02-07 20:46:05

标签: git git-branch git-diff git-log git-cherry-pick

假设如下内容:

                            HEAD/master     
                             |
A<--B<--C<--D<--E<--F<--G<--J  
        ^
        official 

其中official是分支。
我想向official分支挑选2个提交,例如EJ
这两个提交都是影响相同3个文件的修复 当我做git cherry-pick E时它很顺利,但当我git cherry-pick J时,我发生了一些冲突 看看差异,我意识到我还需要提交提交F,它对这3个文件中的两个进行了更改,这些更改基本上是方法定义更改,J在此之上完成。
因此只需执行git cherry-pick F && git cherry-pick J
就可以轻松解决问题 问:
如果我不知道在这些文件中完成的更改并且提交F是一个很大的提交更改了许多文件:是否有另一种方法来确定我们尝试提取的提交依赖于没有手动执行git日志的提交在文件上并通过提交进行提交?

2 个答案:

答案 0 :(得分:2)

  

是否有另一种方法可以找出我们要尝试选择的提交依赖于哪个提交而无需手动在文件上执行git日志并通过提交进行提交?

是的-我写了git-deps来精确地完成该任务。由于它当前接受要分析的一系列提交,因此在您的示例中,您需要将仅提交J的单例范围传递给它,并且还告诉它排除{{1 }}:

official

在后台,该工具将查看git deps --exclude-commits official J^! J^的差异,然后在被删除或修改的任何行上运行J,以及可配置的行数周围的环境。这将导致它发现git blame的一行或多行删除或修改了来自提交J的行,因此它将输出提交F的SHA1。

F不仅可以发现单个提交或提交范围的依赖关系,还可以递归整个依赖关系树。因此,您描述的整个选择樱桃的场景可以自动化为一个命令:

git-deps

请注意,这仅保证所有的樱桃小贴士都能干净利落地使用,而不保证它们在语义上是正确的。因此,仍然需要仔细检查和测试最终的分支头的正确性。

在分支之间更方便地移植提交是git deps --recurse --exclude-commits official J^! | \ tsort | \ tac | \ xargs -t git cherry-pick 的最明显(但不是唯一)用例,因此,我有了dedicated a section of the README specifically to this use case。它甚至还包括一个YouTube视频,向您展示了确切的用法。

如果您想了解更多详细信息,您可能会对我在此工具以及其他相关工具上的一些演讲感兴趣:

我也谈到了 episode #32 of the GitMinutes podcast

答案 1 :(得分:0)

  

我遇到了一些[合并]冲突...是否还有另一种方法来确定我们尝试提取的提交取决于...

不是,不。

  

...没有手动对文件执行git日志并通过提交进行提交?

即使这不一定会这样 - 至少,不是没有实际考虑问题。考虑以下C代码:

android-support

假设一个中间提交引入了另一个变量void f(int x) { int i; /* * additional lines here, enough to mess with git context * since that only looks at +/- 3 lines around each patch * segment */ for (i = 0; i < x; i++) do_something(i); } ,然后稍后提交将j更改为do_something(i)。如果您只选择 以后的提交,Git将很乐意更改该行而不会发生冲突,但代码将不再编译,因为函数{{1}中没有do_something(j) }。

也就是说,可以编写一个工具来解析每个中间提交的int j输出,找出哪些行被更改(相对于工作树中的版本,而不是使用实际的数字)在每个差异中,因为这些可能取决于先前跳过的差异),并指向修改冲突的区域的提交。但我不知道任何这样的工具。