Git-直接在master上工作会出现什么问题?


25

我已经看到了很多有关git分支模型的建议,最普遍的观点似乎是直接在master分支上进行更改是一个坏主意。

我们的一位同事很高兴直接在主分支上进行更改,尽管进行了几次交谈,但他们似乎不太可能更改此更改。

在这一点上,我无法说服一个不擅长直接在师傅上工作的同事,但我想了解会与他的工作方式相抵触的事物,知道何时需要重新访问这个问题。


2
定义“直接工作”。大师之所以存在,是因为它将被使用。您认为这是做什么用的,不是吗?
candied_orange

3
靠师傅工作对您有用吗?如果是这样,您为什么感到现在需要进行更改?如果不起作用,您遇到什么问题?我们可以帮助您解决问题,而不是要求别人向您指出别人的观点。
Thomas Owens

1
听起来他正在做主干开发,再加上持续集成,这在敏捷团队中很正常。如果他想像这样工作,您将需要强制执行WIP以确保一次对一个产品进行的工作不会过多-并使用功能切换以确保可以在关闭不完整功能的情况下释放母版。
Cochese先生16年

...团队有多大?
ZJR

@MrCochese在这里,我不会将主干开发称为“正常”。当然,我使用过Git的许多地方都没有这样的工作方式,我不建议这样做。功能分支工作得更好。
Marnen Laibow-Koser

Answers:


57

将提交直接推送到主目录时会遇到一些问题

  • 如果将进行中的状态推送到远程,则主服务器可能会损坏
  • 如果另一个开发人员从master开始为新功能工作,那么她将处于潜在的故障状态。这减慢了发展
  • 不同的功能/错误修正不是隔离的,因此所有正在进行的开发任务的复杂性都集中在一个分支中。这增加了所有开发人员之间必要的通信量
  • 您不能执行拉取请求,这是代码检查的良好机制
  • 通常,您不能压榨提交/更改git历史记录,因为与此同时其他开发人员可能已经拉了master分支

11
你看!实际上,您回答了这个问题,与其他所有人不同。++欢迎来到SE.SE!
RubberDuck

其中大多数是由于直接在母版上工作不当而产生的问题,而不是直接在母版上本身进行工作。
蚂蚁P

1
@AntP从您的角度来看可以防止哪些问题?
Gernot

10

向他解释,新功能需要他们自己的开发分支,该分支可以在投入生产之前先部署到测试环境。

否则,您将永远处于功能未完成的状态。您无法将半完成的功能部署到生产中,因此,如果您直接在master分支上工作,则其他任何人都必须等待您完成功能,然后其他人的更改才能投入生产(包括错误修复)。

对功能使用独立的分支意味着可以独立于其他每个功能来测试和部署每个新功能。


“您不能将半完成的功能部署到生产中” -根本不正确-完全有可能直接在主分支上工作,每次提交都附带代码,经常部署“半完成的功能”并且永远不会破坏任何内容。连续交付正是要做到这一点:将发布与发布脱钩。这也恰好解决了人们通常会使用不间断的技术解决方案来解决的许多其他组织问题。有时,这涉及到功能切换,但通常可以在没有明显行为改变的情况下构建和部署90%的功能。
蚂蚁P

@AntP:您所描述的过程不是我所说的“半完成功能”。这些特征要么测试,生产准备和使用,或者它们是由一个功能开关或类似的,直到他们这样的时间的东西隐藏测试,生产准备和使用。您不会发布无法正常使用的功能。
罗伯特·哈维

您断言需要在非主分支上开发新功能,因为您不能部署半成品:事实并非如此。您绝对可以直接在母版上开发新功能,并在功能完成之前将与这些功能相关的任何和所有代码交付生产,而无需进行其他开发。
蚂蚁P

1
@AntP:功能分支所无法提供的一件事是对特定功能所做工作的完整说明。在某些商店(尤其是我的商店)中,这种问责制不是一种奢侈,而是一种要求。
罗伯特·哈维

1
@AntP如果我对您的理解正确,我会认为这倒退了一步。我喜欢好的问题跟踪器,并且已经广泛使用它们,但是我想让VCS告诉我任何功能或代码行的开发历史。问题跟踪器可以讲述更改的业务方面的情况,但是如果VCS不能帮助我自己跟踪和审核代码,则说明它没有完成工作。这是我反对基于主干的开发的原因之一:它使VCS变得愚蠢,没有我看到的任何补偿优势。(还:脆性耦合?一个功能代码更改。)
Marnen Laibow-Koser

2

主人应该是潜在的释放者。期。主机中不应有任何完成的工作(除非已通过功能标记禁用)

如此说来,我已经看到一些团队使他们的流程复杂化。

集成到母版时不使用PR是一个错误,因为开发人员将无法选择何时进行集成。

一个开发分支带来的价值很小。通常,它只会使事情复杂化。许多功能分支带来了很多价值。

为每个环境(开发,测试,生产)建立分支是一个错误。这超出了git的范围,应由发布管道处理。应该将完全相同的构建部署到所有环境,如果每个环境都有分支,则不可能。

如果某个功能太大,那么一两天之内无法完成,那么功能分支的所有工作都应该放在单独的分支中并与PR集成。


