如何在 git 中预览合并?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5817579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 10:49:23  来源:igfitidea点击:

How can I preview a merge in git?

gitgit-merge

提问by Glenjamin

I have a git branch (the mainline, for example) and I want to merge in another development branch. Or do I?

我有一个 git 分支(例如主线),我想合并到另一个开发分支中。还是我?

In order to decide whether I really want to merge this branch in, i'd like to see some sort of preview of what the merge will do. Preferably with the ability to see the list of commits that are being applied.

为了决定我是否真的想合并这个分支,我想看看合并会做什么的某种预览。最好能够查看正在应用的提交列表。

So far, the best I can come up with is merge --no-ff --no-commit, and then diff HEAD.

到目前为止,我能想到的最好的方法是merge --no-ff --no-commit,然后是diff HEAD

采纳答案by Kasapo

I've found that the solution the works best for me is to just perform the merge and abort it if there are conflicts. This particular syntax feels clean and simple to me. This is Strategy 2below.

我发现最适合我的解决方案是执行合并,如果有冲突则中止它。这种特殊的语法对我来说感觉干净简单。这是下面的策略 2

However, if you want to ensure you don't mess up your current branch, or you're just not ready to merge regardless of the existence of conflicts, simply create a new sub-branch off of it and merge that:

但是,如果您想确保不会弄乱您当前的分支,或者无论是否存在冲突,您都不准备合并,只需从中创建一个新的子分支并合并它:

Strategy 1: The safe way – merge off a temporary branch:

策略 1:安全的方式——合并一个临时分支:

git checkout mybranch
git checkout -b mynew-temporary-branch
git merge some-other-branch

That way you can simply throw away the temporary branch if you just want to see what the conflicts are. You don't need to bother "aborting" the merge, and you can go back to your work -- simply checkout 'mybranch' again and you won't have any merged code or merge conflicts in your branch.

这样,如果您只想查看冲突是什么,您可以简单地丢弃临时分支。您无需费心“中止”合并,您就可以返回到您的工作中——只需再次签出“mybranch”,您的分支中就不会出现任何合并代码或合并冲突。

This is basically a dry-run.

这基本上是一个试运行。

Strategy 2: When you definitely want to merge, but only if there aren't conflicts

策略 2:当您肯定要合并时,但前提是没有冲突

git checkout mybranch
git merge some-other-branch

If git reports conflicts (and ONLY IF THERE AREconflicts) you can then do:

如果 git 报告冲突(并且仅当存在冲突时),您可以执行以下操作:

git merge --abort

If the merge is successful, you cannot abort it (only reset).

如果合并成功,则不能中止(只能重置)。

If you're not ready to merge, use the safer way above.

如果您还没有准备好合并,请使用上面更安全的方法。

