如何“git show"合并提交的差异? [英] How to "git show" the diffs for a merge commit?

查看:66
本文介绍了如何“git show"合并提交的差异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我进行合并提交并运行 git show <commit-ish> 时,它只显示提交日志,而不显示差异:

When I have a merge commit and run git show <commit-ish>, it shows only the commit log, not the the diffs:

commit c0f50178901e09a1237f7b9d9173ec5d1c4936c
Merge: ed234b ded051
Author: abc
Date:   Mon Nov 21 15:56:33 2016 -0800

    Merge branch 'abc'

我知道真正的提交是在合并日志中,但我想节省输入.有没有办法同时显示差异?

I understand the real commit is in merge log, but I want to save typing. Is there a way to show the diff in one?

推荐答案

使用以下方法之一:

git show -m c05f017
git show --first-parent c05f017
git diff c05f017^ c05f017


你的问题有一个基本错误:提交不是差异;提交是快照.这似乎是一种没有区别的区别——对于某些提交,它就是.但是对于合并提交,不是.


There's a fundamental error in your question: commits are not diffs; commits are snapshots. This might seem like a distinction without a difference—and for some commits, it is. But for merge commits, it's not.

git show(或 git log -p)将提交 as 显示为差异时,它是通过 比较将快照提交到其他内容.git diff 命令做同样的事情:它将一个提交与另一个提交进行比较.(或者它可以将提交与工作树、索引的内容或其他一些组合进行比较.)

When git show (or git log -p) shows a commit as a diff, it's doing so by comparing the commit's snapshot to something else. The git diff command does the same thing: it compares one commit to another commit. (Or it can compare a commit to the work-tree, or to the contents of the index, or a few other combinations as well.)

对于普通提交,比较什么是显而易见的:将这个提交的快照与上一个(即父)提交的快照进行比较.所以这就是 git show 所做的(还有 git log -p ):它运行一个 git diff 从父提交到这次提交.

For ordinary commits, it's trivially obvious what to compare: compare this commit's snapshot to the previous (i.e., parent) commit's snapshot. So that is what git show does (and git log -p too): it runs a git diff from the parent commit, to this commit.

不过,合并提交并不只有一个父提交.他们有两个父母.1这就是他们合并提交"的原因.首先:合并提交的定义是至少有两个父项的提交.

Merge commits don't have just one parent commit, though. They have two parents.1 This is what makes them "merge commits" in the first place: the definition of a merge commit is a commit with at least two parents.

1一个合并提交可以有三个或更多的父项.这些被称为章鱼合并".不过,他们并没有做任何特别的事情,主要是为了炫耀.:-) 你可以在这里忽略它们.

1A merge commit can have three or more parents. These are called "octopus merges". They don't do anything special, though, and are mainly for showing off. :-) You can ignore them here.

git log -p 在默认情况下选择做的是根本不进行比较.你可以通过添加各种标志来让它显示一些东西(见下文).

What git log -p chooses to do by default is not to compare at all. You can make it show something by adding various flags (see below).

git show 默认选择做什么比较复杂.由于有两个父节点,git show 首先与第一个父节点"进行比较,2 然后与第二个父节点进行比较.然后——这部分非常关键——它组合两个差异,产生所谓的组合差异".

What git show chooses to do by default is more complicated. Since there are two parents, git show first compares against the "first parent",2 then compares against the second parent. Then—this part is quite crucial—it combines the two diffs, producing a so-called "combined diff".

在下一节中,让我注意一个棘手但非常有用的 Git 语法.如果你有一个像 c05f017 这样的提交 ID,你可以添加一个插入符号或帽子".字符 ^ 之后,命名父提交.您可以选择添加另一个数字来选择哪个父级.对于常规(非合并)提交,只有一个,因此 c05f017^ 父项.对于合并提交,c05f017^c05f017^1 都表示 第一个父级,而 c05f017^2 表示 第二个父母.

For the next section, let me note a tricky, but very useful, bit of Git syntax. If you have a commit ID like c05f017, you can add a caret or "hat" character ^ after that, to name a parent commit. You can optionally add another number to select which parent. For regular (non-merge) commits there's only one, so c05f017^ is the parent. For merge commits, c05f017^ and c05f017^1 both mean the first parent, while c05f017^2 means the second parent.

2我把它放在引号中,因为第一父的想法在 Git 中特别重要,我们稍后会看到.换句话说,Git 最关心哪个父节点是第一,而其余的只是其余的".

