Subversion FAQ(常见问题解答)

转自:http://subversion.apache.org/faq.zh.htmlhtml

常见问题:

为何会有这样一个项目?

为了接管CVS的用户基础。确切的说,咱们写了一个新的版本控制系统,它和CVS很类似,可是它修正了之前CVS所没有解决的许多问题。请看咱们的首页。java

Subversion是私有软件的吗?我据说它是属于CollabNet公司的。

不是,Subversion一款开源/免费的软件。CollabNet公司为几个全职的开发人员支付薪水,而且拥有相关代码的版权,可是这个版权是一个Apache/BSD-风格的许可证,它彻底听从于Debian Free Software Guidelines。换句话说,你能够为所欲为的去下载,修改,或者从新发布新的版本,而不须要通过CollabNet公司或者其余任何一我的的许可。node

Subversion用在个人项目上是否足够稳定?

是的,绝对能够。它是一款已经准备好进入黄金时段的产品。python

Subversion从2000年开始开发,在一年以后成为一个自足执行(self-hosting)的项目。在以后的一年,当咱们将其称为"alpha"版本的时候,Subversion已经被不少的我的开发人员所使用,并确实发挥了真正的做用。在那以后,有两年多的时间被用来进行Bug追踪(bugfixing)和加强稳定性(stabilization),直到咱们发布了1.0版本。大多数的其它项目可能都会把产品的“1.0”版本叫作早期版本,可是咱们故意的尽量长的推迟了这个版本的发布。咱们意识到不少人在他们最初使用了Subversion以后一直在等待1.0版本的发布,而且对这个意义非凡的版本有着特别的期待,因此咱们在这样一个版本上用了不少的时间而不至于让他们失望。web

Subversion的客户端/服务器在协同工做时的策略是怎样的?

客户端和服务器被设计成只要他们相互之间没有超过一个主要的发行版本,就能够协调工做。例如任何一个1.x的客户端均可以和一个1.y的服务器协调工做。然而,若是客户端和服务器的版本不相匹配,某些特性可能不能使用。算法

客户端和服务器之间的兼容性策略记录在Subversion Community Guide的“兼容性”一节里面。shell

Subversion能够运行在哪些操做系统上?

全部现代风格的操做系统,好比Unix, Win32, BeOS, OS/2, MacOS X。数据库

Subversion是用ANSI C来写的,而且使用了APR,也就是Apache Portable Runtime库做为可移植层。Subversion的客户端将能够运行在任何APR运行的地方,这是最重要的一点。Subversion服务器(例如,版本库端)一样,惟一的例外是在Berkeley DB的Win9x(Win95/Win98/WinME)做为平台的主机上,由于Berkeley DB在Win9x平台上共享存储器的有段问题。FSFS版本库(从版本1.1开始引入)没有这种限制;然而因为Win9x对文件锁定的支持限制,他们仍然不能在Win9x的平台上工做。apache

重申一下,Subversion客户端能够运行在任何APR所运行的平台上。Subversion服务器也能够运行在任何APR平台所能运行的平台,可是不能在Win95/Win98/WinMe上管理版本库。windows

全部它的一切是不是一种新的文件系统?比方说ext2文件系统?

不是。"Subversion文件系统"不是一个能够装在操做系统上的内核级的文件系统,相反,它是Subversion版本库的接口,是一个版本文件系统,在某种意义上说,它能够存储一个文件目录结构(树)而且使这个目录结构从一个修订版本到下一个修订版本的过程当中保留版本信息。访问这个版本库来编写程序和使用其余文件系统的API是很类似的,可是最大的不一样在于,这个特殊的文件系统在你写入的时候不会丢失数据。目录结构(树)的一些旧的状态信息能够被很容易的恢复,就像恢复到最近的状态那样容易。

为了运行一个Subversion服务器,哪一种硬件是我所须要的?

运行Subversion服务器要依赖各方面的多种因素,好比说必定数量的用户,常常性的提交,其它相关联的服务器,版本库的大小以及自定义版本库的负载等。当使用Apache时,有可能Apache自己在内存的使用状况将成为最大的制约因素。请参阅邮件列表上对这个问题的讨论,这里有针对这个问题的明确的答案。

须要记住的是,在同一台服务器上运行其它的应用程序,好比版本库的浏览器一样会使用内存,它是独立于Subversion自己。

一般,和CVS本版库相比,你能够指望须要更少的服务器内存。

我据说Subversion是Apache项目的扩展?我是否须要Apache来作服务器呢?

不用。Subversion是一系列的库,它与一个命令行的客户端相互配合工做。有两类不一样的Subversion的服务器进程,包括一个svnserve进程,这是一个小的相似CVS的pserver进程的独立运行程序,另外一个是使用mod_dav_svn模块的Apachehttpd-2.0svnserve进程能够说是一个经常使用协议,而mod_dav_svn进程使用了WebDAV做为它的网络协议。请参阅Subversion手册第六章以了解更多的内容。

是否意味着我必须首先安装Apache才能使用Subversion?

一句话:没必要。

详细的回答是:若是你仅仅是想去访问一个版本库,你只须要构建一个Subversion的客户端。若是你想拥有一个网络的版本库,那么你须要安装Apache2或者一个“svnserve”服务器。

关于安装一个能够访问的Subversion服务器的详细信息,请参阅:Subversion手册第六章

我如今所运行的是Apache 1.x,可是我不能仅仅为了支持Subversion版本库而将其转换成Apache 2.0。这是否意味着我不能使用Subversion服务器?

没必要,你能够用svnserve做为Subversion的服务器,它能够很好的工做。

在使用Apache server时,若是你想使用分布式创做和版本管理协议(WebDAV)和全部其余一些好的功能特性,那么是的,你须要Apache 2.0。可是无论怎样,当你继续在80端口运行Apache1.0的时候,你老是能够在另一个不一样的端口运行Apache2.0。不一样版本的Apache能够在同一台机器上很好的和平相处。仅仅须要在改变httpd.conf文件中把Listen指令从80改为8080,或者其余你想要改为的端口。而后确保在你公布版本库的URL的时候加以说明:(例如,http://svn.mydomain.com:8080/repos/blah/trunk/)。

为何不象SCM系统Y那样来作X?

咱们历来没有试图在SCM系统上推到重来,开辟出一个新的天地,也没有试图彻底模仿每个SCM系统的好的特性,咱们只是要取代CVS。请参阅咱们的第一个问题。

为何整个库都使用相同的版本号码?我想让个人每个工程都有其本身的版本号。

首先,请注意Subversion没有项目这个概念。版本库只是存储版本化的目录树 — 你能够将某个子目录看成项目,可是Subversion不会对其特殊对待。所以,对于一个项目的构成彻底由用户本身解释。(与之相似的branchestags的习惯是创建在复制之上,而不是创建在Subversion的概念之上。)

每当你提交变动时,版本库会在版本库目录树总体上增长一个修订版本,并将新的树赋予一个新的修订版本号,固然,大多数目录树和前一个修订版本彻底同样,只是部分被更改。

新修订版本号码是一个顺序增长的标签,会附加给每一个新增的树,而不是这个修订中的某个文件或目录,然而,通俗来讲,会使用修订版本号码来引用修订中提交的变动;例如“r588中的变动”(“r588”是“修订版本588”的简写)的真实含义是“版本库目录树587和588的区别”,或者是另外一个说法“将目录树587变成588的变动”。

所以,不断增长的修改版本号码会以一个总体标示版本库的进展;你一般不会使用修订版本号码来度量版本库中特定项目的进展,固然,修订版本号码不该该做为项目可见的发布号码,对此,你应该经过其余机制来区别发布,例如使用tags

Subversion是否有变动集?

这个问题有些麻烦,由于好像每一个人对变动集的定义多少有些不一样,或者至少对版本控制系统的变动集特性多少有些不一样的指望。

基于这个讨论的目的,这里对变动集有一个简单的定义:它是全部改变的惟一的名字的集合,这些改变可能包括对文件内容句法的编辑,目录结构的改变,或者是一些元数据的从新组合。更加一般的理解,一个变动集仅仅是一个你所能进行参阅的补丁的名字。

Subversion按照一阶对象的方式管理版本化目录树(版本库是一个目录树数组),而变动集则是被推生出来的东西(经过比较相邻的目录树)。Arch或Bitkeeper这类程序以相反方向建立:他们用一阶对象的方式管理变动集(版本库是一系列的补丁),而目录树则是由一系列的补丁组合而成。

从根本上来讲,二者都不够好:争论至少能够追溯到三十年之前。对于不一样类型的软件开发,各有利弊。如今咱们不打算讨论这些,这里我将解释使用Subversion能怎么作。

用Subversion,用一个全局的版本编号N来命名版本库目录树:这是说版本库是通过第N次提交。它还包括一些不明显的变动集:若是你比较目录树N和目录树N-1,你能够精确获得提交的补丁。

所以,能够很容易的想到,版本N不只仅是一个变动集。若是你用一个事件追踪去管理bug,你能够用版本号码去引用特殊的补丁,这些补丁很适合bug。例如,“这个事件被稳定在9238版本。”一些人可能运行‘svn log -r9238’来阅读对应Bug的补丁信息,运行‘svn diff -r9237:9238’来查看补丁自己。svn合并命令也是利用了版本号码。只要在合并参数中指明结果集,就能够把结果集从一个分支明确的合并到另外一个分支:‘svn merge -r9237:9238 branchURL’将合并结果集#9238到你的工做拷贝。

彷佛根据结果集构建和主要对象的构建同样复杂,可是已经比CVS方便许多了。

下一个版本何时发布?

看咱们的状态页 http://subversion.tigris.org/project_status.html

我还有其余的一些问题,我从哪里能够获得更多的信息呢?

若是你在阅读这个常见问题回答以后,没有找到你问题的答案,那么你还有其余的几个资源能够利用:

为何个人邮件没有显示在邮件列表上?

咱们的邮件列表为了保持在一个适度的标准,因此你最初的邮件可能会被延迟经过,直到维护人员有机会让它经过。一旦邮件容许经过,全部从相同的地址挂起的邮件将被自动支持,因此你应该不会再被拒绝。固然,若是你的发送地址改变了的话,你将不得再也不次让维护人员检测经过。

如何:

 

我如何才能检出Subversion版本库里的代码?

使用Subversion客户端:

	$ svn co http://svn.collab.net/repos/svn/trunk subversion

这将会从Subversion源文件目录里检出一个名叫subersion的目录到你的本机上。

我如何建立一个版本库呢?而且我又该如何向里导入数据呢?

请参阅 http://svn.collab.net/repos/svn/trunk/README;特别的,在第IV部分,即“快速指南”。

更详细的资料,请阅读Subversion手册第五章。

我如何把一个现存的CVS版本库转换成Subversion版本库?

试一下cvs2svn转换工具,从http://cvs2svn.tigris.org/ (或者从这里 特性列表相关文档)。cvs2svn是大多数人的选择,可是若是有别的缘由使他不能知足你的要求,至少还有其余两种工具供你选择:

也能够参阅Subversion连接页面。

我必须经过代理访问网络,我该怎么办?

Subversion支持经过代理访问网络。首先,修改配置文件中的"servers"部分,并指定你的代理服务器。配置文件所在目录在不一样的操做系统上可能不一样,在Linux或 Unix系统中,一般是~/.subversion;在Windows系统中,一般是"%APPDATA%\Subversion"。(执行"echo %APPDATA%"显示目录的具体路径,注意这是一个隐藏目录。)

配置文件中的注释描述了配置文件书写的格式。若是配置文件还不存在,能够取得最新版的svn,并执行任何svn命令,这将建立配置文件模板及其相应的目录。

其次,请确认你的代理服务器支持全部Subversion必须的HTTP方法。有些代理服务器默认不支持如下命令:PROPFIND, REPORT, MERGE, MKACTIVITY, CHECKOUT。解决办法依赖于你使用的代理服务器软件,对于Squid,配置选项以下:

   #  TAG: extension_methods
   #       Squid only knows about standardized HTTP request methods.
   #       You can add up to 20 additional "extension" methods here.
   #
   #Default:
   # none
   extension_methods REPORT MERGE MKACTIVITY CHECKOUT

(Squid 2.4及其以后的版本支持PROPFIND.)

参见"Subversion用到的HTTP方法是有哪些?"来配置代理服务器来支持HTTP方法。

若是让代理服务器支持Subversion访问网络很困难甚至是不可能的话,而你只想checkout Subversion的源代码,你能够绕过代理服务器。一些代理服务器封锁了80端口,若是是这样的话,能够经过81端口访问svn.collab.net代码库服务器。执行:

   svn checkout http://svn.collab.net:81/repos/svn/trunk subversion

可能代理服务器会放行。另外一个办法是经过SSL来checkout,SSL被大部分代理服务器所支持:

   svn checkout https://svn.collab.net/repos/svn/trunk subversion

固然,你的svn客户端应该支持ssl。在编译源代码的时候,在./configure时添加--with-ssl选项。执行svn --version能够知道你的svn是否支持'https'。

个人管理员不想让我有一个Subversion的HTTP服务器,那么如何作我才能够远程使用?

一个简单的选择是使用svnserve服务器来代替。请参阅SVN手册第6章中的详细内容。

然而,若是你的管理员不但愿你运行Apache,这极可能是他们不想让你在3690端口运行一个客户服务器,则备选答案是假定你的管理员赞成你使用现有的SSH设施。

若是你使用CVS,你可能已经使用SSH来登陆CVS服务器,ra_svn Subversion的访问方法是和使用Subversion是相同的。仅仅是在你的版本库的URL上加上一个"svn+ssh"的前缀。

$ svn checkout svn+ssh://your.domain.com/full/path/to/repository

这将使你的SSH的程序在远程运行一个私有的'svnserve'进程,用你的用户ID访问版本库,并经过加密管道将数据传递回来。

然而,另外的一种能够用来替代的解决方案是将SSH端口转向链接到经过ra_dav保护的服务器上。你能够经过SSH链接到一个防火墙后的一个机器,这个机器能够访问Subversion服务器。注意,这个SSH服务器须要与Subversion安装在同一个机器上,能够是,但不是必须是。

而后你能够建立一个本地端口来链接在你家里的Subversion版本库的HTTP服务器。你能够经过本地端口’链接‘Subversion版本库。而后,请求将被经过SSH服务器’通道‘发送到你的Subversion服务器。

一个示例:在大家公司位于10.1.1.50(叫它svn-server.example.com)的防火墙后面设置了一个Subversion ra_dav,你的公司容许SSH经过公共方式访问ssh-server.example.com,而在内部能够经过http://svn-server.example.com/repos/ours访问Subversion版本库。

实例:那么客户端经过端口转向链接ssh服务器,并经过端口转向检出

% ssh -L 8888:svn-server.example.com:80 me@ssh-server.example.com
% svn checkout http://localhost:8888/repos/ours

请注意svn-server.example.com也可让httpd实例被非信任用户运行在无特权的端口上,这容许Subversion不须要root访问权限。

Joe Orton注明

服务器对正在使用的MOVE和COPY请求头的主机名字是很敏感的,因此这个地方你必需要当心—工做正常可能须要配置"ServerAlias localhost"。

一些SSH端口转向的连接

我如何在Subversion下面管理几个不一样的项目?

这决定与你的项目的复杂度,若是你的项目是相关的,而且有可能要共享数据,那么最好的方式是经过子目录建立一个版本库。像下面这样子:

	$ svnadmin create /repo/svn
	$ svn mkdir file:///repo/svn/projA
	$ svn mkdir file:///repo/svn/projB
	$ svn mkdir file:///repo/svn/projC

若是你的工程是彻底不相关的,而且他们之间不可能共享数据,这样最好建立几个独立的彻底不相关的版本库。

	$ mkdir /repo/svn
	$ svnadmin create /repo/svn/projA
	$ svnadmin create /repo/svn/projB
	$ svnadmin create /repo/svn/projC

这两种方式之间不一样之处在于: (由 Ben Collins-Sussman解释 <sussman@collab.net>):

  • 在第一种状况之下,代码能够很容易的在两个项目之间拷贝和移动,而且操做的历史记录会被保存下来。('svn cp/mv'如今只能在单个版本库中工做。)
  • 由于修订版本号是版本库范围的,在第一种状况下,对任何项目的提交均可能形成全局的版本冲突。因此若是有我的检出了‘projB’,并发现已经发生的10次修订,可是projB没有彻底改变,这看起来有些奇怪。事实上,这可有可无,只是一开始会感到有些奇怪。这就像每当人们向rapidsvn提交,而rapidsvn和svn在同一个版本库之下时,svn的情况。:-)
  • 第二种状况可能更利于安全管理吗;能够很容易的使用Apache访问控制将每一个项目隔绝(就用户和许可的角度来说)。在第一种状况下,你须要在版本库放一个钩子脚原本区分不一样的项目(“是否容许用户在特定的子目录提交?”)固然,咱们已经准备了这些脚本供你使用。

