如何在 git 中预览合并?

发布于 2024-11-03 20:05:44 字数 196 浏览 4 评论 0原文

我有一个 git 分支(例如主线),我想合并到另一个开发分支中。或者我也这样?

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

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

倚栏听风 2024-11-10 20:05:45

如果您像我一样,您正在寻找相当于 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

或者如果你想要从你的头脑到远程的差异:

$ git fetch origin
$ git diff origin/master

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

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 fetch first so that your local repo has the appropriate updates to compare against.

$ 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".

难理解 2024-11-10 20:05:45

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

git log ...@{u}

我相信这需要 git 1.7.x。 @{u} 表示法是上游分支的“简写”,因此它比 git log ...origin/master 更通用一些。

注意:如果您使用 zsh 和扩展的 glog,您可能需要执行以下操作:

git log ...@\{u\}

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.

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

git log ...@\{u\}
情感失落者 2024-11-10 20:05:45

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

因此,构建在“git log ..otherbranch< /code>”,您可以将以下内容添加到 ~/.gitconfig

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

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

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

然后您可以运行“git传入”来显示大量更改,或“git传入-p”来显示补丁(即“diff”),“git传入--pretty=oneline”,以获得简洁的摘要等。然后您可以(可选)运行“git pull”来实际合并。 (不过,由于您已经提取了内容,因此可以直接完成合并。)

同样,“git outing”显示了如果您要运行“git push”。

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 fetch to 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)

So, building on "git log ..otherbranch", you can add the following to ~/.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.)

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

烟火散人牵绊 2024-11-10 20:05:45

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

话虽如此,这里有一个稍微接近的方法:

git log TARGET_BRANCH...SOURCE_BRANCH --cherry

这给出了哪些提交将进入合并的公平指示。要查看差异,请添加 -p。要查看文件名,请添加 --raw--stat--name-only--name-状态

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

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.

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.

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

机场等船 2024-11-10 20:05:45

我尝试用这个东西来查看 Visual Studio 代码中的更改。

从 dev 创建一个临时分支。然后使用 --no-ff --no-commit 标志合并已更改文件的分支。

git checkout dev 
git checkout -b feature_temp 
git merge feature --no-ff --no-commit

功能分支的更改文件将反映在 feature_temp 分支中。

I tried this thing to review the changes in visual studio code.

Create a temporary branch from dev. Then merge the branch in which you have changed the file with --no-ff --no-commit flag.

git checkout dev 
git checkout -b feature_temp 
git merge feature --no-ff --no-commit

The changed file of your feature branch will be reflecting in the feature_temp branch.

胡大本事 2024-11-10 20:05:45

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

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

这些有帮助吗?

git log currentbranch..otherbranch will 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 diff currentbranch otherbranch will 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.

Would these help?

迷乱花海 2024-11-10 20:05:45

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

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.

凉城已无爱 2024-11-10 20:05:45

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

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

唐婉 2024-11-10 20:05:45

我不想使用 git merge 命令作为检查冲突文件的先导。我不想进行合并,我想在合并之前确定潜在的问题 - 自动合并可能对我隐藏的问题。我一直在寻找的解决方案是如何让 git 吐出两个分支中已更改的文件列表,这些文件将在将来合并在一起,相对于某个共同的祖先。获得该列表后,我可以使用其他文件比较工具来进一步查找内容。我已经搜索了多次,但仍然没有在原生 git 命令中找到我想要的东西。

这是我的解决方法,以防它对其他人有帮助:

在这种情况下,我有一个名为 QA 的分支,自上次生产版本以来,该分支有许多更改。我们的最后一个生产版本标记为“15.20.1”。我有另一个名为 new_stuff 的开发分支,我想将其合并到 QA 分支中。 QA 和 new_stuff 都指向“遵循”(由 gitk 报告)15.20.1 标签的提交。

git checkout QA
git pull
git diff 15.20.1 --name-only > QA_files
git checkout new_stuff
git pull
git diff 15.20.1 --name-only > new_stuff_files
comm -12 QA_files new_stuff_files

以下是一些关于为什么我对定位这些特定文件感兴趣的讨论:

如何我信任 Git 合并?

https://softwareengineering.stackexchange.com /questions/199780/how-far-do-you-trust-automerge

I do not want to use the git merge command as the precursor to reviewing conflicting files. I don't want to do a merge, I want to identify potential problems before I merge - problems that auto-merge might hide from me. The solution I have been searching for is how to have git spit out a list of files that have been changed in both branches that will be merged together in the future, relative to some common ancestor. Once I have that list, I can use other file comparison tools to scout things out further. I have searched multiple times, and I still haven't found what I want in a native git command.

Here is my workaround, in case it helps anyone else out there:

In this scenario I have a branch called QA that has many changes in it since the last production release. Our last production release is tagged with "15.20.1". I have another development branch called new_stuff that I want to merge into the QA branch. Both QA and new_stuff point to commits that "follow" (as reported by gitk) the 15.20.1 tag.

git checkout QA
git pull
git diff 15.20.1 --name-only > QA_files
git checkout new_stuff
git pull
git diff 15.20.1 --name-only > new_stuff_files
comm -12 QA_files new_stuff_files

Here are some discussions that hit on why I'm interested in targeting these specific files:

How can I trust Git merge?

https://softwareengineering.stackexchange.com/questions/199780/how-far-do-you-trust-automerge

预谋 2024-11-10 20:05:44
  • git log ..otherbranch
    • 将合并到当前分支的更改列表。
  • git diff ...otherbranch
    • 从共同祖先(合并基础)到要合并内容的头部的差异。 注意三个点,与两个点相比,它们具有特殊含义(见下文)。
  • gitk ...otherbranch
    • 自上次合并以来分支的图形表示。

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

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

  • 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.

Empty string implies HEAD, so that's why just ..otherbranch instead of 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 b but not a and three dots (a...b) means everything that is in only one of a or b. But diff works with two revisions and there the simpler case represented by two dots (a..b) is simple difference from a to b and three dots (a...b) mean difference between common ancestor and b (git diff $(git merge-base a b)..b).

长梦不多时 2024-11-10 20:05:44

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

但是,如果您想确保不会弄乱当前分支,或者无论是否存在冲突,您都没有准备好合并,只需在其上创建一个新的子分支并进行合并即可:

策略 1:安全的方法 - 合并临时分支:

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

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

这基本上是一次预演。

策略 2:当你确实想要合并时,但前提是不存在冲突

git checkout mybranch
git merge some-other-branch

如果 git 报告冲突(并且仅当存在冲突时),你可以这样做

git merge --abort

:合并成功,您无法中止它(只能重置)。

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

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

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 2 below.

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:

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.

This is basically a dry-run.

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

git checkout mybranch
git merge some-other-branch

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

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!]

睫毛上残留的泪 2024-11-10 20:05:44

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

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

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

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

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

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

(感谢 David Normington 提供的链接)

PS:

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

$ 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

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

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 master branch if you merged develop into it, right now:

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

(thanks to David Normington for the link)

P.S.:

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文