git rebase和共享一个特性分支?

4
基于此:https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase git rebase 可以使历史保持线性(合并“总是”导致快进)
但是,如果我想强制要求将开发人员的特性分支始终基于最新的 master 并保持线性历史,那么这不会导致协作/共享功能分支的消失吗?请参见: 不要重写公共历史 所以,是否可能使用 git rebase 强制实现线性历史,同时允许多个开发人员为同一特性分支做出贡献?
还是说 git rebase 意味着特性分支只能有一个所有者?

想要强制实行线性历史记录是很“傻”的。 - leftaroundabout
调试时不需要使用git bisect吗? - u123
3
每个特性分支只有一个负责人肯定是最不痛苦的选择。 - Sergio Tulentsev
2
@leftaroundabout,然而,鼓励将特性分支变基以便于同行审查和提高可维护性确实有其好处。我同意不应该强制执行。 - cmbuckley
你能否详细说明一下为什么你想要“协作”甚至是“共享”的特性分支? - k0pernikus
与其在代码审查界面中编写注释,有人可能希望本地检出分支,实现一些更改,并将这些更改推送给原始作者查看。 - u123
4个回答

6
"Don't rebase public history"是一个不错的起点规则。更全面的建议是,如果你要rebase共享分支,你需要得到所有拥有该分支副本的人的同意/合作。
(此时通常会有人插话并反对说有时无法得到所有人的同意是不切实际的。他们想表达的是这个规则太严格了;但这就像说光速太慢了因为我需要更快地旅行。正确的分析是,是的,有时你无法得到所有人的支持;在这些情况下,你不应该rebase。因此简化的“不要rebase公共历史”。如果你没有每个共享该分支的人的合作,重构该分支是不安全的,你的尝试很容易被意外撤消。但我扯远了……)
因此,如果团队规范是人们在分支上协作后,并且当你准备合并它时,你要rebase它并且每个人都会放弃他们本地的分支副本,那么没问题——你已经得到了每个人对重构的合作。
但这并不一定意味着这是个好主意。重构的营销文献喜欢把线性历史吹嘘为“简单”,但遗漏了你的新线性历史主要由从未经过测试的代码状态组成(这可能会破坏使用bisect进行错误调试的尝试)。一些项目发现保留提交拓扑结构很有价值,这样他们就可以回顾特性分支作为一个单元,而不仅仅是必须弄清楚提交K到N恰好曾经是一个特性分支。
但所有这些都取决于你/你的团队。如果你认为线性历史适合你,那么是的,即使特性分支是共享的,它也可以被实现,只要你在合并后丢弃它们(为什么不这样做?)。

2
我假设你的问题源于使用一个中央git仓库而非私有分支的常见工作流程。在这个远程仓库上,所有开发者都可以将分支推送到其中。
正因为如此,每个开发者都可能觉得有权力推送和合并任何他们想要的代码。在这样的工作流程中,git rebase 确实可能变得危险,因为开发者可能会由于意外删除已经被推送的提交而进行强制推送。
如果你正在使用这种“牛仔”式的git工作流程,那么建议开发者使用--force-with-lease而不是简单的--force
我认为放弃协作和共享特性分支是一件好事。
在我的团队的主要远程git仓库(真相之源)中,我保护了master分支,防止其被rebase。
我建议遵循以下规则:
  • 总是从master分支派生一个特性分支,没有例外
  • 再次强调:永远不要从另一个特性分支派生出一个特性分支
  • 如果你依赖于其他开发人员当前正在开发的另一个特性分支,等待他们将这些更改合并到master中
  • 经常将你的特性分支rebasemaster上(以包含你的依赖项,或者只是为了保持master的最新状态),这有助于在发生合并冲突时解决它们
  • 可选:将你的提交压缩成一个,如果你使用git web前端(github、bitbucket等),他们提供了合并压缩拉取请求的功能,你可能也想使用这个功能
创建分支的开发者拥有该分支。他们可以做任何他们想做的事情:删除、rebase、tango合并,在这个分支上与其他人进行配对编程(其他人可能仍然在他们的分支上提交代码,但只有在所有者明确同意和知道的情况下)。
主要分支,例如masterdevelop,是公共的。它们是神圣的。你不会改变它们的历史,也会保护它们免受删除和其历史被覆盖的影响。如果你需要撤消主干上的一个特性,你将使用revert

你推荐的工作流程完美地描述了我的意思,也是我想要实施的。单一功能分支所有者的想法,如果其他开发人员要为该功能分支做出贡献,必须得到所有者的同意。在大多数情况下,常规做法是所有者将其功能分支变基到主分支并进行强制推送以更新/覆盖之前推送的功能。 - u123

1
是的,这是可能的。虽然建议谨慎一些。
通过变基(rebase),特性分支的更改被添加到主开发线中。这应该在审查后进行(在 GitLab/GitHub 中称为合并/拉取请求被接受之后)。因此,之前的开发不一定涉及任何早期的变基;特性分支可能已经被多个开发人员共享、工作和提交。

不要变基公共历史记录

通常意味着您不应该变基其他人可能基于其工作的提交(例如公共存储库的 master 或 develop 分支)。由于没有人应该基于已完成但尚未合并的特性分支进行工作,因此这不适用于您的情况。

好的,但是如果您需要在审核期间更新到最新的主分支,那么您将不得不合并主分支,因此无法保持线性图。此外,在审核期间,您可能还想压缩/变基提交以使其更易于阅读/审核。 - u123
“这不适用于您的情况” - 据我所了解,这在他们的情况下确实适用。那里的情景是多个开发人员同时开发一个功能(前端+后端开发人员或其他)。 - Sergio Tulentsev
@u123:理想情况下,您应在审核之前压缩/变基。 - Sergio Tulentsev
@u123: "如果在审核期间需要更新到最新的主分支怎么办" - 我只需变基。但我几乎总是该分支的唯一所有者。 - Sergio Tulentsev
@u123 这是一个合理的担忧;合并最新的主分支肯定会使变基过程更加痛苦,并且会嘲弄“线性历史”的概念。这就是我所说的“建议谨慎”的其中之一点。 - kowsky
@SergioTulentsev,这种情况不适用,因为只有在功能完成时才重新定位是没有问题的,因此没有人会继续在将被重新定位的提交上工作。当然,这非常依赖于工作流程,并且可能不适用于您的工作方式;但是OP的问题是是否可能,而它确实是可能的。 - kowsky

0

我建议您可以鼓励(而不是强制)线性历史,通过要求开发人员在同行评审之前重新设置其功能分支。

这将允许开发人员进行协作、交叉合并并对该功能感到满意,在最后重写历史之前,以便评审人员能够轻松阅读。

当然,这仍然存在重设公共历史的风险,并且可能会给那些不熟悉此类做法的开发人员带来问题。这就是为什么我会鼓励那些习惯于此的人进行重新设置,但不会强制执行。


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