我如何合并两个彻底分开的版本库?

若是你不在乎某个版本库的彻底历史,你能够只是在某个版本库为另外一个项目建立一个新的目录,而后导入另外一个项目。

若是你在乎两边的历史,那么你能够使用'svnadmin dump'将一个版本库的内容转储出来,而后使用'svnadmin load'加载到另外一个版本库。原来的修订版本号码会取消,但你还有历史。

Peter Davis <peter@pdavis.cx>也解释了一种方法,能够使用像CVS模块那样使用svn:

只要合并发生在不一样的目录树,你能够使用svn版的CVS模块。

svn:externals属性设置到从其余版本库检出的目录上,不管原来的目录是什么时候检出的。版本库仍是分离的,可是从工做拷贝的角度看,他们好像合并了。若是你在导入的目录中提交,也将会影响外部版本库。

合并并不意味着彻底的干净:导入只是影响了工做拷贝,因此你应该不能使用第一个版本库的URL访问从第二个导入的模块,他们都仍是有各自的URL。

也能够看miscellaneous utilities,里面有一些在合并不一样版本库时帮助选择和重排序修订版本的工具,特别如基本操做的perl脚本svn-merge-repos.pl和高级组织的python类SvnDumpTool

我必须在NFS服务器上存储版本库/工做拷贝吗?

若是你使用Berkeley DB做为版本库的后端(在Subversion 1.0和1.1这是默认值,此后不是默认值),咱们建议你不要将版本库存放在远程文件系统(例如,NFS)。虽然Berkeley DB数据库和日志文件能够存放到远程文件系统,可是Berkeley DB的共享区域文件不能够放到远程文件系统上,因此版本库只有被一个文件系统客户访问时才能保证安全,并且那种状况下并非全部的Subversion功能都在一个客户下工做正常。

若是你使用FSFS做为后端,那么将版本库存放到NFS服务器(应当是支持锁定的服务器)也应当没问题。

工做拷贝能够存放到NFS(一个常见的场景是你的主目录在NFS服务器上)上,在Linux NFS服务器上,由于在检出时Subversion内部使用的重命名的量比较大,一些用户报告应当关闭‘子目录检查(subtree checking)’应当关闭,若是关闭子目录检查的详细信息能够看NFS Howto Server Guideexports(5)

咱们至少接到一份对于经过SMB访问形成工做拷贝楔住的报告,形成错误的服务器是版本很是老的Samba(2.2.7a),在新版本(3.0.6)Samba中并无再出现这个问题。

为什么个人版本库占去这么多的磁盘空间?

在Berkeley DB环境中,版本库会在repos/db/子目录存放全部的数据,这个环境会包含一组表和一组日志文件(log.*)。Berkeley DB会记录对表所做的变动,这样在出现中断后可以恢复到一致的状态(more info)。

若是你听任无论(做为版本库管理员),日志文件会不断的生长,吞噬磁盘空间。在任什么时候刻,Berkeley DB只使用很小一部分的日志文件(能够看这个帖子以及相关的线索);其他的能够安全的删除。若是你永久保存全部的日志文件,理论上Berkeley DB可以根据这个文件回到出生的时刻。可是在实践中,若是你进行了备份,就没有必要在磁盘中浪费空间了。

能够使用svnadmin查看哪些日志文件能够删除,你能够经过crob程序完成这个任务。

$ svnadmin list-unused-dblogs /repos
/repos/db/log.000003
/repos/db/log.000004
[...]

$ svnadmin list-unused-dblogs /repos | xargs rm
# disk space reclaimed!

你也能够使用Berkeley DB的db_archive命令:

$ db_archive -a -h /repos/db | xargs rm
# disk space reclaimed!

还能够看svnadmin hotcopyhotbackup.py

注意:若是你正在使用Berkeley DB 4.2,Subversion建立的版本库会自动删除日志文件,若是你想关闭这个功能,能够在svnadmin create命令中使用--bdb-log-keep选项。能够参考Berkeley DB手册中的 DB_LOG_AUTOREMOVE参数。

我如何恰当的设置个人版本库的权限呢?

试图保证尽量少的用户可以访问版本库,例如以某个用户运行apache或'svnserve -d',那么版本库由这个用户彻底拥有。不容许任何其余的用户经过file:///的URL访问版本库,必须只让拥有版本库的用户运行'svnlook'和'svnadmin'。

若是你的客户端经过file:///svn+ssh://访问,则没法避免多个用户的访问。在那种状况下,能够阅读第6章最后一小节,看一下最下面工具栏的“检查列表”,它总结了让这个场景更安全的步骤。

SELinux / Fedora Core 3+ / Red Hat Enterprise的用户注意:

做为标准Unix许可的补充,在SELinux下,每一个文件、目录和进程都有一个‘安全上下文’。当进程试图访问一个文件时,除了检查Unix访问许可,系统还会检查进程的安全上下文与文件的安全上下文是否兼容。

而Fedora Core 3,随SELinux一块儿安装,在默认状况下Apache会在一个限制的安全上下文中运行。为了在Apache下运行Subversion,你必须设置版本库的安全上下文使之支持Apache的访问(或者关闭对Apache的限制,若是你认为这是过度当心)。chcon命令能够用来设置文件的安全上下文(与chmod设置Unix访问许可相似)。例如,一个用户能够这样运行命令

   $ chcon -R -h -t httpd_sys_content_t PATH_TO_REPOSITORY

设置安全上下文能够成功的访问版本库。

为什么只读的操做仍然须要版本库的写访问?

某些客户端操做是“只读的”,例如检出和更新。从访问控制的角度,Apache会这样处理。可是libsvn_fs(版本库文件系统API)在生成增量树的时候仍是须要写临时数据,因此访问版本库的进程应该可以读写访问Berkeley DB的文件,才能完成功能。

尤为是版本库须要应答许多比较两个目录树的“只读”操做时,一个树多是HEAD修订版本,而另外一个则是临时的事务-目录树 -- 所以许多写权限。

这种限制只存在于Berkeley DB后端;FSFS后端并无显示这种特性。

如何彻底的从版本库历史中删除一个文件?

有某些特殊状况下,你可能但愿彻底的删除你曾经提交文件的全部信息(或许有人意外的提交了一份保密的文档)。可是这个操做不是很容易完成,由于Subversion有意被设计成决不丢失信息,修订版本是基于上一个版本所构建的不可改变(immutable)的文件树。从版本的历史记录里删除一个修订版本将会形成多米诺骨牌效应,形成后继版本的混乱,还有可能使得全部的工做拷贝无效。

项目有计划在将来实现一个svnadmin obliterate命令,可以完成永久删除信息的任务(能够看issue 516。)

如今,你只有求助于你版本库的svnadmin dump命令,将转储文件通过svndumpfilter过滤(排除错误的路径)传递给svnadmin load命令,请参阅Subversion手册第五章的相关详细信息。

一个版本提交以后,如何修改其日志信息?

日志信息做为每一个修订版本的附加属性保存在版本库,默认状况下,日志信息属性(svn:log)不能在提交后修改。这是由于对于修订版本属性svn:log是其中一个)的修改会致使之前的属性永久的消失,Subversion会防止这种意外状况发生。可是,仍是有一些方法能够修改修订版本属性。

第一种方法是让版本库管理员容许修订版本属性修改,这能够经过建立"pre-revprop-change"(更多相关细节能够看Subversion手册的这个小节)。钩子"pre-revprop-change"能够在修改以前访问老的日志信息(例如,经过发送一个邮件),因此能够以某种方式保存它(例如,经过发送邮件)。一旦开启了修订版本属性修改,你能够经过svn propeditsvn propset的--revprop选项修改修订版本属性,就像下面这个:

$ svn propedit -r N --revprop svn:log URL
$ svn propset -r N --revprop svn:log "new log message" URL

这里N是但愿修改的日志信息的修订版本号码,而URL是版本库的位置。若是你从工做拷贝运行这个命令,你能够省略URL。

第二种方法是经过svnadmin setlog修改日志信息。这必须经过引用版本库的文件系统位置来执行,你不能使用这个命令远程修改版本库。

$ svnadmin setlog REPOS_PATH -r N FILE

这里REPOS_PATH是版本库的位置,而N是你但愿修改日志信息的修订版本,而FILE是包含新日志信息的文件。若是"pre-revprop-change"钩子不存在(或者由于钩子脚本的缘由你但愿绕过),你仍是能够经过--bypass-hooks选项实现。然而,若是你要使用这个选项,要很是当心。你会绕过诸如变动的邮件提醒,或者保存修订版本属性的备份系统。

怎么样向Subversion提交一个补丁?

首先,看一下Subversion Community Guide

一旦你消化了这些内容,能够在dev邮件列表发送一个题目有[PATCH]的邮件,并在邮件中包含你的补丁(除非你的邮件客户端会彻底处理它),不久以后就会有提交者捡起来,应用它(做出合适的格式化或内容变动),并将其检入。

