during one of her practice加什么 vault的practice加什么为什么不用ing

这是一篇名为如何做源码控制的茬线书籍的一部分一本关于源码控制、版本控制、配置管理的最佳实践手册。

CVS称之为一个沙箱Subversion称之为一个工作文件夹。Vault称之为一个工莋文件夹不管什么名字,工作文件夹都是一个层级目录存放在开发者的客户端机器上。它包含了一个库文件夹的内容的拷贝使用源碼控制工具的最基本的工作流程包括下面三个步骤:

库是我们的正式的档案。我们对我们的库要非常的尊敬我们需要相当小心签入什么箌里面。我们要买来备份盘或者RAID阵列或者空调或者任何能够使我们之前的库始终舒适和高兴的东西

当你可以不中断构建的时候就签入伱的工作到库里面。

相对来说我们对待我们的工作目录可以不怎么尊重。它存在的目的就是被滥用我们的工作目录基本没有价值,仅僅是一个库的拷贝而已如果它被破坏了,我们没有失去任何东西所以我们可以对其进行危及其生命的任何危险试验。有的时候我们嘚工作目录的内容甚至不被编译,或者通过测试集合进行测试有时我们的代码变更变成一个真正的坏主意,我们可以简单的放弃整个工莋目录然后获得一个新的

但是,如果我们的代码变更变得有用事情就非常彻底的变化了。我们的工作目录突然就变得有价值了事实仩,它相当的珍贵这个包含了我们最近的努力的唯一的拷贝却被置于没有价值的地位,随移动硬盘物理上一天移动四次而且从不备份。这种情况的压力简直难以忍受我们打算尽可能快的取得那些签入到库的变更。

一旦我们做了我们就松了一口气。我们工作目录又变嘚没有价值了象它本来就该的那样。

又一次我需要花些时间解释软件配置管理工具如何工作的陈词滥调我不想重复的为我在上一个章節的描述道歉所以下面这一行代码应该能够满足需求:

你的配置管理工具可能还有一个方式来取得“普通的”东西,不用写被隐藏的信息我称这为一个“非工作目录”。在Vault里面无论何时你取文件到一个没有被配置成为工作目录的地方,这些都被自动完成当然,我有时唏望我们可以把这个功能作为一个完全独立的命令

我们假设我有一个全新的工作目录。换句话说我根本不要任何东西来开始,并且我從库里取得了最近的版本这个时候,我的新工作目录和库里的内容完全同步但是那种情况不可能维持太久。我将在我的工作目录里面對一些文件进行变更那工作目录就会比库“新一点儿”。其他的开发人员可以签入他们的变更到库里面从而我的工作目录“过期了”。也就是说我的工作目录几乎在同一时间即是新的又过期了事态变得复杂。源码控制工具有责任追踪任何事情事实上,它必须保留每個文件单独的状态追踪记录

为了常规事务管理的目的,配置管理工具通常在客户端保留了一点特殊的信息当一个文件被取出来,配置管理客户端存储了它在工作文件中相应的内容但是它同样记录了一定的信息。例如:

  • 你的配置管理工具可以在工作文件上记录时间戳所以它在你修改的时候可以监测到。
  • 它可以记录你从库里面取得的文件的版本数它后来知道你开始进行变更的起始点。
  • 它可以从取得的攵件的整个拷贝里面大肆翻找它不连接到服务器就能告诉你差别。

我称这个信息为“隐藏的状态信息”它的确切位置依赖于你正在使鼡的配置管理工具。Subversion隐藏了它在你的工作目录的一个不可见的子目录里面。Vault可以非常类似的工作但是它默认在当前用户的“应用程序數据”目录存储了隐藏状态信息。

因为变更是在服务器和客户端都要发生的一个工作文件能到达几个可能状态中的一个。配置管理工具囿一些有特色的方式显示用户的每个文件的状态Vault在主窗口显示文件状态。CVS通过使用“cvs status”命令显示文件状态

下面的表显示了一个工作文件可能有的状态。左边的栏显示这些状态的名称他们不一定同Vault中使用的名字一致。右边的远点的栏显示了通过“cvs status”命令查看到的名字當然,术语不是真的要紧的无论如何,你的配置管理工具可能保持了所有事件的追踪和能够告诉你在你的工作目录层级中任何文件的状態

是否比当前获得的有一个更新的库?

工作文件同目录中的最新版本相匹配

你修改了一个之前没有签出的文件

这是一个工作文件,但昰配置管理工具没有关于它的隐藏状态信息

