如何在git中预览合并?

时间:2011-04-28 11:04:17

标签: git git-merge

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

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

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

11 个答案:

答案 0 :(得分:365)

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

空字符串意味着HEAD,因此只有..otherbranch代替HEAD..otherbranch

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

答案 1 :(得分:229)

我发现最适合我的解决方案是只是执行合并并在不喜欢结果时中止它。这种特殊的语法让我感觉干净简单。如果你想确保你没有弄乱当前的分支,或者你不准备合并而不管是否存在冲突,只需创建一个新的子分支并合并它。

策略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现在更像是一个注释,如果合并存在您尚未准备好处理的冲突,您可以简单地中止合并。如果阅读评论请记住!]

答案 2 :(得分:17)

如果你像我一样,你正在寻找相当于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这个解决方案比提出“合并然后中止”的顶级解决方案更容易,更不容易出错(因此风险更小)。

答案 3 :(得分:6)

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

因此,在“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”来显示补丁(即“差异”),“git incoming --pretty=oneline” ,您可以(可选)运行“git pull”进行实际合并。 (虽然,既然你已经获取了,合并可以直接完成。)

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

答案 4 :(得分:6)

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

git log ...@{u}

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

注意:如果你使用zsh和扩展的glog,你可能需要做类似的事情:

git log ...@\{u\}

答案 5 :(得分:3)

如果您进行合并,

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

git diff currentbranch otherbranch将为您提供两个提交之间的区别。这将是一个差异,为您提供将被合并的一切。

这会有帮助吗?

答案 6 :(得分:3)

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

答案 7 :(得分:2)

如果没有以一种抛弃的方式实际进行合并(参见Kasapo的回答),似乎没有一种可靠的方式来看待它。

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

git log TARGET_BRANCH...SOURCE_BRANCH --cherry

这可以很好地指示哪些提交将进入合并。要查看差异,请添加-p。要查看文件名,请添加--raw--stat--name-only--name-status中的任意一个。

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

答案 8 :(得分:2)

此处的大多数答案都需要一个干净的工作目录和多个交互步骤(不利于脚本编写),或者不适用于所有情况,例如过去的合并已经将一些出色的变化带入了您的目标分支,或者执行了同样的操作。

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

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

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

git merge-tree $(git merge-base master develop) master develop | colordiff | $(git var GIT_PAGER)

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

(感谢David Normington提供的链接)

P.S。

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

$ 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

P.S。 2:在我的计算机(香草Mac OS X)上,GIT_PAGER行以less结尾,这不喜欢彩色输入。我必须在我的〜/ .bashrc中添加export LESS=FRX以使其可口。感谢https://unix.stackexchange.com/questions/153943/git-pager-is-less-but-what-is-causing-the-output-coloring

答案 9 :(得分:1)

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

答案 10 :(得分:0)

我不想使用git merge命令作为查看冲突文件的前身。我不想进行合并,我想在合并之前找出潜在的问题 - 自动合并的问题可能会对我隐瞒。我一直在寻找的解决方案是如何让git吐出一个已经在两个分支中被更改的文件列表,这些文件将来会被合并在一起,相对于一些共同的祖先。一旦我有了这个列表,我就可以使用其他文件比较工具来进一步搜索。我已多次搜索,但仍然无法在本机git命令中找到我想要的内容。

这是我的解决方法,以防它可以帮助其他任何人:

在这种情况下,我有一个名为QA的分支,自上一个生产版本以来,它有很多变化。我们的上一个产品版本标有&#34; 15.20.1&#34;。我有另一个名为new_stuff的开发分支,我希望将其合并到QA分支中。 QA和new_stuff都指向&#34;关注&#34; (由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

以下是一些讨论,探讨了我对定位这些特定文件感兴趣的原因:

How can I trust Git merge?

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

相关问题