• svn tour cycle


    基本的工作循环

    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 update
    U  foo.c
    U  bar.c
    Updated to revision 2.
    

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

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

    修改你的工作副本

    现在你可以开始工作并且修改你的工作拷贝了,你很容易决定作出一个修改(或者是一组),像写一个新的特性,修正一个错误等等。这时可以使用的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就会在你的工作拷贝和版本库中被删除。[4]

    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 addition
    C       stuff/loot/lump.c   # file has textual conflicts from an update
    D       stuff/fish.c        # file is scheduled for deletion
    M       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.c
    D      stuff/fish.c
    

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

    $ svn status -v
    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 -u -v
    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,你的READMEtrout.c会被更新,这告诉你许多有用的信息—你可以在提交之前,需要使用更新操作得到文件README的更新,或者说文件已经过时,版本库会拒绝了你的提交。(后面还有更多关于此主题)。

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

    检查你的本地修改的详情

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

    $ 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
    

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

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

    取消本地修改

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

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

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

    $ svn status README
           README
    
    $ svn delete README
    D         README
    
    $ svn revert README
    Reverted 'README'
    
    $ svn status README
           README
    

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

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

    $ svn update
    U  INSTALL
    G  README
    C  bar.c
    Updated 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 update
    C  sandwich.txt
    Updated to revision 2.
    $ ls -1
    sandwich.txt
    sandwich.txt.mine
    sandwich.txt.r1
    sandwich.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就不会认为这个文件是在冲突状态了。[6]

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

    手工合并冲突

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

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

    $ cat sandwich.txt
    Top piece of bread
    Mayonnaise
    Lettuce
    Tomato
    Provolone
    <<<<<<< .mine
    Salami
    Mortadella
    Prosciutto
    =======
    Sauerkraut
    Grilled Chicken
    >>>>>>> .r2
    Creole Mustard
    Bottom piece of bread
    

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

    <<<<<<< .mine
    Salami
    Mortadella
    Prosciutto
    =======
    

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

    =======
    Sauerkraut
    Grilled Chicken
    >>>>>>> .r2
    

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

    Top piece of bread
    Mayonnaise
    Lettuce
    Tomato
    Provolone
    Salami
    Mortadella
    Prosciutto
    Creole Mustard
    Bottom 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 update
    C  sandwich.txt
    Updated 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.txt
    Reverted 'sandwich.txt'
    $ ls sandwich.*
    sandwich.txt
    

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

    提交你的修改

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

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

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

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

    $ svn commit -F logmsg
    Sending        sandwich.txt
    Transmitting file data .
    Committed revision 4.
    

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

    提示

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

    $ svn commit
    Waiting for Emacs...Done
    
    Log message unchanged or not specified
    a)bort, c)ontinue, e)dit
    a
    $
    

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

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

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

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

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



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

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

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

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

  • 相关阅读:
    【转】了解 Boost Filesystem Library
    [转]敏捷软件开发模型SCRUM
    【转】惠普前总裁孙振耀指点职业规划
    新年随想
    C#中使用正则表达式验证电话号码、手机号、身份证号、数字和邮编
    一个简单的QQ客服功能
    特殊符号如(▲)导到EXCEL中产生乱码
    SINA 和腾讯网易微博的OAUTH的DEMO
    分享功能
    发布时选着勾选use fixed naming and single page assemblies 的作用
  • 原文地址:https://www.cnblogs.com/lexus/p/2336432.html
Copyright © 2020-2023  润新知