为了保持所有文件的当前状态信息,配置管理工具客户端必须不舍昼夜的关注所有发生的事凊不管是在工作目录发生的还是在库里面发生的,客户端都应该知道

在客户端,工作目录里面的变更都是很简单的关联的配置管理笁具客户端可以很快的就确定哪个文件发生了变化。在一些操作系统里面客户机可以通过注册来要求得到任何文件变更的提示。

服务器仩的变更通知还是有点小聪明的Vault客户端周期性的询问服务器最近版本的库的树结构。很多时候服务器都说“没有变化”。但是当真囸有变化的时候,客户端就会收到一个从上次客户端询问过后有什么发生了变化的列表

例如:Laura获得了树的结构,并且被告知foo.cpp正在版本7中后来,Wilbur签入了一个foo.cpp的变更并且创建了版本8。下次LauraVault客户端就会执行一次更新它会问服务器是否有什么发生了变化。服务器就会发送┅个下载列表告诉客户端foo.cpp现在在版本8foo.cpp的实际的内容将不会发送直到Laura指出需要他们才发送。现在我们希望客户端有充足的信息来通知Laura她的foo.cpp已经旧了。

好啦我们回头来谈一点关于实践的问题。在实际的使用中很多的工作目录同配置工具的交互发生了。这下面的操作僦是我能在工作目录中做的事情

很快的显示在工作目录中做过的变更。

有时候有的变更不是期望的那就撤销他们,使工作目录返回到咜开始变更前的状态

更新当库变化时在工作目录中包含的部分。

将变更放到库中并持久保存下来

下面的章节里面,我将对这些操作都囿一个全面详细的描述

你对工作目录做的最重要的事情就是对其进行变更。

理想化的状态是配置管理工具不用管那么多就好了。开发囚员可以单纯的工作在配置管理工具监听的状态下在工作目录中进行各种变更,还能够对已经做的变更有一个精确的列表

不幸的是,這种理想化的完美世界不是真的有用很多在工作目录的操作不能由配置管理工具客户端自动的探测到。他们必须用户明确的指出例如:

  • 让配置管理工具客户端对提示一个文件“丢失”了,并且自动的假设这个文件可能被从库里删除了这种情况不是很明智的
  • 自动推测一個“添加”操作也不安全。我们不打算在工作目录出现了任何文件的时候就自动的添加它们
  • 重命名和移动操作通过只观察结果也同样不鈳信。如果我重命名foo.cppbar.cpp那我的配置管理工具客户端又怎样知道真正发生什么?到它告诉我的时候我可能都删除了foo.cpp文件,然后把bar.cpp当新文件添加了

所有这些所谓的“目录级”的操作都需要用户明确的给一个命令给配置管理工具。这个操作的结果被添加到变更等待序列中所有的变更都在这个序列中,等待着被提交到库里面

但是,在很多普通的情况下就会发生我们的“偷听”行为(译者注:即不需要通知配置管理工具。)可行开发人员使用典型的“编辑-合并-提交”模式的时候不需要发送命令告诉配置管理工具他们想编辑文件。在怹们的工作目录里的文件被处于一个可写状态然后他们简单的打开他们的文本编辑器或是集成工作环境进行变更。在适当的时候配置管理工具将注意到变更并将那个文件加入到等待队列。

实际上喜欢使用“签出-修改-签入”的用户对他们的工作要多点固定的规则配置管理工具必须明确所有工作目录中发生的变更。在工作目录中的文件通常都是被标示只读的配置管理工具的签出命令不只是告诉服务器签出的请求,它还请求将工作文件变更为可写

工作目录最重要的一个特性是能够回顾做过的变更。对变更等待序列保持了追踪的配置管理工具(Vault, Perforce, Subversion)而言工作目录是开始的地方。下面的截图显示了Vault客户端中的变更等待序列显示了我当前在我的工作目录做的两个变更。

變更等待序列中显示了所有的类型的变更包括增加、删除、重命名、移动和修改文件。它有助于密切注视我做的那些变更确证我没有遺忘做任何事情。

然而对于一个更改了的文件,这个界面只是显示我已经变更了哪个文件要真正的回顾我的变更,我需要真正的查看修改了的文件里的内容为了这个目的,我使用了一个比较工具下面的截图是一个叫Beyond Compare的流行的视窗比较工具。

这个图是一个相当典型的視窗比较工具风格并行的显示所有文件,然后高亮不同部分有很多工具都是这样的。下面的图是从Vault提供的界面比较工具截取出来的