2I put this in quotes because the first parent idea is especially important in Git, as we will see in a moment. In other words, Git cares most about which parent is first, while the rest are just "the rest".

组合差异格式在 文档,但首先描述了一个关键位此处,以使其特别晦涩:3

The combined diff format is described in the documentation, but a key bit is first described here, so as to make it especially obscure:3

请注意,combined diff 仅列出从所有父级修改的文件.

Note that combined diff lists only files which were modified from all parents.

也就是说,假设 M 是一个合并提交,并且比较 M^1M 表示文件 mainline.txtcommon.txt 都已更改.进一步假设 M^2M 表示文件 sidebranch.txtcommon.txt 都被更改了.合并后的差异将仅显示 common.txt,跳过 mainline.txtsidebranch.txt 因为这两个文件仅从 一个 父级(每个)被修改.(即使这样,Git 也可能只显示 common.txt 的一些差异.)

That is, suppose M is a merge commit, and diffing M^1 vs M says file mainline.txt and common.txt were both changed. Suppose further that diffing M^2 and M says that file sidebranch.txt and common.txt were both changed. The combined diff will show only common.txt, skipping both mainline.txt and sidebranch.txt because those two files were only modified from one parent (each). (Even then Git may show only some of the diffs for common.txt.)

3我花了很长时间才在文档中找到这个,因为我一直在看其他部分.

3It took me a long time to find this in the documentation, as I kept looking at the other section.

-m 选项——m 在这里可能代表 merge——告诉 Git 实际上拆分"合并.也就是说,与其尝试将针对每个父级的差异合并为一个大的合并差异,只需显示针对 每个 父级的差异,一次一个差异.

The -m option—m probably stands for merge here—tells Git to, in effect, "split" the merge. That is, instead of trying to combine the diffs against each parent into one big combined diff, just show the diff against each parent, one diff at a time.

这有时正是您想要的.当它不是您想要的时,您可以运行您自己的显式 git diff 来仅针对两个父级之一进行 diff(或见下文).

This is sometimes what you want. When it's not what you want, you can run your own explicit git diff to just diff against one of the two parents (or see below).

通常,正确答案是第一个父级".

Usually, the correct answer is "the first parent".

第一个父母"的钥匙概念是当 Git 进行合并提交时,它总是将您当时所在的分支记录为第一个父级.另一个分支成为第二个父分支.

The key to the "first parent" notion is that when Git makes a merge commit, it always records the branch you're on at the time, as the first parent. The other branch becomes the second parent.

也就是说,如果您在 develop 上并合并 topic:

That is, if you're on develop and you merge topic:

$ git checkout develop
$ git merge topic

Git 将在您当前的分支 develop 上进行一个新的提交——一个合并提交,有两个父项.合并提交的 第一个 父项将是刚才 develop 提示的提交.第二个 父项将是(仍然)topic 提示的提交.

Git will make a new commit—a merge commit, with two parents—on your current branch, develop. The first parent of the merge commit will be the commit that was the tip of develop just a moment ago. The second parent will be the commit that is (still) the tip of topic.

由于您通常关心合并带来的内容,因此与第一个父级进行比较会给您带来这一点.所以通常这就是你想要的.因此,git show 允许您运行 git show --first-parent.那个分裂"提交然后 git show 只与第一个父级不同.(这与 git show -m 有点不同,后者将提交拆分两次:第一个拆分与第一个父项进行比较,第二个拆分与第二个父项进行比较.)

Since you're usually concerned with what the merge brought in, comparing against the first parent will give you that. So usually that's what you want. For this reason, git show allows you to run git show --first-parent. That "splits" the commit and then git show only diffs against the first parent. (This is a bit different than git show -m, which splits the commit twice: the first split compares against the first parent, and the second split compares against the second parent.)

同样的,你可以运行 git log -p --first-parent 这里,--first-parent 标志还有一个更重要的作用:日志操作根本不查看 任何 侧分支的提交,只查看主(第一父)行上的提交.请注意,如果您的 Git 早于 2.31,您仍然需要 -m 标志(当使用 git log 时,即; git show> 默认为 --cc,因此不需要 -m,所有这些都已在 Git 2.31 中清除).

Similarly, you can run git log -p --first-parent Here, the --first-parent flag has an even more important effect: the log operation does not look at any of the side branch's commits at all, only those on the main (first-parent) line. Note that if your Git is older than 2.31, you still need the -m flag as well (when using git log, that is; git show defaults to --cc and hence does not require the -m, and all of this was cleaned up in Git 2.31).

这篇关于如何“git show"合并提交的差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