【问题标题】:Files changed between commits but with limiting file list to older commit文件在提交之间更改,但文件列表仅限于较旧的提交
【发布时间】:2013-02-06 17:32:41
【问题描述】:

情况:我有一个旧的提交,我需要有选择地与最新的提交合并。有些文件没有更改,而其他文件有重大更改,我需要有选择地查看和合并。

假设旧的提交 1 有文件 ABC

最新的提交 5 涉及更改文件 BC 自提交 1 并添加文件 DEF

所以在提交15之间,文件BC发生了变化,即在1:B5:B上运行diff;在1:C5:C 上会显示差异。

我只需要获取文件名BC

也就是说,所有不属于1但在5之前更改或添加的文件都应该显示出来。

【问题讨论】:

  • 你应该澄清什么“提交1有文件ABC”意味着:只有当提交1时它们存在于树中,或者对它们的更改是在提交1 中提交的。我假设后者,而@Michael Wild 和@hlovdal 的回答假设前者。

标签: git merge diff


【解决方案1】:

你可以试试

git diff --diff-filter=M 1 5

可用的过滤器是

  • A:已添加
  • C:已复制
  • D:已删除
  • M:修改
  • R:改名了
  • T:类型已更改(符号链接、常规文件等)
  • U: 未合并
  • X:未知
  • B: 配对中断

有关所有详细信息,请参阅git-diff(1) 手册页。

编辑

如果您对两次提交之间的what 更改如何 感兴趣,您还可以使用--name-status 选项,该选项对于每个更改的文件都会输出上述内容之一代码。此选项也可以与 git-log 一起使用,告诉您每次提交对哪些文件进行了何种类型的更改。

【讨论】:

  • 很抱歉它根本不起作用(在脚本中使用了另一个命令,该命令只打印了提交“1”的内容并认为这是输出)。
  • 无论我使用的是 git diff --diff-filter 1 5 还是 git diff --diff-filter 5 1 它仍然会显示所有修改过的文件,并且不会将输出限制为旧提交的内容。
  • 我认为您在--diff-filter=M 末尾缺少=M
  • 不,我只是打错了示例命令,这是我的实际命令: git diff --diff-filter=M ce7dece9f43ced88325e12cf8b72cb324a14ac73 HEAD --name-status 。我还尝试了颠倒 sha 和 HEAD 的顺序并得到相同数量的文件。
  • 尝试将--name-status 放在提交之前,就在diff-filter=M 之后。提交参数的顺序无关紧要,因为您只是询问哪些文件不同。如果您遗漏了--name-status,它将翻转差异的左侧和右侧。要确认它确实在工作,请验证 only 状态为 M 的文件是否显示。然后用--diff-filter=ACDRT' and check that you **don't** get files with status M`运行。
【解决方案2】:

要仅考虑提交 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

【讨论】:

  • 这些数字无关。 git ls-tree ce7dece... 显示 299,因为这是您签出该提交时存在的文件数。 git show ce7dece... 显示 16,因为这是与父提交相比更改的文件数。
【解决方案3】:

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

  1. 将旧提交中的更改应用到暂存区域,无需提交 (-n = --no-commit):

    git cherry-pick -n <commit>
    
  2. 取消暂存您刚刚所做的所有更改:

    git reset 
    
  3. 比较这些更改是什么,相对于您的上次提交:

    git diff HEAD
    
  4. 有选择地添加您想要的更改:

    git add -p
    
  5. 最后进行新的提交:

    git commit -m "commit message"
    

来源:改编自this answer

【讨论】:

    【解决方案4】:

    尝试(在您的示例中使用 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 在git 中是一个有效的树状结构,相当于HEAD~11。)

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

    TODO:尚未完全发挥作用。有时它有效,有时我得到“致命:模糊参数'':未知修订或路径不在工作树中。”

    【讨论】:

      猜你喜欢
      • 2014-10-23
      • 2015-05-01
      • 2021-09-23
      • 2010-12-05
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 2016-10-16
      • 2019-12-07
      相关资源
      最近更新 更多