如何列出特定分支中所有已更改的文件?

13

我从主分支创建了一个名称为xyz的分支,我进行了约1000次提交,并且可能修改了xyz分支中的20个文件。现在我想列出我在xyz分支中修改过的所有文件。

以下命令列出了在两个分支中都修改过的文件。

git diff --name-only master...xyz

git diff --name-only master xyz请返回修改的文件名列表。 - LeGEC
根据git diff文档master...xyz语法用于diff(而不是log)应该会给出你所需的内容。如果您认为它给出了错误的结果,能否提供一个最小的示例? - max630
2个回答

11
这里的根本问题是git diff比较的是两个特定的提交。1无论你给它什么参数,它仍然会选择两个具体的提交进行比较。2 这意味着要让git diff显示某个分支中所做的更改,必须选择该分支内的两个提交: 一个称为“起始点”,一个称为“结束点”。如果您选择这样做,通常最好绘制提交图。您可以手动执行此操作,也可以使用git log --oneline --graph来协助完成。(查看两个分支之间的此图形的一种好方法是git log --oneline --graph --decorate --boundary master...xyz。)另一种方法是尝试自己绘制图形,这样可以更简洁地表示它,或者使用gitk或其他一些图形查看器来绘制图形。
如果在master分支上的尖端提交和xyz分支上的尖端提交之间存在单个合并基础提交,则:
git diff --name-only master...xyz

我将比较特定的合并基和分支XYZ的最新提交,并列出已修改的文件名称。也就是说,如果图形看起来像这样:

          o--o--o--o--...--o--Z   <-- master
         /
...--o--*
         \
          F--G-...--X             <-- xyz

那么*就是合并基础提交,Zmaster分支上的尖端提交,3Xxyz分支上的尖端提交,git diff master...xyz将比较提交*与提交X。(相比之下,git diff master..xyz——注意这里有两个点而不是三个——将会比较提交Z与提交X。)

考虑到 git diff --name-only master...xyz 不能显示您想要的内容,您可能需要使用 git log --name-only master..xyz(可能还需要使用 --oneline;我也看到 gucce 将此作为评论添加),以显示在 xyz 中存在但不在 master 中的每个提交中发生了什么。也就是说,在上面的图中,这将对比提交 * 和提交 F,然后对比提交 F 和提交 G,以此类推,直到与提交 X 进行比较。请注意,这是使用 git log 内置的能力来将每个提交与其父提交进行对比。4


1它还可以将一个提交与索引比较,或将一个提交与工作树比较,或将索引与工作树比较。在另一种模式下,它可以用于比较两个特定的文件,其中任何一个或两者都不需要存储在仓库中,但这与您想要使用它的方式有很大不同。

2这也有点夸张:通过给git diff提供多个提交对,您可以让它生成所谓的合并差异。这通常用于合并提交,以显示合并内容与所有父提交不同的点,即解决合并冲突时选择了其他内容而不是“一个分支中的内容”。但是,与您想要实现的目标相比,这也走得太远了。

3我曾将此命名为T,代表“主分支的顶端”,但后来意识到T在字母表中介于FX之间。因为X代表xyz,所以我将T更改为Z,这样它就会排在X之后。总体思路是,我们对大多数仅存在于master上的提交不感兴趣,除非是由名称master选择的顶部提交。

4如果FX链中的任何提交都是合并提交,则git log在不添加其他选项的情况下根本不会尝试进行差异比较。也就是说,当需要对合并进行差异比较时,git log会跳过它们,除非您要求组合差异(-c--cc)或拆分合并(-m)。这三个选项都有缺点,因此最好一开始就避免合并情况。


6

正如 @torek 所指出的那样,git diff 命令完全忽略点符号。

因此,以下命令应该会得到期望的结果:

git log --oneline --name-only develop..xyz | sort | uniq

输出结果大致如下,修改的文件在最后:

0871be6 commit 1
9caad09 commit 2
bb714f0 commit 3
...
path/to/file1
path/to/file2
path/to/file3
path/to/file4

注意,这里只有两个点。这表示要考虑所有在xyz中但不在develop中的修订。

使用三个点将使用仅在两个分支之一中独有的所有修订,而不是在两者中都有的修订。

参考:https://git-scm.com/book/tr/v2/Git-Tools-Revision-Selection#Commit-Ranges


我也尝试过这个,它列出了在xyz分支中我没有修改过的文件。 - Vivek Nuna
这对于所有其他 Git 命令是正确的,特别是 git log,但不适用于 git diff,它(滥用)两个和三个点符号表示法用于其他目的。特别是 git diff X...Y 意味着 git diff $(git merge-base X Y) Y,而 git diff X..Y 意味着 git diff X Ygit diff 不会查看中间提交记录。(如果没有合并基础或者有多个合并基础,则三个点符号表示法也容易出现另一个问题。) - torek
也许您不小心在末尾添加了一个新行,或者更改了行结尾。要验证在您的 xyz 分支中特定文件所做的更改,可以使用 git log -p develop..xyz -- path/to/file 命令。这将列出所有从 xyz(但不包括 develop)修改了 path/to/file 的提交以及差异本身(-p 代表“补丁”)。请在您认为未修改的文件中尝试此操作。 - gucce
正如@torek所指出的那样,git diff与点符号不兼容。在这种情况下,我建议使用git log --oneline --name-only develop..xyz | sort | uniq,它将首先列出缩短的提交哈希和消息,然后列出所有已更改的文件。 - gucce
2
谢谢大家!我使用--pretty=""而不是--online来仅显示文件:git log origin..HEAD --name-only --pretty="" | sort | uniq - olvlvl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接