2013-02-21 95 views
4

情况:我有一个旧的提交,我需要有选择地合并最新的提交。有些文件没有变化,其他文件有重大变化,我需要审查和选择合并。文件在提交之间改变,但限制文件列表更旧提交

比方说,旧承诺1有文件A,B,C

最新提交5已经涉及改变文件BC因为犯1也加入文件DEF

所以承诺之间15文件BC发生了变化,也就是上运行1:B5:Bdiff;并在1:C5:C会显示差异。

我需要获取文件名BC只有

也就是说,所有文件不属于1,但更改或添加,直到包括5应该显示出来。

+0

你应该弄清楚“commit'1'有文件'A','B','C'”意味着:只有在提交'1'时它们出现在树中,或者它们改变了承诺提交'1'。 我假设后者,而@Michael Wild和@hlovdal的答案则假设前者。 – tanius 2014-03-02 01:10:31

回答

2

你可以尝试

git diff --diff-filter=M 1 5 

可用过滤器

  • A:新增
  • C:复制
  • D:删除
  • M:修改
  • R:更名为
  • T:类型已变更(符号链接,普通文件等)
  • U:取消合并
  • X:未知
  • B:配对破

参考git-diff(1)所有细节的手册页。

编辑

如果您有兴趣两次提交之间有什么改变如何,您还可以使用--name-status选项,这对于每一个文件,改变输出上面代码中的一个。该选项还可以与git-log一起使用,告诉您对每个提交的文件进行了哪些类型的更改。

+0

对不起,它毕竟不工作(在脚本中使用另一个命令,只是打印提交“1”的内容,并认为这是输出)。 – LetMeSOThat4U 2013-02-21 17:00:06

+0

无论我使用的是git diff --diff-filter 1 5还是git diff --diff-filter 5 1,它仍然显示所有修改过的文件,并且不会将输出限制为较早提交的内容。 – LetMeSOThat4U 2013-02-21 17:01:01

+0

我觉得你在'--diff-filter = M'结尾缺少'= M'。 – 2013-02-21 17:05:51

1

只考虑了存在于提交1的文件,运行

$ git ls-tree --name-only commit1 | xargs git diff commit1 commit5 -- 

注意,这将包括存在于提交1但删除了提交5(这将显示为已删除的文件文件中的差异)。如果你想避免这种情况,查找文件的公共子集:

$ git ls-tree --name-only commit1 > all-files-in-commit1 
$ git ls-tree --name-only commit5 > all-files-in-commit5 
$ comm -1 -2 all-files-in-commit1 all-files-in-commit5 > common-files 
$ xargs git diff commit1 commit5 -- < common-files 
+0

没有这该死的工作... 看到这样的输出:http://pastie.org/6347702 – LetMeSOThat4U 2013-02-27 13:51:30

+0

这些数字是无关的。 'git ls-tree ce7dece ...'显示299,因为这是当您签出提交时存在多少个文件。 'git show ce7dece ...'显示16,因为这是与父提交相比更改的文件数。 – hlovdal 2013-02-27 14:23:58

0

尝试(使用的SHA 15在你的例子):

git diff 1 5 $(git diff --raw --no-commit-id --name-only -r 1~1 1) 

或者更舒适,所以你只需要键入每个SHA一次:

c1="1"; c2="5" 
git diff $c1 $c2 $(git diff --raw --no-commit-id --name-only -r $c1~1 $c1) 

它是如何工作的:第一个git diff比较两个提交。第二个生成限制比较的路径列表。该列表是通过比较在较早的提交$c1与其父代$c1~1之间更改的文件而生成的。 (此规定有点像第十一次提交使用c1="HEAD~10"时也适用,因为HEAD~10~1是一个有效的树十岁上下的混帐,相当于HEAD~11

子shell使用git diff --raw ALS的工作为合并提交。否则,我们可以使用git diff-tree --no-commit-id --name-only -r $c1,它会自动将提交与其父项进行比较。

TODO:尚未完全实用。有时它工作,有时我得到“致命的:模棱两可的论点”<文件名>':未知的版本或路径不在工作树中。“

0

假设您的“最新提交”5您参考HEAD,您也可以为您的任务使用这种不同的策略。我发现它是迄今为止最可行:

  1. 应用从旧的更改提交到暂存区域,没有提交(-n = --no-commit):

    git cherry-pick -n <commit> 
    
  2. Unstage所有的变化你刚才提出:

    git reset 
    
  3. 比较一下这些变化,相对于上次提交:

    git diff HEAD 
    
  4. 有选择性地添加你想要的改变:

    git add -p 
    
  5. ,最终使新的承诺:

    git commit -m "commit message" 
    

来源:this answer改编。