在长期存在的(远程)特性分支上进行git rebase

11

背景:我们在项目中使用Github,我在我们主要仓库的自己的fork上工作。为了避免大型合并提交,我们使用rebase而不是merge。

情境:我的工作方式如下:

  1. 实现新功能时,在我的fork的主分支上创建本地分支,并在其中放入更改。我和组内其他人进行许多小的提交,因此几乎总会有多个提交影响分支上的同一个文件。
  2. 将本地分支推送到我的fork上,这样我就有了我正在工作的远程副本(如果我的笔记本电脑死机或丢失,我不想失去所有更改。我尽量每天结束时执行此操作)。
  3. 如果完成特性需要很长时间,则偶尔在我的fork的主线上进行rebase,以确保没有更改可能破坏我的特性。这通常能正常工作。
  4. 为了使分支的远程副本保持最新状态,在rebase之后,将本地分支推送到该分支。

问题:第4步是我遇到问题的地方。我几乎总是不得不处理非快进提交并使用git push --force。

我看过了

Git: how to maintain permanent parallel branches

How to maintain (mostly) parallel branches with only a few difference

并没有找到一种使我的工作流程正常工作的方法。进行有关git工作流程的谷歌搜索通常返回假定您所有人都在本地分支上工作,并且不在github上保留远程副本的结果(例如http://nvie.com/posts/a-successful-git-branching-model/)。

我对Git相对较新,所以想知道是否有遗漏。我希望在不使用 --force 的情况下完成第4步。另一种工作流程仍然允许我使用rebase代替merge并保留本地分支的远程副本也非常有用。

2个回答

12

git push --force 是在处理 rebase 和远程分支时不可避免的,因为没有它,git push 将不会进行非快进式推送。在 Git 中,大多数操作都假定历史记录只能增加而不能被编辑,而 rebase 打破了这个假设,所以你需要做一些奇怪的事情来使它正常工作。

我们曾经使用过与您描述类似的 rebase 工作流程,但最终在一段时间后改回了合并工作流程。Rebase 可以让您获得漂亮的线性历史记录,但也有许多缺点,比如需要使用 --force,失去了在将主分支合并之前查看分支状态的能力,等等。

正如 Amber 所提到的,使用 rebase 在同一分支上与其他人协作非常困难 - 在 git push --force 之前,你必须查看远程分支的状态,以查看是否有其他人先推送过,然后使用 pull --rebase 进行拉取,最后再进行 git push --force。即使这样也存在竞争条件——如果有人在你执行 push --force 之前刚好推送了代码,你的更改将会覆盖他们的更改。


3
您可以使用--force-with-lease来避免竞态条件,如果上游版本比本地版本新,它将失败。 - mLuby

6
如果您正在进行rebase,当您推送时,您总是需要使用--force,因为rebase会重写历史记录。这就是它的工作原理。根据定义,重写的历史记录不会在同样的历史记录上进行快进操作。
另一种选择是使用merge而不是rebase。您可以使用相同的工作流程,只需使用合并而不是rebase,并且您不必强制推送。
如果除了您之外没有其他人使用您的远程分支,则使用--force并不会本质上有问题。如果其他人正在使用远程分支,则可能应该使用merge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接