如何在git中预览合并?

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

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

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

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

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

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

这些有帮助吗?

  • git log ..otherbranch < ul >
  • 将合并到当前分支的更改列表。
  • git diff ...otherbranch < ul >
  • 从共同祖先(合并基础)到将要合并的对象的头部的差异。注意三个点,这三个点与两个点相比具有特殊的意义(见下文)。
  • gitk ...otherbranch < ul >
  • 上次合并后的分支的图形表示。
  • 空字符串意味着HEAD,所以这就是为什么只有..otherbranch而不是HEAD..otherbranch

    两点和三点对于diff和列出修订的命令(log、gitk等)的含义略有不同。对于log和其他日志,两个点(a..b)表示所有在b中但不在a中,三个点(a...b)表示所有只在ab中的一个中。但是diff适用于两个修订,其中由两个点(a..b)表示的更简单的情况是ab的简单差异,而三个点(a...b)表示共同祖先与b (b1)之间的简单差异。

    添加到现有的答案,可以创建一个别名来显示合并之前的差异和/或日志。许多答案省略了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}"
    

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

        # 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”将会推送什么。

    如果你像我一样,你正在寻找等价于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
    

    在我看来,这个解决方案比提出“合并然后中止”的顶部解决方案更容易,更不容易出错(因此风险更小)。

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

    git log ...@{u}
    

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

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

    git log ...@\{u\}
    

    我发现最适合我的解决方案是只需执行合并,如果有冲突则中止。在我看来,这种特殊的语法干净而简单。这是下面的策略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现在更多的是说明,如果合并有您还没有准备好处理的冲突,您可以简单地中止合并。请记住,如果阅读评论!]

    我不想使用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 < a href = " https://softwareengineering.stackexchange.com/questions/199780/how-far-do-you-trust-automerge " > < / >

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

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

    git log TARGET_BRANCH...SOURCE_BRANCH --cherry
    

    这很好地说明了哪些提交将进入合并。要查看差异,添加-p。要查看文件名,添加任意--raw--stat--name-only--name-status

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

    Pull Request——我已经使用了大部分已经提交的想法,但我也经常使用的一个想法是(尤其是来自其他开发人员的想法)做一个Pull Request,它提供了一种方便的方法,可以在合并发生之前检查所有的更改。我知道这是GitHub不是git,但它肯定是方便的。

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

    要真正了解如果你将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提供的链接)

    注:

    如果你会得到合并冲突,他们会在输出中显示通常的冲突标记,例如:

    $ 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提出了一个很好的观点:这使得它不适合编写脚本,因为您不能轻易地从状态代码中捕获它。根据不同的环境,冲突标记可能有很大的不同(删除vs修改,等等),这也使得grep很难实现。要小心了。

    我尝试了这个东西来检查visual studio代码中的更改。

    从dev创建一个临时分支。然后合并你用——no-ff——no-commit标记修改了文件的分支。

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

    特性分支的更改文件将反映在feature_temp分支中。