如何在 git 中预览合并?
我有一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
如果您像我一样,您正在寻找相当于
svn update -n
的内容。以下似乎可以解决问题。请注意,请确保首先执行 git fetch ,以便您的本地存储库有适当的更新可供比较。或者如果你想要从你的头脑到远程的差异:
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 agit fetch
first so that your local repo has the appropriate updates to compare against.or if you want a diff from your head to the remote:
IMO this solution is much easier and less error prone (and therefore much less risky) than the top solution which proposes "merge then abort".
如果您已经获取了更改,我最喜欢的是:
我相信这需要 git 1.7.x。
@{u}
表示法是上游分支的“简写”,因此它比git log ...origin/master
更通用一些。注意:如果您使用 zsh 和扩展的 glog,您可能需要执行以下操作:
If you already fetched the changes, my favourite is:
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 thangit log ...origin/master
.Note: If you use zsh and the extended glog thing on, you likely have to do something like:
添加到现有答案中,可以创建别名来显示合并之前的差异和/或日志。许多答案忽略了在“预览”合并之前首先完成的
fetch
;这是一个将这两个步骤合二为一的别名(模拟类似于 Mercurial 的hg 输入
/传出
)因此,构建在“
git log ..otherbranch< /code>”,您可以将以下内容添加到
~/.gitconfig
:为了对称,可以使用以下别名来显示在推送之前已提交和将推送的内容:
然后您可以运行“
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'shg incoming
/outgoing
)So, building on "
git log ..otherbranch
", you can add the following to~/.gitconfig
:For symmetry, the following alias can be used to show what is committed and would be pushed, prior to pushing:
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
".除了以一次性方式实际执行合并(参见 Kasapo 的答案)之外,似乎没有可靠的方法来看待这一点。
话虽如此,这里有一个稍微接近的方法:
这给出了哪些提交将进入合并的公平指示。要查看差异,请添加
-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:
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.我尝试用这个东西来查看 Visual Studio 代码中的更改。
从 dev 创建一个临时分支。然后使用 --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.
The changed file of your feature branch will be reflecting in the feature_temp branch.
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?
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.
也许这可以帮助你?
git-diff-tree - 比较通过两个树对象找到的 blob 的内容和模式
Maybe this can help you ?
git-diff-tree - Compares the content and mode of blobs found via two tree objects
我不想使用 git merge 命令作为检查冲突文件的先导。我不想进行合并,我想在合并之前确定潜在的问题 - 自动合并可能对我隐藏的问题。我一直在寻找的解决方案是如何让 git 吐出两个分支中已更改的文件列表,这些文件将在将来合并在一起,相对于某个共同的祖先。获得该列表后,我可以使用其他文件比较工具来进一步查找内容。我已经搜索了多次,但仍然没有在原生 git 命令中找到我想要的东西。
这是我的解决方法,以防它对其他人有帮助:
在这种情况下,我有一个名为 QA 的分支,自上次生产版本以来,该分支有许多更改。我们的最后一个生产版本标记为“15.20.1”。我有另一个名为 new_stuff 的开发分支,我想将其合并到 QA 分支中。 QA 和 new_stuff 都指向“遵循”(由 gitk 报告)15.20.1 标签的提交。
以下是一些关于为什么我对定位这些特定文件感兴趣的讨论:
如何我信任 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.
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
git log ..otherbranch
git diff ...otherbranch
gitk ...otherbranch
空字符串意味着
HEAD
,所以这就是为什么只是..otherbranch
而不是HEAD..otherbranch
。对于 diff 而言,两个点和三个点的含义与列出修订版本的命令(log、gitk 等)略有不同。对于 log 和其他,两个点 (
a..b
) 表示b
中的所有内容,但不包括a
和三个点 (a ...b
) 表示仅在a
或b
之一中的所有内容。但是 diff 适用于两个修订版,并且由两个点 (a..b
) 表示的更简单的情况是从a
到b
的简单区别,并且三个点 (a...b
) 表示共同祖先和b
之间的差异 (git diff $(git merge-base ab)..b)。
git log ..otherbranch
git diff ...otherbranch
gitk ...otherbranch
Empty string implies
HEAD
, so that's why just..otherbranch
instead ofHEAD..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 inb
but nota
and three dots (a...b
) means everything that is in only one ofa
orb
. But diff works with two revisions and there the simpler case represented by two dots (a..b
) is simple difference froma
tob
and three dots (a...b
) mean difference between common ancestor andb
(git diff $(git merge-base a b)..b
).我发现最适合我的解决方案是仅执行合并并在存在冲突时中止合并。这种特殊的语法对我来说感觉干净简单。这是下面的策略2。
但是,如果您想确保不会弄乱当前分支,或者无论是否存在冲突,您都没有准备好合并,只需在其上创建一个新的子分支并进行合并即可:
策略 1:安全的方法 - 合并临时分支:
这样,如果您只想查看冲突是什么,您可以简单地丢弃临时分支。您不需要费心“中止”合并,并且可以返回到您的工作 - 只需再次签出“mybranch”,您的分支中就不会有任何合并的代码或合并冲突。
这基本上是一次预演。
策略 2:当你确实想要合并时,但前提是不存在冲突
如果 git 报告冲突(并且仅当存在冲突时),你可以这样做
:合并成功,您无法中止它(只能重置)。
如果您还没有准备好合并,请使用上面更安全的方法。
[编辑: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:
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
If git reports conflicts (and ONLY IF THERE ARE conflicts) you can then do:
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!]
这里的大多数答案要么需要一个干净的工作目录和多个交互步骤(对脚本编写不利),要么不适用于所有情况,例如过去的合并已经将一些突出的更改带入目标分支,或者选择执行以下操作相同的。
要真正了解如果将
develop
合并到master
分支中,现在会发生什么变化:— https://git.seveas.net/previewing-a-merge-result.html
(感谢 David Normington 提供的链接)
PS:
如果您遇到合并冲突,它们会以通常的方式显示中的冲突标记输出,例如:
用户@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 mergeddevelop
into it, right now:— 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.:
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.