本文档尚在编写中,内容可能会发生很大变化,可能无法准确描述 Apache™ Subversion® 软件的任何已发布版本。将此页面加入书签或以其他方式向他人推荐此页面可能不是一个好主意。请访问 https://svnbook.subversion.org.cn/ 获取此书的稳定版本。

查看历史

您的 Subversion 仓库就像一台时光机。它记录了所有提交的更改,并允许您通过查看文件的先前版本和目录以及伴随它们的元数据来探索此历史记录。使用单个 Subversion 命令,您可以签出仓库(或恢复现有工作副本),使其与过去任何日期或修订号时的状态完全一致。但是,有时您只是想窥视过去,而不是进入过去。

有几个命令可以为您提供仓库中的历史数据

svn diff

显示特定更改的行级详细信息

svn log

向您展示广泛的信息:附有修订版日期和作者信息的日志消息,以及每个修订版中更改的路径

svn cat

检索特定修订号中存在的文件,并在您的屏幕上显示它

svn annotate

以人类可读的格式检索特定修订号中存在的文件,并以表格形式显示其内容,并在文件的每一行添加最后更改的信息

svn list

显示任何给定修订版中目录中的文件

查看历史更改的详细信息

我们之前已经见过 svn diff——它以统一的 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 -r 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 -r 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
$

比较一个修订版与前一个修订版的更方便的方法是使用 --change (-c) 选项

$ svn diff -c 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
$

最后,即使您在本地机器上没有工作副本,也可以通过在命令行中包含相应的 URL 来比较仓库修订版

$ svn diff -c 5 http://svn.example.com/repos/example/trunk/text/rules.txt
…
$

生成历史更改列表

要查找有关文件或目录历史记录的信息,请使用 svn log 命令。 svn log 将为您提供谁对文件或目录进行了更改、在哪个修订版中进行了更改、该修订版的时间和日期以及(如果提供)伴随提交的日志消息的记录

$ svn log
------------------------------------------------------------------------
r3 | sally | 2008-05-15 23:09:28 -0500 (Thu, 15 May 2008) | 1 line

Added include lines and corrected # of cheese slices.
------------------------------------------------------------------------
r2 | harry | 2008-05-14 18:43:15 -0500 (Wed, 14 May 2008) | 1 line

Added main() methods.
------------------------------------------------------------------------
r1 | sally | 2008-05-10 19:50:31 -0500 (Sat, 10 May 2008) | 1 line

Initial import
------------------------------------------------------------------------

请注意,默认情况下,日志消息按逆时间顺序打印。如果您希望按特定顺序查看不同范围的修订版或只查看单个修订版,请传递 --revision (-r) 选项

表 2.1 常见的日志请求

命令 描述
svn log -r 5:19 按时间顺序显示修订版 5 到 19 的日志
svn log -r 19:5 按逆时间顺序显示修订版 5 到 19 的日志
svn log -r 8 仅显示修订版 8 的日志

您还可以检查单个文件或目录的日志历史记录。例如

$ svn log foo.c
…
$ svn log http://foo.com/svn/trunk/code/foo.c
…

这些将仅显示命名文件(或目录)发生更改的那些修订版的日志消息。

如果您想要更多有关文件或目录的信息,svn log 还接受 --verbose (-v) 选项。由于 Subversion 允许您移动和复制文件和目录,因此能够跟踪文件系统中的路径更改非常重要。因此,在详细模式下,svn log 将在其输出中包含修订版中更改路径的列表

$ svn log -r 8 -v
------------------------------------------------------------------------
r8 | sally | 2008-05-21 13:19:25 -0500 (Wed, 21 May 2008) | 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 还接受 --quiet (-q) 选项,该选项会抑制日志消息正文。当与 --verbose (-v) 结合使用时,它只给出更改文件的名称。

从 Subversion 1.7 开始,Subversion 命令行用户还可以利用 svn log 的一种特殊输出模式,该模式集成了与前面介绍的 svn diff 命令生成的差异报告类似的报告。当您使用 --diff 选项调用 svn log 时,Subversion 将在日志报告中的每个修订版日志块末尾附加一个 diff 样式的差异报告。这是一种非常方便的方法,可以同时查看修订版的高级语义更改和基于行的修改!

从 Subversion 1.8 开始,svn log 接受 --search--search-and 选项。这些选项允许您根据提供的搜索模式过滤 svn log 的输出。使用这些选项时,只有当修订版的作者、日期、日志消息文本或更改路径列表与搜索模式匹配时,才会显示日志消息。

浏览仓库

使用 svn catsvn list,您可以查看文件的不同修订版和目录,而无需更改工作副本的工作修订版。事实上,您甚至不需要工作副本就可以使用这两个命令。

显示文件内容

如果您想查看文件的早期版本,而不是查看两个文件之间的差异,您可以使用 svn cat

$ svn cat -r 2 rules.txt
Be kind to others
Freedom = Chocolate Ice Cream
Everything in moderation
Chew with your mouth open
$

您还可以将输出直接重定向到文件

$ svn cat -r 2 rules.txt > rules.txt.v2
$

显示逐行更改归属

与我们在上一节中讨论的 svn cat 命令非常相似的是 svn annotate 命令。此命令还显示版本控制文件的原始内容,但它使用表格格式。每一行输出不仅显示文件内容的一行,还显示修改该行的用户名、修订版编号以及(可选)修订版的时间戳。

当与工作副本文件目标一起使用时,svn annotate 默认情况下将显示该文件在工作副本中当前显示时的逐行归属。

$ svn annotate rules.txt
     1      harry Be kind to others
     3      sally Freedom = Responsibility
     1      harry Everything in moderation
     -          - Chew with your mouth closed
     -          - Listen when others are speaking

