TL;DR
尝试将-m 选项添加到git log 选项。这使得 Git 每次合并都会“拆分”,因此它会将合并差异 两次,一次针对每个父级。如果没有此选项或其他类似选项,git log 会找到合并,但根本不会查看它们内部。
另外,作为ElpieKay commented,您需要将--grep=<regexp> 放在-- 之前。写"*.sql" 也可能是个好主意,即用引号,以防止您的外壳扩展星号本身(详细信息因外壳而异,取决于您当前的外壳中是否有任何*.sql 文件工作目录)。
加长版
作为Tim Biegeleisen said,问题源于合并提交的性质。
通常,为了向您展示提交中发生了什么变化,Git 运行一个简单的git diff <em>parent</em> <em>self</em>,其中 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。但无论出于何种原因,3git log 默认不这样做。
即使git log 显示差异,但它在合并时的行为特别奇怪(我什至可能说不好)。虽然git log -p 或git log --name-status 在常规提交上运行(单个)差异,但它根本不运行差异 在具有多个可见父级的提交上,除非你强迫它。
单独使用-m 总是有效的。这个标志本质上是告诉git log(和git show)将一个合并分解成多个单独的“虚拟提交”。也就是说,如果提交 M 是与父级 P1 和 P2 的合并,那么——至少出于差异的目的——Git 充当尽管有一个带有父 P1 的提交 MP1,以及带有父 P2 的第二个提交 MP2。您会得到 两个 差异(以及差异标头中的两个提交 ID)。
添加--first-parent 告诉git log 忽略合并的第二个(以及任何其他)父级,从而只留下一个父级。这意味着git log 根本不会跟随分支。因此,您可以使用-m --first-parent,前提是您对源自合并其他方面的历史不感兴趣。这会让你只针对 first 父级的单个差异,而不是每个父级一个差异。
(哪个父级是第一个?嗯,当您运行git merge 时,它就是您的HEAD。这通常是提交的“主线”,即那些“on你的分支”。但如果你的团队随便使用git pull,你可能不想忽略合并的另一面,因为git pull将其他人的主线工作变成"foxtrot merges"小侧枝。)
再次合并差异
除了-m,您还可以将-c 或--cc(注意-c 有一个破折号,而--cc 有两个4)提供给git log产生一个组合差异,就像git show。但是,与所有组合差异一样,这会忽略合并提交和任一父级之间匹配的文件。也就是说,再次给定相同的合并M,这次Git比较M vs P1,以及M vs P2。对于任何 M:F 与 P1:F 或 P2:F 相同的文件 F,Git什么都不显示。
事实证明,这通常是您想要的。如果提交 M 中的文件 F 与两个父提交之一中的文件 F 匹配,则意味着文件 来自 那个家长。 P1 中的 F 可能与 P2 中的 F 不匹配这一事实通常并不有趣:P1 或 P2 中的 >F 可能是历史上一些较早变化的结果,这就是我们应该注意的地方它,而不是在合并 M.
无论如何,这就是组合差异背后的逻辑。它并非在所有情况下都适用,这就是 -m 存在的原因:将合并“拆分”为其组成部分。
1实际上是两个或更多,但“更多”是不寻常的;大多数合并提交恰好有两个父级。具有两个以上父级的合并提交称为 octopus 合并。
2git log 和 git show 都内置了大部分 git diff,因此它们实际上不必运行其他命令,但无论哪种方式都一样.
3我不知道原因,我只是在查看git log 源时才知道这种特殊行为,试图解释为什么git log --name-status 没有显示任何内容。
4这是因为--cc是一个long选项,而在GNU选项解析中,所有像name-only或cc这样的长选项都会得到两个 破折号,而所有短(一个字母)选项,如p 得到一个 破折号。