如何使用SVN,分支?标签?主干?

163

我在网络上搜索了一下,没有找到一份好的“初学者”指南来介绍SVN,这里不是指“如何使用命令”,而是控制源代码的方法。

我想澄清以下主题:

  • 你多久提交一次?像平常按 Ctrl + s 一样经常提交吗?
  • 分支和标签是什么,如何控制它们?
  • SVN 中放入什么?只有源代码还是其他文件也可以共享在这里?(未被视为版本化的文件..)

我不知道分支和标签是什么,也不知道它们的目的,但我猜想当你上传东西到主干时,当你进行重大构建时,你将其移动到分支中?所以,在这种情况下,什么被认为是重大构建呢?


确定提交“频率”的好方法是从合并的角度来看待它。如果您需要将分支中的更改合并到主干中,则挑选几个修订版本而不是数千个修订版本很快就能帮助您找到明智的方法。 - Phil Cooper
11个回答

87

当我们在这里实施Subversion时,我自己也问了同样的问题 -- 大约20个开发人员分布在4-6个项目中。 我没有找到任何一个好的“答案”来源。以下是我们的答案在过去3年中如何发展的一些部分:

-- 尽可能经常提交;我们的经验法则是,每当您完成了足够的工作量,如果修改丢失,必须重新做一遍,则提交;有时我每15分钟提交一次,有时可能是数天(是的,有时需要我一天才能写1行代码)

-- 我们使用分支,就像你早期的回答建议的那样,用于不同的开发路径;现在对于我们的一个程序,我们有3个活动分支:一个用于主要开发,一个用于尚未完成的并行化努力,另一个用于修订为使用XML输入和输出文件的努力;

-- 我们几乎不使用标签,尽管我们认为我们应该使用它们来标识发布给生产环境的版本;

想象开发沿着单一路径进行。在某个时间或开发状态下,市场决定发布产品的第一个版本,因此您会在路径上放置一个标记,标记为“1”(或“1.0”或其他内容)。在某些时候,一些聪明的人决定将程序并行化,但决定那需要几周时间,而人们希望同时继续沿着主路径前进。所以您在路径上建立一个分叉点,并且不同的人走向不同的分支。

道路上的标记称为“标签”,而分叉点则是“分支”划分的位置。偶尔,分支也会重新汇合。

-- 我们将构建可执行文件(或系统)所需的所有材料放入存储库;这意味着至少包括源代码和make文件(或Visual Studio的项目文件)。但当我们有图标和配置文件等所有其他内容时,都会放入存储库。某些文档会进入存储库;当然,任何可能与程序有机融合的文档(例如帮助文件)以及开发人员文档都适合放在这里。

我们甚至将Windows可执行文件放在那里作为我们生产发布的单一位置,以提供给寻找软件的人 -- 我们的Linux版本会发送到服务器,因此不需要存储。
-- 我们不要求仓库始终能够交付可构建和执行的最新版本;某些项目按照该方式工作,而某些项目则不然;决策由项目经理负责,并且取决于许多因素,但我认为当对程序进行重大更改时,该方法会崩溃。

18
* How often do you commit? As often as one would press ctrl + s?

尽可能经常进行代码提交。只有在源代码控制下,代码才存在 :)

频繁的提交(之后是较小的更改集)可以使你轻松地集成你的更改,并增加不破坏任何东西的机会。

其他人指出,当你拥有一个功能完整的代码片段时再提交代码,然而我发现更经常提交代码也很有用。有几次我注意到自己将源代码控制作为快速撤销/恢复机制。

当我在自己的分支上工作时,我喜欢尽可能多地提交代码(字面上就是按ctrl + s键的次数)。

* What is a Branch and what is a Tag and how do you control them?

阅读SVN书籍是学习SVN的起点:

* What goes into the SVN?

文档、编译所需的小型二进制文件以及其他有价值的内容都应该放入源代码控制。


8

提交代码的频率取决于您的项目管理风格。如果提交会破坏构建(或功能),许多人会避免提交。

分支通常有两种用法:1)一个活跃的开发分支(主干保持稳定),或2)用于备选开发路径的分支。

标签通常用于标识版本发布,以便不会在混乱中丢失。'发布'的定义由您决定。


7
我认为主要问题是对源代码控制的概念存在混淆。我们通常有主干和分支,但随后会出现与标签/发布等无关的想法。
如果您更完全地使用树的思路,情况会变得更清晰,至少对我来说是这样。
我们获取主干 -> 创建分支 -> 生成果实(标签/发布)。
这个想法是从主干开始构建项目,一旦主干足够稳定才创建分支。然后,当分支生成果实时,你可以从分支上摘下并将其作为标签发布。
标签本质上是交付成果物,而主干和分支则是产生它们的地方。

4
正如其他人所说,SVN Book 是开始学习和参考的最佳地方。现在回答你的问题... 你提交代码的频率是多少?相当于按下ctrl + s的频率吗? 通常情况下,但不像按下ctrl + s那么频繁。这是个人口味和/或团队政策的问题。我个人认为,每完成一个功能代码块就应该提交一次。 什么是分支和标签以及如何控制它们? 首先,主干(trunk)是您进行活动开发的地方。它是您的代码主线。分支是与主线有所偏离的地方。它可以是重大偏差,例如以前的版本,也可以是您想尝试的微小调整。标签是您的代码快照。它是将标签或书签附加到特定修订版本的方法。
值得一提的是,在Subversion中,主干、分支和标签只是约定俗成的。没有任何限制阻止您在标签中工作或拥有作为主线的分支,或完全忽略标记-分支-主干方案。但是,除非您有非常好的理由,否则最好遵循惯例。 什么放入 SVN?只有源代码还是还分享其他文件? 这也是个人或团队的选择。我喜欢将与构建相关的任何内容放在我的存储库中。这包括配置文件、构建脚本、相关媒体文件、文档等。您不应该提交需要在每个开发人员的计算机上不同的文件。您也不需要提交代码的副产品,例如构建文件夹、对象文件等。

