为什么我的“git rebase master”在最后一次合并后返回的提交比“正常”多?

Cut*_*tis 6 git branch commit rebase

我试图理解我做错了什么,但什么也没有。我完全糊涂了。我知道合并分支(或提交)的另一种方法是使用“git rebase”。我有 3 个分支:master 和另外 2 个用于不同功能的分支。我们来谈谈master,f1和f2。我正在处理我的 f1,我需要另一个功能,所以我创建了 f2。当我完成 f1 时,master 已经有另一个变化。我想在 master 上 rebase f1。我做到了,我看到了 144 个步骤。我尝试修复所有提交并推送更改。现在我将我的 f2 提交应用到 f​​1 并决定向 master 发出拉取请求。我尝试在 master 上重新设置 f1,我得到了 244 步。或者它只是对 master 的 4 个新提交。我已经在我当地的主人身上得到了它们。

我感到很困惑。每次我想使用 rebase 时,似乎我都会得到更多真正完成提交的步骤。

我必须说一开始我只是用“git merge”做合并,但我被要求用“git rebase”来做。

我尝试搜索为什么我的步骤太多,我再次遵循教程,但我无法再次尝试修复超过 200 个步骤。很无聊,需要时间。你能解释我更多并帮助解决这种情况吗?我不想现在解决这个问题,然后再得到 300 多个。谢谢

Vla*_*274 8

你对 rebase 的作用有严重的误解,我相信这就是造成这种非常令人沮丧的情况的原因。

可能发生了什么

假设您有以下情况(我相信这就是您所描述的)。

master  o---o---o---o---o---o
                 \
feature1          A---B---C
                           \
feature2                    X---Y---Z
Run Code Online (Sandbox Code Playgroud)

您已经完成了对 的工作feature1,但是 master 上的一些提交尚未经过feature1更改测试。因此,要更新feature1您,请执行以下操作:

  • git checkout feature1
  • git rebase master

这导致以下情况:

master  o---o---o---o---o---o
                 \           \
feature1          \           A'---B'---C'
                   \        
feature2            A---B---C---X---Y---Z
Run Code Online (Sandbox Code Playgroud)

等等,什么?为什么有两个副本A-B-C!?

这就是rebase它的作用。Rebase从命令中给出的基数开始进行 NEW 提交(master在这种情况下)。

接下来可能发生了什么

现在feature1已经用最新的 from 更新了master,你需要更新feature2。因此,您遵循相同的过程:

  • git checkout feature2
  • git rebase feature1

这导致以下情况:

master  o---o---o---o---o---o
                             \
feature1                      A'---B'---C'
                                         \        
feature2                                  A"---B"---C"---X---Y---Z
Run Code Online (Sandbox Code Playgroud)

哦哦。

正如您所看到的,经过几次此循环后,您最终会陷入非常糟糕的境地,您必须解决“冲突”,这些“冲突”只是一遍又一遍地应用相同的更改。

如何解决当前的烂摊子

只是硬着头皮使用merge。说真的,这是处理它的最快方法。从masterwith更新功能分支git merge master,然后merge将功能分支回 master(在适当的时候)。

或者,您可以深入研究交互式变基的黑暗魔法。-i在运行时使用该标志git rebase,您将看到它尝试重新应用的所有提交的列表。删除重复项并继续您的快乐方式。我不喜欢这种方法,因为它很容易犯错误,而且从这些错误中恢复是一种 PIA。

如何避免这种情况发生

详细文章

简而言之,您需要告诉 git 忽略重复的提交。更新feature1usingrebase很好,问题发生在feature2.

  • git checkout feature2
  • git rebase --onto feature1 feature1@{1} feature2

这让我们

master  o---o---o---o---o---o
                             \
feature1                      A'---B'---C'
                                         \        
feature2                                  X'---Y'---Z'
Run Code Online (Sandbox Code Playgroud)

正是我们想要的!

那么,这个命令是做什么的呢?

git rebase --onto feature1 feature1@{1} feature2

  • --onto feature1 - 我们将把这些提交移到分支上 feature1
  • feature1@{1}- 我们只是rebase'd feature1,所以我们需要获得上一次提交(即变基之前的提交)。这是我们正在移动的提交范围的开始
  • feature2 - 这是我们正在移动的提交范围的结束

注意:feature1@{1}将在用作文章中描述的过程的一部分时起作用,但如果在更新feature1feature2. 在这种情况下,您可以将其替换为原始提交 ID - 通过查看git logwhile on的输出并从中feature2选择最后一次提交feature1(此处给出的示例中的“C”)获得。

其他好读物:

Atlassian 文章:合并与变基

所以问题