Git rebase 和子分支

Git rebase and children branches

我的项目有以下情况

Master M1----M2----M3----M4----M5
                     \
                 Beta B1----B2----B3---B4
                                   \
                          Feature   F1---F2---F3

我正在 Feature 中开发,但是在提交 M5 时发布了一个非常重要的更新,我不想从 B3 中分离 FeatureFeature取决于B1B2),而Beta可以有变化(Beta没有区别)。

如果我在 Beta 上创建 git rebase Master,它只会移动 Beta 分支,对吗(Feature 上没有应用任何更改)?或者它会像这样结束(下面 - 更改也适用于 Feature)?

Master M1----M2----M3----M4----M5
                                 \
                             Beta B1----B2----B3---B4
                                               \
                                      Feature   F1---F2---F3

而且,要变成这样(应用于 Feature 的更改),我该怎么办?那是我想要的状态...

实际上它会以这样的方式结束:

Master M1----M2----M3----M4----M5
                    \            \
                     \       Beta B1----B2----B3---B4
                      \
                       \--B1'---B2'---B3'----F1---F2---F3
                                                       ^
                                                    feature

基本上,您对 Beta 的变基将在当前 master 提示之上重新应用 Beta 上的提交。但是,原始提交将仍然存在,如果其他任何内容(例如另一个分支)引用这些提交,它们将仍然存在。

您需要先变基 Beta,然后变基 feature 才能移动所有内容 "into the correct place"。

你是正确的:运行 git rebase MasterBeta 不会影响 Feature。 (旁白:为什么是大写字母?)

这里的根本问题是git rebase“意味着”复制一些提交。诀窍是查看哪些提交被复制,复制到何处,以及之后分支名称发生了什么。如果被复制的提交也可以从某个 other 分支访问,那么原始文件——在复制之前——仍然可以从其他分支访问。

请记住,所有分支名称都只是指针,指向分支上的最新提交。所有较早的父提交都在该分支上,即使那些较早的提交也在其他分支上。所以“所有 Beta 提交”最初包括 M1M3

那么,第一个git rebase怎么知道只复制B1B2B3B4?我认为一个关键项目是绘制图形有点不同:

M1----M2----M3----M4----M5   <-- Master
              \
               B1----B2----B3---B4   <-- Beta
                            \
                             F1---F2---F3   <-- Feature

要查看将被复制的内容,请使用绿色荧光笔指向分支的尖端提交,即 Beta 所指向的 B4,并在您关注时为所有提交涂上绿色向左的线。这包括 M3 及更早的提交。然后,使用 red 荧光笔到 Master 的提示提交(即 M5),并按照以下方式为所有提交着色 red线向左。红色覆盖了绿色,因此 M3 及更早版本不考虑用于复制。这留下了正确的提交集来复制。

副本本身在参数的尖端提交之后着陆。那是 Master,所以副本在 M5 之后。

在Git完成复制后,Git将名称Beta移动到指向B4的副本,我们称之为B4'。这使得原始 Bn 提交悬空...除了 B3 可以从 F1:

访问
                          B1'---B2'---B3'--B4'   <-- Beta
                         /
M1----M2----M3----M4----M5   <-- Master
              \
               B1----B2----B3---B4   [no name]
                            \
                             F1---F2---F3   <-- Feature

所以这对 Beta 没问题,但现在您想复制 Feature 的提交。如果你:

git checkout Feature
git rebase Beta

Git 会把 F3 染成绿色,然后 F2F1 ……然后继续标记 B3B1 绿色也是如此。只有 副本 B1'B2'B3'B4' 和五个 M 提交,才会着色或被红色覆盖。所以 Git 会复制太多提交。

解决方案是使用git rebase --onto <name>。添加 --onto 告诉 Git 将副本放在哪里:您希望它们放在 B4' 之后,所以您可以说 --onto Beta 表示副本放在 Beta 之后,即, B4'.

这实际上并没有修复任何东西......还。但它释放了 other 的论点, Beta 的论点,嗯,是别的东西。

您想要的是告诉 Git 从哪里开始将提交标记为红色。那是 B3,或者如果它更容易,B4。这会将 B3 及其所有较早的提交(包括 M3 和更早的提交)标记为红色:请勿复制。

你可以使用B3的原始ID,如果你保存它。或者您可以轻松地让 Git 使用 Beta@{1}:

查找 Betaprevious 提示
git rebase --onto Beta Beta@{1}

这会使用 Beta.

的 reflog 找到提交 B4 的哈希 ID