如何在git中预览合并?

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

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

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

我发现最适合我的解决scheme就是执行合并,并在不喜欢结果的情况下中止合并 。 这个特殊的语法让我觉得干净而简单。 如果你想确保你不会混淆你当前的分支,或者你只是没有准备好合并,不pipe冲突的存在,只需创build一个新的子分支并合并。

策略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月 – 我换了2战略1,因为它似乎是大多数人正在寻找“安全的方式”。 策略2现在更像是一个注意事项,如果合并冲突,你可以简单地中止合并,你还没有准备好处理。 请记住,如果阅读评论!]

  • git log ..otherbranch
    • 将被合并到当前分支的更改列表。
  • git diff ...otherbranch
    • 从共同的祖先(合并基础)到将要合并的头部的差异。 注意三点。
  • gitk ...otherbranch
    • 上次合并后的分支的graphics表示。

空string意味着头,所以这就是为什么..otherbranch而不是HEAD..otherbranch

这两点与三点在diff方面的含义略有不同,比列出修订版(log,gitk等)的命令略有不同。 对于日志和其他人来说,两个点( a..b )表示b所有东西,但不是a和三个点( a...b )意味着只有ab之一的所有东西。 但是diff有两个修正版本,那么由两个点( a..b )表示的简单情况与ab和三个点( a...b )的差别就是简单的区别, a共同祖先和b之间的平均差异( git diff $(git merge-base ab)..b )。

如果你像我一样,你正在寻找相当于svn update -n 。 以下似乎是做的伎俩。 请注意,请确保首先执行git fetch以便您的本地回购具有适当的更新进行比较。

 $ 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 

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

所以,build立在“ 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}" 

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

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

然后你可以运行“ git incoming ”来显示很多的变化,或者“ git incoming -p ”来显示补丁(比如“diff”),“ git incoming --pretty=oneline ”等等。然后你可以(可选地)运行“ git pull ”来实际合并。 (但是,既然你已经提取了,合并可以直接完成。)

同样,“ git outgoing ”显示如果你运行“ git push ”,会推送什么。

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

 git log ...@{u} 

这需要git 1.7.x我相信虽然。 @{u}符号是上游分支的“简写”,所以它比git log ...origin/master更通用一些。

注意:如果你使用zsh和扩展glog的东西,你可能不得不做一些事情:

 git log ...@\{u\} 

git log currentbranch..otherbranch会给你提交进入当前分支的列表,如果你做一个合并。 logging提交细节的通常参数将给你更多的信息。

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

这些帮助吗?

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

实际上以抛弃式的方式进行合并(见卡萨波的答案),似乎没有一种可靠的方法来看待这一点。

话虽如此,这是一个接近边缘的方法:

 git log TARGET_BRANCH...SOURCE_BRANCH --cherry 

这就明确地表明了哪些承诺会融入合并。 要查看差异,请添加-p 。 要查看文件名,请添加--raw ,– --raw ,– --raw --name-only--name-status --raw --name-status

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

我不想使用git merge命令作为审查冲突文件的先兆。 我不想合并,我想在合并之前发现潜在的问题 – 自动合并的问题可能会对我隐瞒。 我一直在寻找的解决scheme是如何让git吐出两个分支中将被合并在一起的文件列表,相对于一些共同的祖先。 一旦我有了这个列表,我可以使用其他文件比较工具来进一步侦察。 我search了多次,我仍然没有find我想要的本地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

拉取请求 – 我已经使用了大部分已经提交的想法,但是我经常使用的是(特别是如果来自另一个开发者的话)执行合并请求,该合并提供了一种方便的方式来检查合并之前的所有改变地点。 我知道这是GitHub不是混帐,但它确实是方便的。