描述您使用版本控制(VCS或DVCS)的工作流程。

51
我想了解其他人在使用版本控制系统或分布式版本控制系统时的工作流程。
请描述您处理以下任务的策略:
  • 实现一个新功能
  • 修复缺陷(在开发和部署应用程序期间)
  • 代码审查
  • 重构代码(经过代码审查后)
  • 合并补丁
  • 发布应用程序的新版本(桌面、Web、移动端,您是否会以不同的方式处理?)
请随意组织您的答案,不必按任务分组,但请按 VCS / DVCS 分组(请不要混淆它们)。
谢谢。

5
由于这个问题本质上没有一个答案比其他答案更正确,所以它应该是一个维基页面。 - sbi
你是在单纯地询问 SVN 和 Git 吗?如果是,请更改标题。如果不是,请更改文本。 - anon
2个回答

43
所有版本控制系统用于您提到的各种任务的主要功能是分支:以协作的方式隔离开发工作。由于它是一个中央版本控制系统,多个开发人员可以在同一个分支上进行协作,在文件上使用悲观或乐观锁,以便开发并行历史记录。
但是,作为版本控制系统对分支有两个主要影响:
  1. 它倾向于阻止提交,因为一旦提交文件,它将立即影响具有相同配置的其他视图的工作区(即“正在同一分支上工作”)。
    ~“发布”过程是主动的,并具有直接后果,
    ~而“消费”部分(更新您的工作区)是被动的(您被迫在更新工作区时立即处理由其他人发布的更改)
  2. 它适用于线性 合并工作流(即“仅从分支A合并到分支B,不混合在两个方向上合并”——A到B到A到B...)。合并是微不足道的,来自A的所有修改都简单地转移到了B
现在:

实施一个功能

任何版本控制系统都可以通过创建分支来实现,但令我惊讶的是,“特性”分支并不容易:
* 特性可能会变得过于复杂
* 它可能准备好了,但却要等到下一个发布时间
* 只有其中一部分需要合并回主开发分支
* 它可能依赖于其他尚未完全完成的特性
因此,您需要小心地管理特性分支和提交记录:如果它们与同一特性紧密相关,则会很顺利(在需要时将整个内容合并回主开发分支)。否则,使用这些工具进行部分合并并不容易。

修复漏洞

在开发期间和发布后修复漏洞之间的区别在于,在前者的情况下,您通常可以在线性地在同一分支上进行,而在后者的情况下,您将不得不建立一个漏洞修复分支,并决定哪些漏洞需要被反向移植到您当前的开发分支中。

代码审查

最好使用外部工具(例如Crucible),并广泛使用VCS功能(如blame或注释)来更好地分配代码修复任务。

重构代码(代码审查后)

如果重构是较小的,则可以在同一分支上进行。但如果重构很大,则需要设置一个特殊的分支,在开始重构之前进行单元测试。

合并补丁

与上一点相同。如果补丁很大,则需要创建一个分支。

发布您的应用程序的新版本

当涉及到发布应用程序时,版本控制系统只能做到有限的作用,因为它不是一个发布管理工具。
您需要正式确定要发布的版本(标签),但在此之后需要进行部署过程,其中包括:

  • 停止当前正在运行的内容
  • 复制新文件
  • 部署它们(更新 SQL 数据库、Web 应用程序等)
  • 实例化所有配置文件(使用正确的值、地址、端口号、路径等)
  • 重新启动(如果您的系统由多个组件组成,则以正确的顺序重新启动它们!)

版本控制和发布管理的关键点是:

  • 它们不太适合存储要发布的二进制文件,这意味着您需要它们来构建您的应用程序,而不是存储生成的可执行文件
  • 它们并不总是受欢迎的生产环境(安全约束限制写入访问权限以及在这些平台上运行的工具数量,主要是监视和报告工具)

发布机制还会影响二进制依赖关系:

  • 对于外部二进制依赖项,您可能会使用诸如 Maven 等机制来获取外部库的固定修订版本
  • 但是对于内部依赖项,当您不仅开发一个应用程序而是多个应用程序相互依赖时,您需要知道如何引用其他应用程序生成的二进制文件(内部二进制依赖项),它们通常不会存储在您的版本控制系统中(特别是在开发阶段,您可以为您的其他应用程序生成很多不同的发布版本以供使用)

