Rebasing and what does one mean by rebasing pushed commits

It is often said that, you should not rebase commits that you have already pushed. What could be meaning of that?

71037 次浏览

ProGit 书很好的解释

你问题的具体答案可以在题为“ The Perils of Rebasing”的章节中找到:

When you rebase stuff, you’re 放弃现有的提交和 创造出新的类似但是 different. If you push commits somewhere and others pull them down 在他们的基础上,然后你 rewrite those commits with git rebase and push them up again, your 合作者必须重新合并 他们的工作和事情会变得一团糟 当你想把他们的工作拉回来的时候 进入你的世界。

更新:
基于你下面的评论,看起来你的 Git 工作流有点困难。下面是一些可能有帮助的参考资料:

Rebase 改变了存储库的历史。如果您向世界推出提交,也就是说,让其他人可以使用它们,然后您改变了对提交历史的看法,那么与任何拥有您的旧历史的人一起工作就会变得困难。

Rebase 被认为是有害的 是一个很好的概述,我认为。

改写历史。如果没人知道那段历史,那也没关系。然而,如果这段历史是公开的,那么在 Git 中重写历史就像在现实世界中一样: 你需要一个阴谋。

阴谋是 really难以保持在一起,所以你最好避免重新定位公共分支机构摆在首位。

请注意,这里有一些成功合谋的 例子: Junio C. Hamano 的 Git 存储库(Git SCM 的官方存储库)的 pu分支经常被重新定位。这种方法的工作原理是,几乎所有使用 pu的人都订阅了 Git 开发人员的 mailinglist,而且 pu分支的重新定位在 mailinglist 和 Git 网站上得到了广泛宣传。

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

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

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

So let's say that my-branch has gone stale, and you want to bring it up to date with the latest version of master. To put it another way, my-branch needs to contain c and d. You could do a merge, but that causes the branch to contain weird merge commits that make reviewing the pull request much more difficult. Instead, you can do a rebase.

enter image description here

当你重建基础时,git 找到你的分支的基础(在这个例子中是 b) ,找到基础和 HEAD 之间的所有提交(在这个例子中是 e 和 f) ,然后重新播放你重建基础的分支的 HEAD 上的提交(在这个例子中是 master)。Git 实际上创建了新的提交,表示您的更改在 master 顶部的样子: 在图中,这些提交被称为 e’和 f’。Git 不会删除您以前的提交: e 和 f 保持不变,如果 rebase 出了问题,您可以回到以前的状态。

当许多不同的人同时处理一个项目时,拉请求很快就会过时。“陈旧的”拉请求不再是开发主线的最新请求,在合并到项目中之前需要对其进行更新。拉取请求失效的最常见原因是由于冲突: 如果两个拉取请求都修改同一文件中的相似行,并且一个拉取请求被合并,那么未合并的拉取请求现在将有冲突。有时候,一个拉请求可能会过时而没有冲突: 可能代码库中不同文件的更改需要在你的拉请求中进行相应的更改以符合新的体系结构,或者可能分支是在有人不小心将失败的单元测试合并到主分支时创建的。不管是什么原因,如果您的拉请求已经过时,您需要将分支重新基于主分支的最新版本,然后才能合并它。