多分支的 Git - 重新设置基础分支

3

我正在处理3个分支,我想同时将一个分支从另外两个分支上进行变基。


我得到的结果是:

git log --graph --decorate --pretty=oneline --abbrev-commit

以下是分支A:
* f751d1a (A) commit2
* 4e552f3 (master) commit1

分支B:

* 3770d35 (B) commit3
* 4e552f3 (master) commit1

这是 C 分支,我首先从 A 分支进行了变基,然后又从 B 分支进行了变基:

* 9740b0e (HEAD, C) commit4
* a280f0a commit2                   //same commit name but different sha code
* 3770d35 (B) commit3
* 4e552f3 (master) commit1

当我执行

git checkout C
git rebase A

我得到了以下内容:
* 2e08816 (HEAD, C) commit4
* bbc77ad commit3                   //different sha-code
* f751d1a (A) commit2
* 4e552f3 (master) commit1

当我执行以下操作时:
git checkout C
git rebase B

我收到了以下内容:

* bf67d55 (HEAD, C) commit4
* f69ecdd commit2                   //different sha code
* 3770d35 (B) commit3
* 4e552f3 (master) commit1

但是,我真正需要的是创建 C 分支。

* 1234567 (HEAD, C) commit4
* 3770d35 (B) commit3
* f751d1a (A) commit2
* 4e552f3 (master) commit1

不改变分支A和B的情况下。

我做了一些研究,但无法弄清楚如何操作。是否有可能实现,有什么方法可以做到?

换句话说,我该如何转换

master---A
      \
       B---C
or

master---B
      \
       A---C

to

       A
      /
master---B
      \
       A---B---C

or something like this.

提前感谢...

附加问题:

谢谢(@Brian Phillips, @Useless)! 合并后,它似乎按照我的要求工作。然而,后来我在B中进行了提交,并使用git rebase master -i与行进行了“修复”。

pick 3770d35 commit3
fixup 3cbf79d commit4

它随着git merge B而变成以下内容:
*   5fa9192 (HEAD, C) Merge branch 'B' into C
|\  
| * 147258a (B) commit3 //changed content after fixup
* |   7768962 Merge branch 'B' into C
|\ \  
| * | 3770d35 B commit3
| |/  
* | f751d1a (A) commit2
|/  
* 4e552f3 (master) commit1

使用 git rebase B 命令后,它将变成:

* 0e1355b (HEAD, C)
* 147258a (B) commit3 //changed content after fixup
* 4e552f3 (master) commit1

有没有办法保持它这样:
*  (HEAD, C) 5454215 Merge branch 'B' into C
|\ 
| * 147258a (B) commit3 //changed content after fixup
| |  
* | f751d1a (A) commit2
|/  
* 4e552f3 (master) commit1

关于您的后续问题...您是指从B分支中删除提交3吗? - Useless
对不起,我犯了一个错误,刚刚进行了编辑。 - Alper
2
啊,所以你有两个版本的commit3(原始版本和rebase后的版本)都合并到了C中。好吧,有一种方法可以得到你要求的结果(将reset --hard C重置到合并之前,并使用新的B重新执行所有操作)。然而,更好的解决方案是_永远不要rebase已经在本地分支外可见的提交_。只需应用修复程序,合并它,停止试图掩盖你的错误-我们都会犯错... - Useless
2个回答

2
当你进行变基操作时,会创建一个新的提交记录,其中内容与原来相同,但元数据(祖先等)是新的。因此,你不能轻易地使用变基来完成这个任务。
现在让我们看看你的目标状态:
           2 [A]
          /
1 [master]--- 3 [B]
          \
           2 -- 3 -- 4 [c]

我重写了它,将您的提交与分支名称一起显示。这是不可能的,因为有两个具有不同元数据(它们有不同的父提交)的提交3的副本。

但是,您可以这样做:

           2 [A] ----
          /           \
1 [master]--- 3 [B] -- m -- 4 [C]

通过创建一个合并提交(m)来将分支A和B合并,然后在其之上对C进行变基。

谢谢!我在原始问题的底部添加了另一个问题,因为它没有适合这里:)请注意:) - Alper

2
由于git的SHA1提交ID不仅基于提交内容,还基于提交时间和祖先(以及其他因素)而创建,所以你所要求的是不可能的。除非发生SHA-1哈希冲突,否则提交ID 3770d35不能存在于任何其他地方。如果您对此话题感兴趣,可以阅读更多关于git内部的内容(http://git-scm.com/book/en/Git-Internals-Git-Objects 可以作为入门指南)。
我建议您不要过分重视提交ID,而应更多地考虑提交内容(如果有兴趣,也可以考虑排序)。您上面列出的第一次尝试(git checkout C; git rebase A)似乎在语义上符合您的要求。

谢谢,但是当我执行 git checkout C; git rebase A 后,在 git log --graph --decorate --pretty=oneline --abbrev-commit 中,f751d1a (A) commit2 行通过 (A) 引用了分支 A,然而 bbc77ad commit3 只显示了提交的名称。那么,有没有办法让 commit3 引用分支 B,即 bbc77ad (B) commit3。再次感谢... - Alper
1
不,提交只有作为分支的祖先才属于该分支。如果您想保留提交3来自“B”分支的事实,您应该使用merge而不是rebase - Brian Phillips
我已经合并了分支,请注意我在底部的附加问题,它没有适合这里:),谢谢! - Alper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接