【问题标题】:git - rebasing from multiple branchesgit - 从多个分支变基
【发布时间】:2012-10-27 13:03:39
【问题描述】:

我正在使用 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

       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?
  • 对不起,我弄错了,刚刚重新编辑了。
  • 啊,所以你有两个版本的 commit3(原始版本和重新定位的版本)都合并到 C 中。嗯,有一种方法可以得到你的要求(在合并,然后用新的 B) 再做一遍。然而,更好的解决方案是永远不要对在本地分支之外已经可见的提交进行变基。只需应用修复、合并它,然后停止试图掩盖你的错误——我们都会犯错......

标签: git branch rebase


【解决方案1】:

由于 git 的 SHA1 提交 ID 不仅基于提交的内容,而且还基于这些提交的时间和祖先(除其他外),因此您要求的内容是不可能的。提交 ID 3770d35 只能作为它开始的确切位置(缺少 SHA-1 哈希冲突)而存在。如果对这个主题感兴趣,您可能想了解更多关于 git 内部的信息(http://git-scm.com/book/en/Git-Internals-Git-Objects 可能对初学者有好处)。

我会鼓励您不要对提交 ID 过于重视,而是更多地考虑提交内容(以及排序,如果感兴趣的话)。您在上面列出的第一次尝试 (git checkout C; git rebase A) 在语义上似乎就是您要查找的内容。

【讨论】:

  • 谢谢,但是当我在git log --graph --decorate --pretty=oneline --abbrev-commit 中执行git checkout C; git rebase A 时,f751d1a (A) commit2 行通过 (A) 引用分支 A b>,但是 bbc77ad commit3 只显示提交的名称。那么,有没有办法让commit3引用分支B,即bbc77ad (B) commit3。再次感谢...
  • 不,提交仅属于分支,因为它是分支的尖端(HEAD)的祖先。如果你想保留 commit3 来自分支“B”的事实,你应该使用merge 而不是rebase
  • 我合并了分支,请注意我在底部的附加问题,它不适合这里:),谢谢!
【解决方案2】:

当你变基时,你创建了一个 new 提交,其内容相同,但 new 元数据(祖先等)。所以,你不能随便使用 rebase 来做到这一点。

让我们看看你的目标状态:

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

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

但是,您可以这样做:

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

通过创建一个合并分支 A 和 B 的合并提交 (m),然后在此基础上重新设置 C。

【讨论】:

  • 谢谢!我在原始问题的底部添加了另一个问题,因为它不适合这里:) 请注意:)
猜你喜欢
  • 2016-09-20
  • 2014-05-21
  • 2020-07-04
  • 2015-03-28
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
  • 1970-01-01
  • 2011-02-05
相关资源
最近更新 更多