博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
svn tour cycle
阅读量:7003 次
发布时间:2019-06-27

本文共 11301 字,大约阅读时间需要 37 分钟。

基本的工作循环

Subversion有许多特性、选项和华而不实的高级功能,但日常的工作中你只使用其中的一小部分,在这一节里,我们会介绍许多你在日常工作中常用的命令。

典型的工作周期是这样的:

  • 更新你的工作拷贝

    • svn update

  • 做出修改

    • svn add

    • svn delete

    • svn copy

    • svn move

  • 检验修改

    • svn status

    • svn diff

  • 可能会取消一些修改

    • svn revert

  • 解决冲突(合并别人的修改)

    • svn update

    • svn resolved

  • 提交你的修改

    • svn commit

更新你的工作副本

当你在一个团队的项目里工作时,你希望更新你的工作拷贝得到所有其他人这段时间作出的修改,使用svn update让你的工作拷贝与最新的版本同步。

$ svn updateU  foo.cU  bar.cUpdated to revision 2.

这种情况下,其他人在你上次更新之后提交了对foo.cbar.c的修改,因此Subversion更新你的工作拷贝来引入这些更改。

当服务器通过svn update将修改传递到你的工作拷贝时,每一个项目之前会有一个字母,来让你知道Subversion为保持最新对你的工作拷贝作了哪些工作。关于这些字母的详细含义,可以看。

修改你的工作副本

现在你可以开始工作并且修改你的工作拷贝了,你很容易决定作出一个修改(或者是一组),像写一个新的特性,修正一个错误等等。这时可以使用的Subversion命令包括svn addsvn deletesvn copysvn move。如果你只是修改版本库中已经存在的文件,在你提交之前,不必使用上面的任何一个命令。

你可以对工作拷贝做出两种修改:文件修改和目录树修改。你不需要告诉Subversion你希望修改一个文件,只需要用你的编辑 器、字处理器、图形程序或任何工具做出修改,Subversion自动监测到文件的更改,此外,二进制文件的处理方式和文本文件一样—也有同样的效率。对 于目录树更改,你可以告诉Subversion将文件和目录预定的删除、添加、拷贝或移动标记,这些动作会在工作拷贝上立刻发生效果,但只有提交后才会在 版本库里生效。

下面是Subversion用来修改目录树结构的五个子命令。

svn add foo

预定将文件、目录或者符号链foo添加到版本库,当你下次提交后,foo会成为其父目录的一个子对象。注意,如果foo是目录,所有foo中的内容也会预定添加进去,如果你只想添加foo本身,请使用--non-recursive (-N)参数。

svn delete foo

预定将文件、目录或者符号链foo从版本库中删除,如果foo是文件,它马上从工作拷贝中删除,如果是目录,不会被删除,但是Subversion准备好删除了,当你提交你的修改,foo就会在你的工作拷贝和版本库中被删除。[]

svn copy foo bar

建立一个新的项目bar作为foo的复制品,会自动预定将bar添加,当在下次提交时会将bar添加到版本库,这种拷贝历史会记录下来(按照来自foo的方式记录),svn copy并不建立中介目录。

svn move foo bar

这个命令与与运行svn copy foo bar;svn delete foo完全相同,bar作为foo的拷贝准备添加,foo已经预定被删除,svn move不建立中介的目录。

svn mkdir blort

这个命令同运行 mkdir blort; svn add blort相同,也就是创建一个叫做blort的文件,并且预定添加到版本库。

检查你的修改

当你完成修改,你需要提交他们到版本库,但是在此之前,检查一下做过什么修改是个好主意,通过提交前的检查,你可以整理一份精确的日志信息,你也可以发现你不小心修改的文件,给了你一次恢复修改的机会。此外,这是一个审查和仔细察看修改的好机会,你可通过命令svn status浏览所做的修改,通过svn diff检查修改的详细信息。

Subversion已经被优化来帮助你完成这个任务,可以在不与版本库通讯的情况下做许多事情,详细来说,对于每一个文件,你的的工作拷贝在.svn包含了一个“原始的”拷贝,所以Subversion可以快速的告诉你那些文件修改了,甚至允许你在不与版本库通讯的情况下恢复修改。

查看你的修改概况

