我从主分支创建了一个名称为xyz的分支,我进行了约1000次提交,并且可能修改了xyz分支中的20个文件。现在我想列出我在xyz分支中修改过的所有文件。
以下命令列出了在两个分支中都修改过的文件。
git diff --name-only master...xyz
我从主分支创建了一个名称为xyz的分支,我进行了约1000次提交,并且可能修改了xyz分支中的20个文件。现在我想列出我在xyz分支中修改过的所有文件。
以下命令列出了在两个分支中都修改过的文件。
git diff --name-only master...xyz
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
那么*
就是合并基础提交,Z
是master
分支上的尖端提交,3X
是xyz
分支上的尖端提交,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
在字母表中介于F
和X
之间。因为X
代表xyz
,所以我将T
更改为Z
,这样它就会排在X
之后。总体思路是,我们对大多数仅存在于master
上的提交不感兴趣,除非是由名称master
选择的顶部提交。
4如果F
到X
链中的任何提交都是合并提交,则git log
在不添加其他选项的情况下根本不会尝试进行差异比较。也就是说,当需要对合并进行差异比较时,git log
会跳过它们,除非您要求组合差异(-c
或--cc
)或拆分合并(-m
)。这三个选项都有缺点,因此最好一开始就避免合并情况。
正如 @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
git log
,但不适用于 git diff
,它(滥用)两个和三个点符号表示法用于其他目的。特别是 git diff X...Y
意味着 git diff $(git merge-base X Y) Y
,而 git diff X..Y
意味着 git diff X Y
。git diff
不会查看中间提交记录。(如果没有合并基础或者有多个合并基础,则三个点符号表示法也容易出现另一个问题。) - torekxyz
分支中特定文件所做的更改,可以使用 git log -p develop..xyz -- path/to/file
命令。这将列出所有从 xyz
(但不包括 develop
)修改了 path/to/file
的提交以及差异本身(-p
代表“补丁”)。请在您认为未修改的文件中尝试此操作。 - guccegit diff
与点符号不兼容。在这种情况下,我建议使用git log --oneline --name-only develop..xyz | sort | uniq
,它将首先列出缩短的提交哈希和消息,然后列出所有已更改的文件。 - gucce--pretty=""
而不是--online
来仅显示文件:git log origin..HEAD --name-only --pretty="" | sort | uniq
- olvlvl
master...xyz
语法用于diff(而不是log
)应该会给出你所需的内容。如果您认为它给出了错误的结果,能否提供一个最小的示例? - max630