您还可以选择处于源依赖关系中(获取您自己所需的所有其他内部项目的源代码),版本控制系统非常适合此类情况,但是重新编译所有内容并不总是可行/实用的。


@Benjol:感谢您进行了众多的编辑 :) - VonC

37
DVCS(分布式版本控制系统)与VCS的主要区别在于它的分布式工作本质,使其能够做好一件事情,那就是:合并。因此,您提到的任务可以从这个角度来看待。分支仍然会被创建,但并不是所有分支都会被其他开发人员看到。其中很多分支实际上并不会离开您的本地存储库。作为DVCS对合并有两个主要影响:
  1. 您可以随意提交多次。这些提交不会立即对其他人可见(即“在下次更新他们的工作区之后,他们不必立即合并它们”)
    ~ 发布过程是被动的:其他仓库可以忽略您的推送。
    ~ “消费”部分是主动的:在将其合并到您的分支之前,您可以检查已经被推送给您的内容,并决定要从谁那里合并以及要合并什么(而不仅仅是因为您都在同一个“分支”上工作)。
  2. 它适用于任何合并工作流程(部分、交叉、递归等)。这些DVCS(至少Git和Mercurial)通常使用DAG(有向无环图)记录历史,使查找已经合并的内容和查找共同祖先变得容易。这是SVN和其DVCS对应物之间的一个重要差异,但也有其他差异

现在:

实现一个功能

如我在CVCS(集中式版本控制系统)答案中详细介绍的那样,“功能”分支背后的困难在于许多子功能最终将交织在一起。
这就是DVCS发挥作用的地方,因为它们允许您重新组织本地(指“尚未推送”的历史记录(Mercurial的更改集,Git的SHA1提交)),以便促进部分合并或子功能分支的创建。

修复错误

如果您愿意,几乎可以为每个错误修复创建一个分支。想法是确保一个错误修复由一组简单的线性提交组成,这些提交合并回开发分支(或者如果已发布,则是维护分支)。
在将dev分支与bug-fix分支合并之前(快进合并:现在主分支引用所有修复程序),我prefer making sure to first rebase修复错误的分支放在开发分支的顶部(以确保我的修复仍符合可能在该主分支上并行完成的任何工作)。

代码审查

责备或注释功能仍然有助于在代码审查期间分配任务,但这次,并非所有开发人员都在一个站点上(因为它是*分布式*VCS),也不使用相同的标识方案(例如,不使用相同的LDAP)。

组织代码审查的DVCS方式是将新更改推送到特殊的代码审查存储库,该存储库将:

  • 如果它们不符合质量标准,拒绝这些提交
  • 接受这些提交(将其与代码审查存储库合并),并将它们推送到新的存储库(例如用于各种测试)

重构代码(代码审查后)

在开发者的本地存储库中,在一个分支上完成(因为很容易将其合并回来)

整合补丁

与上一节相同的过程。

发布您的应用程序的新版本(桌面、Web、移动版,您会对待它们有所不同吗?)

实际的发布过程只是通过软件的特定标识(tag)版本启动。(发布管理过程的部署和配置部分在CVCS答案中详细说明)
问题是,使用DVCS:
"官方版本的软件将来自哪个存储库?"

您需要建立一个 "中央" 或者说 "官方" 存储库,它将扮演以下角色:

  • 版本发布的存储库
  • 新存储库想要贡献的存储库

因此,它既可以用于发布目的,可以用于新开发目的。


我希望我能投2个答案的票 :) - edwin.nathaniel
是的,非常抱歉,我不小心点了赞(又一次),结果变成了踩,无法返回到之前的状态。感谢您编辑答案。 - edwin.nathaniel
@vonc:像往常一样,非常好的回答。有没有直接联系你的方式? - pablo
@pablo:当然,写到“vonc at laposte dot net”。我不太了解Plastic SCM ;) 至于你的分支模型(http://nvie.com/git-model),它让我想起了我在我的分支答案中提到的一个模型(https://dev59.com/gHI95IYBdhLWcg3w5iU4),“软件如何演化”(http://oreilly.com/catalog/practicalperforce/chapter/ch07.pdf)。 - VonC
2
我处于职业生涯的初期阶段,正在学习协作开发的技巧。你的回答给了我非常需要的见解。 - Vatsala

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