|
3#
楼主 |
发表于 2007-10-16 13:56:59
|
只看该作者
(续)svn基本工作周期
CVS用户:控制另类的更新!
你也许使用cvs update来看你做了哪些修改,svn status会给你所有你做的改变—而不需要访问版本库,并且不会在不知情的情况下与其他用户作的更改比较。
在Subversion,update只是做这件事—将工作拷贝更新到版本库的最新版本,你可以消除使用update察看本地修改的习惯。
如果你在工作拷贝的顶级目录运行不带参数的svn status命令,它会检测你做的所有的文件或目录的修改,以下的例子是来展示svn status可能返回的状态码(注意,#之后的不是svn status打印的)。
L abc.c # svn已经在.svn目录锁定了abc.c
M bar.c # bar.c的内容已经在本地修改过了
M baz.c # baz.c属性有修改,但没有内容修改
X 3rd_party # 这个目录是外部定义的一部分
? foo.o # svn并没有管理foo.o
! some_dir # svn管理这个,但它可能丢失或者不完整
~ qux # 作为file/dir/link进行了版本控制,但类型已经改变
I .screenrc # svn不管理这个,配置确定要忽略它
A + moved_dir # 包含历史的添加,历史记录了它的来历
M + moved_dir/README # 包含历史的添加,并有了本地修改
D stuff/fish.c # 这个文件预定要删除
A stuff/loot/bloo.h # 这个文件预定要添加
C stuff/loot/lump.c # 这个文件在更新时发生冲突
R xyz.c # 这个文件预定要被替换
S stuff/squawk # 这个文件已经跳转到了分支
在这种格式下,svn status打印五列字符,紧跟一些空格,接着是文件或者目录名。第一列告诉一个文件的状态或它的内容,返回代码解释如下:
A item
文件、目录或是符号链item预定加入到版本库。
C item
文件item发生冲突,在从服务器更新时与本地版本发生交迭,在你提交到版本库前,必须手工的解决冲突。
D item
文件、目录或是符号链item预定从版本库中删除。
M item
文件item的内容被修改了。
R item
文件、目录或是符号链item预定将要替换版本库中的item,这意味着这个对象首先要被删除,另外一个同名的对象将要被添加,所有的操作发生在一个修订版本。
X item
目录没有版本化,但是与Subversion的外部定义关联,关于外部定义,可以看“外部定义”一节。
? item
文件、目录或是符号链item不在版本控制之下,你可以通过使用svn status的--quiet(-q)参数或父目录的svn:ignore属性忽略这个问题,关于忽略文件的使用,见“svn:ignore”一节。
! item
文件、目录或是符号链item在版本控制之下,但是已经丢失或者不完整,这可能因为使用非Subversion命令删除造成的,如果是一个目录,有可能是检出或是更新时的中断造成的,使用svn update可以重新从版本库获得文件或者目录,也可以使用svn revert file恢复原来的文件。
~ item
文件、目录或是符号链item在版本库已经存在,但你的工作拷贝中的是另一个。举一个例子,你删除了一个版本库的文件,新建了一个在原来的位置,而且整个过程中没有使用svn delete或是svn add。
I item
文件、目录或是符号链item不在版本控制下,Subversion已经配置好了会在svn add、svn import和svn status命令忽略这个文件,关于忽略文件,见“svn:ignore”一节。注意,这个符号只会在使用svn status的参数--no-ignore时才会出现—否则这个文件会被忽略且不会显示!
第二列说明文件或目录的属性的状态(更多细节可以看“属性”一节),如果一个M出现在第二列,说明属性被修改了,否则显示空白。
第三列只显示空白或者L,L表示Subversion已经在.svn工作区域锁定了这个项目,当你的svn commit正在运行的时候—也许正在输入log信息,运行svn status你可以看到L标记,如果这时候Subversion并没有运行,可以推测Subversion发生中断并且已经锁定,你必须运行svn cleanup来清除锁定(本节后面将有更多论述)。
第四列只会显示空白或+,+的意思是一个有附加历史信息的文件或目录预定添加或者修改到版本库,通常出现在svn move或是svn copy时,如果是看到A +就是说要包含历史的增加,它可以是一个文件或是拷贝的根目录。+表示它是即将包含历史增加到版本库的目录的一部分,也就是说他的父目录要拷贝,它只是跟着一起的。 M +表示将要包含历史的增加,并且已经更改了。当你提交时,首先会随父目录进行包含历史的增加,然后本地的修改提交到更改后的版本。
第五列只显示空白或是S,表示这个目录或文件已经转到了一个分支下了(使用svn switch)。
如果你传递一个路径给svn status,它只给你这个项目的信息:
$ svn status stuff/fish.c
D stuff/fish.c
svn status也有一个--verbose(-v)选项,它可以显示工作拷贝中的所有项目,即使没有改变过:
$ svn status --verbose
M 44 23 sally README
44 30 sally INSTALL
M 44 20 harry bar.c
44 18 ira stuff
44 35 harry stuff/trout.c
D 44 19 ira stuff/fish.c
44 21 sally stuff/things
A 0 ? ? stuff/things/bloo.h
44 36 harry stuff/things/gloo.c
这是svn status的“加长形式”,第一列保持相同,第二列显示一个工作版本号,第三和第四列显示最后一次修改的版本号和修改人。
上面所有的svn status调用并没有联系版本库,只是与.svn中的元数据进行比较的结果,最后,是--show-updates(-u)参数,它将会联系版本库为已经过时的数据添加新信息:
$ svn status --show-updates --verbose
M * 44 23 sally README
M 44 20 harry bar.c
* 44 35 harry stuff/trout.c
D 44 19 ira stuff/fish.c
A 0 ? ? stuff/things/bloo.h
Status against revision: 46
注意这两个星号:如果你现在执行svn update,你的README和trout.c会被更新,这告诉你许多有用的信息—你可以在提交之前,需要使用更新操作得到文件README的更新,或者说文件已经过时,版本库会拒绝了你的提交。(后面还有更多关于此主题)。
svn diff
另一种检查修改的方式是svn diff命令,你可以通过不带参数的svn diff精确的找出你所做的修改,这会输出统一区别格式:[3]
$ svn diff
Index: bar.c
===================================================================
--- bar.c (revision 3)
+++ bar.c (working copy)
@@ -1,7 +1,12 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <stdio.h>
int main(void) {
- printf("Sixty-four slices of American Cheese...\n");
+ printf("Sixty-five slices of American Cheese...\n");
return 0;
}
Index: README
===================================================================
--- README (revision 3)
+++ README (working copy)
@@ -193,3 +193,4 @@
+Note to self: pick up laundry.
Index: stuff/fish.c
===================================================================
--- stuff/fish.c (revision 1)
+++ stuff/fish.c (working copy)
-Welcome to the file known as 'fish'.
-Information on fish will be here soon.
Index: stuff/things/bloo.h
===================================================================
--- stuff/things/bloo.h (revision 8)
+++ stuff/things/bloo.h (working copy)
+Here is a new file to describe
+things about bloo.
svn diff命令通过比较你的文件和.svn的“原始”文件来输出信息,预定要增加的文件会显示所有增加的文本,要删除的文件会显示所有要删除的文本。
输出的格式为统一区别格式(unified diff format),删除的行前面加一个-,添加的行前面有一个+,svn diff命令也打印文件名和打补丁需要的信息,所以你可以通过重定向一个区别文件来生成“补丁”:
$ svn diff > patchfile
举个例子,你可以把补丁文件发送邮件到其他开发者,在提交之前审核和测试。
svn revert
假设你通过上面的diff输出发现你不小心用编辑器在README中输入了一些字符。
这是使用svn revert的好机会。
$ svn revert README
Reverted 'README'
Subversion把文件恢复到未修改的状态,叫做.svn目录的“原始”拷贝,应该知道svn revert可以恢复任何预定要做的操作,举个例子,你不再想添加一个文件:
$ svn status foo
? foo
$ svn add foo
A foo
$ svn revert foo
Reverted 'foo'
$ svn status foo
? foo
注意
svn revert ITEM的效果与删除ITEM然后执行svn update -r BASE ITEM完全一样,但是,如果你使用svn revert它不必通知版本库就可以恢复文件。
或许你不小心删除了一个文件:
$ svn status README
README
$ svn delete README
D README
$ svn revert README
Reverted 'README'
$ svn status README
README
看!没有网络!
这三个命令(svn status、svn diff和 svn revert)都可以在没有网络的情况下工作,这让你在没有网络连接时的管理修改过程更加简单,像在飞机上旅行,乘坐火车往返或是在海滩上奋力工作时。
Subversion通过在.svn管理区域使用原始的版本缓存来做到这一点,这使得恢复本地版本而不必访问网络,这个缓存(叫做“text-base”)也允许Subversion可以根据原始版本生成一个压缩的增量(“区别”)提交—即使你有个非常快的网络,有这样一个缓存有极大的好处,非常的快,只向服务器提交修改的部分,这一点乍一看好像并不重要,但当你要提交一个400M大小的文件的修改时,你就会明白! |
|