3

另一个git问题......我处于以下情况:

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

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

我希望历史看起来像这样

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

但是我无法弄清楚如何使用 git-rebase 来做到这一点,知道吗?

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

4

2 回答 2

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 的唯一父级来修复图形。

于 2012-06-28T00:22:32.323 回答
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 做同样的事情,它有两个父母(C1 和 C2):

git cat-file commit D

删除C1对应的“父”行,并散列,替换为:

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

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

于 2012-06-28T00:07:28.163 回答