git“重新定金的黄金法则”是如此重要吗?


22

最近,我与绝对反对在GIT上对功能分支的重新定位策略的人们进行了讨论。这似乎是一种公认​​的模式,仅对本地私有分支使用rebase,但是当有多个人在同一个功能和分支上工作时,从不使用它,这就是所谓的“重新分配的黄金法则”(如此处所述:https ://www.atlassian.com/git/tutorials/merging-vs-rebasing/conceptual-overview

我只是对此感到惊讶。我花了3年的时间制定了完整的重新调整策略,大约有20位开发人员共同努力,并猜出了什么有效。

该过程基本上是:

  • 创建功能分支,我们将其称为“ myfeature”,并将其推送到origin / myfeature
  • 其他人可能会检查出来并进行处理
  • 您有时可能会从master重新设置它的基准:从“ myfeature”,git rebase origin / master ; 然后,是的,您必须强制使用它。
  • 当其他人想要推送他们的提交时会发生什么?他们只是重新设置它的基础:git rebase origin / myfeature。因此,他们现在处在快速前进的过程中,无需强求就可以推动它。

要遵守的唯一原则是要素分支由某人拥有。所有者是唯一可以推动力量的人。

因此,我承认:只要有推动力,就有犯错误的风险。确实如此。但是也有很多方法可以从错误中恢复,实际上,在3年的开发中,我没有看到很多强制错误,而且当它发生时,我们总能找到一种正确恢复的方法。

那么,为什么这种“黄金基础规则”被如此广泛地接受呢?我还有其他想念的吗?我了解这需要最少的组织(每个策略都需要某些组织),但是它可以工作。


我忘了讲些什么,但是它很重要:根据我以前的经验,我们使用gerrit作为代码审查工具。这意味着,如果某人在分支所有者进行基础更改时推送了提交,则不会丢失提交,因为它将提交推送到gerrit而不是直接推送到原始存储库。而且由于分支机构所有者是唯一有权从Gerrit提交提交的人,因此犯错的风险非常低。
2015年

如果将其他人的功能分支合并到我自己的分支中怎么办?
Winston Ewert 2015年

如果您的功能依赖于另一个功能,那么我想您可以从另一个功能中重新设置您的功能:git rebase origin / otherFeature(我说是重新设置而不是合并,因为目标是保持历史记录的线性化)。我承认,当您在分支之间引入越来越多的依赖关系时,所有这些的复杂性就会大大增加。
乔尔

Answers:


10

强制推送的问题与您的功能分支和母版无关,而与将母版推到其他人的母版有关–同步将通过您的更改覆盖其母版,而忽略了他们的建议。

考虑到这种危险,有一个原因,就是除非事情搞砸了,否则您根本不应该使用它,而您绝对需要使用它来进行维修。如果SCM系统这样做是因为出了点太严重的错误(在这种情况下,我的第一个方法将是还原备份并重复操作以保持历史记录完整),那么它就永远不必这样强迫。

因此,也许的问题是,为什么您要全部撤离?将功能重新掌握时的“干净”历史记录?如果是这样,那么纯粹出于样式原因,您会丢掉所有有关分支的良好历史记录。恕我直言,快速合并也不是最佳实践,您应该保留所有历史记录,以便可以看到自己的实际操作,而不是之后的版本。


当然,您可以拉紧主服务器,重新设置基础,然后强制推入,但这不是原子的。
凯文

@gbjbaanb你是完全正确的,重新调整策略是所有关于样式的原因/更具可读性的历史。我并不是要争辩说它更好还是不更好。但是有可能这样做,这就是我要提出的重点。当然,我不是在谈论在master上强制推,而是在功能分支上。
乔尔2015年

4
恕我直言,重新设计和快速合并的设计功能是一个错误。SCM旨在保留历史记录,以便您可以查看需要时发生的情况,并为相关时间点拍摄快照。至少那是大多数人想要的,我想莱纳斯希望历史对他来说尽可能简单,以便他受益。恕我直言,他应该付出更多的努力使两个修订版之间的差异更易于管理(例如,使视图更简单,而不是基础的历史记录)
gbjbaanb

2
发表论文时,您是否发表初稿?是否有法律规定您用来编写第一稿的工具不能用于编辑该稿以进行发布?Git是一种开发工具。如果要可靠且可验证地保留系列,请保留它。如果您想编辑它以进行发布,请对其进行编辑。Git在这两个任务上都表现出色。
jthill

5

变基并不是必不可少的,因为您说的主要是修饰。有时,合并要简单得多。因此它可以具有一些“实际”价值,但只有“有时”

错误使用rebase可能会造成高昂的成本。如果您不了解紧急情况并查找恢复过程,就不太可能丢失数据,但是“嘿,没人要我修复一段时间……”并不是很好。也没有人花时间在研究恢复和测试上,因为他们本来可以添加功能或压缩错误(或带家人回家)。

有了这种权衡,“很少有人进行改组和强行推动”的结果就不足为奇了。

某些工作流程可以降低风险,例如将其降低为“零,只要您记住允许强制执行的分支和不能强制执行的分支”即可。实际上,它们可能足够安全以证明风险,但人们经常根据更大的民俗来做出选择。那么实际上收益又是很小的,那么风险真正需要多少呢?


3
“嘿,没人要我修复一段时间……”听起来像是使用Visual Source Safe的旧时代。我认为git比那更好。
gbjbaanb 2015年

是的,因此人们制定了“不要使用锋利的工具!(强行推动)”这样的规则,这样就可以避免治疗可避免的伤口!
条纹

2
@gbjbaanb是的,如果正确使用Git,它会比这更好。抱怨Git在不断修改基础并更改所有内容的提交哈希时无法优雅地处理并发开发,就好像在抱怨汽车不如马车,因为马车要沉重得多。人们坚持使用错误不是工具的过错……
Idan Arye

4
嗯,这是该工具的错误。Git暴露了很多锐利的边缘,虽然有时会指出它们很锐利,但通常不会。如果您将其与CVS进行比较(如果所有的尖锐位都在SINGLE子命令中)(“ cvs admin”?这已经有一段时间了……),那么您会说“这会伤到您,不要这么做”除非有迫切需要,否则请使用它。” 或其他版本控制系统忽略了可能会损害功能的功能。
条纹

4
但这并不是说git尚未做出有效的设计选择(通过子命令对相关功能进行分组,并且更愿意让git在右手解决更复杂的问题)...但是它们是选择,并且可能会批评选择具有如此多的尖锐边缘,就像对其他VCS的选择可能会提出批评一样,就是遗漏了这么多有用的功能,“只是因为有人会受伤”。
条纹

2

要添加其他声音:

是的,如果按照您的描述进行工作,则使用rebase和强制推动没有问题。关键点是:您的团队已达成协议。

关于rebase和的警告是针对没有特殊协议的情况。通常,git会自动保护您,例如,不允许非快进推送。使用rebase和强行推压会超过此安全性。如果您还有其他地方,那没关系。

在我的团队中,如果历史变得混乱,有时我们还会为要素分支重新设置基础。我们要么删除旧的分支,然后使用新名称创建一个新分支,要么我们只是非正式地进行协调(这是可能的,因为我们是一个很小的团队,在存储库中没有其他人工作)。


请注意,git项目本身也具有类似的功能:它们具有一个定期重新创建的集成分支,称为“ pu”(“建议的更新”)。据记录,该分支会定期重新创建,并且您不应该在此基础上进行新工作。


1

因此,我承认:只要有推动力,就有犯错误的风险。确实如此。但是也有很多方法可以从错误中恢复,实际上,在3年的开发中,我没有看到很多强制错误,而且当它发生时,我们总能找到一种正确恢复的方法。

Git用户倾向于避免共享的可变历史记录的原因是因为没有自动避免或修复这些问题。您必须知道自己在做什么,如果您搞砸了,就必须手动修复所有问题。完全允许一个人进行推力是不直观的,并且与Git的分布式设计相反。如果那个人去度假怎么办?别人是否暂时拥有分支机构?您怎么知道他们不会走遍原始所有者的所有工作?在开源世界中,如果分支机构的所有者在没有正式离开的情况下逐渐远离社区,该怎么办?您可能会浪费大量时间等待将分支机构所有权移交给其他人。

但是真正的问题是:如果您搞砸了并且没有立即意识到这一点,那么经过足够的时间之后,旧的提交最终消失。到那时,问题可能无法恢复(或者至少可能很难恢复,具体取决于您的备份故事-您是否备份Git存储库的旧副本,即不只是克隆副本?)。

将此与Mercurial的Changeset演化工作(我应该指出,尚未完成或稳定)进行对比。只要更改集未标记为公开,每个人都可以对自己喜欢的历史进行任何更改。这些修改和变基可以完全不受惩罚地推入和拉出,不需要分支机构所有者。永远不会删除任何数据;整个本地存储库只能追加。不再需要的变更集已标记为过时,但可以无限期地保留。最后,当您弄乱历史记录(这被视为日常工作流程的正常部分)时,有一个漂亮的命令可以自动为您清理历史记录。 是那种UX他们四处修改共同的历史之前,人们期待。


我同意这种“ git哲学”,我也认为哲学有时可能会被黑:)。更严重的是,正如我在评论中指出的那样,距今已有3年了,在特殊情况下,我将Gerrit用作代码审查工具,充当了事实上的备份工具,避免了这种潜在的巨大损失。现在,当您确定要“控制”分支时,我仍然认为重新设置是可以的。即使在开放源代码项目中,如果我正在开发功能并打开拉取请求,我也“拥有”该公关,我认为我有权对其分支机构进行基础调整,这取决于我自己,在重新定级的过程中不要搞砸自己的工作...(1/2)
乔尔

...,如果有人想对该PR进行修改,那么我认为他们应该先告诉我,这是沟通的问题。(2/2)
乔尔

PS:感谢您的Changeset演化链接,这很有趣
Joel

实际上,rebase就像是说:“让我们从头开始重写所有工作(从最新的主文件开始),删除所有以前的工作。” 如果可以这样做,则可以重新设置基准。
乔尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.