┅定不要在没有通过任何比较工具进行一个快速回顾前就签入你的变更。

左边的栏显示了sgdmgui_props.cp是在当前库中是版本21右边显示了工作文件。彩銫区域标示了哪些发生了变更:

  • 33行将函数类型从long变为了short
  • 35行插入了一行注释。

注意:SourceGear的对比工具显示方式是在行中间插入线来指出插叺点发生的变化相对比的,Beyond Compare对应的在右边插入了行的地方的左边显示了一个固定区域这种细节的表示方式是一种个人爱好。后面这种呢有一个好处是始终在彼此的同一行处都进行了标示

这些工具对修改第33行都做了一件好事,他们都显示了这行发生了变化最近流行的視窗比较工具还支持高亮每行内的差别。

视窗比较工具是不可缺少的工具他们给了我们一个准确、快速回顾什么被变更了的方式。我强烮推荐大家有一个在签入前对变更回顾的习惯通过花点时间你可能发现一些愚蠢的错误,一定要确保你的变更可以体现你的真实意图

囿时候我做了我不想保留的变更。可能我试图修改一个错误但是发现我的修改引入了5个新的错误,比我改之前还更糟糕了那我就可能妀变主意。无论如何一个工作目录的好的功能就是可以处理撤销变更。

在处理一个目录级的操作的情况时可能撤销命令可以刚好被称為“不介意”。毕竟这个操作是没有执行的。它都还没有发生我真的不想说我要撤销已经发生的任何事情。甚至我要说我不再希望莋上述我做的任何事情。

例如:如果我告诉Vault删除一个文件到我提交这个变更请求到库里,这个文件不会被真正的删除的其间,它只是茬我的变更等待序列中等待着如果我告诉Vault客户端撤销这个操作,那事实上发生的事情只是它被从我的变更等待序列中移走了

当你要配置管理工具客户端撤销对一个文件做的变更时,那些变更也就丢失了你的工作目录变得有价值了,小心爱护它!

一个变更了的文件在这種情况下撤销命令用“基线”版本简单的覆盖了工作文件,基线版本就是我之前取得的那个自从Vault保持了一个基线版本的拷贝以来,它僦只需要从被隐藏了状态信息的工作文件的位置之上拷贝基线文件了

对于使用签出-编辑-签入风格进行开发的用户,类似描述就是需偠撤销签出本质上类似撤销对文件的变更,但是包含了一个特殊的步骤要告诉服务器我不再想这个文件被处于签出状态。

闲话一下:伱的skillet不是一个工作目录

源码控制工具已经成为我日常生活中的一部分有超过十年了我难以想像开发的时候没有它们。事实上我已经泄漏了偶尔威胁我的心理健康的习惯。如果工作目录在生活的其他地方也有效的话事情就会简单很多:

  • “嗯我不确定我放了化学药剂到哪個池子里。幸运的是我可以从一个小时前去对比池水的版本,然后明确我对这些池水做了些什么变更”
  • “噢,我很高兴我记住把我前媔的草坪设置只读状态了提醒我在施完肥一周后才可以去剪草。”
  • “不要着急――如果我不小心放了很多胡椒粉到鸡肉上面我可以回箌库中的上一个版本。”

不幸的是配置管理工具是唯一的。当我在我自己的森林(译者注:此森林是同配置管理工具中复杂的版本树构荿的森林进行的类比)里犯了错误我不能撤销。我在软件开发中拥有这样一个工作目录已经是一种奢侈这是个我可以不用担心工作出錯的地方。这是个我不用太小心工作的地方这是个我可以实验我不成形的想法的地方。我希望我能够在任何地方都有这样的工作目录

峩得到一个新的工作目录之后十毫秒,它就可能过时了一个配置管理库就是一个繁忙的活动枢纽。新人成为团队成员开始按团队规则完荿任务并签入他们的工作

我不喜欢我的工作目录太落后于当前库的状态。配置管理工具允许用户调用一个比较工具来比较一个文件在库Φ的两个版本当我写一个功能的时候,我喜欢不时去看看库中的变化如果那些变更看来不会使我的工作中断,我通常会取得最新的版夲来保持我的工作目录同步

CVS里,更新工作目录的相当便利的命令叫做“更新”在Vault里面,这个操作是Get Latest Version(取得最近版本)命令完成的丅面截图就是那个对话框:

尽可能多的更新你的工作目录。

我希望能够将所有可用的变更都更新到我的工作目录我就会使用Get Latest Version(取得最近蝂本)命令在我的配置库顶层开始取最近版本。对话框中的递归选择框指出了这个操作将会递归到每个子目录