经常,但不像按ctrl + s那样频繁。同意。您可能必须保存更改才能看到效果。我可能会这样做10次,一点一点地构建一些代码,然后才能提交并对我所做的事情进行有意义的评论。换句话说,我希望我的评论说“添加了此功能”或“修复了该错误”,而不是“在几行代码中四处试探,不确定这将如何工作”。因此,我每天可能提交大约半打次。 - Nathan Long

4

补充一组答案:

  • 我在完成一项工作后才提交。有时它只是一个微小的bugfix,只改变了一行代码,只花费了2分钟;而有时它可能是两周的努力。另外,一般来说,您不会提交任何破坏构建的内容。因此,如果您做了很长时间的工作,请在提交之前获取最新版本,并查看您的更改是否破坏了构建。当然,如果我很长时间没有提交,我会感到不安,因为我不想失去那份工作。在TFS中,我使用“shelvesets”这个好东西。在SVN中,您需要用另一种方式解决问题。也许创建自己的分支或手动将这些文件备份到另一台机器上。
  • 分支是整个项目的副本。它们的最佳用途可能是产品版本控制。想象一下,您正在开发一个大型项目(比如Linux内核)。经过几个月的努力,您终于发布了1.0版本。之后,您开始开发即将推出的2.0版本,这将是更好的版本。但与此同时,还有很多人在使用1.0版本。这些人发现了错误,您必须修复它们。现在,您不能修复即将推出的2.0版本中的错误并将其发送给客户-它根本没有准备好。相反,您必须提取1.0源代码的旧副本,在那里修复错误,并将其发送给用户。这就是分支的作用。在发布1.0版本时,您在SVN中创建了一个分支,该分支在该点上复制了源代码。此分支命名为“1.0”。然后,您继续在主要源代码副本中工作下一个版本,但是1.0副本仍然保留在发布时的状态。您可以继续在那里修复错误。标签只是附加到特定修订版本的名称,以便于使用。您可以说“源代码的第2342个修订版本”,但是将其称为“第一个稳定修订版本”更容易:)
  • 我通常将所有与编程直接相关的内容都放入源代码控制中。例如,由于我正在制作网页,因此还将图像和CSS文件放入源代码控制中,更不用说配置文件等等。项目文档不会放在那里,但实际上这只是个人喜好的问题。

3

有人说这取决于你的风格。

对你来说,最重要的问题是你有多频繁地“集成”你的软件。测试驱动开发、敏捷和Scrum(以及许多其他方法)依赖于小的改变和持续集成。他们宣扬做出小的改变,每个人都找到了错误并一直修复。

然而,在一个更大的项目中(考虑政府、国防、10万行以上的代码),你根本无法使用持续集成,因为这是不可能的。在这种情况下,最好使用分支进行许多小的提交,但只将能够工作并准备好集成到构建中的内容带回主干。

但是,分支的一个缺点是,如果没有得到妥善管理,将会是在你的仓库中将工作带回主干的噩梦,因为每个人都是从主干的不同位置开发的(这恰恰是持续集成的最大争议之一)。

对于这个问题,没有明确的答案,最好的方法是与你的团队合作,共同寻找最佳折中的解决方案。


1
我们工作的政策是这样的(多人开发团队开发面向对象的框架):
  • 每天从SVN更新以获取前一天的更改

  • 每天提交代码,以便如果您生病或缺席,其他人可以轻松接手。

  • 不要提交会导致错误的代码,因为这会影响其他开发人员。

  • 按小块工作并每天提交有意义的注释!

  • 作为团队:保持开发分支,然后将预发布代码(供QA使用)移动到生产分支。此分支应始终具有完全可用的代码。


1

对于提交代码,我采用以下策略:

  • 尽可能频繁地提交。

  • 每个功能更改/错误修复都应该有自己的提交(不要一次提交多个文件,因为这会使该文件的历史记录不清晰--例如,如果我独立更改了日志模块和GUI模块并同时提交了两者,则两个更改将在两个文件历史记录中都可见。这使得阅读文件历史记录变得困难),

  • 不要在任何提交中破坏构建--应该能够检索存储库的任何版本并构建它。

所有构建和运行应用程序所需的文件都应在SVN中。测试文件等不应该包括在内,除非它们是单元测试的一部分。


您的规则1和3有些矛盾。然而,如果在功能分支上进行了重大开发,那么对于较小的更改,规则#3可以是“不要破坏主干”,这样分支就会过度。 - Chris Charabaruk

1
这里有很多好的评论,但有一些没有提到的是提交信息。这些应该是强制性和有意义的,特别是对于分支/合并。这将使您能够跟踪哪些更改与哪些错误特性相关。
例如 svn commit . -m 'bug #201 fixed y2k bug in code' 将告诉查看历史记录的任何人该修订版用于什么目的。
一些缺陷跟踪系统(例如 trac)可以在存储库中查找这些消息并将它们与票证关联起来。这使得确定每个票证所关联的变更非常容易。

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