请注意,对于某些行,没有提供归属。在这种情况下,这是因为这些行已在工作副本的该文件版本中进行了修改。通过这种方式,svn annotate 成为另一种查看您在文件中更改了哪些行的工具。您可以使用 BASE 修订版关键字(参见 名为“修订版关键字”的部分)来查看驻留在工作副本中的未修改形式的文件。

$ svn annotate rules.txt@BASE
     1      harry Be kind to others
     3      sally Freedom = Responsibility
     1      harry Everything in moderation
     1      harry Chew with your mouth open

--verbose (-v) 选项会导致 svn annotate 在每一行上还包含与该行报告的修订版编号关联的时间戳。(这会显著增加每行输出的宽度,因此我们将在此处跳过演示。)

svn cat 一样,您还可以要求 svn annotate 显示文件的先前版本。当您发现谁最近修改了您感兴趣的特定行,然后您希望查看谁在之前修改了同一行时,这将是一个方便的技巧。

$ svn blame rules.txt -r 2
     1      harry Be kind to others
     1      harry Freedom = Chocolate Ice Cream
     1      harry Everything in moderation
     1      harry Chew with your mouth open

svn cat 命令不同,svn annotate 的功能与人类可读文件中的 的概念密切相关。因此,如果您尝试对 Subversion 确定为人类可读的文件运行命令(根据文件的 svn:mime-type 属性——参见 名为“文件内容类型”的部分以获取详细信息),您将收到错误消息。

$ svn annotate images/logo.png
Skipping binary file (use --force to treat as text): 'images/logo.png'
$

如错误消息所揭示,您可以使用 --force 选项来禁用此检查,并继续进行注释,就好像文件的原始内容实际上是人类可读且基于行的。当然,如果您强制 Subversion 尝试对非文本文件执行基于行的注释,您将得到您要求的:一屏幕乱码。

$ svn annotate images/logo.png --force
     6      harry \211PNG
     6      harry ^Z
     6      harry 
     7      harry \274\361\MI\300\365\353^X\300…
[Tip] 提示

取决于您执行此命令时的状态以及执行此操作的原因,您可能会发现自己键入了 svn blame …svn praise … 而不是使用规范的 svn annotate 命令形式。这没关系——Subversion 开发人员预料到了这一点,所以这些特定的命令别名也同样有效!

最后,与 Subversion 的许多信息命令一样,您也可以通过其仓库 URL 在 svn annotate 命令调用中引用文件,即使您无法轻松访问工作副本,也可以访问此信息。

列出版本化的目录

svn list 命令向您显示仓库目录中的哪些文件,而无需实际将文件下载到您的本地机器

$ svn list http://svn.example.com/repo/project
README
branches/
tags/
trunk/

如果您想要更详细的列表,请传递 --verbose (-v) 标志以获得如下输出

$ svn list -v http://svn.example.com/repo/project
  23351 sally                 Feb 05 13:26 ./
  20620 harry            1084 Jul 13  2006 README
  23339 harry                 Feb 04 01:40 branches/
  23198 harry                 Jan 23 17:17 tags/
  23351 sally                 Feb 05 13:26 trunk/

这些列告诉您文件或目录上次修改的修订版、修改该文件或目录的用户、如果它是文件则为其大小、最后修改的日期以及项目的名称。

[Warning] 警告

svn list 命令在没有参数的情况下默认为当前工作目录的 仓库 URL而不是 本地工作副本目录。毕竟,如果您想要本地目录的列表,您可以使用简单的 ls(或任何合理的非类 Unix 等效项)。

获取旧的仓库快照

除了所有先前的命令之外,您还可以使用 --revision (-r) 选项与 svn update 一起将整个工作副本 回溯到过去:[8]

# Make the current directory look like it did in r1729.
$ svn update -r 1729
Updating '.':
…
$
[Tip] 提示

许多 Subversion 新手尝试使用前面的 svn update 示例来 撤消 提交的更改,但这行不通,因为如果您从将工作副本回溯到过去获得的更改文件中存在较新的修订版,则无法提交更改。请参阅 名为“恢复已删除的项目”的部分,了解如何 撤消 提交。

如果您希望从旧的快照创建全新的工作副本,您可以通过修改典型的 svn checkout 命令来实现。与 svn update 一样,您可以提供 --revision (-r) 选项。但出于我们在 名为“挂钩修订版和操作修订版”的部分 中介绍的原因,您可能更愿意在 Subversion 的扩展 URL 语法中指定目标修订版。

# Checkout the trunk from r1729.
$ svn checkout http://svn.example.com/svn/repo/trunk@1729 trunk-1729
…
# Checkout the current trunk as it looked in r1729.
$ svn checkout http://svn.example.com/svn/repo/trunk -r 1729 trunk-1729
…
$

最后,如果您正在构建版本并希望捆绑您的版本化文件和目录,您可以使用 svn export 来创建本地副本,包括所有或部分仓库,而不包括任何 .svn 管理目录。此子命令的基本语法与 svn checkout 的语法相同。

# Export the trunk from the latest revision.
$ svn export http://svn.example.com/svn/repo/trunk trunk-export
…
# Export the trunk from r1729.
$ svn export http://svn.example.com/svn/repo/trunk@1729 trunk-1729
…
# Export the current trunk as it looked in r1729. 
$ svn export http://svn.example.com/svn/repo/trunk -r 1729 trunk-1729
…
$


[8] 看到了吗?我们告诉过您 Subversion 是个时间机器。

TortoiseSVN 官方中文版 1.14.7 发布