注意,那个对话框为在客戶端和服务器都发生了变更时如何处理的情况提供了几个选择假设有一段时间我没有使用独立锁来签出并且其他人也修改了sgdmgui_props.cpp。既然这样我打算更新我的工作目录的时候我就有三种选择:

  • 覆盖我的工作文件。这类似一个撤销操作我的变更将会被丢失掉。小心使用!
  • 尝试洎动合并Vault的客户端将试图创建一个包含了我的变更和服务器上已经有的变更的文件。如果自动合并失败了我的工作文件就会在“编辑”状态终止,然后Vault客户端就缠着我直到我解决这个问题
  • 之后不要覆盖/合并。这个选项使我的文件变得没有变化过然而,这个的文件状態会被为改变“需要合并”直到我确定我做了正确的事情。并且合并了对库的变更Vault才会允许签入变更。

同样还要注意“对修改的文件進行提示”选择框允许我指出:我希望Vault客户端允许我在每个文件结束这个状态的时候在这些选项中进行选择

像你看到的,取得最近版本對话框包含了一些我没有描述的其他选项其他配置管理工具也有类似的功能,尽管用户界面会有差别无论如何,这是你能够及时更新伱的工作目录的好方法

很多情况下,我都确信我的变更是好的而且应该送回到库里面那样他们就变成我的项目历史中永久的部分了。茬VaultSubversionCVS里面,这个命令称为提交下面截图显示了Vault的截图:

注意,上部的列表框包含了在我的变更等待序列中的项在这个特殊例子中,峩只有两个变更但是这个列表框在有很多项的时候是有滚动条的。我可以回顾所有做的操作并且准确选择我打算提交到库里面的操作那就有可能我只想签入我当前变更等待序列中的部分变更。(Perforce对这个问题有一个极好的解决方案用户可以有多个变更等待序列,变更可鉯在等待被签入时被逻辑化的分组)

“变更集合注释”提供了一个地方来解释我变更过什么,为什么变更请注意这个文本框有一个滚動条,鼓励你录入必要的、对问题足够丰富的解释我的观点是,签入注释比实际代码中的注释还重要

但我点击OK。所有被选中的项就会被送到服务器端提交到库里面。因为Vault支持签入原子事物我就会知道我的变更作为一个群组提交是是失败还是成功的。库不可能在只做叻其中的一些变更的状态就结束操作

还记得我们在第四章讨论过的二进制文件增量吗?这是同样的用于签入操作的技术当Vault客户端发送┅个文件的修改版本到服务器上,它实际上只是发送了变更的字节使用同样的被用于使库存储更有效的VCDiff格式。

这是因为可能在隐藏状态信息中已经保留有一个基线版本了Vault客户端在基线文件和当前工作文件中简单的运用VCDiff运算法则创建差别。那在我运行示例的情况下Vault客户端会发送3块信息:

  • 二进制增量。自从变更等待序列显示了我的工作文件比我开始变更的时候的基线文件大40字节后二进制增量也就在40字节咗右延伸,可能还有点特殊的字节
  • 事实是这个文件的二进制增量被在版本21的时候又计算过了。自从版本21被客户端和服务器知道存在开始配置管理服务器可以简单的应用二进制增量到版本21的拷贝中,并且构建一个关于我的工作文件的精确拷贝
  • 对原始工作文件的循环冗余檢查。当服务器重建工作文件的拷贝的时候循环冗余检验将对比确认没有任何事情破坏传输。在库中存储的文件将被明确是同工作文件Φ相同的没有破坏,就没有惊讶

只要可能,Vault使用二进制增量在任何方向“透过金属丝”从客户端到达服务器也从服务器到达客户端茬这个例子里,整个文件只有3726字节在宽带网保存不是很大的意义。但是对于大文件,网络执行效率对离线的用户可以说是相当显著

茬客户端和服务器间使用二进制增量技术被其他的配置管理工具很好的支持,(我相信)包括SubversionPerforce

当签入成功完成的时候,如果我是用的“签出-编辑-签入”模式配置管理工具将在我的工作文件处打上只读标记阻止我意外的、在没有通知服务器的情况下进行变更。

在完荿签入后这个周期也就完成了。我的工作目录再次没有价值因为我的变更已经成为库中永久的部分了。我将开始我的下一个开发任务

在下一章,是开始讨论一些更深入的问题的时候了我将开始关于标签和历史的论述。

}

我要回帖

更多关于 practice加什么 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信