### 检验历史 我们曾经说过,版本库就像是一台时间机器,它记录了所有提交的修改,允许你检查文件或目录以及相关元数据的历史。通过一个Subversion命令你可以根据时间或修订号取出一个过去的版本(或者恢复现在的工作拷贝),然而,有时候我们只是想*看看*历史而不想*回到*历史。 有许多命令可以为你提供版本库历史: **svn log** 展示给你主要信息:附加在版本上的日志信息和所有版本的路径修改。 **svn diff** 展示一个文件改变的详细情况。 **svn cat** 取得在特定版本的某一个文件显示在当前屏幕。 **svn list** 显示一个目录在某一版本存在的文件。 ### **svn log** 找出一个文件或目录的历史信息,使用**svn log**命令,**svn log**将会提供你一条记录,包括:谁对文件或目录作了修改、哪个修订版本作了修改、修订版本的日期和时间、还有如果你当时提供了日志信息,也会显示。 ~~~ $ svn log ------------------------------------------------------------------------ r3 | sally | Mon, 15 Jul 2002 18:03:46 -0500 | 1 line Added include lines and corrected # of cheese slices. ------------------------------------------------------------------------ r2 | harry | Mon, 15 Jul 2002 17:47:57 -0500 | 1 line Added main() methods. ------------------------------------------------------------------------ r1 | sally | Mon, 15 Jul 2002 17:40:08 -0500 | 1 line Initial import ------------------------------------------------------------------------ ~~~ 注意日志信息缺省根据*时间逆序排列*,如果希望察看特定顺序的一段修订版本或者单一版本,使用`--revision` (`-r`)选项: ~~~ $ svn log --revision 5:19 # shows logs 5 through 19 in chronological order $ svn log -r 19:5 # shows logs 5 through 19 in reverse order $ svn log -r 8 # shows log for revision 8 ~~~ 你也可以检查单个文件或目录的日志历史,举个例子: ~~~ $ svn log foo.c … $ svn log http://foo.com/svn/trunk/code/foo.c … ~~~ 这样*只会*显示这个工作文件(或者URL)做过修订的版本的日志信息。 如果你希望得到目录和文件更多的信息,你可以对**svn log**命令使用`--verbose` (`-v`)开关,因为Subversion允许移动和复制文件和目录,所以跟踪路径修改非常重要,在详细模式下,**svn log** 输出中会包括一个路径修改的历史: ~~~ $ svn log -r 8 -v ------------------------------------------------------------------------ r8 | sally | 2002-07-14 08:15:29 -0500 | 1 line Changed paths: M /trunk/code/foo.c M /trunk/code/bar.h A /trunk/code/doc/README Frozzled the sub-space winch. ------------------------------------------------------------------------ ~~~ **为什么**svn log**给我一个空的回应?** 当使用Subversion一些时间后,许多用户会遇到这种情况: ~~~ $ svn log -r 2 ------------------------------------------------------------------------ $ ~~~ 乍一看,好像是一个错误,但是想一下修订版本号是作用在版本库整体之上的,如果你没有提供路径,**svn log**会使用当前目录作为默认的目标,所以,作为结果,如果你对一个本身和子目录在指定版本到现在没有做过修改的目录运行这个命令,你会得到空的日志。如果你希望察看某个版本做的修改的日志,只需要直接告诉**svn log**使用版本库顶级的目录作为参数,例如**svn log -r 2 。 ### svn diff 我们已经看过**svn diff**―使用标准区别文件格式显示区别,它在提交前用来显示本地工作拷贝与版本库的区别。 事实上,**svn diff**有*三*种不同的用法: - 检查本地修改 - 比较工作拷贝与版本库 - 比较版本库和版本库 #### 比较本地修改 像我们看到的,不使用任何参数调用时,**svn diff**将会比较你的工作文件与缓存在`.svn`的“原始”拷贝: ~~~ $ svn diff Index: rules.txt =================================================================== --- rules.txt (revision 3) +++ rules.txt (working copy) @@ -1,4 +1,5 @@ Be kind to others Freedom = Responsibility Everything in moderation -Chew with your mouth open +Chew with your mouth closed +Listen when others are speaking $ ~~~ #### 比较工作拷贝和版本库 如果传递一个`--revision`(`-r`)参数,你的工作拷贝会与指定的版本比较。 ~~~ $ svn diff --revision 3 rules.txt Index: rules.txt =================================================================== --- rules.txt (revision 3) +++ rules.txt (working copy) @@ -1,4 +1,5 @@ Be kind to others Freedom = Responsibility Everything in moderation -Chew with your mouth open +Chew with your mouth closed +Listen when others are speaking $ ~~~ #### 比较版本库与版本库 如果通过`--revision` (`-r`)传递两个版本号,通过冒号分开,这两个版本会进行比较。 ~~~ $ svn diff --revision 2:3 rules.txt Index: rules.txt =================================================================== --- rules.txt (revision 2) +++ rules.txt (revision 3) @@ -1,4 +1,4 @@ Be kind to others -Freedom = Chocolate Ice Cream +Freedom = Responsibility Everything in moderation Chew with your mouth open $ ~~~ 你不仅可以用**svn diff**比较你工作拷贝中的文件,你甚至可以通过提供一个URL参数来比较版本库中两个文件的的区别,通常在本地机器没有工作拷贝时非常有用: ~~~ $ svn diff --revision 4:5 http://svn.red-bean.com/repos/example/trunk/text/rules.txt … $ ~~~ ### **svn cat** 如果你只是希望检查一个过去的版本而不希望察看它们的区别,使用**svn cat**: ~~~ $ svn cat --revision 2 rules.txt Be kind to others Freedom = Chocolate Ice Cream Everything in moderation Chew with your mouth open $ ~~~ 你可以重定向输出到一个文件: ~~~ $ svn cat --revision 2 rules.txt > rules.txt.v2 $ ~~~ 你一定疑惑为什么不只是使用**svn update --revision** ,将文件更新到旧的文件,我们有使用**svn cat**的原因。 首先,你或许希望使用外置的比较工具(或许是一个图形化的工具,或者你的格式无法用标准区别格式察看)察看这两个版本的区别,这种情况下,你需要得到一个旧的版本的拷贝,所以重定向到一个文件,并且在你的比较工具中指定这两个版本来察看区别。 有时候察看整个文件比只看区别要容易。 ### **svn list** **svn list**可以在不下载文件到本地目录的情况下来察看目录中的文件: ~~~ $ svn list http://svn.collab.net/repos/svn README branches/ clients/ tags/ trunk/ ~~~ 如果你希望察看详细信息,你可以使用`--verbose` (`-v`)参数: ~~~ $ svn list --verbose http://svn.collab.net/repos/svn 2755 harry 1331 Jul 28 02:07 README 2773 sally Jul 29 15:07 branches/ 2769 sally Jul 29 12:07 clients/ 2698 harry Jul 24 18:07 tags/ 2785 sally Jul 29 19:07 trunk/ ~~~ 这些列告诉你文件和目录最后修改的修订版本、做出修改的用户、如果是文件还会有文件的大小,最后是修改日期和项目的名字。 ### 关于历史的最后一个词 除了以上的命令,你可以使用带参数`--revision`的**svn update**和**svn checkout**来使整个工作拷贝“回到过去”: ~~~ $ svn checkout --revision 1729 # Checks out a new working copy at r1729 … $ svn update --revision 1729 # Updates an existing working copy to r1729 … ~~~ 看到了吧?我们说过Subversion是一个时间机器。