基本的过程看起来以下:

	$ svn co http://svn.collab.net/repos/svn/trunk subversion
	$ cd subversion/www

		[ make changes to faq.html ]
	
	$ svn diff faq.html > /tmp/foo

	$ Mail -s "[PATCH] FAQ updates" < /tmp/foo

固然,你的邮件应当包含补丁完成什么功能的解释,按照Subversion Community Guide所说的,可是你已经知道了,由于在你Hack以前已经彻底阅读和理解,不是吗?:)

我如何进行“iplace”的导入(例如:向Subversion添加一个目录结构,而原先的数据直接成为工做拷贝)?

例如,假设你但愿把/etc下的一些文件归入版本控制:

     # svn mkdir file:///root/svn-repository/etc \
         -m "Make a directory in the repository to correspond to /etc"
     # cd /etc
     # svn checkout file:///root/svn-repository/etc .
     # svn add apache samba alsa X11 
     # svn commit -m "Initial version of my config files"

这里利用了svn checkout的一个非当即但明显的优点:你能够从版本库直接检出一个目录到已存在的目录,这里,咱们首先在版本库建立一个目录,而后将其检出到已存在的目录/etc,将/etc目录变成工做拷贝。一旦完成,你能够使用普通的svn add命令选择文件和子目录进入版本库。

这是svn import的一个加强问题,它本应该可以在导入目录树时自动建立工做拷贝;能够看issue 1328

人们在讨论升级Subversion时所说的“转储/加载(dump/load)”是什么?

Subversion的版本库数据库模式在开发中会偶尔改变,使用1.0之前的Subversion开发版本建立的老版本库在升级时须要以下操做。若是在发布X和Y之间的模式发生变动,则版本库管理员升级到Y的时候必须以下操做:

  1. 关闭svnserve、Apache和任何可能访问版本库的东西。
  2. 使用版本X的svnadmin执行svnadmin dump /path/to/repository > dumpfile.txt 
  3. mv /path/to/repository /path/to/saved-old-repository
  4. 如今升级到Subversion Y(经过构建和安装Y,替换X)。
  5. 使用版本Y的svnadmin执行svnadmin create /path/to/repository
  6. 在使用版本Y的svnadmin执行svnadmin load /path/to/repository < dumpfile.txt 
  7. 从老版本库拷贝钩子脚本等到新版本库。
  8. 重启svnserve、Apache等等。

关于转储和加载的更多信息能够看Subversion手册的这个小节

注意:大多数Subversion的升级会须要转储和加载,若是某个版本须要,新版本的发布声明和CHANGES文件会显著说明这一点。若是你没有看到这个说明,那么应该是没有模式变动,也就没有转储/加载的必要。

如何设置客户端经过使用SSPI认证的Windows域控制器进行认证?

TortoiseSVN有个在Windows下设置Subversion服务器的完美文档,能够看http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-serversetup.html#tsvn-serversetup-apache-5中的SSPI authentication小节。

配置中比较重要的一部分是这几行:

   SSPIOfferBasic On

若是没有这行,支持SSPI的浏览器会提示用户输入凭证,可是不支持SSPI的客户端例如Subversion就不会提示。(当前版本的Neon - Subversion的HTTP库 - 只能处理基本的认证。)由于客户端永远不会被请求凭证,任何须要认证的操做都会失败。添加这一行告诉mod_auth_sspi对客户端使用基本认证,但使用Windows域控制器认证凭证。

我不喜欢“.svn”这样的目录名字,而喜欢“SVN”或者其余一些目录名,我该如何改变呢?

若是可能,咱们推荐你使用".svn",然而,若是你在Windows下使用ASP.NET,你可能须要按这里的介绍设置环境变量SVN_ASP_DOT_NET_HACK。

或者你能够使用一个彻底自定义的管理区域名称,咱们反对这样作,由于你的工做拷贝可能没法与你的Subversion客户端协调工做,然而,若是你喜欢,只须要将subversion/include/svn_wc.h的这一行从

#define SVN_WC_ADM_DIR_NAME   ".svn"

修改成(例如)

#define SVN_WC_ADM_DIR_NAME   "SVN"

而后从新编译客户端。

如何更改一个文件名的大小写?

这个问题在两种状况下会发生。若是你的操做系统使用的文件系统对大小写不敏感,例如windows系统,当你在添加文件的时候,你可能会不当心的添加一个文件名大小写错误的文件。或者,你可能只是想改变版本库中已有文件的大小写。

若是你是在一个大小写敏感的文件系统上工做,那基本上就不会出现这样的问题。直接将文件改为新的名字。例如,

svn mv file.java File.java

但这样的方式在windows这类大小写不敏感的文件系统上是不能正常运做的。在windows下,你只能临时地将文件拷贝到其余地方,而后从Subversion中删除该文件,而后从新添加名字大小写正确的文件副本。或者更好的办法就是对Subversion的URL执行移动操做。推荐使用操做URL的方法,由于这样能够保持文件的历史日志,并且可以当即生效。

尽管如此,这两种方式都会致使windows下的工做拷贝出现一些问题,由于当试图更新文件名产生冲突的文件的时候,windows仍是会不知所措。(你可能会获得一条消息如:svn: Failed to add file 'File.java': object of the same name already exists)。一个解决这个问题的办法就是删除工做拷贝而后从新检出。若是你不想这么作的话,那么你就必须执行上面提到的两个步骤来更新。

对于每一个大小写错误的文件,执行下面的命令将会改变大小写:

svn mv svn://svnserver/path/to/file.java svn://svnserver/path/to/File.java

要更新工做拷贝,你先得转到相关的目录,而后执行:

svn update file.java
svn update

第一步的更新会从你的工做拷贝中删除file.java,第二步更新会添加File.java,这样就会生成一个正确的工做拷贝。或者若是你有不少这种问题的文件,你能够按下面的方式来更新工做拷贝:

svn update *
svn update

就像你看到的,添加一个大小写错误的文件在文件系统大小写不敏感的操做系统上,是须要一些小技巧来修正的。因此最好当你第一次添加文件的时候,一次性就添加对了。为了防止相似的问题再发生,你能够建立一个pre-commit的钩子脚本,在其中调用文件check-case-insensitive.pl。这个文件放在Subversion的源代码包里,在contrib/hook-scripts目录中

我不能象CVS那样使用标签将一个分支的变动合并到主干(trunk),能够吗?

就像下面展现的,你能够不须要记住版本号就将一个分支合并到主线上面。反之亦然(在例子中并无展现)。

下面这个例子假设在/home/repos存在一个版本库,你但愿从中建立一个名叫bar的、包含你即将编辑的文件foo的分支。

为了跟踪分支合并的历史,版本库创建了tags/branch_traces/目录用来保存tags。

# setup branch and tags
$ svn copy file:///home/repos/trunk \
           file:///home/repos/branches/bar_branch \
           -m "start of bar branch"
$ svn copy file:///home/repos/branches/bar_branch \
           file:///home/repos/tags/branch_traces/bar_last_merge \
           -m "start"

# checkout branch working copy
$ svn checkout file:///home/repos/branches/bar_branch wc
$ cd wc

# edit foo.txt file and commit
$ echo "some text" >>foo.txt
$ svn commit -m "edited foo"

# switch to trunk and merge changes from branch
$ svn switch file:///home/repos/trunk
$ svn merge file:///home/repos/tags/branch_traces/bar_last_merge \
            file:///home/repos/branches/bar_branch

# Now check the file content of 'foo.txt', it should contain the changes.

# commit the merge
$ svn commit -m "Merge change X from bar_branch."

# finally, update the trace branch to reflect the new state of things
$ svn delete -m "Remove old trace branch in preparation for refresh." \
             file:///home/repos/tags/branch_traces/bar_last_merge
$ svn copy file:///home/repos/branches/bar_branch                     \
           file:///home/repos/tags/branch_traces/bar_last_merge       \
           -m "Reflect merge of change X."

为何$Revision$关键字不是我预想的那样?它替换的是文件最后修改的修订版本,但有时候我但愿它能替换文件的当前修订版本。

Subversion每次都将整个版本库的版本号整个进行自增,因此它不能将关键词替换成你想要的数字 - 它可能不得不在每次更新或者提交时对工做拷贝中的每一个文件进行搜索或者修改。

你想要的信息(你的工做拷贝的版本号)能够经过svnversion命令来获取;你能够根据指定的工做拷贝的路径提供其版本相关的信息(更多细节参考svnversion --help)。

你能够将其组合到你的构建或发布过程当中,以获取须要存放到源代码的信息。例如,在一个基于GNU make的构建环境中,在你的Makefile中添加以下的信息

##
## To use this, in yourfile.c do something like this:
## printf("this program was compiled from SVN revision %s\n",SVN_REV);
##

SVNDEF := -D'SVN_REV="$(shell svnversion -n .)"'
CFLAGS := $(SVNDEF) ... continue with your other flags ...

(注意这段代码在非GNU版本的make中无效,若是你的构建过程须要可移植,请不要使用它。)

或者使用如这些方法:

##
## on every build, record the working copy revision string
##
svn_version.c: FORCE
    echo -n 'const char* svn_version(void) { const char* SVN_Version = "' \
                                       > svn_version.c
    svnversion -n .                   >> svn_version.c
    echo '"; return SVN_Version; }'   >> svn_version.c

##
## Then any executable that links in svn_version.o will be able
## to call the function svn_version() to get a string that
## describes exactly what revision was built.
##

Windows用户会但愿使用SubWCRev.exeTortoiseSVN的下载页面就有;能够用当前工做拷贝的修订版本替换给定文件中的全部$WCREV$标签。

Subversion是否有一个功能相似CVS的$Log$的关键字呢?

没有。在CVS中没有对应的$Log$关键字,若是你但愿将日志信息输入某个特定文件,你能够使用'svn log your-file-name'或'svn log url-to-your-file'。邮件列表中有几个解释$Log$缺点的例子:

“当你开始合并分支之间的变动时,$Log$会是一个彻底的梦魇。你必定会在这里获得冲突 -- 由于关键字的本性 -- 很难简单的自动解决冲突。”

并且:

Subversion的日志信息是能够改变的,能够经过设置svn:log修订版本属性修改。因此在任意文件扩展$Log:$会形成数据的过期,更新操做可能须要访问全部出现$Log:$关键字的文件,即便这些文件没有其余的变动。

我对此并不在乎,我仍是指望使用它,你能实现吗?

不能,咱们本身没有计划实现它,也不会接受实现这个特性的补丁。若是你但愿发布包含某种变动日志的文件,你能够在你的构建系统中跳出这个限制。

在个人工程里有一个文件,每一个人都必须改变它,可是我不但愿他们本地的修改被提交,如何让'svn commit'忽略这个文件?

答案是:不要将文件归入版本控制,而是将文件的模板归入版本控制,例如“file.tmpl”。

而后,在初始化的‘svn checkout’以后,让你的用户(或你的构建系统)执行经过普通的操做系统复制将文件修改成正确的文件名,文件未版本化,因此毫不会提交。而且若是你但愿,你能够将文件加入到父目录的svn:ignore属性中,这样它就不会在‘svn status’命令中显示‘?’。

当我经过svn+ssh来访问一个版本库的时候,个人密码没有被缓存在~/.subversion/auth/,我应该如何避免每次都要键入密码?

ssh拥有本身的密码短语和认证缓存模式,它的认证缓存是Subversion以外的,须要独立于Subversion设置。

OpenSSH使用ssh-keygen建立密钥、经过ssh-agent缓存密码短语、使用ssh-add将密码短语添加到代理缓存中。一个简化ssh-agent使用的脚本是keychain。在Windows下,PuTTY是一个流行的ssh客户端选择;将OpenSSH密钥导入到pageant并缓存密码短语能够看PuTTYgen

设置ssh-agent已经超出了本文的范围,可是在Google中搜索“ssh-agent”能够快速获得答案,或者若是你没有耐心,能够是看这些:

   http://mah.everybody.org/docs/ssh
   http://kimmo.suominen.com/docs/ssh/

个人svnserve二进制程序不在个人用户的默认路径中,他们使用svn+ssh,我不知道怎样修改他们的路径来让他们运行svnserve

注意:这里都假设你使用了OpenSSH。也有一些其余的ssh实现,大概它们也实现了这些功能,可是咱们不知道具体的方法。

你已经对修改过各类诸如.bash_profile的登陆文件,可是没有效果!那是由于当Subversion客户端调用ssh时会忽略那些文件。可是没有必要修改PATH;相反,你能够直接在svnserve命令中使用ssh的彻底名,下面是一个例子:

对于每一个须要经过svn+ssh访问的用户,生成一个新的Subversion使用的ssh公钥对—不是用来登录的。让他们给密钥对不一样的名称,例如~/.ssh/id_dsa.subversion。将密钥的公共部分添加到服务器主机的~/.ssh/authorized_keys中,在开始部分包含ssh-rsassh-dss以及一些幻数的行中,以下:

