我现在只是在敏捷方面进行一些正式培训,我提出的一个问题是关于持续构建的价值与经常提交到版本控制系统的价值。
我对版本控制的理解是经常更好地提交,因为那样你就有了历史,能够以细粒度的方式回到以前的变化。
我对敏捷和持续构建的理解是,它会给开发人员施加压力,使他们始终拥有工作代码。那打破源树是一个禁忌的事情。
现在我同意这两种观点,但有时候这些观点可能会相互影响。您可能正处于较大的代码更改过程中,并希望提交代码以确保您具有历史记录,但这会破坏源代码树。
有人对此有任何想法吗?
答案 0 :(得分:10)
在大多数源代码管理系统中,分支/标签可解决此问题。
它们允许您标记或仅仅“分支”(双关语)代码段/修订版,并将其作为“稳定版本”。然后,您可以将更改提交到主干线,或“补丁”分支或其他方法。
这两个概念共同发挥作用。
答案 1 :(得分:10)
对于出错的事情,什么可能比禁忌更敏捷?我认为禁忌是让构建破坏而不是破坏构建。偶尔的构建破坏是可以的。这正是您运行连续构建和测试的原因。 CI构建/测试确定构建何时被破坏,理想情况是谁破坏了它。这可以确保快速修复。如果偶尔发生这种情况,你就可以了。如果每天发生二十次,团队可能会遇到麻烦。
禁忌是干扰其他人完成工作。当你打破构建时,他们会收到一封电子邮件,说“我们的源代码分支被破坏了”。他们将无法将其他人的更改或更改与主线集成,直到他们收到所有明确的电子邮件。
在这种不断整合的环境中工作的真正挑战是: 1)保持团队相当小。一般来说,在大约25名开发人员加入团队后,我们开始看到麻烦事情开始变得脆弱。使用团队级别的分支,组件或带有流的多阶段CI可以帮助更大的团队分成更小的团队。
2)选择小单位的工作。通常不应该在定期检查改进和不破坏一切之间存在冲突。当进行小的工作变更时,应该完成提交。新功能可能尚未向用户公开,但如果进行的连贯API更改不会破坏测试,请检入。
3)快速,准确的构建。当构建变得更快时,团队往往会有更多的竞争条件。加上可重现的构建将确保开发人员在自己的机器上进行构建(她有时间做,因为它很快)可以合理准确地预测提交成功。
答案 2 :(得分:5)
实际上,一种常见的敏捷哲学(我实际上对此非常满意)的理念是“如果你在回家之前不能做出承诺,那就恢复原状。”
起初这听起来很残酷,所以我通常首先在本地复制我的源树或分支它,然后我回到我开始的地方。第二天,我开始工作。它通常变得非常快,我改进了前一天所做的事情,而且我很少看到副本(好吧,有时我会撤回一些我已经“完成”并且确定并重新整合它们的课程
我几乎没有必要在没有办理登机手续的情况下超过几个小时。我尝试使用重构(它们总是很短且无害或者它们不是重构)而且我添加的代码就是这样的不要打破。这可能涉及添加经过测试的代码(新方法或对象)并在链接其余代码之前将其签入。
总的来说,您的单元测试应始终运行。我倾向于每分钟进行几次测试,每十分钟进行一次。
采取小步骤可能需要更长的时间,但你将避免那些3-4天的代码重写会话,你无法进行任何测试或检查,这些可能是残酷的,浪费大量的时间!
答案 3 :(得分:4)
我会再添加一个答案,因为对我来说似乎没有提到一些最重要的观点。
我对版本控制的理解 这是经常提交的好处, 因为那时你有历史和 能够回到以前的变化 以细粒度的方式。
我绝对同意这一点。
我对敏捷与敏捷的理解 它的存在是持续的 给开发者施加压力 总是有工作代码。
不那里给开发人员施加压力 - 我宁愿将持续集成描述为一个友好的安全网,它可以帮助您在提交问题后立即发现问题,修理它们通常很容易。 (查看Martin Fowler的seminal article以获得更多CI优势。) 对于始终拥有正常工作代码非常重要,而且版本控制分支也是silky pointed out。但与他描述的传统情景不同(以及福勒谈到的内容:“每个人每天都向主线提交”),我建议相反:让你的主干保持稳定,最好总是处于可释放状态,并做好所有重大发展临时工作分支。
我已经在SO here和here上插入了稳定主干方法;查看这些帖子,了解该模型的一些理由和经验。另外,我热烈推荐这篇影响我思路的文章:Henrik Kniberg撰写的Version Control for Multiple Agile Teams。
破坏dev分支中的构建远非禁忌,尽管你仍然应该尝试保持所有编译和所有测试都通过。打破 trunk 构建,在这种情况下,有点更严重,但我仍然不会把它称为禁忌 - 这些事情不时发生,而不是找人责备,它是对于团队来说,修复它是非常重要的(并且很高兴找到问题现在,而不是很久以后,也许是客户)。
答案 4 :(得分:3)
使用Git轻松进行分支,合并和重新定位。
答案 5 :(得分:2)
Silky是现货,分支/标记解决了这个问题(svn插件用于此功能)。
我经常忠实于提交,我个人觉得它可以更容易地防止破坏构建,因为我每次都会对少量代码进行单元测试。
答案 6 :(得分:1)
这个明显悖论的一个解决方案是Test Driven Design(TDD)的敏捷软件开发实践。实践得很好,通常很容易提交代码 和 具有很少被非工作代码破坏的连续构建。
首先从存储库中获取最新代码并运行所有测试。 (如果它们都没有通过,请将最后一个人提交。)为一小段功能编写测试(在之前实现了功能),然后实现功能,然后运行再次进行所有测试。从版本控制系统更新您的代码,以防您在工作时发生任何变化,再次运行所有测试,如果它们全部通过,您可以立即提交。那就是敏捷概念Red-Green-Refactor的“Red-Green”。之后,进行任何需要的重构并再次运行所有测试。如果你仍然是绿色,那么你可以在那时再次提交。
大多数敏捷团队都有Continuous Integration服务器,该服务器定期运行(通常每小时或更长时间),并且有一个大的可见指示器(如交通信号灯),显示最近的构建是否已通过,失败或正在进行中。
如果您绝对无法摆脱“更改代码”,那么请使用您自己的本地版本控制存储库,使用类似git的内容,如Gordon Potter建议的那样,并在您完成后提交更改。即使您的团队使用其他版本控制产品,您也可以这样做。
答案 7 :(得分:0)
对于可能破坏相关代码段的重大或大的更改,分支是合适的。在您希望集成此更改并检查主干或任何集成分支的位置,您将要将其推广到,解决了破损问题并使测试全部工作至关重要。
我不认为这两件事应该相互对立。使用分支或分布式源代码控制可以使这更容易管理。
答案 8 :(得分:0)
您必须检查合并期间哪种历史记录有意义。假设您有一个使用大量可加载模块的程序,可以是内核...... Web服务器,无论如何。
在编写一个模块时,你进行了200次提交,当你与主项目合并时,你可能只需要一个(虽然很大)补丁,也许只有两个:
这就是为什么Git在DVCS世界中占据主导地位的原因之一。
您选择的提交频率与您想要采用的软件开发方法无关。您可以提交200个经过良好测试的修订版,或者一个,只要人们拉动您推送的内容不会在您的代码中引入由您自己引起的有毒修订或回归(当然,除非您的代码暴露了他们的问题)。
我(个人)喜欢做很多小提交,原因与你提出的相同。事实上,如果每个人都在一个中心分支上工作,它通常是理想的。但是,如果你在某个子系统上工作了6个月,我真的希望你给我发几个大补丁,而不是继承你的整个历史......你总是把自己的历史留在自己的工作回购中,而且它可能只对你有用了你:)
答案 9 :(得分:0)
如果较大的代码更改位于单独的分支中,则不会破坏构建。通过将分支放在自身上,更改将保留在代码之外,直到更改完成,然后整个事物可以合并回主干或主代码行。关键是,虽然有持续的构建发生,但它不一定包括不是"done-done."的东西
答案 10 :(得分:0)
在我看来,Git解决了这个问题。保持本地存储库并提前提交,经常提交,然后当代码到达非破坏里程碑时推送到主共享存储库。如果整个团队使用Git,那么当他们提取更改时,可以在所有其他人的存储库中维护所有整个存储库历史记录。而且一切都没有打破构建。
通过重新定位,您甚至不必在推出里程碑时公开整个本地提交历史记录。