我同意您所说的大部分内容,除了以下几点:“应该将相同的构建部署到所有环境中”。实际上,发布管道通常应该能够将不同的构建部署到不同的环境,然后在测试通过时对其进行升级。如果不使用不同的分支(或至少使用不同的标签),该如何处理?
Marnen Laibow-Koser

也许我还不太清楚。将构建部署到环境后。应该将相同的工件部署到下一个环境,而无需重建。
Esben Skov Pedersen

如果您具有可重复的构建,则是否进行重建都无关紧要。如果您没有可重复的版本,则将遇到更大的问题。:)
Marnen Laibow-Koser

...但是,是的,我确实认为您应该标记已部署的提交,以便可以升级相同的代码(无论是否重建)。
Marnen Laibow-Koser

是的,但是大多数CI服务器都可以直接将构建链接到发行版,从而可以轻松跟踪部署。正确设置后,实际上并不需要在git中跟踪部署。Git是一个SCM。不是部署工具。
Esben Skov Pedersen

2
  • 母版应反映出生产分支,即最终版本。
  • 直接在master环境中工作意味着,如果您创建错误,则除了“撤消/删除/重置”提交外,别无选择“返回”,这不是一种干净的工作方式,并且可能导致您丢失新代码的一部分,还可以
  • 当然,在开发的最初阶段,也许您可​​以直接在master上开始工作,但是在交付一些东西之后,您应该使用开发,测试或实验分支而不接触已发布的完整工作版本。

2

首先,我想指出的是,在git中,每个pull实际上都是分支操作,而每个push都是合并。该master开发人员的机器上是从一个完全独立的分支master上您共享中心回购,从技术角度讲平等的地位。我偶尔会将本地版本重命名为upstream如果我更适合我的目的,或其他名称。

我指出这一点是因为许多组织认为他们比您的同事更有效地使用分支机构,而实际上他们所做的只是为分支机构创建其他名称而已,而这些都不会保存在历史记录中。如果您的同事正在一次原子提交中提交要素,那么撤消就像要素分支的合并提交一样容易。绝大多数功能分支应该是短暂的,并且无论如何都应经常合并。

话虽如此,他的工作方式的主要弊端是双重的。首先,这使得在未完成的功能上进行协作非常困难。但是,在需要协作的那些时间创建分支并不困难。

其次,这使得合并前的审核非常困难。在这一点上,您实际上不需要说服他。您可以采用github,gerrit或gitlab之类的工具,并要求拉取请求代码进行审查,并通过所有合并的自动化测试。如果您没有做这样的事情,坦率地说,您没有充分利用git的潜力,也难怪您的同事没有看到这种潜力。


1
每天都向开发人员推销他/她的分支机也是一个很好的备份。
伊恩

我不明白你的初衷。我看不到a pull将如何创建新分支或a push将如何进行合并操作。相反,a pull字面意思fetch后面跟有一个merge
mkrieger1 '16

@ mkrieger1我可以轻松地看到如何将本地视为与master的不同分支origin master。从技术上讲,它们是两个不同遥控器上的不同分支,每个都有自己的历史记录。
RubberDuck

@RubberDuck是的,完全是。使用pull:之前:两个分支可能指向不同的提交-之后:两个分支指向相同的提交-没有创建分支,因此,我不会将其称为“分支操作”。如果使用这两个命令中的任何一个,我会称之为push,因为它可能会在远程中创建一个新分支。它能做什么不能做什么,是合并。
mkrieger1年

@ mkrieger1,您还需要考虑合并的方向
RubberDuck

2

其他答案已经提到了不直接在master上工作的各种优点(隔离功能,始终在master上可交付的代码等)。

对我来说,您似乎有一个不同的问题。显然,您没有所有开发人员都同意或使用的开发流程(或者您的开发人员完全忽略了该流程)。

您是否具有功能分支,这些分支已合并到master中,或者您也具有不同的发行版分支,或者您使用的是完全不同的过程?

“不使用master分支”是不够的。


2

我们的一位同事很高兴直接在主分支上进行更改,尽管进行了几次交谈,但他们似乎不太可能更改此更改。

这使我相信还有更多问题。是否进行母版工作是关于如何,什么以及何时发布产品的更大哲学的一部分。

因此,与“您永远都不应该在主版本上工作”串联在一起,您是否进行了功能测试,是否测试了彼此的工作,是否审查了彼此的代码。验收和整合测试。

如果您没有以上所有内容,而只是为了“做git”而已,那么您不妨使用master。


1

直接在分支机构上工作没有“坏习惯”。但是,您必须决定哪种方法最能支持您的流程:

问题1:您的母版是否可以代表软件的当前发行状态?然后,您应该引入一个全球开发分支,并在发布开发结束时合并开发。

问题2:您是否要进行代码审查流程?然后,您应该具有“功能分支”,这些特征分支将通过拉取请求合并到主节点(或开发,如果有的话)。

问题3:是否需要与其他开发人员共享中间代码状态,而这些中间状态不应发布到生产(或测试)中?就是这种情况,不止一个开发人员开发了一项功能。然后,您应该引入“功能分支”。


标记是一种非常有用的方式来表示发布时代码库的状态。Git使结帐特定标签变得非常容易。使dev分支有点麻烦。
RubberDuck
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.