【问题标题】:Is it possible to rebase onto the middle of a branch (connecting both ends)?是否可以重新定位到分支的中间(连接两端)?
【发布时间】:2018-01-25 13:34:29
【问题描述】:

不是重复的!

我看到的所有原版变基示例都显示了如何将分支变基到另一个分支/提交的顶部。比方说,是否可以将分支 A 移动到分支 B 的具体中间位置?

        O--O--O Branch B             O--0--0--O--O Branch B
       /                            /  
O--O--O--0--0   Branch A     O--O--O

编辑:我不是在寻找变基为任意提交,而是在分支中间变基,连接两端

【问题讨论】:

  • 当然可以,你可以签出一个提交,在那里创建一个分支,然后再变基
  • @Dunno 情况不同。在您的链接示例中,我的情况相当于将 D 放在 B 和 C 之间
  • 你可以在任何提交之上重新设置基准。
  • @axiac 我知道,但我想要的不是“在特定提交之上的变基”而是“另一个分支的 2 个提交之间的变基”

标签: git git-branch rebase branching-and-merging


【解决方案1】:

您要求从一个分支获取提交并将它们放在另一个分支的中间。 (这个措辞真的与 git 如何“思考”分支和提交的关系不符,但我认为你的意思很清楚,所以好吧......)

FROM:

x -- x -- A -- B -- C -- F -- G <--(branch_1)
      \
       D -- E <--(branch_2)

TO:

x -- x -- A -- B -- C -- D' -- E' -- F' -- G' <--(branch_1)

(目前尚不清楚您希望 branch_2 引用结束的位置 - 或者您是否只想删除它 - 但正确提交是更大的问题,您可以在之后计算出引用。)

重要的旁注:在此图中,D 之后的提交被替换D' 之后的提交;这是因为不能以任何方式“移动”或更改提交,所以我们要做的是创建新的提交。这意味着提交 DEFG(原始版本)已从分支的历史记录中删除,如果分支已被删除,这可能会导致问题推。请参阅git rebase 文档 (https://git-scm.com/docs/git-rebase) 以获取有关可能导致的问题以及如何解决这些问题的更多信息;请注意,如果不解决这些问题,其他开发人员很可能会无意中撤消您的工作。

也就是说,有多种方法可以解决;通常你需要两个 rebase 操作。

考虑它的更直接的方法之一是,只需正常执行 rebase,然后执行交互式 rebase 以更改提交顺序。

如果你想要一些更具脚本性的东西,你可以从

git rebase --onto branch_1~2 branch_1 branch_2

这里的--onto 选项指定了一个新的基数,而不是默认值(默认值是“上游的尖端”)。因为我在此示例中将提交插入到 branch_1 的父级的父级之后,所以我可以使用 branch_1~2branch_1^^ 作为新的基本表达式。要重写的提交以通常的方式指定(在这种情况下“可从branch_2 访问,但不能从branch_1 访问)。所以你有

x -- x -- A -- B -- C -- F -- G <--(branch_1)
                     \
                      D' -- E' <--(branch_2)

现在你以正常方式简单地将rebase branch_1 冷到branch_2 的末尾。

git rebase branch_2 branch_1

屈服

x -- x -- A -- B -- C -- D' -- E' -- F' -- G' <--(branch_1)
                                ^(branch_2)

【讨论】:

    【解决方案2】:

    您的问题含糊不清,幸运的是,该图阐明了您想要什么。

    如果我理解正确的话,这是repo的输入状态

            M--N--P   <-- Branch B
           /
    O--O--X--Y--Z     <-- Branch A
    

    这就是您想要实现的目标。我用字母来表示提交。

            M--Y--Z--N--P   <-- Branch B
           /
    O--O--X
    

    首先,您必须创建一个指向 M 的新分支 (C) 以使其在操作结束前一直可见

    git branch C B~2
    

    B~2 替换为从NB(包括两者)的实际提交数或使用绝对引用(现有分支或提交哈希)。

    以下命令将N-P 移动到Z 之上。它将所有在B 中但不在C 中的提交移动到A 之上

    # Move N-P on top of Z (A points to Z, B points to P, C points to M)
    git rebase --onto A C B
    

    最后一步是将B 中但不在C 中的所有提交移到C 之上:

    # Move Y-Z-N-P on top of M (B still points to P, A still points to Z)
    git rebase C B
    

    回购现在看起来像这样:

            +-- Branch C
            v
            M--Y'-Z'-N'-P'  <-- Branch B
           /
    O--O--X--Y--Z           <-- Branch A
    

    分支A仍然指向原来的Z提交;原始的Y 提交也仍然存在。当前分支是B

    提交Y'Z'N'P'YZNP 的副本。它们仅在提交日期和父项上与原件不同;没有代码更改。

    现在可以删除分支AC。 (git branch -D A C)。

    阅读更多关于git rebase的信息。

    【讨论】:

      【解决方案3】:

      是的,有可能,你需要先

      git checkout <commit>
      

      然后变基你的分支,然后推送到原点。

      【讨论】:

      • 感谢您的回答!这会像第二张照片一样显示吗?我会放弃 B 分支的最后一次提交吗?
      • 在您的图片中,这将是两个变基,一个从 A 到 B,因此您将图形移到右侧(顶部),然后另一个从 B 到 A 进行连接
      • 我仍然不确定这是否正是我的情况,抱歉。看起来每个人都认为我希望分支粘在另一个分支上,而不是集成
      • 比这是否是 Whimusical 指定的操作更基本,它似乎不正确。当您执行 rebase 时检查出的提交不会以这种方式建议的方式确定重写提交的新基础。 (它确实为最后一次重写的提交提供了默认值,但我几乎从不使用这个事实。)
      【解决方案4】:

      我首先通常将分支 A 重新设置为分支 B。然后我将使用 git rebase -i HEAD~n(其中 n 是交互式编辑的提交数)并重新排列提交(通过简单地更改编辑器中的行顺序)。

      【讨论】:

        猜你喜欢
        • 2014-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-08
        • 1970-01-01
        • 1970-01-01
        • 2016-11-17
        • 2020-09-19
        相关资源
        最近更新 更多