情况:我有一个旧的提交,我需要有选择地与最新的提交合并。某些文件没有更改,其他文件有重大更改,我需要选择性地查看和合并。
假设旧提交1
包含文件A
,B
,C
。
最新提交5
涉及自提交B
以及添加文件C
,1
和{后更改文件D
和E
{1}}。
因此,提交F
和1
文件5
和B
之间已经发生了变化,即C
和{{}上的diff
正在运行1}};并且1:B
和5:B
会显示差异。
我需要获取文件名1:C
和5:C
。
也就是说,所有不属于B
但在C
之前更改或添加的文件都应不显示。
答案 0 :(得分:2)
您可以尝试
git diff --diff-filter=M 1 5
可用的过滤器
A
:已添加C
:已复制D
:已删除M
:已修改R
:已重命名T
:类型已更改(符号链接,常规文件等)U
:未合并X
:未知B
:配对损坏有关所有详细信息,请参阅git-diff(1)
手册页。
修改强>:
如果您对两次提交之间的 更改 感兴趣,还可以使用--name-status
选项,该选项对于每个更改输出的文件以上代码。此选项也可以与git-log
一起使用,告诉您对每个提交的文件所做的更改类型。
答案 1 :(得分:1)
要仅考虑提交1
中存在的文件,请运行
$ git ls-tree --name-only commit1 | xargs git diff commit1 commit5 --
请注意,这将包括提交1中存在但在提交5中删除的文件(将在diff中显示为已删除的文件)。如果您想避免这种情况,请找到文件的公共子集:
$ 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
答案 2 :(得分:0)
尝试(在示例中使用SHA 1
和5
):
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
是git中的有效树,等同于HEAD~11
。)
子shell使用git diff --raw
来进行合并提交。否则我们可以使用git diff-tree --no-commit-id --name-only -r $c1
,它会自动将提交与其父级进行比较。
TODO:尚未完全正常运作。有时它会起作用,有时我会“致命:模棱两可的论证”&lt; filename&gt;':未知的修订或路径不在工作树中。“
答案 3 :(得分:0)
假设您的“最新提交”5
引用HEAD
,您也可以将此不同的策略用于您的任务。到目前为止,我发现它是最可行的:
将旧提交中的更改应用到暂存区域,而不提交(-n
= --no-commit
):
git cherry-pick -n <commit>
取消您刚才所做的所有更改:
git reset
比较这些更改相对于您上一次提交的内容:
git diff HEAD
有选择地添加所需的更改:
git add -p
最后进行新的提交:
git commit -m "commit message"
来源:改编自this answer。