重新定位以及通过rebasing推动提交意味着什么

时间:2010-04-26 16:28:16

标签: git rebase

通常会说,你不应该重新推销你已经推过的提交。这可能意味着什么?

4 个答案:

答案 0 :(得分:228)

要理解这一点,我们需要了解git的工作原理。 git存储库是树结构,其中树的节点是提交。这是一个非常简单的存储库的示例: When you fork

它在master分支上有四个提交,每个提交都有一个ID(在本例中为a,b,c和d)。您会注意到d当前是主分支的最新提交(或HEAD)。 enter image description here

在这里,我们有两个分支:master和my-branch。您可以看到master和my-branch都包含提交a和b,但随后它们开始发散:master包含c和d,而my-branch包含e和f。与主人相比,b被称为my-branch的“合并基础” - 或者更常见的是,只是“基础”。这是有道理的:你可以看到my-branch基于以前版本的master。

所以,让我们说my-branch已经过时了,你想让它与最新版本的master保持同步。换句话说,my-branch需要包含c和d。您可以进行合并,但这会导致分支包含奇怪的合并提交,这使得审查拉取请求变得更加困难。相反,你可以做一个变基。

enter image description here

当你重新绑定时,git找到你的分支的基础(在这种情况下,b),找到该基础和HEAD之间的所有提交(在这种情况下,e和f),并在HEAD上重新播放这些提交您正在重新定位的分支(在本例中为master)。 Git实际上创建了新的提交,表示你的更改在master之上的样子:在图中,这些提交称为e'和f'。 Git不会删除你以前的提交:e和f保持不变,如果rebase出现问题,你可以回到以前的状态。

当许多不同的人正在模拟地处理项目时,拉取请求可能会很快变得陈旧。 “陈旧”拉取请求是与主要开发线不再同步的请求,并且需要在合并到项目之前进行更新。拉请求过时的最常见原因是由于冲突:如果两个pull请求都修改了同一文件中的相似行,并且一个pull请求被合并,则unmerged pull请求现在将发生冲突。有时,拉请求可能会在没有冲突的情况下变得过时:代码库中不同文件的更改可能需要对您的pull请求进行相应更改以符合新架构,或者当有人意外地将失败的单元测试合并到主分公司。无论原因如何,如果您的请求已经过时,您需要将分支重新绑定到最新版本的主分支,然后才能合并。

答案 1 :(得分:78)

ProGit bookgood explanation

您的问题的具体答案可在标题为“ Rebasing的危险”的部分中找到。该部分的引用:

  

当你改变东西时,你就是   放弃现有的提交和   创造类似的新的但是   不同。如果你推送提交   在某个地方,其他人把它们拉下来   和基础工作,然后你   用git rebase重写这些提交   再推它们,你的   合作者将不得不重新合并   他们的工作和事情会变得混乱   当你试图把他们的工作拉回来   进入你的。

<强>更新
根据您在下面的评论,听起来您的Git工作流程有问题。以下是一些可能有用的参考资料:

答案 2 :(得分:66)

重新定位会重写历史记录。如果没有人知道那段历史,那就完全没问题了。然而,如果历史是公开的,那么在Git中重写历史就像它在现实世界中所做的那样:你需要一个阴谋。

阴谋真的非常难以保持在一起,所以你最好首先避免重新定位公共分支机构。

请注意, 成功阴谋的例子:Junio C. Hamano的git存储库(Git SCM的官方存储库)的pu分支经常被重新命名。这种方式的工作方式是,几乎所有使用pu的人都订阅了Git开发人员的邮件列表,并且pu分支被重新定位的事实在邮件列表和Git网站上被广泛宣传。

答案 3 :(得分:6)

rebase会改变存储库的历史记录。如果您将提交推送到世界,即将其提供给其他人,然后您更改了对提交历史记录的视图,则很难与具有旧历史的任何人一起工作。

我认为

Rebase considered harmful是一个很好的概述。