分类: 项目管理
2008-10-28 17:16:36
· 团队开发?
· 修改文件而他人也在改?你修改的内容丢失?
· 保存了文件可又后悔了?想得到几天前的版本?
· 发现了bug,想知道bug何时引入的?
Subversion是版本管理的后台系统,其核心是保存数据的档案库-repository。 档案库用分层的“文件-目录”文件系统数来存储数据。连接到档案库的客户能读写数据。档案库记录了你的每一次修改!客户端可以从档案库中取到过去的版本。
图2.1. 典型服务器/客户机模型
基本问题:共享数据而不相互覆盖?
在合作开发中文件共享的问题是显而易见的。
图 2.2. 要避免的问题
Visual SourceSafe采用的就是这种模型。
Figure 2.3. 锁定-修改-解锁方案
问题:
· 锁定可能引起管理问题: 如忘记解锁别人无法使用。
· 锁定造成不必要的串行作业。
· 锁定可引起安全问题。
Subversion和CVS等采用拷贝-修改-合并模型。项目成员从档案库读取个人的工作拷贝,所有项目成员并行地在工作拷贝上工作,然后合并在一起形成新的版本(version)。
图 2.4. 拷贝-修改-合并方案
Figure 2.5. ...Copy-Modify-Merge Continued
如果修改不重叠,TortoiseSVN可自动合并。修改重叠则引起冲突(conflict)。冲突只能靠手工修改!
这种模型好像很混乱,但实际上很好用。解决冲突的时间大大小于因锁定而等待的时间。解决冲突的最好办法是沟通。
Subversion的工作拷贝就是包含文件的本地目录树,与一般目录的树状结构相同,可以进行任意的工作!工作结束后可将新的文件“发布”到档案库。
工作拷贝中包含了由Subversion创建和维护的一个特殊的子目录.svn ,该目录保存了重要的信息。不要删除这个目录!
例如,假定你的档案库包含两软件项目:paint和calc。
图 2.6. 档案库文件系统
用取出(checkout)得到工作拷贝。
Repository URLs:档案库URL
Subversion的档案库借助不同方法得到:本地磁盘、网络协议等:
Table 2.1. Repository Access URLs
Schema |
Access Method |
file:/// |
本地磁盘. |
http:// |
透过Apache. |
例:
File:///c:/svn/prj/template ,
File:///c:/svn/prj/template/Dist
c:/svn/prj/template是档案库的目录,Dist是档案库的子目录名称
/Dist
是Apache设置的URL,prj是通过Apache设置的位置,template是档案库名称,Dist是目录名
svn commit 操作送交修改。档案库接受一次送交后,在文件系统树创建新的状态,称之为版本revision。每个版本是一个递增的自然数。
图 2.7. 档案库
全局版本号
版本号代表整个档案库而非单个文件!
工作拷贝如何跟踪档案库?
Subversion将下列两种管理信息记录在.svn/:
· 工作版本 working revision
· 从档案库更新的时间。
通过这些信息,在与档案库交换信息后,Subversion可得出文件的四种状态:
l 未修改,新版本,送交无效
l 本地修改,新版本,可送交,更新无效
l 未修改,但在档案库中已修改,过期,送交无效,可更新
l 本地修改,在档案库中已修改,过期。先更新,修改冲突,再送交。
这是设置Subversion服务器的最好方法。优点:
l 利用WebDAV
l 用浏览器浏览档案库
l 认证
l 安全
图 3.1. 没有版本控制的文件夹TortoiseSVN菜单
1. 进入资源管理器
2. 创建档案库的子目录,如C:/SVNRepository。
3. 在新建的目录中右键 ->.
可用FSFS和BDB两种格式创建。
注意:不要编辑档案库中的文件!
本地进入方式:file:///C:/SVNRepository/
最简单的办法是备份档案库文件夹!
推荐办法:
svnadmin hotcopy path/to/repository path/to/backup --clean-logs
图 4.1. TortoiseSVN右键菜单
所有TortoiseSVN命令均可以在资源浏览器的右键菜单中执行。
如果档案库设置了权限保护,则会弹出认证对话框。
图 4.2. 认证对话框
如果使用Windows域认证,用户名前需要包括域名,如MYDOMAIN/johnd.
根据不同需要来建立档案库的结构:
1. 创建新的空文件夹。
2. 创建目录结构 – 先不放文件!
3. 右键菜单,点击将结构加入到档案库中。
注意:文件夹的名字不汇入档案库。
通过档案库浏览器(Repo Browser)可直接浏览档案库结构。
在将项目文件汇入到档案库前,先进行下列操作:
1. 删除与项目无关的中间文件如生成的临时文件*.obj等。 如果设置了忽略的文件类型,或忽略的目录,可不删除。
2. 在文件夹中组织文件。
在资源浏览器中进入项目顶层文件夹,右键得到快捷菜单,选择 ,出现对话框:
图 4.3. 汇入对话框
在对话框中输入仓库的URL。
汇入信息(import message)作为记录信息。
注意
只要点击 TortoiseSVN将把整个目录及目录内的文件加入到档案库中。顶层文件夹的名字不会加入到档案库中,但其他子文件夹的名字均加入以保持档案库的结构。该项目的文件现在处在档案库版本控制中。请注意:目前的本地项目文件夹不处在版本控制下!要得到版本控制,必须取出checkout档案库得到工作拷贝!
有时你有一个包含用户特定数据的文件需要在版本控制下,这意味着每个开发人员需要修改它以适应他的本地设置,用户每次送交均要保存这文件的变化,因此对这类文件进行版本控制很困难。
对此建议使用template 文件,创建一共文件,它包含所有开发人员需要信息,将它加入到版本控制下,每个开发人员均可取出这个文件, 复制并重新命名,然后修改就没有问题了。不需要加入版本控制的文件可通过设置Subversion 特性(property) svn:ignored 来忽略。
从档案库执行取出(checkout)就能得到工作拷贝。
在资源浏览器中选定将要存放工作目录的拷贝,右键弹出快捷菜单,选择,将出现对话框:(如果该目录已在版本控制下,则没有取出而是和)
图 4.4. 取出对话框
如果文件夹不存在,会自动创建。
你只能将文件取出到一个空目录里。如果你想取出刚汇入的文件,Subversion将报错。你只能将文件取出到另一个目录或先删除已经存在的源文件再执行取出。
如果不想包含.svn ,可将档案库汇出到一个空目录。这时所有文件不处在版本控制下。方法:右键,选择TortoiseSVN-〉 。
通过图标可知道文件的状态:修改/新增/删除/换名。
图 4.5. 资源浏览器显示的图标
新近取出的工作拷贝。Subversion状态是正常normal.
文件已修改,需要送交到档案库。Subversion状态是已修改modified。
在更新文件后自己的修改与他人的修改冲突。状态是冲突conflict。
将加入到版本控制的文件或文件夹。状态是新增added 。
文件(夹)将从版本控制中删除,版本控制将忽略这些文件(夹)。状态是删除deleted。
图 4.6. 检查更新
想知道别人修改了哪些文件?用 命令。弹出的对话框将显示出你的修改或档案库中别人的修改,这样可在更新前检查是否有冲突。
. 命令也可用来显示本地的修改,如果不想实际送交到档案库,点击 即可。
图 4.7. 已完成更新的进度对话框
有时你想将他人的改动合并到你本地的工作拷贝。从服务器上取改动到本地的过程叫更新updating。 更新也许是单个文件、或选择的一组文件、或整个目录。在资源浏览器中选择待更新的文件或目录, 右键并选择 ,他人的修改将合并到你本地的文件中,你所做的改动保存在同一文件中。这时档案库没有受变化,即合并只在本地进行。
如果你和他人改动的是相同部分但改动不一样,就会在更新过程中产生冲突 conflicts。冲突在对话框中用红色表示,双击后用外部编辑器解决冲突。
TortoiseSVN也允许你将工作拷贝更新到指定版本。用 命令,在弹出的对话框中输入指定的版本号即可。
如果你更新到指定版本,再送交是将出现out of date 错误!如果你想撤销修改并从以前的版本开始工作,你必须使用从“显示记录”对话框中选择 命令或使用快捷菜单中的 菜单命令。
命令允许复原至低版本。比如你的工作目录版本是100,你想复原至版本50-直接填写在复原对话框中填写复原至版本50。通常,不复原单个文件,确实需要,从记录对话框(Log)选择 命令。
有时你从档案库更新文件会有冲突。冲突产生于两人都修改文件的某一部分。解决冲突只能靠人而不是机器。当产生冲突时,你应该打开冲突的文件,查找以<<<<<<<开始的行。冲突部分被标记:
<<<<<<< filename
your changes
=======
code merged from repository
>>>>>>> revision
Subversion为每个冲突文件产生三个附加文件:
filename.ext.mine
更新前的本地文件。
filename.ext.rOLDREV
你作改动的基础版本。
filename.ext.rNEWREV
更新时从档案库得到的最新版本。
使用外部合并工具或使用快捷菜单的 命令来解决冲突。然后从快捷菜单中执行 命令,将改动送交到档案库。请注意,解决命令并不解决冲突,而仅仅是删除filename.ext.mine and filename.ext.r* 文件并允许你送交。
这个过程叫送交committing 。 在送交前需要确认工作拷贝是最新的。用 或先用 检查变更了的文件。如果你的工作拷贝已更新且没有冲突,可用快捷菜单中的 完成送交过程。
图 4.8. 送交对话框
如果某文件不想在版本控制下,取消复选框即可。
许多不需要版本控制文件如obj文件等也出现在送交对话框中,解决办法:
· 在服务器端编辑配置文件config,将不需要控制的文件 (或通配符)添加到排除文件列表。其影响是全局的。
· 通过快捷菜单命令将文件添加到svn:ignore 列表。只影响到本目录。
图 4.9.送交进度
图 4.11. 加入快捷菜单
开发中新增文件或文件夹,如需要加入到版本控制,选择;如果不想要加入到版本控制,选择加入
图 4.12. 不需要版本控制快捷菜单
大多数项目会有一些文件(夹)不需要版本控制,如编译产生的*.obj, *.lst,等。每次送交,TortoiseSVN提示那些文件不需要控制,挺烦的。
最好是在项目中加入忽略列表。
忽略文件的另一个办法是加入全局忽略列表global ignore list。 全局忽略列表是客户端特性,他影响所有项目,但只在该客户端PC起作用。通常用 svn:ignore 会更好因为它对所有客户起作用。
从快捷菜单的TortoiseSVN 子菜单进入删除、改名等操作
Figure 4.13. Explorer context menu for versioned files
如果你想在工作拷贝中移动文件:
1. 选择待移动的文件和文件夹;
2. 按住左键拖动right-drag 文件(夹)到跟踪拷贝内的新地方;
3. 松开左键
4. 在弹出菜单中选择
如果你在资源管理器中象往常那样删除了文件而没有在版本控制中删除,送交对话框将提示这些文件并让你在送交前在版本控制中删除它们。
如果你想撤销自上次更新后所作的改动,选择文件,左键right click,在快捷菜单的TortoiseSVN子菜单中选择 ,在对话框中选择你想要复原的文件,点击.
图 4.14. 复原对话框
只撤销本地的改动,而不撤销已送交文件的改动。如果你想撤销某一版本的全部变更,可从版本记录对话框中处理。
对每次送交的更改,你必须同时提供更改的记录,以便日后能找出为什么/如何改动。记录对话框
记录对话框显示所有记录信息并显示在3个格里:
· 顶格显示版本号,包括日期,送交者等。
· 中格显示上格所选版本的完整记录Log。
· 底格显示该版本改动的文件列表。
在顶格还提供快捷菜单!
图4.15. 记录对话框
弹出Log记录对话框的方式:
· 从TortoiseSVN 子快捷菜单
· 从属性页
· 更新进度对话框。
版本控制的作用是能将变更隔离成独立的方向,称之为分支branch. 分支用于主发布前尝试新特性。
另一特性是标记特殊版本,以利于在任何时间重新创建环境。这个过程叫标记tagging.
Subversion并没有特别的用于分支和标记的命令,而是用cheap copies代替。Cheap copies有点像连接links。
在由工作拷贝创建branch/tag前,你必须确认已更新档案库。
创建branch/tag非常简单:
图 4.18. 分支/标记对话框
从工作目录父文件夹点出快捷键,选择 ,输入档案库中存放分支/标记路径的URL,在原来输入trunk 的地方输入tags/tagname ,这里tagname 可能是ProjectName_v1.10.
C:/SVNRepository/trunk/ProjectName/...
C:/SVNRepository/trunk/AnotherProject/...
C:/SVNRepository/branches/ProjectName_SpecialDebugBuildBasedOn_v1.09/
C:/SVNRepository/tags/ProjectName_v1.10
点击 ,Subversion在你选择的档案库的目录内创建了一个cheap copy。创建Branch / Tag不影响你的工作目录。
…这确实是个问题!由于Checkout取出了分支中的所有数据, 只是转移你工作目录中变化了的数据。
为了能在新的的工作拷贝上工作,你可以:
· 再次执行 。你可以取出任意次到你本地硬盘上的任何地方。
· 转换到新创建的档案库拷贝上。只需执行
在下面的对话框中输入你的分支的URL,保留“Head Revision”点击 ,你的工作目录将切换到新的分支/标记branch / tag.
切换与更新,不会丢失你在本地所作的修改,而是将未送交的修改合并。
Figure 4.19. 切换对话框
分支与标记的不同点:
· 标记用于创建项目特殊阶段的静态快照 – 不再用于开发 – 而分支是用于开发的。这是我们建议使用/trunk /branches /tags 的理由。
· 如果你在工作拷贝上修改并送交,则在分支的修改体现在分支上而不是主干上。。
将分支合并到主干上
图 4.20. 合并对话框
(略)
如果谁都可以修改,项目将没完没了,永远不会稳定下来。怎么办呢?通过“补丁patch”!将补丁送交的具有写权限开发团队,他们先审查补丁,再决定是否送交到档案库。
补丁文件仅显示工作拷贝和基础版本的差异。
首先你需要测试你的修改是否正确,然后用 而不是使用 ,这将创建包含改动的文件。
Figure 4.21. The Relocate Dialog
如果因为某种原因档案库修改位置,你需要使用重新定位命令。
直接在档案库上工作!
图 4.22. 档案库浏览器
进入档案库浏览器后,使用快捷菜单!
Figure 4.28. 注解/谴责对话框
有时你不但要知道那些代码改动了,还要知道谁改动的!使用 即可!将Blame翻译成真不好,其意思只是
图 4.29. TortoiseBlame
使用内建在TortoiseSVN中的TortoiseBlame可非常方便地查看修改的历史