我正在执行以下命令:
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
我显然在这里误解了一些东西,因为我希望看到合并期间发生变化的文件。有没有办法在输出中包含这些文件?
答案 0 :(得分:21)
尝试将-m
选项添加到git log
选项中。这使得Git"分裂"每次合并,以便它将合并两次,一次针对每个父项。如果没有这个或其他类似的选项,git log
会找到合并但后来根本看不到它们。
此外,作为ElpieKay commented,您需要将--grep=<regexp>
放在--
之前。编写"*.sql"
(也就是引号)也可能是一个好主意,以防止shell扩展星号本身(细节因shell而异,取决于是否有*.sql
当前工作目录中的文件。)
作为Tim Biegeleisen said,问题源于合并提交的性质。
通常,为了向您展示提交中的更改,Git会运行一个简单的git diff parent self
,其中 parent
和 self
分别是提交的父级和提交本身。 git log
和git show
都以不同的方式和略有不同的情况执行此操作。最明显的是git show
默认每次都显示差异,但git log
仅在给定-p
或其中一种差异控制选项(例如--name-only
)时执行差异
合并提交是一个包含两个 1 父项的提交。这意味着git log
和git show
必须运行两个 git diff
命令。 2 事实上,git show
确实运行了两个差异,但是 - 默认情况下 - 将它们变成combined diff,shows only those files whose merge-commit version differs from both parents。但无论出于何种原因, 3 git log
默认情况下不会这样做。
即使git log
显示差异,但它在合并时表现得特别奇怪(我甚至可能会说很糟糕)。虽然git log -p
或git log --name-status
在常规提交上运行(单个)差异,但在具有多个可见父项的提交上并不运行差异 ,除非你强迫它。
单独使用-m
始终有效。该标志实质上告诉git log
(和git show
)将分解合并为多个单独的虚拟提交&#34;。也就是说,如果提交 M 是与父母 P1 和 P2 的合并,那么 - 为了diff的目的,至少-Git充当虽然有一个提交 MP1 与父 P1 ,另一个提交 MP2 与父 P2 。你得到两个差异(以及差异标题中的两个提交ID)。
添加--first-parent
告诉git log
忽略合并的第二个(以及任何其他)父级,这使得它只有一个父级。这意味着git log
不会跟随所有的旁边分支。因此,您可以使用-m --first-parent
,前提是您对合并的其他方面的历史不感兴趣。这会让你只针对第一个父级而不是每个父级的一个差异。
(哪个家长是第一个?嗯,当你跑HEAD
时,它就是你git merge
的那个。通常情况下,&# #34;提交的主线和#34;即你的分支上的#34;但是如果你的小组随便使用git pull
,你可能不想要忽略合并的另一面,因为git pull
将其他人的主要工作转变为"foxtrot merges"小方分支。)
除了-m
,您可以提供-c
或--cc
(请注意-c
有一个短划线而--cc
有两个 4 )git log
让它产生组合差异,就像git show
一样。但是,与所有组合差异一样,这会忽略合并提交与父级之间匹配的文件。也就是说,再次给出相同的合并 M ,这次Git比较 M vs P1 , M vs < EM> P2 。对于 F 的任何文件,其中 M:F 与 P1:F 或 P2:F 相同,Git什么都没显示。
事实证明,这通常是你想要的。如果提交 M 中的文件 F 与两个父提交之一中的文件 F 匹配,则表示文件来自那个父母。 P1 中 F 与 P2 中 F 不匹配的事实通常并不有趣:中的任何更改 P1 或 P2 中的> F 可能是历史记录中某些早期更改的结果,其中包含我们应该注意它,而不是合并 M 。
无论如何,这是组合差异背后的逻辑。它并不适用于所有情况,这就是-m
存在的原因:&#34;分裂&#34;合并成其组成部分。
1 实际上是两个或两个以上,但是&#34;更多&#34;不寻常;大多数合并提交都有两个父母。具有两个以上父项的合并提交称为章鱼合并。
2 git log
和git show
都内置了大部分git diff
,因此他们实际上不必运行其他命令,但它两种方式都是一样的。
3 我不知道原因,当我浏览git log
来源时,我才了解到这种特殊行为,试图解释原因git log --name-status
没有表现出什么。
4 这是因为--cc
是 long 选项,并且在GNU选项解析中,所有长选项如name-only
或{{1获取两个短划线,而所有短(单个字母)选项(如cc
)获取一个短划线。
答案 1 :(得分:1)