为了浏览修改的内容,你会使用这个svn status命令,在所有Subversion命令里,svn status可能会是你用的最多的命令。

如果你在工作拷贝的顶级目录运行不带参数的svn status命令,它会检测你做的所有的文件或目录的修改,以下的例子是来展示svn status可能返回的状态码(注意,#之后的不是svn status打印的)。

A       stuff/loot/bloo.h   # file is scheduled for additionC       stuff/loot/lump.c   # file has textual conflicts from an updateD       stuff/fish.c        # file is scheduled for deletionM       bar.c               # the content in bar.c has local modifications

在这种格式下,svn status打印6列字符,紧跟一些空格,接着是文件或者目录名。第一列告诉一个文件或目录的状态或它的内容,返回代码如下:

A item

预定加入到版本库的文件、目录或符号链的item

C item

文件item发生冲突,在从服务器更新时与本地版本发生交迭,在你提交到版本库前,必须手工的解决冲突。

D item

文件、目录或是符号链item预定从版本库中删除。

M item

文件item的内容被修改了。

如果你传递一个路径给svn status,它只给你这个项目的信息:

$ svn status stuff/fish.cD      stuff/fish.c

svn status也有一个--verbose (-v)选项,它可以显示工作拷贝中的所有项目,即使没有改变过的:

$ svn status -vM               44        23    sally     README                44        30    sally     INSTALLM               44        20    harry     bar.c                44        18    ira       stuff                44        35    harry     stuff/trout.cD               44        19    ira       stuff/fish.c                44        21    sally     stuff/thingsA                0         ?     ?        stuff/things/bloo.h                44        36    harry     stuff/things/gloo.c

这是svn status的“加长形式”,第一列保持相同,第二列显示一个工作版本号,第三和第四列显示最后一次修改的版本号和修改人(这些列不会与我们刚才提到的字符混淆)。

上面所有的svn status调用并没有联系版本库,只是与.svn中的原始数据进行比较的结果,最后,是--show-updates (-u)选项,它将会联系版本库为已经过时的数据添加新信息:

$ svn status -u -vM      *        44        23    sally     READMEM               44        20    harry     bar.c       *        44        35    harry     stuff/trout.cD               44        19    ira       stuff/fish.cA                0         ?     ?        stuff/things/bloo.hStatus against revision:   46

注意这两个星号:如果你现在执行svn update,你的READMEtrout.c会被更新,这告诉你许多有用的信息—你可以在提交之前,需要使用更新操作得到文件README的更新,或者说文件已经过时,版本库会拒绝了你的提交。(后面还有更多关于此主题)。

关于文件和目录,svn status可以比我们的展示显示更多的内容,完整的描述可以看。

检查你的本地修改的详情

另一种检查修改的方式是svn diff命令,你可以通过不带参数的svn diff精确的找出你所做的修改,这会输出统一区别格式的区别信息:

$ svn diffIndex: bar.c===================================================================--- bar.c	(revision 3)+++ bar.c	(working copy)@@ -1,7 +1,12 @@+#include 
+#include
+#include
++#include
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

举个例子,你可以把补丁文件发送邮件到其他开发者,在提交之前审核和测试。

Subversion使用内置区别引擎,缺省情况下输出为统一区别格式。如果你期望不同的输出格式,你可以使用--diff-cmd指定外置的区别程序,并且通过--extensions传递其他参数,举个例子,察看本地文件foo.c的区别,同时忽略大小写差异,你可以运行svn diff --diff-cmd /usr/bin/diff --extensions '-bc' foo.c

取消本地修改

假定我们在看svn diff的输出,你发现对某个文件的所有修改都是错误的,或许你根本不应该修改这个文件,或者是从开头重新修改会更加容易。

这是使用svn revert的好机会:

$ svn revert READMEReverted 'README'

Subversion把文件恢复到未修改的状态,叫做.svn目录的“原始”拷贝,应该知道svn revert可以恢复任何预定要做的操作,举个例子,你不再想添加一个文件:

$ svn status foo?      foo$ svn add fooA         foo$ svn revert fooReverted 'foo'$ svn status foo?      foo

注意

svn revertITEM的效果与删除ITEM然后执行svn update -r BASEITEM完全一样,但是,如果你使用svn revert它不必通知版本库就可以恢复文件。

或许你不小心删除了一个文件:

$ svn status README       README$ svn delete READMED         README$ svn revert READMEReverted 'README'$ svn status README       README

解决冲突(合并别人的修改)

我们可以使用svn status -u来预测冲突,当你运行svn update一些有趣的事情发生了:

$ svn updateU  INSTALLG  READMEC  bar.cUpdated to revision 46.

UG没必要关心,文件干净的接受了版本库的变化,文件标示为U表明本地没有修改,文件已经根据版本库更新。G标示合并,标示本地已经修改过,与版本库没有重迭的地方,已经合并。

但是C表示冲突,说明服务器上的改动同你的改动冲突了,你需要自己手工去解决。

当冲突发生了,有三件事可以帮助你注意到这种情况和解决问题:

  • Subversion在更新时打印C标记,并且标记这个文件已冲突。

  • 如果Subversion认为这个文件是可合并的,它会置入冲突标记—特殊的横线分开冲突的“两面”—在文件里可视化的描述重叠的部分(Subversion使用svn:mime-type属性来决定一个文件是否可以使用上下文的,以行为基础的合并,更多信息可以看。)

  • 对于每一个冲突的文件,Subversion放置三个额外的未版本化文件到你的工作拷贝:

    filename.mine

    你更新前的文件,没有冲突标志,只是你最新更改的内容。(如果Subversion认为这个文件不可以合并,.mine文件不会创建,因为它和工作文件相同。)

    filename.rOLDREV

    这是你的做更新操作以前的BASE版本文件,就是你在上次更新之后未作更改的版本。

    filename.rNEWREV

    这是你的Subversion客户端从服务器刚刚收到的版本,这个文件对应版本库的HEAD版本。

    这里OLDREV是你的.svn目录中的修订版本号,NEWREV是版本库中HEAD的版本号。

举一个例子,Sally修改了sandwich.txt,Harry刚刚改变了他的本地拷贝中的这个文件并且提交到服务器,Sally在提交之前更新它的工作拷贝得到了冲突:

$ svn updateC  sandwich.txtUpdated to revision 2.$ ls -1sandwich.txtsandwich.txt.minesandwich.txt.r1sandwich.txt.r2

在这种情况下,Subversion会允许你提交sandwich.txt,直到你的三个临时文件被删掉。

$ svn commit -m "Add a few more things"svn: Commit failed (details follow):svn: Aborting commit: '/home/sally/svn-work/sandwich.txt' remains in conflict

如果你遇到冲突,三件事你可以选择:

  • 手动”合并冲突文本(检查和修改文件中的冲突标志)。

  • 用某一个临时文件覆盖你的工作文件。

  • 运行svn revert <filename>来放弃所有的本地修改。

一旦你解决了冲突,你需要通过命令svn resolved让Subversion知道,这样就会删除三个临时文件,Subversion就不会认为这个文件是在冲突状态了。[]

$ svn resolved sandwich.txtResolved conflicted state of 'sandwich.txt'

手工合并冲突

第一次尝试解决冲突让人感觉很害怕,但经过一点训练,它简单的像是骑着车子下坡。

这里一个简单的例子,由于不良的交流,你和同事Sally,同时编辑了sandwich.txt。Sally提交了修改,当你准备更新你的工作拷贝,冲突发生了,我们不得不去修改sandwich.txt来解决这个问题。首先,看一下这个文件:

$ cat sandwich.txtTop piece of breadMayonnaiseLettuceTomatoProvolone<<<<<<< .mineSalamiMortadellaProsciutto=======SauerkrautGrilled Chicken>>>>>>> .r2Creole MustardBottom piece of bread

小于号、等于号和大于号串是冲突标记,并不是冲突的数据,你一定要确定这些内容在下次提交之前得到删除,前两组标志中间的内容是你在冲突区所做的修改:

<<<<<<< .mineSalamiMortadellaProsciutto=======

后两组之间的是Sally提交的修改冲突:

=======SauerkrautGrilled Chicken>>>>>>> .r2

通常你并不希望只是删除冲突标志和Sally的修改—当她收到三明治时,会非常的吃惊。所以你应该走到她的办公室或是拿起电话告诉Sally,你没办法从从意大利熟食店得到想要的泡菜。[]一旦你们确认了提交内容后,修改文件并且删除冲突标志。

Top piece of breadMayonnaiseLettuceTomatoProvoloneSalamiMortadellaProsciuttoCreole MustardBottom piece of bread

现在运行svn resolved,你已经准备好提交了:

$ svn resolved sandwich.txt$ svn commit -m "Go ahead and use my sandwich, discarding Sally's edits."

现在我们准备好提交修改了,注意svn resolved不像我们本章学过的其他命令一样需要参数,在任何你认为解决了冲突的时候,只需要小心运行svn resolved,—一旦删除了临时文件,Subversion会让你提交这文件,即使文件中还存在冲突标记。

记住,如果你修改冲突时感到混乱,你可以参考subversion生成的三个文件—包括你未作更新的文件。你也可以使用三方交互合并工具检验这三个文件。

复制文件到你的工作文件

如果你只是希望取消你的修改,你可以仅仅拷贝Subversion为你生成的文件替换你的工作拷贝:

$ svn updateC  sandwich.txtUpdated to revision 2.$ ls sandwich.*sandwich.txt  sandwich.txt.mine  sandwich.txt.r2  sandwich.txt.r1$ cp sandwich.txt.r2 sandwich.txt$ svn resolved sandwich.txt

脚注:使用svn revert

如果你得到冲突,经过检查你决定取消自己的修改并且重新编辑,你可以恢复你的修改:

$ svn revert sandwich.txtReverted 'sandwich.txt'$ ls sandwich.*sandwich.txt

注意,当你恢复一个冲突的文件时,不需要再运行svn resolved

提交你的修改

最后!你的修改结束了,你合并了服务器上所有的修改,你准备好提交修改到版本库。

svn commit命令发送所有的修改到版本库,当你提交修改时,你需要提供一些描述修改的日志信息,你的信息会附到这个修订版本上,如果信息很简短,你可以在命令行中使用--message(或-m)选项:

$ svn commit -m "Corrected number of cheese slices."Sending        sandwich.txtTransmitting file data .Committed revision 3.

然而,如果你把写日志信息当作工作的一部分,你也许会希望告诉Subversion通过一个文件名得到日志信息,使用--file选项:

$ svn commit -F logmsgSending        sandwich.txtTransmitting file data .Committed revision 4.

如果你没有指定--message或者--file选项,Subversion会自动地启动你最喜欢的编辑器(见的editor-cmd部分)来编辑日志信息。

提示

如果你使用编辑器撰写日志信息时希望取消提交,你可以直接关掉编辑器,不要保存,如果你已经做过保存,只要简单的删掉所有的文本并再次保存,然后退出。

$ svn commitWaiting for Emacs...DoneLog message unchanged or not specifieda)bort, c)ontinue, e)dita$