[EDIT: 2016-Nov - I swapped strategy 1 for 2, because it seems to be that most people are looking for "the safe way". Strategy 2 is now more of a note that you can simply abort the merge if the merge has conflicts that you're not ready to deal with. Keep in mind if reading comments!]

[编辑:2016 年 11 月 - 我将策略 1 换成了 2,因为似乎大多数人都在寻找“安全的方式”。策略 2 现在更重要的是,如果合并存在您尚未准备好处理的冲突,您可以简单地中止合并。如果阅读评论,请记住!]

回答by Jan Hudec

  • git log ..otherbranch
    • list of changes that will be merged into current branch.
  • git diff ...otherbranch
    • diff from common ancestor (merge base) to the head of what will be merged. Note the three dots, which have a special meaning compared to two dots (see below).
  • gitk ...otherbranch
    • graphical representation of the branches since they were merged last time.
  • git log ..otherbranch
    • 将合并到当前分支的更改列表。
  • git diff ...otherbranch
    • 从共同祖先(合并基础)到将要合并的内容的头部的差异。请注意三个点,与两个点相比,它们具有特殊的含义(见下文)。
  • gitk ...otherbranch
    • 自上次合并以来分支的图形表示。

Empty string implies HEAD, so that's why just ..otherbranchinstead of HEAD..otherbranch.

空字符串意味着HEAD,所以这就是为什么只是..otherbranch代替HEAD..otherbranch

The two vs. three dots have slightly different meaning for diff than for the commands that list revisions (log, gitk etc.). For log and others two dots (a..b) means everything that is in bbut not aand three dots (a...b) means everything that is in only one of aor b. But diff works with two revisions and there the simpler case represented by two dots (a..b) is simple difference from ato band three dots (a...b) mean difference between common ancestor and b(git diff $(git merge-base a b)..b).

两个点和三个点对于 diff 的含义与列出修订版本的命令(log、gitk 等)的含义略有不同。对于 log 和其他人,两个点 ( a..b) 表示所有内容b但不包含a在内,三个点 ( a...b) 表示所有内容仅包含在aor之一中b。但是 diff 适用于两个修订版,两个点 ( a..b)表示的更简单的情况是与ato 的简单差异b,三个点 ( a...b) 表示共同祖先和b( git diff $(git merge-base a b)..b)之间的差异。

回答by djschny

If you're like me, you're looking for equivalent to svn update -n. The following appears to do the trick. Note that make sure to do a git fetchfirst so that your local repo has the appropriate updates to compare against.

如果你像我一样,你正在寻找相当于svn update -n. 以下似乎可以解决问题。请注意,请确保git fetch先进行,以便您的本地存储库具有适当的更新以进行比较。

$ git fetch origin
$ git diff --name-status origin/master
D       TableAudit/Step0_DeleteOldFiles.sh
D       TableAudit/Step1_PopulateRawTableList.sh
A       manbuild/staff_companies.sql
M       update-all-slave-dbs.sh

or if you want a diff from your head to the remote:

或者,如果您想要从头部到遥控器的差异:

$ git fetch origin
$ git diff origin/master


IMO this solution is much easier and less error prone (and therefore much less risky) than the top solution which proposes "merge then abort".

IMO 与建议“合并然后中止”的顶级解决方案相比,此解决方案更容易且更不容易出错(因此风险更低)。

回答by hraban

Most answers here either require a clean working directory and multiple interactive steps (bad for scripting), or don't work for all cases, e.g. past merges which already bring some of the outstanding changes into your target branch, or cherry-picks doing the same.

这里的大多数答案要么需要一个干净的工作目录和多个交互步骤(不利于脚本编写),要么不适用于所有情况,例如过去的合并已经将一些未完成的更改带入了您的目标分支,或者选择了执行相同的。

To truly see what would change in the masterbranch if you merged developinto it, right now:

要真正查看master如果合并develop到分支中会发生什么变化,现在:

git merge-tree $(git merge-base master develop) master develop

As it's a plumbing command, it does not guess what you mean, you have to be explicit. It also doesn't colorize the output or use your pager, so the full command would be:

由于它是一个管道命令,它不会猜测您的意思,您必须明确。它也不会为输出着色或使用您的寻呼机,因此完整的命令将是:

git merge-tree $(git merge-base master develop) master develop | colordiff | less -R

https://git.seveas.net/previewing-a-merge-result.html

https://git.seveas.net/previewing-a-merge-result.html

(thanks to David Normington for the link)

(感谢大卫诺明顿的链接)

P.S.:

PS:

If you would get merge conflicts, they will show up with the usual conflict markers in the output, e.g.:

如果您遇到合并冲突,它们将在输出中显示通常的冲突标记,例如:

$ git merge-tree $(git merge-base a b ) a b 
added in both
  our    100644 78981922613b2afb6025042ff6bd878ac1994e85 a
  their  100644 61780798228d17af2d34fce4cfbdf35556832472 a
@@ -1 +1,5 @@
+<<<<<<< .our
 a
+=======
+b
+>>>>>>> .their

User @dreftymac makes a good point: this makes it unsuitable for scripting, because you can't easily catch that from the status code. The conflict markers can be quite different depending on circumstance (deleted vs modified, etc), which makes it hard to grep, too. Beware.

用户@dreftymac 提出了一个很好的观点:这使得它不适合编写脚本,因为您无法轻松地从状态代码中捕捉到它。根据情况(删除与修改等),冲突标记可能会有很大不同,这也使得 grep 变得困难。谨防。

回答by Pablo Olmos de Aguilera C.

If you already fetched the changes, my favourite is:

如果您已经获取了更改,我最喜欢的是:

git log ...@{u}

That needs git 1.7.x I believe though. The @{u}notation is a "shorthand" for the upstream branch so it's a little more versatile than git log ...origin/master.

我相信这需要 git 1.7.x。该 @{u}符号是上游分支的“简写”,因此它比git log ...origin/master.

Note: If you use zsh and the extended glog thing on, you likely have to do something like:

注意:如果您使用 zsh 和扩展 glog 的东西,您可能必须执行以下操作:

git log ...@\{u\}

回答by michael

Adding to the existing answers, an alias could be created to show the diff and/or log prior to a merge. Many answers omit the fetchto be done first before "previewing" the merge; this is an alias that combines these two steps into one (emulating something similar to mercurial's hg incoming/ outgoing)

添加到现有答案中,可以创建别名以在合并之前显示差异和/或日志。许多答案省略了fetch在“预览”合并之前先完成的工作;这是将这两个步骤合二为一的别名(模拟类似于 mercurial 的hg incoming/ outgoing

So, building on "git log ..otherbranch", you can add the following to ~/.gitconfig:

因此,基于“ git log ..otherbranch”,您可以将以下内容添加到~/.gitconfig

...
[alias]
    # fetch and show what would be merged (use option "-p" to see patch)
    incoming = "!git remote update -p; git log ..@{u}"

For symmetry, the following alias can be used to show what is committed and would be pushed, prior to pushing:

为了对称,以下别名可用于在推送之前显示已提交和将被推送的内容:

    # what would be pushed (currently committed)
    outgoing = log @{u}..

And then you can run "git incoming" to show a lot of changes, or "git incoming -p" to show the patch (i.e., the "diff"), "git incoming --pretty=oneline", for a terse summary, etc. You may then (optionally) run "git pull" to actually merge. (Though, since you've already fetched, the merge could be done directly.)

然后你可以运行“ git incoming”来显示很多变化,或者“ git incoming -p”来显示补丁(即“差异”),“ git incoming --pretty=oneline”,一个简洁的摘要等。然后你可以(可选)运行“ git pull”来实际上合并。(不过,由于您已经获取了,因此可以直接完成合并。)

Likewise, "git outgoing" shows what would be pushed if you were to run "git push".

同样,“ git outgoing”显示如果您要运行“ git push”将被推送的内容。

回答by G-Man

Pull Request - I've used most of the already submitted ideas but one that I also often use is ( especially if its from another dev ) doing a Pull Request which gives a handy way to review all of the changes in a merge before it takes place. I know that is GitHub not git but it sure is handy.

拉取请求 - 我已经使用了大部分已经提交的想法,但我也经常使用的一个是(特别是如果它来自另一个开发者)做一个拉取请求,它提供了一种方便的方法来在合并之前合并中的所有更改地方。我知道 GitHub 不是 git,但它确实很方便。

回答by Noufal Ibrahim

git log currentbranch..otherbranchwill give you the list of commits that will go into the current branch if you do a merge. The usual arguments to log which give details on the commits will give you more information.

git log currentbranch..otherbranch如果您进行合并,将为您提供将进入当前分支的提交列表。提供有关提交详细信息的日志的常用参数将为您提供更多信息。

git diff currentbranch otherbranchwill give you the diff between the two commits that will become one. This will be a diff that gives you everything that will get merged.

git diff currentbranch otherbranch会给你将成为一个的两个提交之间的差异。这将是一个差异,它为您提供将要合并的所有内容。

Would these help?

这些会有帮助吗?

回答by antak

Short of actually performing the merge in a throw away fashion (see Kasapo's answer), there doesn't seem to be a reliable way of seeing this.

除了以一次性方式实际执行合并(参见 Kasapo 的回答)之外,似乎没有一种可靠的方式来看待这一点。

Having said that, here's a method that comes marginally close:

话虽如此,这是一种稍微接近的方法:

git log TARGET_BRANCH...SOURCE_BRANCH --cherry

This gives a fair indication of which commits will make it into the merge. To see diffs, add -p. To see file names, add any of --raw, --stat, --name-only, --name-status.

这给出了哪些提交将使其进入合并的公平指示。要查看差异,请添加-p. 要查看文件名,请添加--raw--stat--name-only、 中的任何一个--name-status

The problem with the git diff TARGET_BRANCH...SOURCE_BRANCHapproach (see Jan Hudec's answer) is, you'll see diffs for changes already in your target branch if your source branch contains cross merges.

git diff TARGET_BRANCH...SOURCE_BRANCH方法的问题(参见 Jan Hudec 的回答)是,如果您的源分支包含交叉合并,您将看到目标分支中已有更改的差异。

回答by Chugaister

Maybe this can help you ? git-diff-tree- Compares the content and mode of blobs found via two tree objects

也许这可以帮助你? git-diff-tree- 比较通过两个树对象找到的 blob 的内容和模式