如何在不实际合并的情况下测试合并
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 master
output 可能对您来说太大而无法观察引发冲突。
我非常喜欢这个……安全又简单。【参考方案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 在<<<
和>>>
之间:
$ 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 需要更新程序的环境中是完美的。以上是关于如何在不实际合并的情况下测试合并的主要内容,如果未能解决你的问题,请参考以下文章