以前
ssh-dss AAAAB3Nblahblahblahblah
以后
command="/opt/subversion/bin/svnserve -t" ssh-dss AAAAB3Nblahblahblahblah

很明显,须要将/opt/subversion/bin/svnserve替换为你主机上的相应值。你也会但愿在命令行指明Subversion版本库的彻底路径(经过-r选项),节省用户使用时的输入。

command=魔法可让远程主机的sshd调用svnserve,即便你的用户尝试运行其余命令,更多细节能够看sshd(8)的man页(AUTHORIZED_KEYS FILE FORMAT部分)。

如今当你的用户运行Subversion客户端时,请肯定他们有一个SVN_SSH环境变量是“指向”他们密钥对的私有部分,经过下面的方法(Bourne Again shell):

SVN_SSH="ssh -i $HOME/.ssh/id_dsa.subversion"
export SVN_SSH

这个主题的详细讨论能够看这个文件

我但愿容许经过svn+ssh://来访问版本库,但我很忧虑。我讨厌为每一个用户分配一个登陆账号的方法,那样我会为他们是否容许访问个人机器感到担忧。

能够看对其余问题的回答中关于修改~/.ssh/authorized_keys的部分;先无论将svnserve设置到路径的问题。

我怎么才能为版本库的全部文件设置一个的属性?另外,我该如何确保每一个添加到版本库里的新文件都有这些属性?

Subversion缺省状况下不会修改文件的内容;你能够设置svn:eol-stylesvn:keywords属性实现这个功能。这让Subversion比CVS的缺省行为模式更加安全,可是安全也带来了不便。

第一个问题的答案是:设置全部已经进入版本库的文件,将会有点困难。你所要作的是在每一个文件(工做拷贝文件)上执行svn propset,而后执行svn commit,经过脚本应该能够帮助你作这件事。

可是对之后的文件呢?很不幸,没有在服务端自动设置提交文件属性的机制。这意味着你须要让你的用户记住在每一个svn add的文件上添加属性,幸运的是,有一个客户端的工具能够帮助咱们作这件事,能够阅读本书的auto-props特性。你须要保证全部的用户配置了合适的自动化属性。

你能够写一个pre-commit钩子脚原本拒绝忘记在新文件添加属性的提交(例子能够看http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/check-mime-type.pl)。然而这个方法有点过激了,例如某人忘记了设置svn:eol-style,那么在其余系统上用户很快就会注意到,一旦发现,能够很简单的修正:只要设置正确的值,并提交。

注意:许多用户指望获得服务器“自动广播”运行中设置的特性,例如自动化属性设置。对此已经有了一个特性请求(issue 1974),然而这个特性还存在争议,尚未去实现。

我如何处理编辑器路径中的空白?另外,如何定义编辑器的命令行选项?

Subversion命令行客户端会调用经过环境变量SVN_EDITOR. 定义的编辑器,这个环境变量以及要编辑日志的临时文件会直接传递给操做系统。

由于是要将SVN_EDITOR的字符串传递给系统命令行,因此若是你不加引号,编辑器名称中的空格或路径中的空格会形成错误。

例如,在Windows下,若是你的编辑器在C:\Program Files\Posix Tools\bin\vi,你须要这样设置环境变量:

   set SVN_EDITOR="C:\Program Files\Posix Tools\bin\vi"

请注意没有必要在windows下回避引号,由于他们不是set命令语法的一部分。

而在UNIX系统中,你须要听从你shell的特定方法来设定变量,例如在bash shell中,应该这样:

   SVN_EDITOR='"/usr/local/more editors/bin/xemacs"'
   export SVN_EDITOR

若是调用编辑器须要命令行选项,只要在SVN_EDITOR环境变量的编辑器名称后面输入选项,就像你平时调用它时那样。例如,若是你的编辑器须要-nx -r选项,能够按照下面的方式设置:

在Windows下:

   set SVN_EDITOR="C:\Program Files\Posix Tools\bin\vi" -nx -r

在UNIX/bash中:

   SVN_EDITOR='"/usr/local/more editors/bin/xemacs" -nx -r'
   export SVN_EDITOR

请注意SVN_EDITOR是Subversion特定的设置编辑器的环境变量,Subversion也支持使用更广泛的EDITOR环境变量,可是若是你但愿一些对于Subversion特殊的行为方式,最好仍是使用SVN_EDITOR变量。

如何肯定版本库正在使用的Berkeley DB的版本?

若是它是一个活动的版本库,那么对于这个问题最简单的答案是“你安装的Berkeley DB的版本”。可是,若是它是备份的或其它未知源获得的版本库,你对其的Berkeley DB版本一无所知,下面是你肯定它的方法:

运行命令查看版本库中的高位计数文件db/log.*中位移12到16(10进制)的两个4字节的整数。这里是GNU od的例子:“od -j12 -N8 -tx4 log.<number>”。而这里是Mac OS X hexdump的例子:“hexdump -s12 -n8 -x log.<number>”。第一个整数必定是幻数0x00040988,用来注明这是Berkeley DB日志文件,第二个数字是日志格式版本 - 能够使用下面的表格和Berkeley DB的版本匹配:

日志格式版本 Berkeley DB版本
5 (0x00000005) 4.0
7 (0x00000007) 4.1
8 (0x00000008) 4.2
10 (0x0000000a) 4.3
11 (0x0000000b) 4.4
12 (0x0000000c) 4.5
13 (0x0000000d) 4.6

我在版本库中管理了一个网站,如何才能实现每次提交以后站点自动更新?

这个早已经解决,能够经过为版本库添加post-commit钩子脚本简单实现,能够读一下手册第5章关于钩子脚本的内容,基本的思想是让“活动站点”变成一个普通的工做拷贝,让post-commit在工做拷贝中执行‘svn update’。

在实践中,有许多地方须要当心。执行提交的服务器程序(svnserve或apache)也是执行post-commit钩子脚本的程序,这意味着程序必须有正确的更新工做拷贝的访问许可。换句话说,运行svnserve或apache的用户应该拥有工做拷贝 -- 或至少工做拷贝设置了合适的访问许可。

若是服务器须要更新它并不拥有的工做拷贝(例如,用户joe的~/public_html/区域),一个技巧是建立一个+s的二进制程序运行更新,由于Unix不容许为脚本运行+s,编译一个小的C程序:

#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
  execl("/usr/local/bin/svn", "svn", "update", "/home/joe/public_html/",
        (const char *) NULL);
  return(EXIT_FAILURE);
}

... 而后对二进制程序chmod +s,并确认它确实被用户‘joe’全部,而后在post-commit钩子中,添加一行运行二进程程序。

若是在让钩子运行时发生了问题,能够看“为何个人钩子脚本都不能正常工做?”

另外,你可能但愿防止apache把工做拷贝中的.svn/目录暴露出去,在你的httpd.conf添加下面的内容:

# Disallow browsing of Subversion working copy administrative dirs.
<DirectoryMatch "^/.*/\.svn/">
    Order deny,allow
    Deny from all
</DirectoryMatch>

我如何检出一个单独的文件?

Subversion不支持检出单个文件,它只支持检出目录结构。

然而,你能够使用‘svn export’来导出单个文件,这会得到文件的内容,只是不会建立版本化的工做拷贝。

如何在工做拷贝执行完添加、删除、拷贝和重命名操做以后检测这些操做?

你不须要检测,你也最好不要尝试去作这样的检测。

工做拷贝的基本设计有两个原则:(1) 你能够任意编辑文件,而后(2)使用Subversion客户端执行任何树目录的改动(增长、删除、移动、拷贝)。若是这两个原则可以很好的遵照,那么客户端就能够顺利的维护工做拷贝。若是重命名或者其余改动是在Subversion以外进行的,那么UI就会被破坏,工做拷贝也可能发生问题。客户端不能猜想究竟发生了什么事。

人们有时候会遇到这样的错误,由于他们想要把版本控制变得透明化。他们诱使用户使用一份工做拷贝,而后在稍候运行一个脚本,这个脚本会猜想用户作了什么样的操做,而后执行相应的客户端命令。不幸的是,这样的方式只能在短时间内正常工做。‘svn status’会显示出缺失条目或者未被归入版本控制的条目,这些条目在脚本运行的时候会自动的被‘svn rm’或者‘svn add’。但若是发生了文件移动或者拷贝,那么你就不那么幸运了。即便脚本有很是可靠的方法来检测这些动做,但‘svn mv’和‘svn cp’不能在这些操做已经完成的状况下运行。

总的来讲,工做拷贝必须整个放置在Subversion的版本控制之下,Subversion原本就不是设计成对用户透明的。若是你想要得到这种透明性,那么你应该创建一个apache服务器,而后本书附录C使用的“SVNAutoversioning”特性。这将容许用户将版本库挂载成一个网络磁盘的形式,任何对这个磁盘的修改,都会自动提交到远程服务器上。

在Windows上如何将svnserve看成服务来运行?

对于1.4.0及之后的版本,你能够查看这里

对于1.4.0之前的版本,svnserve二进制自己并不能够被安装成一个windows服务,但有不少“service wrappers”能够完成同样的工做。例如:

  • SVNService Magnus Norddahl写的一个免费的工具
  • SrvAny 微软出的免费的工具

在 TortoiseSVN手册还有一点内容关于怎么将svnserve安装成服务的形式。

如何转换个人版本库,从BDB到FSFS,或者从FSFS到BDB?

有三步:

  1. 使用dump/load将旧格式转到新格式。
  2. 拷贝钩子脚本。
  3. 拷贝配置文件。

假设你在/svn/myrepos目录中放置了一个版本库,使用的是BDB,你想要将其转换成FSFS:

  1. 关闭你的服务器,这样在这个过程当中数据不会发生变化。
  2. 建立一个使用fsfs的新的版本库(这在1.2版本依赖就是默认的行为)。例如,svnadmin create /svn/myreposfsfs --fs-type fsfs
  3. /svn/myrepos的转储输出经过管道重定向到/svn/myreposfsfs的加载输入上,例如,svnadmin dump /svn/myrepos -q | svnadmin load /svn/myreposfsfs。Windows用户应该转储到一个文件中,而且从那个文件中加载,须要分两步完成。
  4. 复制在/svn/myrepos/hooks中仍使用的钩子脚本到/svn/myreposfsfs/hooks中。不要全部东西都拷贝,有些模板是由Subversion自动生成的,可能会不同。
  5. 比较/svn/myreposfsfs/hooks目录中svnadmin create命令生成的脚本模板和/svn/myrepos/hooks中的有什么不同,将这些不一样按需合并到你正在使用的钩子脚本中。
  6. /svn/myrepos/conf复制配置文件到/svn/myreposfsfs/conf中(若是有密码文件的话,也不要忘了)。或者你想要将配置文件中所作的修改合并到新的默认配置文件中。
  7. 重命名/svn/myrepos/svn/myreposbdb,还有/svn/myreposfsfs重命名为/svn/myrepos,这样能够确保文件权限和BDB版本的同样。
  8. 重启服务器。

一旦一切工做正常后,删除旧的版本库便可。

若是要反过来操做,即从FSFS移植到BDB,只须要改变svnadmin create命令,将其指定为BDB便可。

版本库如何处理二进制文件?

当你第一次添加或者导入文件到Subversion中时,Subversion会检测该文件是不是二进制文件。目前,Subversion的策略是只检测文件的前1024个字节;若是每一个字节都是0,或者超过15%都是非ASCII码可打印字符的话,那么Subversion就认定该文件是二进制文件。这种启发式方法未来可能会改进。

若是Subversion认定文件是二进制文件,那么这个文件就会自动添加svn:mime-type属性,并设置为“application/octet-stream”。(你随时能够使用auto-props特性来重写这样的行为,或者使用svn propset手动设置属性。)

Subversion对如下的文件作普通文本处理:

  • 没有设置svn:mime-type属性的文件
  • 文件的svn:mime-type属性值以“text/”开头
  • 文件的svn:mime-type属性值等于“image/x-xbitmap”
  • 文件的svn:mime-type属性值等于“image/x-xpixmap”

全部其余文件都将被视为二进制文件处理,这意味着Subversion:

  • 不会尝试在svn update或者svn merge操做时将远程修改合并到本地中
  • svn diff中不会显示出不一样
  • svn blame不会显示出每一行的贡献者

在其余方面,Subversion将二进制文件和其余文本文件同样对待,例如,若是你设置了svn:keywords或者svn:eol-style属性,Subversion会在二进制文件中执行关键词替换或者行转换。

须要注意,无论是否是二进制文件,都不会影响版本库中用来存储文件变动的空间大小,也不会影响客户端和服务端之间的通信量。出于存储和传输考虑,Subversion使用的是对二进制文件和普通文本文件一致处理的diffing方法;这和‘svn diff’使用的diffing方法彻底不相关。

如何让svn diff仅显示被改变的文件的名字,而不是连内容也显示出来?

