我知道版本控制系统(VCS)很有用。
但是,我平时只是业余写一些小程序,感觉特地装一个VCS太麻烦,所以一直没有用。最近,因为想认真做一个中等规模的项目,所以决心好好学一下怎么用。
下面就是我翻译的一篇入门教程,主要解释了VCS的一些主要概念。
======================
A Visual Guide to Version Control
版本控制入门插图教程
作者:Kalid Azad
译者:阮一峰
原文网址:http://betterexplained.com/articles/a-visual-guide-to-version-control/
版本控制(Version Control)的作用是追踪文件的变化。为什么需要版本控制?简单说,就是当你出错了,可以很容易地回到没出错时的状态。
你可能已经在不知不觉中,布置了自己的版本控制系统。比如,创建了类似下面这样的文件名:
* KalidAzadResumeOct2006.doc
* KalidAzadResumeMar2007.doc
* instacalc-logo3.png
* instacalc-logo4.png
* logo-old.png
这就是软件中为什么有"Save As"命令的原因。它使得你可以在不破坏源文件的基础上,得到一个类似的新文件。文件的多版本保存是一个常见问题,通常的解决办法是这样的:
* 做一个文件备份(比如Document.old.txt)。
* 在文件名中加入版本号或日期(比如Document_V1.txt,DocumentMarch2007.txt)。
* 在多人编辑的环境下,共享一个文件目录,并且要求每个人编辑完以后,在文件上做出标识。
什么是版本控制系统(VCS)?
通过文件名识别版本,对于小型项目或者单个文件也许可行。但是对于软件开发来说,是不适用的。
你能想像吗,要是Windows操作系统的源文件,是在一个叫做"Windows2007-Latest-UPDATED!!"的共享目录中开发的,并且每个程序员都可以编辑,都有一个自己的子目录,那会发生什么情况?那么,Windows就根本不可能被制造出来。
大型的、频繁修改的、多人编写的软件项目,需要一个版本控制系统(简称VCS,行话叫做"文件数据库"),追踪文件的变化,避免出现混乱。一个好的VCS应该做到以下几点:
* 备份(Backup)和恢复(Restore)。文件的每一次编辑都得到保存,可以恢复到任意一个日期。需要2007年2月23日的版本?没问题。
* 同步(Synchronization)。让不同用户随时都能得到文件的最新版本。
* 短期撤销(Short-term undo)。文件被你搞乱了,怎么办?那就撤销编辑,回到最近一次的无差错版本。
* 长期撤销(Long-term undo)。有时候,你会过了很久才发现出错了。如果你想撤销一年前的一次编辑,怎么办?那就去取回一年之前的那个版本。
* 追踪修改(Track Changes)。文件的每一次编辑,你都可以写下注解,解释编辑的原因。(这些信息储存在VCS中,而不是文件中。)这样就很容易看出,长期中文件变化的脉络和原因。
* 追踪权限(Track Ownership)。VCS会记录每一次提交新版本的用户名。这样就容易追踪责任。
* 试验功能(Sandboxing)。当你对文件做出重大变更时,你可以把编辑内容暂时性地保存在一个单独的区域,不断进行测试和除错。等到确认正确以后,再加入主版本。
* 分支(Branching)和合并(merging)。分支功能可以看成是一个更大的测试版本。你将整个的代码做一份拷贝,然后再起一个独立的名字,追踪其变化,与原版本脱离关系,这就是分支。以后,你还可以将分支版本再并入源版本,这就是合并。
虽然共享文件夹操作起来更快速和简单,但是它做不到上面这些功能。
一些术语
大多数VCS都有下面一些共同的概念,不过名字可能会稍有不同。
基本概念
* Repository (repo): 储存文件的数据库。
* Server: 储存repo的计算机。
* Client: 连接repo的计算机。
* Working Set/Working Copy: 当你编辑文件时,编辑对象所在的本地文件目录。
* Trunk/Main: repo中储存代码文件的主位置。你可以把代码想像成一棵家族树,“trunk”就是主线的那条树干。
基本操作
* Add: 将一个文件第一次加入repo,也就是开始用VCS追踪这个文件。
* Revision: 文件的版本编号(即v1, v2, v3等等)。
* Head: repo中保存的文件最新版本。
* Check out:从repo中下载一个文件。
* Check in: 上传文件进入repo(如果文件发生了变化)。这个文件将得到一个新的版本编号,用户将可以“check out”这个文件。
* Checkin Message: 描述所做修改的短说明。
* Changelog/History: 一个记录文件自从创建开始所有变动的清单。
* Update/Sync: 将你本地的文件同repo中最新版本进行同步的过程。这将使得本地文件始终能够跟上最新的变动。
* Revert: 放弃对文件所做的编辑,从repo中重新获得未编辑前的版本。
高级操作
* Branch: 在repo中对一个文件或文件目录,创建一个独立的拷贝。Branch在这里既是动词(branch the code),又是名词(Which branch is it in?)。
* Diff/Change/Delta: 找出两个文件之间的差别。对于比较不同版本之间的变动很有用。
* Merge (or patch): 将一个文件上的改动,应用于另一个文件,使得两者保持相同。比如,你可以将一个branch中的功能merge到另一个branch中。
* Conflict: 当你check in的时候,你所做的变动可能与其他用户发生冲突。(这时双方的编辑都不会生效。)
* Resolve: 修改互相冲突的变动,check in正确的版本。
* Locking: 取得一个文件的“控制权”,使得在你解锁之前,其他人不能编辑这个文件。有些VCS用这个功能避免conflict。
* Breaking the lock: 强制解锁一个文件,使得你可以对其进行编辑。比如,某人lock了一个文件,但是他又去度假了。
* Check out for edit: Check out到一个文件“可编辑”的版本。有些VCS默认允许编辑,另一些要求明确发出命令后,才提供可编辑的版本。
一次典型的使用过程是这样的:
爱丽丝add一个文件(list.txt)进入repo。然后,她又把这个文件check out,做了一次编辑(在文件中加入milk这个单词)。接着,她将修改后的文件check in,并附有一条checking message(“加入了新的条目”)。第二天早上,鲍勃update了他本地的working set,看到了list.txt的最新修订版,其中包含了单词“milk”。如果他使用changelog或diff,都可以发现前一天爱丽丝加入“milk”这个词。
下面,我们用一些例子,来讲解VCS的使用。
Check in
最简单的情况是,check in一个文件(list.txt),然后经常修改它。
在subversion系统中的命令是:
svn add list.txt
(modify the file)
svn ci list.txt -m "Changed the list"
最后一个命令中的-m标识,表示check in时附带的message。
Check out和编辑
你不一定总是Check in文件,有时候你需要check out,进行编辑,然后再check in。这个过程可以用下图表示:
如果你对自己的编辑不满意,想要从头开始,你可以revert到上一个版本。当你check out的时候,默认情况下,你总是会得到最新版本。如果你想得到以前的版本,你可以在命令中指定版本号。在Subversion中,运行下面的命令:
svn co list.txt (get latest version)
...edit file...
svn revert list.txt (throw away changes)svn co -r2 list.txt (check out particular version)
Diff
Diff就是你编辑时所做的变动。你可以想象一下,单独将变动部分保存下来,然后将它们应用到一个文件上:
比如,从r1版到r2版,我们加入eggs(+Eggs)。你可以将这个过程想象成,单独将图中红色的部分保存下来,然后将它应用到r1上,就可以得到r2。
从r2版到r3版,我们加入了Juice(+Juice)。从r3版到r4版,我们删去了Juice加入了Soup(-Juice, +Soup)。
大多数版本控制系统,只保存diff,而不是文件的完整版本。这样可以节省磁盘空间。你做了4次修改,不意味着系统保留了4份拷贝。实际上,系统内只有1份拷贝和4个diff。在SVN中,我们用下面的命令diff一个文件的两个版本:
svn diff -r3:4 list.txt
Branch
Branch可以将源文件做一份拷贝,保存在VCS的另一个位置,然后我们对拷贝进行修改,不会影响到源文件。
比如,上图中我们创建了一个branch,在其中加入了Rice,而在trunk上加入的是Bread。有的VCS在创建Branch时,可能会修改版本号。
在Subversion中,创建branch的命令很简单,只要从一个目录拷贝到另一个目录就可以了。
svn copy http://path/to/trunk http://path/to/branch
所以,branch并不难理解,你只要想像将代码拷贝到不同目录就行了。它的好处在于,不管你做错了什么,你总可以回到一个安全的版本。
Merge
如果你要将一个branch中的变动,并入另一个branch,这可不太简单。
比如,我们要将Rice这个词从一个branch,并入主线中的文件。我们应该怎么做?Diff一下r6和r7,然后再并入主线?
错了。我们只需要找到branch所做的变动就可以了。也就是说,我们只要diff一下r5和r6,然后再应用到trunk上就可以了。
如果我们diff了r6和r7,我们就会漏掉“Bread”这个已经在主干中的词。这是很微妙的一个地方,branch中的变动在于Rice这个词(+Rice),只要将这个词加入主干就可以了。主干文件中也许还有其他变化,不过这不要紧,我们所要的只是插入Rice这个特性。
在Subversion中,merge命令与diff很类似。在一个主干中,运行下面的命令:
svn merge -r5:6 http://path/to/branch
这个命令diff了r5和r6,然后将其加入当前位置的文件中。不幸的是,Subversion没有提供一种容易的途径,追踪merge中到底有什么变动。所以如果你不小心的话,你可能将同样的变动应用两次。SVN已经计划提供这个功能,但是目前的建议还是,保留一份changelog message,提醒你r5-r6已经并入了主干。
Conflict
Conflict往往来自不同用户,同时对同一个内容做出了不同的修改。Joe想删除eggs,加入cheese(-eggs, +cheese),Sue想删除eggs,加入hot dog(-eggs, +hot dog)。
从某个角度看,这有点像一场比赛:如果Joe首先check in,那么他的编辑将写入文件。(Sue的编辑将被拒绝。)
如果他们同时提交了这种互相冲突的变动,VCS将报告一个conflict,不允许check in。由你来决定,是check in一个更新的版本,还是就地解决这个冲突。下面是一些可能的办法:
* 重做一遍编辑。首先,将文件Sync到最新的版本(r4),这时cheese已经在文件中了。你再重做一遍剪辑,加上hot dog。
* 覆盖掉他人的修改。将文件check out到最新的版本(r4),用你的版本将这个版本覆盖,再check in。也就是说,你等于删掉了cheese,替换为hot dog。
Conflict不是很常见,但是处理起来很麻烦。通常,我会选择上面第一种处理方法。
Tag
大概不会有人想到VCS早就符合Web 2.0的潮流吧?许多VCS允许你对任意编辑做一个标签(label),方便以后的引用。这样一来,你就可以用“Release 1.0”,指代内部的版本号码。
在Subversion中,tag其实是不再让你编辑的branche,它们只是方便为了以后的使用,让你能够明确看到1.0版中到底包含了哪些东西。因此它们就停顿在那里,不再变动了。
(in trunk)
svn copy http://path/to/revision http://path/to/tag
一个实际的例子:管理Windows源码
我们前面说过,微软公司不用共享文件夹管理代码,那么他们怎么管理呢?
* 首先有一条main line,专门保存稳定版本的Windows。
* 然后,每个开发小组(网络、用户界面、媒体播放器等等)都有各自的branch,来添加新功能。这些新功能还在开发当中,并不稳定。
你在你的branch中,开发了一个新功能。然后,你用“Reverse Integrate (RI)”,将它并入主版本。接着,你再用“Forward Integrate”,你再去得到最新的主版本,将它并入你的branch。
假设老版本是Media Player 10和IE 6。Media Player开发小组,在他们的branch中制作了第11版,然后他们用一个10 - 11的补丁,将第11版加入老版本中。这是一个reverse integration,从branch到trunk。IE开发小组也是同样的步骤。
接着,Media Player开发小组从其他小组(比如IE小组)得到最新的代码。在这个例子中,Media Player从trunk得到最新的补丁,运用到他们的branch中,这叫做forward integration。
reverse integration和forward integration,分别简称RI和FI。这样的安排让变动主要在branch中发生,而使得主干保持相对不受影响。
在微软实际运作中,有很多层的branch和sub-branch,还有许多质量控制标准,确定什么时候才可以进行RI。这里只是希望帮助你建立一个想法,那就是branch有助于管理复杂的项目。现在,你应该明白了世界上最大的软件项目之一,是怎么进行组织的。
结束语
如果你以前没有用过VCS,我建议你使用它。因为它是一种很好的工具,即使你不打算写一个操作系统,单单就是为了备份,也值得用它。
网上有许多VCS软件可供选择,并且都有详细的教程或手册,比如SVN、CVS、RCS、Git、Perforce等等。Eric Sink写过一个详细的version control guide可供参考。
(完)
相关推荐
首先,教程从C#的基础语法开始讲解,包括变量、数据类型、运算符、控制结构(如if语句、for循环、while循环)等。这些基础知识构成了编程的基本骨架,让读者能够编写出简单的逻辑代码。 接着,教程深入到类和对象的...
链接:https://pan.baidu.com/s/1z1o3_xKKoJo2_jYa7Gq1gg 提取码:3xi7
VB 6.0 入门速成教程 VB 6.0 是微软公司推出的可视化编程工具,当前是世界上使用最广泛的程序开发工具。它具有快捷的开发速度、简单易学的语法和体贴便利的开发环境,非常适合初学者。 VB 6.0 的优点: 1. 快捷的...
《插图详解C# 2008》是一本针对初学者和有一定基础的程序员设计的教程,通过图文并茂的方式深入浅出地讲解了C# 2008编程语言的核心概念和技术。这本书旨在帮助读者理解C#的语法结构、编程逻辑以及.NET Framework的...
Illustrator作为一款强大的矢量图形处理软件,广泛应用于网页设计、UI设计、插图绘制、logo设计等多个领域。通过本课程的学习,你可以系统地了解并掌握这一专业工具,为自己的职业生涯添加一项重要的技能。 课程...
AI基础知识图文教程--入门知识学习 AI基础知识图文教程是为了帮助初学者快速入门AI相关知识,而本教程的重点是 Illustrator 软件的使用和矢量图形设计。下面是本教程的知识点概况: 一、Illustrator 简介及应用...
这个过程中,读者将学习到版本控制的重要性,如何使用Git进行代码管理,以及如何发布游戏到Google Play商店。 总的来说,《Android游戏开发入门》是一本全面而实用的教程,不仅教导读者掌握Android游戏开发的基本...
LaTeX还提供了各种排版命令和环境,用于控制文字排版、列表环境、对齐方式等。 在排版数学公式方面,LaTeX具有无与伦比的优势。它提供了专门的数学模式和丰富的数学排版命令,如字母、指数、下标、根号、分数、...
"AI基础知识图文教程---入门知识学习" 从给定的文件信息中,我们可以生成以下重要知识点: 一、Illustrator 简介及应用领域 * Illustrator 是美国 Adobe 公司出品的重量级矢量绘图软件,是出版、多媒体和网络图像...
本视频教程将深入讲解这两个工具的使用方法,帮助初学者从入门逐步掌握高级技巧。 钢笔工具是Photoshop中用于绘制自由曲线路径的利器,它允许用户精确地控制线条的走向和形状。钢笔工具包括多个子工具,如简单钢笔...
### 狐表(FoxTable)从入门到精通图文教程 #### 一、关于FoxTable **FoxTable**是一款高效的数据管理软件,适用于各种规模的企业和个人用户。它结合了传统电子表格的功能与数据库的强大特性,提供了更为灵活和...
未受版本控制的属性 版本库数据存储 Berkeley DB FSFS 版本库的创建和配置 钩子脚本 Berkeley DB配置 版本库维护 管理员的工具箱 svnlook svnadmin svndumpfilter svnshell.py Berkeley DB工具 版本库清理 管理磁盘...
本压缩包文件提供了三本经典的Python入门书籍,包括《python基础教程》、《A Byte of Python》以及《Head First Python》(中文版),旨在帮助快速掌握Python编程基础。 《python基础教程》是一本自编的精品教材,...
Photoshop是由Adobe公司开发的专业图像处理软件,广泛应用于平面设计、照片编辑、插图创作等领域。这个实例教程可能涵盖了Photoshop的基础操作,如工具箱的使用、图层管理、选区工具、调整图像色彩、添加文字、滤镜...
### LaTeX入门教程:掌握专业排版的艺术 #### 引言:历史与背景 LaTeX是一种基于Donald Knuth的TeX排版系统的高级文本编辑工具,它以其卓越的文档排版能力和数学公式的美观呈现而闻名于学术界。由Leslie Lamport在...
这个文件名表明教程是以PDF格式提供的,可能包含两种版本:插图版和文字版。插图版可能包含图表、示意图或者漫画形式的解释,使得复杂概念更加直观易懂,适合视觉学习者。文字版则可能更侧重于详细的文字描述和示例...
通过这套《AI CS5入门到高级学习》视频教程,你可以逐步掌握Adobe Illustrator的基础到高级技巧,无论你是准备进入设计行业的新人,还是寻求技能提升的专业设计师,都能从中受益匪浅。记住,理论知识结合实际操作是...