使用 git 日志显示合并期间更改的文件
Using git log to display files changed during merge
我正在执行以下命令:
git log --name-only –pretty="format:%H %s" -- *.sql --grep="JIRA-154"
其中 returns 的结果格式为:
[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 log
:
时使用 --first-parent -m
选项
git log --name-only --grep="JIRA-154" --first-parent -m –-pretty="format:%H %s" -- "*.sql"
这将告诉 Git 将 onlg 集中在合并发生的主分支上,仅显示此提交的文件集。
TL;DR
尝试将 -m
选项添加到 git log
选项。这使得每次合并 Git "split",因此它将比较合并 两次 ,一次针对每个 parent。如果没有这个或其他类似的选项,git log
会找到合并但根本不会查看它们的内部。
此外,作为ElpieKay commented,您需要将--grep=<regexp>
放在--
之前。写 "*.sql"
也可能是个好主意,即带引号,以防止 shell 扩展星号本身(细节因 shell 而异,取决于是否您当前的工作目录中有 *.sql
个文件。
长版
如Tim Biegeleisen said,问题源于合并提交的性质。
通常,为了向您展示提交中的更改,Git 运行 是一个简单的 git diff <em>parent</em> <em>self</em>
,其中 parent
和 self
分别是提交的 parent 和提交本身。 git log
和 git show
都以略有不同的方式和略有不同的情况执行此操作。最明显的是 git show
默认每次都显示差异,但 git log
仅在给定 -p
或各种差异控制选项之一(例如 --name-only
时显示差异.
合并不同
一个合并提交是一个有两个1parent的提交。这意味着 git log
和 git show
必须 运行 两个 git diff
命令。2 事实上,git show
做了 运行 两个差异,但随后——默认情况下——将它们变成了 combined diff, which shows only those files whose merge-commit version differs from both parents。但是无论出于什么原因,3 git log
默认情况下不会这样做。
即使 git log
显示差异,它在合并时的表现也特别奇怪(我什至可以说很糟糕)。虽然 git log -p
或 git log --name-status
运行 是常规提交的(单个)差异,但它 根本 运行 差异 具有多个可见 parents 的提交,除非 你强迫它。
单独使用 -m
总能奏效。这个标志基本上告诉 git log
(和 git show
)分解 合并成多个单独的 "virtual commits"。也就是说,如果提交 M 是与 parents P1 和 P2 的合并,然后——至少为了差异的目的——Git 就像有一个提交 MP1 和 parent P1,第二个提交 MP2 parent P2。你得到 两个 差异(以及差异 headers 中的两个提交 ID)。
添加 --first-parent
告诉 git log
忽略合并的第二个(和任何附加的)parent,只剩下一个 parent。这意味着 git log
根本不会跟随边 b运行ch 。因此,您可以使用 -m --first-parent
,前提是您对源自合并另一方的历史记录不感兴趣。这使您仅针对 firstparent 进行一次差异化,而不是针对每个 parent.
进行一次差异化
(哪个 parent 是 第一个? 好吧,这是你 HEAD
当你 运行 git merge
. 这通常是提交的 "main line",即那些 "on your branch"。但是如果你的小组随便使用 git pull
,你可能 不想 忽略合并的另一面,因为 git pull
将其他人的 main-line 工作变成 "foxtrot merges" 的小面 b运行ches。)
再次合并差异
除了 -m
,您还可以提供 -c
或 --cc
(注意 -c
有一个破折号,而 --cc
有两个 4) 到 git log
以使其产生组合差异,就像 git show
一样。但是,与所有组合差异一样,这会忽略合并提交和 parent 之间匹配的文件。也就是说,再次给定相同的合并 M,这次 Git 比较 M 与 P1,以及 M 对比 P2。对于任何文件 F,其中 M:F 与 P1:F 或 P2:F, Git 什么都没显示。
事实证明,这通常就是您想要的。如果提交 M 中的文件 F 与两个 parent 提交之一中的文件 F 匹配,这意味着文件 来自 而 parent。事实上 F in P1 可能与 F in P2 不匹配=] 通常并不有趣:P1 或 P2 中 F 的任何变化都可能是结果一些早期历史变化,这是我们应该注意的地方,而不是在合并时M.
无论如何,这就是组合差异背后的逻辑。它并非在所有情况下都适用,这就是 -m
存在的原因:"split up" 合并到其组成部分。
1实际上是两个或更多,但是"more"是不寻常的;大多数合并提交恰好有两个 parent。具有两个以上 parent 的合并提交称为章鱼合并.
2git log
和 git show
都内置了大部分 git diff
,因此它们实际上不必 运行 额外的命令,但两种方式的结果都是一样的。
3我不知道原因,我只是在查看 git log
源代码时才了解到这种特殊行为,试图解释为什么 git log --name-status
没有显示任何东西。
4这是因为--cc
是一个长选项,在GNU选项解析中,所有长选项如name-only
或 cc
得到 两个 破折号,而所有 短 (一个字母)选项如 p
得到 一个破折号。
我正在执行以下命令:
git log --name-only –pretty="format:%H %s" -- *.sql --grep="JIRA-154"
其中 returns 的结果格式为:
[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 log
:
--first-parent -m
选项
git log --name-only --grep="JIRA-154" --first-parent -m –-pretty="format:%H %s" -- "*.sql"
这将告诉 Git 将 onlg 集中在合并发生的主分支上,仅显示此提交的文件集。
TL;DR
尝试将 -m
选项添加到 git log
选项。这使得每次合并 Git "split",因此它将比较合并 两次 ,一次针对每个 parent。如果没有这个或其他类似的选项,git log
会找到合并但根本不会查看它们的内部。
此外,作为ElpieKay commented,您需要将--grep=<regexp>
放在--
之前。写 "*.sql"
也可能是个好主意,即带引号,以防止 shell 扩展星号本身(细节因 shell 而异,取决于是否您当前的工作目录中有 *.sql
个文件。
长版
如Tim Biegeleisen said,问题源于合并提交的性质。
通常,为了向您展示提交中的更改,Git 运行 是一个简单的 git diff <em>parent</em> <em>self</em>
,其中 parent
和 self
分别是提交的 parent 和提交本身。 git log
和 git show
都以略有不同的方式和略有不同的情况执行此操作。最明显的是 git show
默认每次都显示差异,但 git log
仅在给定 -p
或各种差异控制选项之一(例如 --name-only
时显示差异.
合并不同
一个合并提交是一个有两个1parent的提交。这意味着 git log
和 git show
必须 运行 两个 git diff
命令。2 事实上,git show
做了 运行 两个差异,但随后——默认情况下——将它们变成了 combined diff, which shows only those files whose merge-commit version differs from both parents。但是无论出于什么原因,3 git log
默认情况下不会这样做。
即使 git log
显示差异,它在合并时的表现也特别奇怪(我什至可以说很糟糕)。虽然 git log -p
或 git log --name-status
运行 是常规提交的(单个)差异,但它 根本 运行 差异 具有多个可见 parents 的提交,除非 你强迫它。
单独使用 -m
总能奏效。这个标志基本上告诉 git log
(和 git show
)分解 合并成多个单独的 "virtual commits"。也就是说,如果提交 M 是与 parents P1 和 P2 的合并,然后——至少为了差异的目的——Git 就像有一个提交 MP1 和 parent P1,第二个提交 MP2 parent P2。你得到 两个 差异(以及差异 headers 中的两个提交 ID)。
添加 --first-parent
告诉 git log
忽略合并的第二个(和任何附加的)parent,只剩下一个 parent。这意味着 git log
根本不会跟随边 b运行ch 。因此,您可以使用 -m --first-parent
,前提是您对源自合并另一方的历史记录不感兴趣。这使您仅针对 firstparent 进行一次差异化,而不是针对每个 parent.
(哪个 parent 是 第一个? 好吧,这是你 HEAD
当你 运行 git merge
. 这通常是提交的 "main line",即那些 "on your branch"。但是如果你的小组随便使用 git pull
,你可能 不想 忽略合并的另一面,因为 git pull
将其他人的 main-line 工作变成 "foxtrot merges" 的小面 b运行ches。)
再次合并差异
除了 -m
,您还可以提供 -c
或 --cc
(注意 -c
有一个破折号,而 --cc
有两个 4) 到 git log
以使其产生组合差异,就像 git show
一样。但是,与所有组合差异一样,这会忽略合并提交和 parent 之间匹配的文件。也就是说,再次给定相同的合并 M,这次 Git 比较 M 与 P1,以及 M 对比 P2。对于任何文件 F,其中 M:F 与 P1:F 或 P2:F, Git 什么都没显示。
事实证明,这通常就是您想要的。如果提交 M 中的文件 F 与两个 parent 提交之一中的文件 F 匹配,这意味着文件 来自 而 parent。事实上 F in P1 可能与 F in P2 不匹配=] 通常并不有趣:P1 或 P2 中 F 的任何变化都可能是结果一些早期历史变化,这是我们应该注意的地方,而不是在合并时M.
无论如何,这就是组合差异背后的逻辑。它并非在所有情况下都适用,这就是 -m
存在的原因:"split up" 合并到其组成部分。
1实际上是两个或更多,但是"more"是不寻常的;大多数合并提交恰好有两个 parent。具有两个以上 parent 的合并提交称为章鱼合并.
2git log
和 git show
都内置了大部分 git diff
,因此它们实际上不必 运行 额外的命令,但两种方式的结果都是一样的。
3我不知道原因,我只是在查看 git log
源代码时才了解到这种特殊行为,试图解释为什么 git log --name-status
没有显示任何东西。
4这是因为--cc
是一个长选项,在GNU选项解析中,所有长选项如name-only
或 cc
得到 两个 破折号,而所有 短 (一个字母)选项如 p
得到 一个破折号。