使用git合并两个非常不同的分支?

时间:2011-05-10 20:49:36

标签: git

我有master分支,而verydifferentbranch这些分支拥有相同的祖先...大约300个提交前。现在verydifferentbranch已完成功能,我想将其置于主branch下。执行rebase会导致每个补丁都有很多合并冲突,直到它本身就是一个大型项目才能完成所有冲突。

除了强迫将verydifferentbranch的头部推入master分支外,我不知道该怎么做。我这样做会失去我所有的历史,而这不是我真正想做的事情。

我的其他选择是什么?

4 个答案:

答案 0 :(得分:10)

听起来你的历史是这样的:

...---o---A---o---...---o---o---B   master
           \
            o---o---...---o---C     verydifferentbranch

如果你强行推动verydifferentbranchmaster,你说你担心失去历史记录。这样的操作实际上会在A之后丢弃所有内容,直至B

您可以通过合并历史记录来保存历史记录,或者只是在废弃的分支尖端放置标记并使其保持未合并状态。

使用合并

合并将允许您保留历史记录的两面:

...---o---A---o---...---o---o---B
           \                     \
            o---o---...---o---C---M  master

您执行的合并类型将决定为提交M创建的内容。正常合并(使用recursive合并策略)听起来好像会在您的情况下产生大量冲突。 如果您确实需要合并A..B提交中的更改,那么除了合并或rebase提供的冲突之外,没有别的办法可以做。(将来你会如果您可以更频繁地合并或更换以解决冲突,那么问题可能会更少。)但是,如果您只是希望M具有与C相同的内容(即您想要忽略)由A..B提交表示的更改,然后您可以使用ours合并策略。

git-merge(1)描述了ours合并策略:

  

这解决了任意数量的头,但是合并的结果树始终是当前分支头的树,实际上忽略了来自所有其他分支的所有更改。它旨在用于取代侧枝的旧发展历史。请注意,这与递归合并策略的-Xours选项不同。

您可以使用Merge commit 'abandoned/foo-features'这样的消息生成M:

git tag -m 'describe reason for abandonment here...' \
    abandoned/foo-features master                   # tag abandoned branch tip
git checkout verydifferentbranch                    # checkout dominant branch
git branch -M verydifferentbranch master            # replace master
git merge -s ours abandoned/foo-features            # merge only other's history
git tag -d abandoned/foo-features                   # optional: delete the tag
git push wherever master tag abandoned/foo-features # publish them

这些命令的变化会为M提供略有不同的自动提交消息(您可以随时提供git merge -mgit commit --amend之后修改它。)

主要观点是,生成的master将包含两段历史记录,但没有原始master方面的更改(这些更改仍在历史记录中,它们只是没有代表在commit M)引用的树中。

保持悬挂

如果“重写”master是可以接受的(即没有基于任何提交A..B的其他工作,或者所涉及的用户不介意它将采取的工作master 3}}),然后您可以在master的当前提示处留下标记,并将verydifferentbranch替换为...---o---A---o---...---o---o---B (tag: abandoned/foo-features) \ o---o---...---o---C master

git tag -m 'describe reason for abandonment here...' \
    abandoned/foo-features master                    # tag abandoned branch tip
git branch -M verydifferentbranch master             # replace master
git push wherever +master tag abandoned/foo-features # publish them

像这样安排:

{{1}}

答案 1 :(得分:2)

这就是git merge功能存在的原因。

$> git checkout master
$> git merge verydifferentbranch

赔率是你第一次这样做会有很多冲突(如果他们的分歧与你声称的差不多)。但是如果你掌握了最新的东西,那么在初始合并之后它就不会太糟糕了。

答案 2 :(得分:1)

你为什么先做一次改变?这可能会导致您的更改集出现问题,因为您的更改集将从您从主服务器转移的提交开始查找文件版本。

改为使用git merge。

答案 3 :(得分:0)

我发现,通过将verydifferentbranch上的每10次提交合并到master中并以此方式解决冲突,就可以更轻松地推理和解决合并冲突。是的,这意味着如果您有300次提交,那么您将进行30次合并,但是与您尝试一次全部合并相比,到目前为止每个合并的差异都没有那么大。