正确地修改合并

时间:2012-06-27 23:23:38

标签: git git-merge git-rebase

另一个git问题......我遇到以下情况:

A1 ---- B1 ---- C1
                   \
                    > D ---- E ---- F
                   /
A2 ---- B2 ---- C2

{A1,B1,C1}和{A2,B2,C2}共有 no 文件(这是合并两个不同存储库的结果,所以我目前有两个根)

我希望历史看起来像这样

A1 ---- B1 ---- C1 ---- A2 ---- B2 ---- C2 ---- D ---- E --- F

但我无法弄清楚如何使用git-rebase做任何想法?

奖励:如果我可以保留标签(我在所有三个分支上都有)而无需手动执行...

2 个答案:

答案 0 :(得分:3)

我设法按顺序执行以下两个命令:

git filter-branch -f --parent-filter 'test $GIT_COMMIT = <a2> && echo "-p <c1>" || cat'
git filter-branch -f --parent-filter 'test $GIT_COMMIT = <new head> && echo "-p <c2>" || cat'

当然,您必须通过相应的提交哈希替换<a2><c1><new head>等。请注意,头部的哈希值在第一个命令之后发生变化,这就是我称之为<new head>而不是<d>的原因。

实际上非常简单:第一个命令将C1设置为A2的父级。第二个命令通过将C2设置为D的唯一父级来修复图形。

答案 1 :(得分:1)

好的我找到了办法。既然它对git内部的理解有了很大帮助,我在这里给出一个详细的答案:

首先,你必须给A2一个新的父母,因为它之前没有:

git cat-file commit A2

生成一个摘要,其中没有“父出现”。因此,创建该行,并创建一个新的哈希:

git cat-file commit A2 | sed -e '2aparent C1' | git hash-object -t commit -w --stdin

这将给出一个哈希值{H1}作为输出,我们用这个新哈希替换A2:

git replace A2 H1

瞧,A2现在已经将C1作为父母。但现在历史看起来像这样:

A1 ---- B1 ---- C1 --------------------- D ----- E ----- F
                  \                     /
                     A2 ---- B2 ---- C2

对D做同样的事情,D有两个父母(C1和C2):

git cat-file commit D

删除对应于C1和hash的“parent”行,并替换:

H2=`git cat-file commit D | sed -e '/parent C1/d' | git hash-object -t commit -w --stdin`
git replace D H2

看起来它对我有用。如果我很清楚我做了什么,这很有效,因为我在两个存储库中都有不同的文件。我认为如果我在两个存储库中都有共同的文件在D中以某种方式合并,那么事情可能会出错。