[读书笔记]版本控制模式------With SubVersion
2006-08-16 11:09
190 查看
Common Branching Patterns
Version control is most often used for software development, so here's a quick peek at two of the most common branching/merging patterns used by teams of programmers. If you're not using Subversion for software development, feel free to skip this section. If you're a software developer using version control for the first time, pay close attention, as these patterns are often considered best practices by experienced folk. These processes aren't specific to Subversion; they're applicable to any version control system. Still, it may help to see them described in Subversion terms.Release Branches
Most software has a typical lifecycle: code, test, release, repeat. There are two problems with this process. First, developers need to keep writing new features while quality-assurance teams take time to test supposedly-stable versions of the software. New work cannot halt while the software is tested. Second, the team almost always needs to support older, released versions of software; if a bug is discovered in the latest code, it most likely exists in released versions as well, and customers will want to get that bugfix without having to wait for a major new release.Here's where version control can help. The typical procedure looks like this:
Ø Developers commit all new work to the trunk. Day-to-day changes are committed to
/trunk: new features, bugfixes, and so on.
Ø The trunk is copied to a “release” branch. When the team thinks the software is ready for release (say, a 1.0 release), then
/trunkmight be copied to
/branches/1.0.
Ø Teams continue to work in parallel. One team begins rigorous testing of the release branch, while another team continues new work (say, for version 2.0) on
/trunk. If bugs are discovered in either location, fixes are ported back and forth as necessary. At some point, however, even that process stops. The branch is “frozen” for final testing right before a release.
Ø The branch is tagged and released. When testing is complete,
/branches/1.0is copied to
/tags/1.0.0as a reference snapshot. The tag is packaged and released to customers.
Ø The branch is maintained over time. While work continues on
/trunkfor version 2.0, bugfixes continue to be ported from
/trunkto
/branches/1.0. When enough bugfixes have accumulated, management may decide to do a 1.0.1 release:
/branches/1.0is copied to
/tags/1.0.1, and the tag is packaged and released.
This entire process repeats as the software matures: when the 2.0 work is complete, a new 2.0 release branch is created, tested, tagged, and eventually released. After some years, the repository ends up with a number of release branches in “maintenance” mode, and a number of tags representing final shipped versions.
Feature Branches
A feature branch is the sort of branch that's been the dominant example in this chapter, the one you've been working on while Sally continues to work on/trunk. It's a temporary branch created to work on a complex change without interfering with the stability of
/trunk. Unlike release branches (which may need to be supported forever), feature branches are born, used for a while, merged back to the trunk, then ultimately deleted. They have a finite span of usefulness.
Again, project policies vary widely concerning exactly when it's appropriate to create a feature branch. Some projects never use feature branches at all: commits to
/trunkare a free-for-all. The advantage to this system is that it's simple—nobody needs to learn about branching or merging. The disadvantage is that the trunk code is often unstable or unusable. Other projects use branches to an extreme: no change is ever committed to the trunk directly. Even the most trivial changes are created on a short-lived branch, carefully reviewed and merged to the trunk. Then the branch is deleted. This system guarantees an exceptionally stable and usable trunk at all times, but at the cost of tremendous process overhead.
Most projects take a middle-of-the-road approach. They commonly insist that
/trunkcompile and pass regression tests at all times. A feature branch is only required when a change requires a large number of destabilizing commits. A good rule of thumb is to ask this question: if the developer worked for days in isolation and then committed the large change all at once (so that
/trunkwere never destabilized), would it be too large a change to review? If the answer to that question is “yes”, then the change should be developed on a feature branch. As the developer commits incremental changes to the branch, they can be easily reviewed by peers.
Finally, there's the issue of how to best keep a feature branch in “sync” with the trunk as work progresses. As we mentioned earlier, there's a great risk to working on a branch for weeks or months; trunk changes may continue to pour in, to the point where the two lines of development differ so greatly that it may become a nightmare trying to merge the branch back to the trunk.
This situation is best avoided by regularly merging trunk changes to the branch. Make up a policy: once a week, merge the last week's worth of trunk changes to the branch. Take care when doing this; the merging needs to be hand-tracked to avoid the problem of repeated merges (as described in the section called “Tracking Merges Manually”). You'll need to write careful log messages detailing exactly which revision ranges have been merged already (as demonstrated in the section called “Merging a Whole Branch to Another”). It may sound intimidating, but it's actually pretty easy to do.
At some point, you'll be ready to merge the “synchronized” feature branch back to the trunk. To do this, begin by doing a final merge of the latest trunk changes to the branch. When that's done, the latest versions of branch and trunk will be absolutely identical except for your branch changes. So in this special case, you would merge by comparing the branch with the trunk:
$ cd trunk-working-copy
$ svn update
At revision 1910.
$ svn merge http://svn.example.com/repos/calc/trunk@1910 / http://svn.example.com/repos/calc/branches/mybranch@1910 U real.c
U integer.c
A newdirectory
A newdirectory/newfile
…
By comparing the
HEADrevision of the trunk with the
HEADrevision of the branch, you're defining a delta that describes only the changes you made to the branch; both lines of development already have all of the trunk changes.
Another way of thinking about this pattern is that your weekly sync of trunk to branch is analogous to running svn update in a working copy, while the final merge step is analogous to running svn commit from a working copy. After all, what else is a working copy but a very shallow private branch? It's a branch that's only capable of storing one change at a time.
相关文章推荐
- 《高性能MySQL》读书笔记--多版本并发控制算法
- 《高性能MySQL》读书笔记之 MySQL锁、事务、多版本并发控制的基础知识
- svn版本控制之道-读书笔记
- 《高性能MySQL》读书笔记--多版本并发控制算法
- 使用VSTS的Git进行版本控制(六)——拉取请求
- git 增加空目录到版本控制中
- Git版本控制--tag标签的使用(二)
- 工作流模式详解之流程控制模式(12、13、14、15)——Multiple Instances
- Unity3d SVN版本控制 详细讲解和原理
- SVN同步(更新)版本控制报错:svn: Working copy '...\WEB-INF\classes\com' is missing
- 强制设置IE浏览器的版本模式
- 多版本并发控制(MVCC)在分布式系统中的应用
- svn使用手记:取消不需要版本控制的文件的版本控制
- Struts 2读书笔记-----使用Struts 2控制文件下载
- 《TCP/IP详解 卷1:协议》 读书笔记 第六章 ICMP:Internet控制报文协议
- 【吐血整理】SVN命令行,Subversion的正确使用姿势,让版本控制更简单~
- 设计模式读书笔记-----装饰者模式
- 【吐血整理】SVN命令行,Subversion的正确使用姿势,让版本控制更简单~
- 版本控制
- 【吐血整理】SVN命令行,Subversion的正确使用姿势,让版本控制更简单~