如何在不实际合并的情况下测试合并

Posted

技术标签:

【中文标题】如何在不实际合并的情况下测试合并【英文标题】:How to test a merge without actually merging first 【发布时间】:2011-11-21 00:03:43 【问题描述】:

有没有什么方法可以在当前工作分支和主分支这两个分支之间模拟git merge,但不做任何更改?

当我必须创建git merge 时,我经常会发生冲突。有没有办法先模拟合并?

【问题讨论】:

另见***.com/questions/501407/… 【参考方案1】:

您可以使用git merge --no-commit 来阻止实际提交合并,如果您不喜欢合并的结果,只需重置为原始头部。

如果您绝对不想完成合并,即使它是快进(根据定义因此没有冲突),您也可以添加 --no-ff

【讨论】:

我不认为 git merge --abort 存在 - 也许你的意思是 git reset --merge 不,我只是忘记了,与rebase 不同,git merge 没有--abort 我也会加入--no-ff。防止发生 ff 合并。 @Andy 的--no-ff 在这里几乎是强制性的,因为--no-commit 不会停止快进更改。 @Anant Anand Gupta - 这是一个很好的技巧,但它应该是: git config --global alias.tm "merge --no-commit --no-ff"【参考方案2】:

在您尝试合并之前,我认为没有办法模拟会发生什么。但是,如果您在进行合并之前确保 git status 的输出为空,那么继续尝试是非常安全的。如果发生冲突,您可以立即恢复到之前的状态:

git reset --merge

从 git 1.7.4 开始,您还可以通过以下方式中止合并:

git merge --abort

(作为the commit message that added that option explains,这是为了与git rebase --abort等保持一致而添加的。)

【讨论】:

@Amber 的答案是准确回答“如何模拟合并”的问题。在我看来,使用--no-commit 要容易得多 @samirahmed:@Amber 更从字面上回答了这个问题,当然,尽管使用 --no-commit 您仍在更改索引和工作树,这并不完全是“不做任何更改”: ) 我的观点是,当人们提出此类问题时,通常是因为他们不知道了解合并的最佳方式是尝试合并,通常是因为他们'不知道如果出现问题,要恢复到以前的状态是多么容易。 我不知道这是否是在较新版本的 git 中添加的,但在文档 (1.8.4) 中它指出“git merge --abort 相当于 git reset --merge MERGE_HEAD存在”,所以更容易记住:) @SamuelMeacham:感谢您指出这一点——它是在 1.7.4 中引入的。我已经更新了答案。谢谢! 这个建议对我没有任何帮助,在 git 1.9.4 上。【参考方案3】:

我最近可以使用git merge --abort。但是,这只能在存在合并冲突时使用。如果您确定不想提交,请使用上面提到的其他方法。

【讨论】:

以上还有哪些方法?他们都提到git merge --abort。您应该通过指定谁写了您所指的答案来证明您的答案。【参考方案4】:

如果我想将某个主题分支上的更改与 master 进行比较,我发现执行以下操作是最简单和最安全的:

git checkout master
git checkout -b trial_merge
git merge topic_branch

完成合并后,很容易从master上看到合并后的变化

git diff master

完成后,只需删除 trial_merge 分支

git checkout master
git branch -D trial_merge

这样,主分支永远不会改变。

【讨论】:

你也可以git checkout --detach 测试任何你想要的东西。稍后,如果您想保留更改,请执行git checkout -b new_branch。如果您想放弃更改,请查看您想要的任何分支 (git checkout master)。 如果topic_branch 很大(如果您首先遇到这个问题,可能就是这种情况),如果合并正在进行,diff masteroutput 可能对您来说太大而无法观察引发冲突。 我非常喜欢这个……安全又简单。【参考方案5】:

我用:

git merge --ff-only

根据documentation:

拒绝合并并以非零状态退出,除非当前 HEAD 已经是最新的,或者可以将合并解析为快进。

这并不是真正的模拟,因为在两个分支之间没有冲突的情况下会有一个快进合并。但万一发生冲突,您将被告知并且不会发生任何事情。

【讨论】:

【参考方案6】:

为什么不直接创建一个一次性分支 (git checkout -b),然后在那里进行测试合并?

【讨论】:

你的建议实际上是伊恩简洁表达的答案:)【参考方案7】:

我不知道是不是你的情况,但你的问题记得我,有时我会启动一个功能,我在几天内提交并多次合并开发。

在这一点上,我失去了对我更改的确切文件的控制权,只有在我的功能关闭并且我的代码开始开发时我才会知道。

在这种情况下,了解您所做的修改(不是来自合并的其他修改)的好方法是使用 Sourcetree。

您必须在基础分支上单击右键并选择Diff Against Current

如果你将分支合并到基础分支,sourcetree 将显示所有将被合并的修改。

当然,它不会显示冲突,但它在合并中是一个有用的工具。

【讨论】:

【参考方案8】:

这是我找到的解决方案:git merge-tree 确实“在内存中”合并并打印差异而不接触您的工作目录。您甚至可以在不检查分支的情况下对其进行测试。

获取合并差异

首先,这样做是为了确保您的存储库知道所有远程分支:

$ git fetch --all

现在使用这个 bash sn-p 查看分支 $branch 如何合并到 $master

$ branch='feature'
$ git merge-tree $(git merge-base $branch master) master $branch

不会对您的工作目录或索引进行任何更改。这是一个试运行合并

从输出中挑选信息

输出是一个差异。 如果分支已合并,则为空。

查看是否有冲突,grep 为<<<

$ git merge-tree $(git merge-base $branch master) master $branch | fgrep '<<<'

要提取冲突差异,use sed to extract lines 在&lt;&lt;&lt;&gt;&gt;&gt; 之间:

$ git merge-tree $(git merge-base $branch master) master $branch | \
  sed -ne '/^\+<<</,/^\+>>>/ p'

特点

如果分支已经合并,则差异将为空 使用 grep/sed 提取冲突信息 使用origin/feature 测试您从未使用过的分支 可用于查看 2 个分支如何发散

将其添加到您的收藏夹

获取合并的差异:

git config --global alias.mergediff '!f() branch="$1" ;进入="$2" ; git 合并树 $(git merge-base "$branch" "$into") "$into" "$branch" ; ;f'

用法:

$ git mergediff <feature-branch> <merge-into>
$ git mergediff feature master

获取合并冲突:

git config --global alias.mergetest '!f() git mergeiff $@ | sed -ne "/^+>>/p" ; ;f'

用法:

$ git mergetest <feature-branch> <merge-into>
$ git mergetest feature master

【讨论】:

太棒了!您的“git merge-tree”语句检查合并是否会导致冲突,而不会干扰本地存储库的工作区域。这在 Git 需要更新程序的环境中是完美的。

以上是关于如何在不实际合并的情况下测试合并的主要内容,如果未能解决你的问题,请参考以下文章

如何在不采用其中更改的情况下将 git 分支声明为合并?

如何在不丢失任何信息的情况下合并两个 pdf?

如何在不进行任何更改的情况下恢复推送的合并?

如何在不丢失 SQL 中的任何行的情况下合并两个表?

如何在不命名所有列的情况下合并两个表?

如何在不覆盖以前数据的情况下使用 rxSwift 压缩、合并或连接?