版本库不知道也不关心你的修改作为一个整体是否有意义,它只检查是否有其他人修改了同一个文件,如果别人已经这样做了,你的整个提交会失败,并且提示你一个或多个文件已经过时了:

$ svn commit -m "Add another rule"Sending        rules.txtsvn: Commit failed (details follow):svn: Your file or directory 'sandwich.txt' is probably out-of-date…

(错误信息的精确措辞依赖于网络协议和你使用的服务器,但对于所有的情况,其思想完全一样。)

此刻,你需要运行svn update来处理所有的合并和冲突,然后再尝试提交。

我们已经覆盖了Subversion基本的工作周期,还有许多其它特性可以管理你得版本库和工作拷贝,但是只使用前面介绍的命令你就可以很进行日常工作了,我们还会覆盖更多用的还算频繁的命令。


[] 当然没有任何东西是在版本库里被删除了—只是在版本库的HEAD里消失了,你可以通过检出(或者更新你的工作拷贝)你做出删除操作的前一个修订版本来找回所有的东西,详细请见。

[] 而且你也没有WAN卡,考虑到你得到我们,哈!

[] 你也可以手工的删除这三个临时文件,但是当Subversion会给你做时你会自己去做吗?我们是这样想的。

[] 如果你向他们询问,他们非常有理由把你带到城外的铁轨上。

转载地址:http://rbutl.baihongyu.com/

你可能感兴趣的文章