使用git日志显示合并期间更改的文件

使用git日志显示合并期间更改的文件,git,merge,git-log,Git,Merge,Git Log,我正在执行以下命令: git log --name-only –pretty="format:%H %s" -- *.sql --grep="JIRA-154" 以以下格式返回结果: [commitid1] [comment] path/to/file1/file1.sql path/to/file2/file2.sql path/to/file3/file3.sql [commitid2] [comment] path/to/file2/file2.sql path/to/file4/fi

我正在执行以下命令:

git log --name-only –pretty="format:%H %s" -- *.sql --grep="JIRA-154"
以以下格式返回结果:

[commitid1] [comment]
path/to/file1/file1.sql
path/to/file2/file2.sql
path/to/file3/file3.sql

[commitid2] [comment]
path/to/file2/file2.sql
path/to/file4/file4.sql
输出被重定向到一个文件,格式正是我想要的,但是合并提交是一个问题。作为合并的一部分而更改的文件永远不会列出。相反,我最终得到了如下结果:

[commitid3] [merge comment]
[commitid4] [comment]
path/to/file3/file3.sql

我显然误解了这里的某些内容,因为我希望看到在合并过程中更改的文件。有没有办法将这些文件包括在输出中?

您观察到这种行为的原因是,在合并提交的情况下,有两组已更改的文件,其中一组来自每个父级。这里的一个选项是在运行
git日志时使用
--first parent-m
选项:

git log --name-only --grep="JIRA-154" --first-parent -m –-pretty="format:%H %s" -- "*.sql"
这将告诉Git只关注正在进行合并的主分支,只显示此提交的文件集

查看文档和一篇精彩的博客文章。

TL;博士 尝试将
-m
选项添加到
git日志
选项中。这使得Git对每个合并进行“拆分”,这样它将对合并进行两次区分,一次针对每个父级。如果没有此选项或其他类似选项,
git log
将查找合并,但甚至不查看它们的内部

同样,您需要将
--grep=
放在
--
之前。编写
“*.sql”
(即使用引号)也可能是一个好主意,以防止shell本身扩展星号(详细信息因shell而异,取决于当前工作目录中是否有
*.sql
文件)

长版本 如前所述,问题源于合并提交的性质

通常,为了向您展示提交中的更改,Git运行一个简单的
Git diff parent self
,其中
parent
self
分别是提交的父级和提交本身。
git-log
git-show
都是以稍微不同的方式和在稍微不同的环境下执行此操作的。最明显的是,
git show
默认每次显示一个diff,但是
git log
仅在给定
-p
或各种diff控制选项(如
--name only
)时才执行diff

合并是不同的 合并提交是具有两个1父级的提交。这意味着
git-log
git-show
必须运行两个
git-diff
命令。2事实上,
git-show
确实运行两个diff,但默认情况下会将它们转换为一个。但无论出于何种原因,3
git log
在默认情况下都不会这样做

即使当git log
显示差异时,它在合并时的行为也特别奇怪(我甚至可以说很糟糕)。虽然
git log-p
git log--name status
在常规提交时运行(单个)差异,但在具有多个可见父级的提交时,它根本不会运行差异,除非您强制它

单独使用
-m
总是有效的。该标志本质上告诉
git log
(和
git show
)将合并分解为多个单独的“虚拟提交”。也就是说,如果commit M是与父P1和P2的合并,那么出于区分的目的,至少Git的行为就好像存在与父P1的commit MP1和与父P2的第二commit MP2一样。您将获得两个差异(在差异头中有两个提交ID)

添加
--第一个父项
告诉
git log
忽略合并的第二个(以及任何其他)父项,这使合并只剩下一个父项。这意味着,
git log
根本不会跟随分支。因此,如果您对源自合并其他方面的历史不感兴趣,那么可以使用
-m--第一个父级。这将使您仅针对第一个父级获得一个差异,而不是每个父级获得一个差异

(哪一个父级是第一个?嗯,当您运行
git merge
时,它是您的
头。这通常是提交的“主线”,即“在您的分支上”。但是如果您的团队随意使用
git pull
,您可能不想忽略合并的另一面,因为
git pull
将其他人的主线工作变成了一系列小分支。)

又是组合差异 除了
-m
,您还可以将
-c
-cc
(注意
-c
有一个破折号,而
-cc
有两个破折号)提供给
git log
,以使其产生组合的差异,就像
git show
一样。但是,与所有组合的差异一样,这会忽略合并提交和任一父级之间匹配的文件。也就是说,再次给定相同的合并M,这次Git比较M与P1,以及M与P2。对于M:F与P1:F或P2:F相同的任何文件F,Git根本不显示任何内容

事实证明,这通常是你想要的。如果commit M中的文件F与两个父提交之一中的文件F匹配,则表示该文件来自该父提交。P1中的F可能与P2中的F不匹配这一事实通常并不有趣:P1或P2中F的任何变化都可能是历史上某些早期变化的结果,这就是我们应该注意的地方,而不是在merge M

无论如何,这就是组合差异背后的逻辑。它并不适用于所有情况,这就是为什么存在
-m
:将合并“拆分”为其组成部分


实际上是两个或更多,但“更多”是不寻常的;大多数合并提交只有两个父级。具有两个以上父级的合并提交称为octopus合并

2
git log
git show
都内置了大部分
git diff
,因此它们实际上不必运行额外的命令,但两者的效果都是一样的

3我不知道原因,a