svn diff没有一个选项能够作到这一点,可是

  • 若是你只是对修订版本号10和以前的版本之间的变更感兴趣,那么使用
    svn log -vq -r10
    彻底能够实现你的目的;
  • 不然,若是你是在使用Unix系统的话,下面这个方法对于任意范围的版本号都起做用:
        svn log -vq -r123:456 | egrep '^ {3}[ADMR] ' | cut -c6- | sort | uniq 
1.4版本的 svn diff命令有一个“--summarize”的参数。

我如何使用通配符(wildcards)或者点号来一次移动多个文件?

你或许是想作这样一些事情

svn mv svn://server/trunk/stuff/* svn://server/trunk/some-other-dir

可是却失败了

svn: Path 'svn://server/trunk/stuff/*' does not exist in revision 123

... 或者还有其余一些看起来不可理解的错误信息。

简而言之,很不幸:Subversion没有内置这样的方法来进行这样一种操做;许多其余的命令,例如mv,不会接受任意数目的参数...在任何状况下,Subversion都不会扩展如shell所支持的“*”号通配符。

若是你恰好有一个工做拷贝包含了和目标目录一摸同样的源文件,那么你能够使用你的shell中的通配符特性来完成移动文件的目的,例如(在bash下):

  for i in stuff/*; do svn mv $i some-other-dir; done
  svn ci -m "moved all the stuff into some other dir"

在任何状况下,你均可以将源文件的名字拼成一个列表,而后使用“svn mv”命令对列表中的每一项都执行一样的指令,就像下面所作的同样:

        s=svn://server/trunk/stuff/
        svn ls "$s"  | \
        while read f
           do svn mv "$s/$f" svn://server/trunk/some-other-dir -m "Moved just one file"
        done

可是须要注意的是,这样会形成每一个文件都执行一次提交动做,这和上面的方法(使用工做拷贝)不一样,上面的方法总共就会执行一次提交动做。

有一个程序叫“svnmucc”或者“mucc”能够解决你的这个问题,不过它依赖于你的Subversion版本号,它的源代码已经发布在Subversion中了(对于Subversion 1.4以及更早的版本,这个工具的源文件放置在/contrib/client-side/mucc/mucc.c,对于1.5及以后的版本,则在/tools/client-side/svnmucc/svnmucc.c能够找到)。

注意:随着1.5版本的正式发布,Subversion事实上容许你一次性同时“cp”和“mv”多个文件。

我如何用Subversion维护一个由第三方不断修正版本的软件呢?(一个"供方分支")?

人们一般但愿使用Subversion去跟踪他们的变化的第三方代码,甚至从第三的代码进行升级,换句话说,他们想维护他们本身的一个分支,与此同时仍然但愿从上游的代码并入新的发布。这一般被叫作供方分支(这个术语早于Subversion),Subversion维护这种分支的技术能够看这个描述

若是供方代码是远程的主机上的Subversion版本库,你能够使用Piston来管理你的供方代码拷贝。

最后,若是使用svn_load_dirs.pl花太多时间的话,或者你正在寻找一个偷懒的方案,则能够参考Jon Stevens的渐进介绍如何使用Subversion供方分支。这种解决方案在你拷贝新的代码去覆盖旧代码的时候并不能利用Subversion后端的节省空间特性换;在这种解决方案中,每一份导入的供方代码都会是一个新的拷贝,相同的文件不会节省存储空间。

疑难解答:

 

 

个人版本库常常看起来卡住了,一直报一个须要从新恢复(DB_RUNRECOVERY)的错误,怎么会致使这个问题?

版本库使用的Berkeley DB数据库很容易受到破坏。若是进程退出时没有正常关闭数据库,那么数据库就处在非正常状态中。常见的缘由多是:

  • 进程遇到访问权限问题而退出时
  • 进程崩溃或段错误
  • 进程被强制杀死
  • 磁盘空间用尽

多数状况下,你能够执行"svnadmin recover",这个命令能够将版本库回退到上一个正常状态,详细解释请见bdb-recovery。注意,当频繁的checkout和update且磁盘空间用尽的时候,可能致使版本库处于没法恢复的状态(因此请多作备份)。

进程崩溃,被杀死以及磁盘空间用尽都是极端状况。访问权限问题多是更常见的缘由:当一个进程访问版本库且改变了版本库的全部者或访问权限,那么另外一个访问这个版本库的进程可能被阻塞在访问权限上。

避免这种状况出现的最好办法是正确设置你的版本库的全部者和权限。查看更多信息

 

每次我想访问个人版本库,进程就会挂起。个人版本库坏掉了吗?

你的版本库没有坏掉,数据也没有丢失。当你的进程直接访问版本库(mod_dav_svn、svnlook、svnadmin,或经过‘file://’)的时候,进程将直接经过Berkeley DB来访问版本库。Berkekey DB包含日志系统,也就是说全部的操做在执行前都被记录在日志中。当你的进程崩溃(Control-C,或段错误),遗留下文件锁,它记录了全部未完成操做的信息。此时全部试图访问数据库的进程将由于要访问文件锁而被挂起。要想解除文件锁,你能够调用Berkeley DB来完成全部未完成的操做或者回退到前一个正常状态。

警告:当一个进程正在访问版本库,而你又试图恢复版本库的时候,版本库可能会严重损坏。

在你恢复数据库以前,请确保没有其余进程在访问版本库(关闭Apache, 去掉'svn'的执行权限) 。确认你是以数据库全部者及管理员的用户进行操做的,而不是root用户。不然数据库将只能被root用户访问,而其余用户(你本身或Apache)将没法对数据库进行操做。同时,还要确保umask被正确设置,不然其余隶属与能够访问该数据库的组的用户可能没法对数据库进行操做。

执行:

   svnadmin recover /path/to/repos

当命令执行完毕, 检查版本库db目录的访问权限

有时"svnadmin recover"会失败,错误信息以下:

  Repository lock acquired.
  Please wait; recovering the repository may take some time...
  svnadmin: DB_RUNRECOVERY: Fatal error, run database recovery
  svnadmin: bdb: Recovery function for LSN 175 7066018 failed on backward pass
  svnadmin: bdb: PANIC: No such file or directory
  svnadmin: bdb: PANIC: fatal region error detected; run recovery

或者:

  Repository lock acquired.
  Please wait; recovering the repository may take some time...
  svn: DB_RUNRECOVERY: Fatal error, run database recovery
  svn: bdb: DB_ENV->log_flush: LSN of 115/802071 past current end-of-log
  of 115/731460
  svn: bdb: Database environment corrupt; the wrong log files may have
  been removed or incompatible database files imported from another
  environment
  [...]
  svn: bdb: changes: unable to flush page: 0
  svn: bdb: txn_checkpoint: failed to flush the buffer cache Invalid argument
  svn: bdb: PANIC: Invalid argument
  svn: bdb: PANIC: fatal region error detected; run recovery
  svn: bdb: PANIC: fatal region error detected; run recovery
  [...]

这种状况下能够试试Berkeley DB的工具db_recover (参见db_recover文档).这个命令一般在Berkeley DB安装目录的子目录"bin/"中, 例如你从源代码安装的Berkeley DB,命令多是/usr/local/BerkeleyDB.4.2/bin/db_recover;或在某些系统中预安装的Berkeley DB,多是 /usr/bin/db_recover.若是你的系统中安装了多个版本的 Berkeley DB,请确保使用匹配版本库的Berkeley DB版本

执行db_recover,附带参数"-c" ("灾难恢复").你还能够附带 "-v"来看到执行的详细信息, "-h"指定被恢复的数据库。例如:

   db_recover -c -v -h /path/to/repos/db

用版本库的拥有者的账号执行这个命令,同时,请绝对确保没有其余进程在 访问版本库。(例如,关闭svnserve或)。

个人版本库一直报告错误"Cannot allocate memory",我该怎么办?

若是你经过http://来访问版本库,"Cannot allocate memory"应该出如今httpd服务器的日志中,像下面这样:

[Wed Apr 07 04:26:10 2004] [error] [client 212.151.130.227] (20014)
Error string not specified yet: Berkeley DB error while opening 
'strings' table for filesystem /usr/local/svn/repositories/svn/db: 
Cannot allocate memory
[Wed Apr 07 04:26:10 2004] [error] [client 212.151.130.227] 
Could not fetch resource information.  [500, #0]
[Wed Apr 07 04:26:10 2004] [error] [client 212.151.130.227] 
Could not open the requested SVN filesystem  [500, #160029]     
[Wed Apr 07 04:26:10 2004] [error] [client 212.151.130.227] (17) 
File exists: Could not open the requested SVN filesystem  [500, #160029]

这一般表示Berkeley DB版本库用光了全部数据库锁(FSFS版本库不会出现这种状况)。一般的运行过程当中不该该出现这种状况,若是确实出现了,解决办法是用本文中描述的方法来恢复数据库。若是这种状况时常发生,你极可能应该提升db/DB_CONFIG文件中锁设置(set_lk_max_locksset_lk_max_lockersset_lk_max_objects)的默认值。改变已存在的版本库的DB_CONFIG配置后,记得恢复数据库。

每当我试图运行一个svn命令时,都会提示个人工做拷贝已经被锁定了,是个人工做拷贝坏掉了吗?

你的工做拷贝没有坏掉,数据也没有丢失。Subversion的工做拷贝是一个日志系统,全部的操做在执行以前都被记录在日志中。若是svc客户端程序被强制停止(段错误或杀进程,不包括Control-C),会有多个文件锁遗留下来,记录了未完成的操做。('svn status'命令会在被锁定的目录后显示'L'。)其余试图访问工做拷贝的进程看到这些锁后会返回操做失败。想解锁你的工做拷贝,须要让svn客户端完成未完的操做。执行:

svn cleanup working-copy

我试图去提交,可是Subversion说个人工做拷贝是过期的?

三种状况下会出现这个问题

  1. 提交失败致使了你的工做拷贝被破环。

    在你提交时,新版本被添加到服务器上,而后你的客户端执行提交后的管理任务(包括刷新本地拷贝)。在第二个操做以前,你的提交处在一个“过时”的状态之中。致使这种状况发生的缘由有,(极少数状况下)数据库一端出现了问题,(大多数状况下)网络在错误的时间中断了。

    这时,极可能你的提交已经成功了。你能够执行"svn log -rHEAD"来查看提交是否真的成功了。若是成功了,执行“svn revert”,回退本地修改,而后执行“svn update”来取回你已经提交的修改。(注意,“svn update”能更新你的本地拷贝,而revert不能。)

  2. 版本混杂。

    提交的时候,在客户端的工做拷贝中,只有这次提交涉及的节点会被更新,而不是全部节点。这意味着,你最后一次提交决定你的工做拷贝中了文件和目录的版本号,他们可能不是同一版本。对于像修改目录属性等特定操做,若是版本库中有更新的版本,你的提交会被拒绝,以防止数据丢失。详细请见版本混杂的局限使用Subversion作版本控制中。

    执行'svn update'能够解决这个问题。

  3. 你的版本可能确实是过期的 — 即在你提交的时候,有人基于你的上一次改动又做了更新。执行'svn update'来解决这个问题。

我为项目贡献了一个补丁,而这个补丁添加了一个新文件,如今svn update不能工做了。

若是要往补丁里加入新文件,你可能得使用svn add命令,这样svn diff命令才会将新文件包含在补丁里面。若是你的补丁已经提交到代码库里头了,而后你运行svn update,这个时候你可能会收到错误提示:“svn:Failed to add file ‘my.new.file’。object of the same name already exists”(不能增长“my.new.file”,同名文件已经存在)。

之因此会产生这个错误是由于你的工做拷贝中已经有这个文件了。解决这个问题的步骤以下:

  1. 运行svn revert命令,把原先标记为添加的修改撤销掉。
  2. 删除文件或者将其移动到工做拷贝外的其余位置。
  3. 如今你应该能够运行svn update命令了。

你可能须要把版本库中的新文件和你的本地的文件作一下比较。

我编译了Subversion的发行版,当我试图check out的时候,我获得一个错误"Unrecognized URL scheme."这时怎么回事呢?

Subversion使用了插件系统来访问版本库。如今支持三个插件:ra_local支持访问本地版本库,ra_dav支持经过WebDAV访问版本库,ra_svn支持经过svnserver服务器访问远程或本地的版本库。当你执行Subversion的操做时,会根据URL scheme来决定加载哪个插件。以`file://'开头的URL会加载ra_local,`http://'开头的URL会加载ra_dav。

你看到的错误是说没法找到正确的插件。发生这个问题,一般是由于你将Subversion的库文件编译成动态库后,却没有执行'make install'。或者虽然你执行了'make install',可是操做系统仍是找不到Subversion的动态库所在的路径。在Linux系统中,你能够把相应的路径加入到/etc/ld.so.conf中,而后运行ldconfig。若是你不想这么做,又或者你没有root权限,你能够在LD_LIBRARY_PATH中指定相应的路径。

当我查找或打开一个版本库时出现错误,可是我知道我版本库URL是正确的,哪里出错了?

参考这个FAQ条目。

当我运行`configure'命令时,出现一些错误subs-1.sed line 38: Unterminated `s' command。 这是怎么回事?

可能你系统里的/usr/local/bin/apr-config/usr/local/bin/apu-config太旧了。删了它们,更新apr/apr-util/,使其和你编译的版本保持一致,再从新编译。

我在Windows下用MSVC++6.0构建Subversion时候有些麻烦,我该怎么办?

可能你须要最新版本的platform SDK,VC++ 6.0带的SDK太旧了。

我如何在file:格式的URL中指定Windows盘符?

像这样:

svn import file:///d:/some/path/to/repos/on/d/drive

更多细节请见Subversion书中的版本库URL

VS.NET/ASP.NET彷佛不能处理".svn"目录名。我该怎么办?

VS.Net有一个ASP.Net子系统,它使用WebDAV来经过IIS来远程发布。这个子系统剔除了全部以"."开头的目录。在你试图远程发布你的工做目录的时候,".svn"将致使问题。错误信息相似"unable to read project information"。

要想绕过这个问题,设置环境变量SVN_ASP_DOT_NET_HACK为任意值 — 这将告诉Windows clients在你的工做拷贝中使用"_svn"做为目录名。参见Subversion 1.3发布说明的相关章节来取得更多信息,参见这个问题来用其余方法配置管理目录名。

我在经过网络对Subersion版本库进行写操做的时候有些麻烦。

例如,有用户反映,经过本地协议访问的,导入功能正常工做:

  $ mkdir test
  $ touch test/testfile
  $ svn import test file:///var/svn/test -m "Initial import"
  Adding         test/testfile
  Transmitting file data .
  Committed revision 1.
但若是从远程访问的话就出错了:
  $ svn import http://svn.sabi.net/test testfile -m "import"
  nicholas's password: xxxxxxx

  svn_error: #21110 : <Activity not found>

  The specified activity does not exist.

咱们曾经遇到过这样的问题,当httpd进程对REPOS/dav/目录没有可写权限的时候会发生。你须要检查一下相关的权限问题,确保Apache可以往dav/目录中写入东西。(固然还有db/目录)。

在Windows XP下,Subversion服务器有时候会发布一些错误数据,真的是这样吗?

你须要安装Windows XP的SP1补丁。你能够在下面这里找到全部相关的信息:

在Subversion服务器和客户端之间进行交互时,跟踪网络的最好方法是什么?

能够参考hacking.html#net-trace

为何svn revert要求有一个明确的目标?为何它默认不是递归执行的呢?这与全部其余的子命令都不一样。

简而言之,这是为你好。

Subversion对保护你的数据很是重视,不仅是你已经版本化的数据。你对已经版本控制的文件所作的修改,或者你即将添加到版本库中的文件,都必须当心对待。

使用svn revert命令须要很是明确地指定目标—即便目标是‘.’—就是其中一个方面。这个要求(一样对于--recursive (-R)标记,若是你真的须要递归执行某个操做,你也要这样作)是为了让你清楚的知道你要作的事情,由于一旦你执行了撤销工做拷贝修改的命令,全部本地的修改都会永远消失。

当我启动Apache时,mod_dav_svn报告"bad database version",它发现的是db-3.X,而不是db-4.X。

你的apr-util连接的是DB-3,而svn连接的是DB-4。不幸的是,DB符号并非不相同的。当mod_dav_svn被加载入Apace的进程空间的时候,他会使用apr-util的DB-3库来解析符号。

解决办法就是确保apr-util是在DB-4下编译的。你能够在编译的时候指定特定的开关为apr-util的配置或者apache的配置:“--with-dbm=db4 --with-berkeley-db=/the/db/prefix”。

在Red Hat 9中,我获得一个"Function not implemented"错误,一切都中止工做。我该如何修正它呢?

这确实不是Subversion的问题,但常常会影响Subversion用户。

随Red Hat 9还有Fedora发行的Berkeley DB库依赖于对NPTL的内核支持(本地Posix线程库)。

Red Hat提供的内核对这方面有内置的支持,但若是你是本身编译的内核,那么你可能不会有NPTL的支持。若是是这个缘由的话,那么你可能会看到以下的错误:

svn: Berkeley DB error
svn: Berkeley DB error while creating environment for filesystem tester/db:
Function not implemented

这个问题能够按照下面的方法解决:

  • 根据你使用的内核从新编译Berkeley DB。
  • 使用Red Hat 9内核。
  • 使用NPTL内核补丁。
  • 使用内置了NPTL支持的比较新的内核版本(2.5.x)。
  • 检查LD_ASSUME_KERNEL环境变量是否已经设置为了2.2.5,若是是的话,在从新启动Subversion(Apache)以前删除此环境变量。(一般只有当你在Red Hat 9上面运行 Wine或者Winex才须要设置这个环境变量)

要使用NPTL版本的Berkeley DB,你还须要使用支持NPTL的glibc库,极可能是i686版本。参考 http://svn.haxx.se/users/archive-2004-03/0488.shtml

为何文件经过Apache(ra_dav)被提交和导入时,SVN的日志说“(no author)”?

若是你在Apache上开启了匿名用户的写权限的时候,Apache服务器就不会向svn客户端询问用户名,而是直接不通过验证就容许执行写操做。由于Subversion不知道谁作了这些操做,日志中这些操做信息就变成下面这样了:

$ svn log
------------------------------------------------------------------------
rev 24:  (no author) | 2003-07-29 19:28:35 +0200 (Tue, 29 Jul 2003)

关于如何配置Apache的访问权限,参考Subversion书籍("Networking a Repository")。

我在Windows平台上偶尔会获得一个"Access Denied"错误,它的发生好像没有什么规律,为何呢?

这多是因为一些监听文件系统变化的windows服务(如杀毒软件,索引服务,COM+事件通知服务)。这不属于Subversion的Bug,因此咱们很难修正这个问题。关于这种状况的调查说明能够在这里找到。在7598版本中,对这个问题作了改进,对于大多数人来讲,应该会下降这种状况出现的概率。若是你使用的是较早的版本,请更新到最新的发行版。

在FreeBSD上,某些操做(尤为是svnadmin create)有时候会被挂起。为何?

这一般是因为系统中某些资源不足的缘故形成的。你极可能须要配置一下系统,使其可以从源那里获取足够的资源,如硬盘还有网络中断。查阅你的系统说明手册,找到random(4)还有rndcontrol(8)这几节,看如何修改。

我能够从一个WEB浏览器上查看个人版本库,可是在执行'svn checkout' 时发生一个错误:"301 Moved Permanently"。那个地方出错了?

这意味着你的httpd.conf配置有问题,一般状况下,当你设置的Subversion虚拟目录同时存在两种寻址方式的时候会出现这样的错误。

例如,当你将版本库放到/www/foo目录下,可是你又同时设置了你的版本库的根目录为/www,那么你就麻烦了。当有人请求一个/www/foo/bar文件的时候,apache根本不会知道,对方真正想要寻找的文件,是在根目录里下的/foo/bar,仍是经过调用mod_dav_svn模块从/www/foo版本库中去把/bar文件给取回来,一般Apache的处理行为是采起前者的方式,所以就会出现“永久转移”这样的错误了。

解决这个问题的办法就是确认你的版本库路径不会有重叠,或者存在其余网络共享可访问的路径里面。

出现这个问题还有一个可能的缘由,就是在网站根目录存在一个和版本库的URL同名的文件(文件夹)。例如,假设你的WEB服务器的根目录设置在/var/www,你的Subversion版本库被放置在/home/svn/repo目录下,而后你在Apache下将该版本库的URL配置成http://localhost/myrepo。若是你这时又在/var/www下建立了一个myrepo的目录,那么一样会产生301的错误。

为何HTTP摘要认证(HTTP Digest auth)不能正常工做?

这个问题极可能是由于Apache服务器的一个已知的bug(存在于2.0.48或者更早期的版本),你能够在http://nagoya.apache.org/bugzilla/show_bug.cgi?id=25040找到相应的补丁。你也能够在https://issues.apache.org/jira/browse/SVN-1608 上看有没有和你说的状况相似的已反馈的bug。

我在AIX上面编译xls的时候出现编译错误,为何呢?

在环境变量CFLAGS中加入-qlanglvl=extended做为配置参数,这会使到编译xls的时候更加灵活,这样应该不会再出现编译错误了。更详细的信息请参阅http://svn.haxx.se/dev/archive-2004-01/0922.shtml 及相关的文章。

我使用非递归的方式(使用 -N参数)检出一个目录后,如今我想让某些特定的子目录再“出现”,但svn up subdir命令不能正常使用。

参考 issue 695. 当前的svn checkout -N命令的实现很是糟糕。它会形成工做拷贝某些条目缺失,但它自己又没有意识到已经出现了不完整性的问题。很显然,不少的CVS用户已经对这种使用方式习觉得常了,可是Subversion的用户还并不习惯。目前尚未好的办法解决这个问题,只能让你本身改变操做的流程:先试着检出单独的子目录,而后再手动嵌入到你的工做拷贝中。

我试着在win32平台的Apache上使用mod_dav_svn模块,可是却提示我模块未找到的错误,可是mod_dav_svn.so 这个文件明明就放在\Apache\modules目录中。

这个错误信息在这里有点误导人。一般这样的错误是由于Apache没法正确加载mod_dav_svn.so模块所依赖的模块。若是当前Apache是以服务的形式运行的,那么它的path环境变量和普通用户的并不相同。请确认libdb4*.dll、intl3_svn.dll、 libeay32.dll还有ssleay32.dll均可以在\Apache\bin或者\Apache\modules目录中找到。若是没有找到,你能够从Subversion的安装目录下拷贝一份。

若是这样还解决不了问题的话,那么你能够使用相似Dependency Walker这样的工具来查看mod_dav_svn.so库的依赖性,看是否还有还没有解决的依赖性问题存在。

为何个人钩子脚本都不能正常工做?

这些钩子脚本应该会触发外部程序的,可是这个触发过程彷佛并无执行。

当Subversion调用一个钩子脚本时,它会将全部环境变量都清除干净,包括unix下的$Path和windows下的%Path%变量,所以,若是你的脚本要访问外部程序的话你就必须指定好外部程序的完整路径。

调试技巧:

若是你正在运行Linux或者Unix操做系统,试一下按照下面的步骤手动运行一下脚本:

  1. 使用 "su"、"sudo"或者相似的命令来切换到通常状况下可能会运行该脚本的用户。若是你运行的是Apache服务器的话,那么这个用户一般是httpd或者www-data。若是你运行svnserve的话,那么极可能是使用svn的账户来运行该脚本。这样切换用户以后来运行脚本的好处就是不会再有脚本运行权限错误的问题出现。
  2. 使用env程序清除全部环境变量而后再运行该脚本,以下所示:
                      $ env - ./post-commit /var/lib/svn-repos 1234
    
    注意到传递给env程序的第一个参数是一个横杠,这样能够保证环境变量为空。
  3. 查看控制台有没有输出错误信息。

为何个人--diff-cmd会有关于‘-u’的报错,我想用--extensions去覆盖它,可是不起做用。

当使用一个外部的diff命令时,Subversion会生成一个很是复杂的命令行。第一个参数就是具体的--diff-cmd,而后就是具体的--extensions (尽管使用空白的 --符号时会忽略扩展),或者若是没有指定--extensions或者--extensions为空的话,就加上‘-u’参数。第三和第四个参数,Subversion会传递一个“-L”还有第一个文件的标签(例如,“"project_issues.html (revision 11209)”)。第五个和第六个就是另外一个“-L”和第二个文件的标签。第七和第八个参数分别是第一个和第二个文件的名称(例如,“.svn/text-base/project_issues.html.svn-base”和“.svn/tmp/project_issues.html.tmp”)。

若是你指定的diff命令不支持这些参数的话,你可能须要建立一个简单的封装脚原本忽略这些参数,而后将最后的你须要的文件的路径参数传递给diff命令。

警告:Subversion并不但愿外部的diff工具会改变它接收到的文件,不然可能会破坏当前工做拷贝。

更多信息请参考issue #2044.

啊呀,我刚刚发现个人Subversion客户端竟然把个人密码以明文的方式缓存在本地硬盘中!!!

冷静一下,深呼吸。

在windows 2000及以后的版本上,svn 1.2以后的版本都使用标准的windows API来加密数据,因此只有用户本身可以解密出缓存的密码来。

在Mac OS X, svn 1.4之后的版本使用系统的keychain功能来加密以及存储svn的密码。

Subversion 1.6会为UNIX/Linux处理这个问题,对于GNOME Keyring和KWallet的支持已经实现,均可以方便的在磁盘上存储加密的密码。这些程序能够在运行中的或编译中添加。若是没有,客户端会使用明文缓存密码,可是它若是以明文存储咱们会首先询问是否容许。

Subversion 1.5以及以前的版本在UNIX/Linux中,密码会以明文形式保存在~/.subversion/auth/中,请注意,虽然是明文存储(一般是~/.subversion/auth/),可是密码的访问许但是700,只有你能够阅读。

尽管如此,若是你仍是担忧的话,那么你能够将密码缓存的功能永久关闭。在svn 1.0的客户端中,你只须要在你的运行时配置文件设置‘store-auth-creds = no’。对于svn 1.1以及以后的版原本说,你能够使用粒度更细的设置‘store-passwords = no' (这样服务器的证书仍是会缓存)。更多关于密码缓存的信息已经能够看“日构建”Subversion手册之中第六章的“客户端凭证缓存

最后要说的是,咱们知道CVS不少年来一直都是将缓存的密码存放在.cvspass文件中的。表面上来看存放在里面的数据是加密过的,但实际上,他们只是使用很是简单的算法来进行混淆,就像rot13同样。这些所谓的密码能够很轻易就被破解掉。这种混淆的惟一做用就是防止其余用户如管理员意外的看到密码。可是目前尚未人但愿Subversion也这样作。若是你感兴趣的话,你能够为其写补丁而后发送到dev@list。

我获得一个错误"svn: bdb: call implies an access method which is inconsistent with previous calls"。我该如何修正它呢?

Berkeley DB 4.1版本至关的不稳定,而4.0和4.2都相对比较稳定。这条错误信息就是4.1版本有时候发生问题时的提示信息。

这个问题是因为使用Berkeley数据库作支撑的Subversion版本库中的其中一张表的某个数据库格式域(database format field)被破坏了。目前还不知道什么缘由,这一般都是由于“copies”表出错,致使它从“btree”类型转换成“recno”类型。你能够按照下面列举的简单的恢复流程来处理。若是下面的步骤未能成功,你应该联系Subversion的用户邮件列表。

  • 确保当前没有其余的进程在访问版本库。
  • 如今,将你的版本库备份到一个tar或者zip或者相似格式的文件中。
  • 转到你版本库的db子目录。
  • 执行删除指令:rm __db.* log.*
  • 执行转储指令:db_dump -p -r copies > copies.dump
  • 如今编辑copies.dump文件,在最上面的内容中将“type=recno”改为 to “type=btree”,而后删除以“re_len=”开头的行。
  • 执行删除指令:rm copies
  • 执行重加载指令:db_load copies < copies.dump
  • svnadmin dump .. > ../../my-recovered.svndump
  • 如今建立一个新的版本库,从新加载刚刚生成的转储文件(dump file),而后拷贝全部自定义的钩子脚本或者配置文件,最后查看一下最新的版本号是不是你指望的。

我没法热备份个人版本库,当文件大于2Gb时svnadmin会出错。

早期版本的APR在0.9版本分支上,若是使用Apache 2.0.x和Subversion 1.x,那么对于大文件是没有支持的(2Gb以上)。在APR 0.9.5及之后的版本还有Apache 2.0.50及之后的版本中已经考虑到这个问题了,并作了修正。可是这个修正并非针对全部操做系统的,而是只针对Linux。

我看不到我刚刚提交的文件的日志记录,为何呢?

假设你在版本库上运行‘svn checkout’,而且得到了修订号为7的工做拷贝(aka,r7),其中有一个文件叫作foo.c。你对这个文件进行了修改而且提交了修改,那么这个时候会发生两件事情。

  • 服务器上的版本库升级到修改号为8。
  • 在你的工做拷贝中,只有foo.c升级到修订号8,其余工做拷贝目录下的内容都保持在修订号7。

如今你有了一个咱们称为混合版本(mixed revision)的工做拷贝。其中一个文件修订号为8,其他的为7。只有在当你把全部文件都提交的时候版本号才会更新,或者你能够显式的运行‘svn update’。

   $ svn -v status
   7        7 nesscg       .
   8        8 nesscg       foo.c
   $

若是你运行‘svn log’命令可是没有传递任何参数,那么它会打印出当前目录下的日志信息(对应上面列表中的.)。既然目录版本号仍是停留在第7次修订,那么你固然看不到第8次修订的日志信息了。

若是你想要查看最新的日志,能够按照下面的方法来作。

  1. 运行‘svn log -rHEAD’。
  2. 运行‘svn log URL’,其中URL指向的就是版本库的路径。
  3. 运行‘svn log foo.c’直接获取以前修改的文件的日志信息。
  4. 将工做拷贝更新到第8次修订,而后在运行‘svn log’。

升级到Berkeley DB 4.3或更新的版本以后,版本库出错了。

在Berkeley DB 4.3以前,svnadmin recover可以适当的将Berkeley DB的版本库进行升级。可是Berkeley DB 4.3版本中的一个行为的改变致使了如今的升级过程失败。

使用下面的流程来置换升级你目前基于Berkeley DB 4.3及以后版本之上的版本库:

  • 确认没有其余进程在访问你的版本库(中止Apache、svnserve、svnlook和svnadmin,显示经过file://的访问,等等)。
  • 使用旧的svnadmin工具(即用来连接到老版本Berkeley DB上的):
    1. 修复版本库:‘svnadmin recover /path/to/repository
    2. 将当前版本库作一个备份。
    3. 删除全部未使用的日志文件,你能够经过运行‘svnadmin list-unused-dblogs /path/to/repeository’来查看。
    4. 删除共享内存的文件,它们应该位于版本库中的db子目录下,文件名形如__db.00*

如今版本库应该可以在Berkeley DB 4.3上正常使用了。

当我经过http://从MacOS X 10.4 (Tiger)的平台上检出版本库的时候,为何偶尔会获得一些不一致的错误?

注意,这里假设版本库是运行在Apache 2.0.x之上。

APR 0.9.6 有个bug,当运行在Tiger上的时候会存在,当你尝试检出一个大于64KB的文件时会出现这个错误。这会致使检出失败,一般给出的错误信息都是不可预料的。下面是可能会出现的提示信息,你看到的可能不大同样。

   svn: Invalid diff stream: [tgt] insn 1 starts beyond the target view position
   svn: Unexpected end of svndiff input
   svn: REPORT request failed on '/path/to/repository'
   svn: REPORT of '/path/to/repository/!svn/vcc/default': Chunk delimiter was invalid

一样,在Apache的error_log日志中也会记录相应的错误,如:

   [error] Provider encountered an error while streaming a REPORT response.  [500, #0]
   [error] A failure occurred while driving the update report editor [500, #190004]

为了确认这个bug是否存在—假设你能够访问版本库所在的机器—尝试使用File://的方式来检出,这样就能够绕过Apache直接经过文件系统来访问了。若是这样检出成功的话,那么问题就出在上面提到的bug上。

目前最好的解决方案就是升级到APR 1.2.0+。

或者你也能够从各自的源里从新编译Apache还有Subversion,在运行Apache配置前先设置好相应的环境变量。

   setenv ac_cv_func_poll no

或者以Bourne shell 的语法,以下:

   ac_cv_func_poll=no; export ac_cv_func_poll

若是你分别编译APR / APRUTIL(例如,你并不想使用Apache发行包中的某些部分),你必须在配置APR以前设置好环境变量,由于这就是问题所在。

我不能构建Subversion,个人工做拷贝源码在Debian GNU/Linux上,在连接阶段我获得了一些错误,哪里错了呢?

若是你在编译Subversion主线源代码的最后一步出现了下面的错误:

   /usr/local/apache2/lib/libaprutil-0.so.0: undefined reference to `db_create'
   /usr/local/apache2/lib/libaprutil-0.so.0: undefined reference to `db_strerror'

那极可能是因为你使用的是Debian系统,你须要升级你的‘libtool’。(我据说Debian的打包者不得不作了一些小的改动来修正一些错误。这可能会致使Subversion编译的时候出现问题。但这只是猜想,在写这个FAQ条目的时候我并无时间去验证一下细节的东西。你能够查看http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=112617 还有相关的帖子获得更详细的讨论。)

无论怎么样,若是你在2005年11月15号的时候在Debian GNU/Linux系统上面运行最新的testing发行版,而后遇到这个问题,那么解决方法就是,将libtool 1.5.20的源代码使用标准的“./configure && make && sudo make install”从新编译,再对工做拷贝执行了一次“make clean”的清理,而后运行“./autogen.sh”, “./configure”,“make”,最后一切都正常了。

注意,有一个相似的反馈也已经发布在 http://svn.haxx.se/dev/archive-2003-01/1125.shtml,可是在上面却没有提到这个解决方案。

我在使用FreeBSD,而且已经启动了svnserve,可是看起来并无监听3690端口。

一句话归纳:使用--listen-host=0.0.0.0参数调用svnserveShort。

再具体一点,FreeBSD的守护进程默认状况下只监听tcp6。上面这个选项用来启用tcp4的监听。

我不能添加一个目录,由于Subversion说“它已经处于版本控制了”。

那是由于你要添加的目录已经包含了.svn的目录了 — 它已是工做拷贝了 — 但那个目录是来自其余的版本库中而不是你当前正在访问的版本库。这种现象极可能就是由于你使用了操做系统的拷贝功能直接从另一个工做拷贝上复制(没有使用svn copy)该目录到当前工做拷贝中。

比较快可是有些不雅的解决方案就是删除你以前复制的文件夹下全部的.svn目录,而后add命令就能够顺利执行了。若是你使用的是Unix,你能够使用下面的命令:

  find dir -type d -name .svn -exec rm -rf {} \;

然而,若是工做拷贝来自同一个版本库,直接删除或移走工做拷贝,而后经过svn copy得到一个正确的拷贝也比较理想,能够节省版本库的空间。

若是来自不一样的版本库,你应当问本身为何要做这个拷贝;你应该确保经过添加目录,你不会在版本库中作出非预期的拷贝。

有时候经过svnserve访问一个非公开的版本库实在是太慢了。

当编译APR时使用/dev/random设备,服务器没有办法获取足够的内存量的时候这个问题常常会出现。若是服务器上只有Subversion在使用APR,那么你能够安全的从新编译APR,编译的时候带上参数 --with-devrandom=/dev/urandom 。固然,若是有其余进程在使用APR的时候,那么你就不能这样来作了,不然会形成其余服务不安全。

当执行的Subversion操做须要经过SSL传递大量数据的时候,碰到一个错误SSL negotiation failed: SSL error: decryption failed or bad record mac。

这个错误多是因为OpenSSL 0.9.8版本的问题。你能够下载早期不存在此问题的版本(或者可能的话,升级到更新的版本)。

我获得一个错误"This client is too old"。(客户端版本太旧)

若是你正在同时使用很老的(1.4之前的)Subversion命令行客户端还有Subclipse,而后你最近更新了Subclipse,接着你的命令行客户端提示你:
svn: This client is too old to work with working copy
'/path/to/your/working/copy'; please get a newer Subversion client
这是由于Subversion工做拷贝的格式发生了不兼容的改动—新版本的Subclipse对你的工做拷贝作了升级,因此你的命令行客户端程序,由于是版本比较老的,所以没法读取其内容。(这个问题并不仅是存在于Subclipse上,也有多是当你同时使用另一个1.4之后的新版本的时候,旧版本的程序也会出现相似的问题)你能够简单的把你的命令行客户端升级到1.4及以后的版本。 对于Subversion 1.5,提供了一个降级工做拷贝到较早版本的辅助脚本;见  这个FAQ。

为何有时候svn switch不能工做?

有时候,工做拷贝中包含了一些未被归入版本控制的文件,这个时候svn switch就会发生错误。switch的过程就会中止,这会致使工做拷贝一半被switch,另外一半却保持原样。

不幸的是,若是这个时候你采起的措施不正确的话,那么你的工做拷贝将会不能使用。有时候,svn会提示用户执行清理(svn cleanup)。但清理命令又有可能形成错误。参考:issue #2505

用户能够手动的删除那些形成问题的文件或目录,而后再执行清理命令,接着继续swich,这样即可以恢复。

注意,对从版本库中检出的原始副本进行switch一般不会发生错误。若是你正在开发过程当中须要使用到svn switch命令,那么有3种方式能够使用:

  1. 在进行路径切换以前,完整地清理一下你的工做拷贝中的未被归入版本控制的文件(包括那些被忽略的文件) 
    警告!这会删除全部未被版本控制的目录或文件,必定要肯定你即将删除的文件是你已经再也不须要了的。
    # Check and delete svn unversioned files: 
    svn status --no-ignore | grep '^[I?]' | sed 's/^[I?]//'
    svn status --no-ignore | grep '^[I?]' | sed 's/^[I?]//' | xargs rm -rf
  2. 保持最原始的干净的检出,更新到最新版本,而后复制到你原先但愿switch到某个分支的工做拷贝上。
  3. 这个方法比较危险 :不须要预先进行清理,直接在分支之间进行switch,但若是你遇到一个switch错误,你要知道你必须对此次switch进行适当的修复。删除错误提示中提到的未被版本控制的文件及目录,若是须要的话,使用svn cleanup,而后再继续进行切换工做,除非你删除了全部的未被版本控制的文件,不然你会重复好几回刚才遇到的错误。

在 issue 2505 中有更详细的例子。这个问题的产生是由于svn客户端为了保险起见,不会直接删除全部未被版本控制的文件。

下面还有两个更具体的例子描述了相似的问题。还有其余的svn switch错误在这里没有说起,你只有在从一个干净检出的工做拷贝中执行swich才能避免。

  1. 若是分支中的任何目录被移动或者更名,那么任何没有被版本控制的东西都会形成错误。在这种状况下,你会看到以下的错误:
    wc/$ svn switch $SVNROOT/$project/branches/$ticket-xxx
    svn: Won't delete locally modified directory '<dir>'
    svn: Left locally modified or unversioned files

    删除全部未被版本控制的文件,而后继续切换过程,这样能够恢复。

  2. 若是一个临时的编译文件(刚编译完)被加入版本库或者从版本库中删除了,那么从包含这个未被版本控制文件的版本库中检出就会失败你会看到和下面一摸同样的错误。
    wc/$ svn switch $SVNROOT/$project/branches/$ticket-xxx
    svn: Won't delete locally modified directory '<dir>'
    svn: Left locally modified or unversioned files

    在这种状况下,删除未被版本控制的文件并不能恢复,执行cleanup的时候会出错,可是svn switch会提示你去执行svn cleanup。

    wc/$ svn switch $SVNROOT/$project/branches/$ticket-xxx
    svn: Directory '<dir>/.svn' containing working copy admin area is missing
    wc/$ svn cleanup
    svn: '<dir>' is not a working copy directory
    wc/$ svn switch $SVNROOT/$project/branches/$ticket-xxx
    svn: Working copy '.' locked
    svn: run 'svn cleanup' to remove locks (type 'svn help cleanup' for details)

    删除目录(还有其余全部未被版本控制的文件,这样能够避免转换命令不会再重复出现相似的错误。而后继续转换的过程,这样能够恢复。

TortoiseSVN的cleanup错误有一点不一样,你可能会遇到下面的错误:

Subversion reported an error while doing a cleanup!
<dir>/<anotherdir> is not a working copy directory

在这里讲到的每个例子中,svn switch命令会失败,使到你的工做拷贝变成只有一半发生转换成功的,svn status会显示出全部发生转换的文件,用S标记出来(在根目录看到的状况可能有所不一样),用!标记出发生问题的目录,~标记出出错的问题文件(可能还有L用来标记锁定的文件),就像下面列举的同样:

wc/$ svn status 
!      .
!      <dir>
    S  <switched_things>
~      <dir>/<thing_that_is_now_unversioned>

在Windows平台上,经过命令行客户端的执行更新操做时,我碰到一个错误"The system cannot find the path specified",而且提示说个人工做拷贝可能损坏了,可是我能经过TortoiseSVN更新时彻底正常,这是怎么回事呢?

仔细研究了windows关于文件命名的API文档才发现形成这一问题的最多见缘由。简单的说,当你使用unicode版本的windows和路径相关的函数时,你能够指定的路径长度比较长,并且提供了绝对路径定位,而不是相对路径定位。幸运的是Subversion使用的Apache Portable Runtime(APR)库透明的对这种绝对路径(如C:\WorkingCopy\file.txt)进行了转换,将其转换成符合windows API要求的格式(\\?\C:\WorkingCopy\file.txt),这种转换也能够反向。不幸的是,你只有在使用绝对路径的时候才享用了这些长路径的好处。

要查看路径长度是否是形成你所遇到的问题,你能够在Subversion命令行客户端下使用绝对路径代替相对路径(或者根本不提供路径参数)。换句话说,若是你原先是这么作的:

C:\> svn up WorkingCopy

或者这样作的:

C:\> cd C:\WorkingCopy
C:\WorkingCopy> svn up

把它改为下面这样的方式

C:\> svn update C:\WorkingCopy

若是问题解决了,那么恭喜你——你已经成功突破了windows的路径长度限制,而且如今你已经知道怎么解决这个问题了。

为何这个问题不会影响TortoiseSVN呢? 由于TortoiseSVN对SubversionAPI提供的永远都是绝对路径。

那为何Subversion命令行客户端不是永远都把输入转换成绝对路径,而后使用绝对路径呢?Subversion的开发者在开发的时候基于一个原则,那就是出于对用户体验的考虑,在工具的输出中显示的路径必须匹配输入的路径的语法。若是输入的相对路径转换到绝对路径没有太多价值的话,那么这个转换出于复杂性考虑就去掉了。(换句话说,这是一个比较难的问题,但不是一个比较迫切的问题)。

我碰到一个错误"This client is too old to work with working copy '...' ",不升级Subversion可以解决吗?

有时候在次版本改动的发行包下,工做拷贝中的元信息格式也会发生不兼容的改变。例如,假设你使用Subversion1.4.4建立了一个工做拷贝,但有一天你升级到1.5.0版本。但后来你又想将其改为1.4.4,这个时候就出错了——提示信息就如你所描述的。

这是由于1.5.0将你的工做拷贝升级到能够支持新特性的格式(例如,修改列表,keep-local标志,variable-depth目录)尽管1.4.4并不知道任何这些特性,但它可以识别出来,工做拷贝里面使用的格式已经被升级到一个新的它不能支持的版本。

1.5.0升级工做拷贝是出于一个好的缘由,那就是它知道1.4.4如今并不了解工做拷贝的任何元信息,所以若是让1.4.4的版本去干扰工做拷贝中的元数据,那么重要的信息可能会丢失,颇有可能会形成破坏(例如你能够参考issue #2961)。

可是这种自动升级的行为在当你想要尝试一个新版本可是又不想永久安装时,挺让人讨厌的。出于这一点的考虑,咱们发布了一个脚本,用来安全的对工做拷贝进行版本降级。你能够在下面的地址下载到:

http://svn.collab.net/repos/svn/trunk/tools/client-side/change-svn-wc-format.py

使用--help参数调用此脚本,能够查看怎么脚本的运行帮助。将来Subversion新版本发布时,咱们会尽可能更新这个FAQ条目,使他覆盖到更多的降级的场景。

当我在64位Linux上编译Neon库时,发生一个错误"relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object"。

Neon库,是用来做为Subversion服务器和HTTP客户端进行通信的库,一般被编译成静态库。可是它后来被连接到不一样的动态连接库中,这会致使在AMD 64位操做系统系统上面编译的过程出现错误,出现相似下面的信息:

subversion-1.4.6/neon/src/.libs/libneon.a(ne_request.o): relocation R_X86_64_32
against `a local symbol' can not be used when making a shared object;
recompile with -fPIC
/home/jrandom/subversion/subversion-1.4.6/neon/src/.libs/libneon.a: could not
read symbols: Bad value

在开发者邮件列表中有一篇文章提到了这一点。

解决方法就是为Subversion的配置脚本提供一个“--enable-shared”的参数。

为何从Apache检出时获得“Could not read response body: Secure connection truncated”的错误?

简而言之,这个错误表明了一类问题,也就是Apache认为Subversion的客户端不会再处理它创建的网络链接。取决因而否使用SSL,或者Apache什么时候决定中断链接,相似情形也会报告一些其余的错误信息,

Subversion客户端保证工做拷贝永远处于正常状态,一个方法是会临时保存全部检出文件的全部原始版本,直到得到给定目录的全部文件和子目录。一旦目录的数据被下载,客户端会整理目录,并将将文件的原始版本复制回工做区域,做为管理数据等等。在这个目录整理过程当中,客户端会关注这些任务而不会去关心网络链接。有时候 —一般是版本化目录包含大量文件,或者很是大的文件—客户端会在整理目录(无论网络传输流)上花费大量时间,因此Apache会认为客户端已经永远离开了,所Apache关闭了网络传输流,而后客户端发现服务器放弃了链接,并报告了这样的错误。

一个办法是增长Apache一直等待客户端还在监听网络流的最长时间,你能够修改Apache的Timeout配置参数。你也应该注意一下你的数据集。若是你一个目录有大量的文件,就会更容易致使这个问题。若是你能将一组文件分配到一些目录中,将会对你们都有益。

开发者问题:

 

怎样在RAM磁盘上进行回归测试?

若是将Subversion的测试数据保存在RAM磁盘上,那么测试的过程将会变得很是快。在Linux系统上,你能够直接将RAM磁盘挂载:

mount -t tmpfs tmpfs /path/to/src/subversion/tests/cmdline/svn-test-work -o uid=$USER,mode=770,size=32m

或者,若是要更长期的挂载,能够将下面这一行添加到你的/etc/fstab文件中:

tmpfs /path/to/src/svn/subversion/tests/cmdline/svn-test-work tmpfs defaults,user,noauto,exec,size=32m

RAM磁盘空间至少为大约700MB。尽管如此,你仍是能够经过清理测试目标来大大下降空间需求(在上面的配置例子中咱们已经看到了)还有你的内存占用。清理意味着占用更多的IO资源,可是因为测试数据仍是存在于内存中的,所以不会形成任何性能的降低。

make check CLEANUP=true

参考 http://svn.haxx.se/dev/archive-2003-02/0068.shtml 能够看到更多关于RAM磁盘使用的权威讨论。

怎样在不安装的状况下对动态Subversion库运行调试器?

在往unix-y系统上运行make install这一步以前,动态编译Subversion源代码实际上执行的是libtool-generated脚本,这个脚本会从新连接而且运行真正的二进制文件,就以下面显示的同样,这会让调试更加复杂:

subversion$ gdb subversion/svn/svn
... "/path/to/subversion/subversion/svn/svn": not in executable format: File format not recognized

若是编译的时候使用--disable-shared参数来配置使用静态连接到二进制库,或者从新安装而后将调试器指向新安装的版本,这样可能能解决一部分问题,可是常常咱们须要在源代码中临时直接的进行调试。

要作到这一点,在shell脚本中编辑上一次执行的语句,而后在你的调试器中运行真正的二进制库。在gdb中,就是将exec "$progdir/$progname"替换exec gdb --args "$progdir/$progname"

这个小技巧在使用libtool-generated的shell脚本进行白盒测试的时候中很是有用。

怎样在让编译器不内联混淆(inlining obfuscating)源代码的状况下对Subversion库运行调试器?

默认状况下,gcc会常常优化那些私有变量及函数,还有相关的操做。这样会形成调试的时候跟进一段代码变得更复杂。

unix-y systems上的解决办法就是在make这一步的时候将这个优化过程关闭。

subversion$ make EXTRA_CFLAGS=-O0

(那是一个横杠加两个字母的O)。你也能够经过运行下面的配置使到此配置应用到之后全部的调试过程当中:

subversion$ ./configure --enable-debug

对于产品的安装来讲,要记住在从源码安装Subversion时撤销这个操做,你能够经过从新运行make或者configure并不附加任何参数来撤销上面的修改操做。

参考:

 

Subversion用到的HTTP方法是有哪些?

Subversion 客户端使用WebDAV/DeltaV 协议的一个子集来做为 mod_dav_svn server 模块的一部分。简而言之:

     OPTIONS, PROPFIND, GET, REPORT,
     MKACTIVITY, PROPPATCH, PUT, CHECKOUT, MKCOL,
     MOVE, COPY, DELETE, LOCK, UNLOCK, MERGE

关于协议的细节问题能够在下面这个连接找到相应的文档:

http://svn.collab.net/repos/svn/trunk/notes/webdav-protocol

什么是'bikeshed'?

参阅 Poul-Henning Kamp的关于freebsd-hackers的帖子:http://www.freebsd.org/doc/en_US.ISO8859-1/books/faq/misc.html#BIKESHED-PAINTING.

你是怎样读"Subversion"的?

Jim Blandy设计了Subversion的名字和版本库的设计,把“Subversion”读做 “Subversion”。

什么是'baton'?

在Subversion的源代码中有不少引用指向‘baton’对象。他们只是一些对象。有不少void *的数据结构做为某个函数的上下文。在另一些API里,他们一般经过void *ctx或者void *userdata来调用的,就像Subversion的开发者经过“batons”数据结构来调用同样,可是更省资源。

当你说版本库是'楔住(wedged)'的时候,是什么意思?

被楔住版本库:

一个Subversion版本库由两个不一样的内部组件组成,一个是工做区,一个是存储区。一个楔住的版本库指的是出于未知的缘由,版本库的工做区不能访问了,可是存储区是完整的。所以,一个楔住的版本库并不会丢失任何数据,可是在你正常访问版本库以前工做区必须修复好。参阅this条目查看具体怎么去修复。

被破坏了的版本库:

一个被破坏了的版本库指的是存储区已经被破坏了,所以版本库中的数据可能多多少少会有丢失。

你可能须要查看Jargon File关于‘wedged’的定义。

相关文章
相关标签/搜索