使用开源工具SVNKit编写程序管理Subversion

转载自:


http://www.loggingselenium.com/2013/09/使用开源工具svnkit编写程序管理subversion.html

 
Subversion和SVNKit介绍

 

做为软件研发人员,几乎无人不晓Subversion(简称为SVN)。Subversion是一个追踪文件和目录变更记录的开源版本控制系统,纳入版本控制的文件和目录以树状结构存在于Subversion资源库里,和普通文件系统类似,它们有自己的属性元数据。在一个原子操作中,对该树结构的变更被客户端提交到版本资源库,每次执行提交操作均会创建一个新的资源库树结构的快照,包含最新提交的数据和未发生变化的数据,这样的快照被称为一个修订版本(Revision)。Subversion从修订版本0开始,那时候只有根目录存在,随着文件和目录被导入到资源库,提交变更数据或其他针对资源库的变更操作都会产生新的修订版本,资源库每次变更都会把修订版号增加1。Subversion实际上并不是在每次修订中都保存树结构的完整内容,而是利用智能机制只存储与上一修订版本的差异部分。我们可以从Subversion资源库中获取任一修订版本的文件或目录,甚至整个资源库,因为单一的修订版本针对整个资源库。每个修订版本是个版本资源库(Repository)树结构的持久快照,被纳入管理的文件不能完全删除,总可以在增加和修改它的修订版本中重新获取该文件。常见的一个使用subversion的场景是,从资源库中检出一个副本(Copy)到本地工作环境,在本地环境上对检出的文件或目录进行修改操作,并将修改后的工作成果提交到资源库。本地的纳入版本控制的数据被称为工作副本(Working Copy)。Subversion作为领先的开源版本控制系统已流行十几年,网络上有丰富的学习资料,developerWorks上也有很多优秀的文章和教程供参考。本文主要介绍SVNKit,那么SVNKit是什么呢?

 

SVNKit是访问Subversion版本控制系统的编程解决方案,纯Java语言编写而成,实现了操作Subversion的全部功能特性,并且兼容Subversion的最新版本。通过调用SVNKit对外提供的API编程接口,可以在应用程序中操作被Subversion版本控制系统管理的数据。它可以作为集成工具以标准方式来操作工作副本中版本化的数据,还可以作为引擎在资源库访问协议层直接操作版本资源库。SVNKit不需要额外的类库文件,非常轻便,不依赖于操作系统平台。作为开源软件,可以在遵循开源许可协议的条件下,免费使用。

 

SVNKit支持的主要功能特性如下:

l  支持通过http(s),svn,svn(+ssh) 和 file文件协议访问SVN资源库;

l  支持本地工作副本的全部操作;

l  支持如下资源库管理操作:create,load,dump 和 replay;

l  除了SVNKit自身API,它还实现了JavaHL API;

l  SVNKit支持Windows,OSX,Linux,BSD 和 OpenVMS等操作系统;

l  SVNKit不需要本地库,开箱即用;

l  默认支持Subversion自带的配置文件;

l  SVNKit还提供由Java实现的Subversion命令行客户端工具;

l  最新版本SVNKit支持Subversion 1.7.4。

 

SVNKit在架构上主要由如下四部分组成:

l  顶层(High Level)API

顶层API的作用类似于Subversion自带的命令行客户端,用来实现工作副本支持的各种操作。

管理工作副本的操作都在逻辑上归类到不同的SVN*Client类里,通过使用SVNKit顶层API中的SVNClientManager类,开发者可以调用不同的SVN*Client类以编程方式的访问和操作Subversion工作副本。SVNKit 顶层API支持很多操作,例如检出、更新、提交、查看历史、比对差异、浏览资源库等。比如,对工作副本的更新操作(检出、更新、转换等)都可以通过调用SVNUpdateClient类的方法来实现,那些方法的参数类似于Subversion命令行客户端的参数选项。顶层API提供的用来管理工作副本的接口非常容易使用,并支持定制。当需要访问资源库时,顶层API会调用底层API的接口。后文会通过详细的例子进一步描述如何使用顶层API操作管理Subversion的工作副本。

l  底层(Low Level)API

底层API的作用类似于Subversion版本资源库的协议访问层,底层API实现了各种与版本资源库通讯的协议,并负责使用各种协议与版本资源库进行通讯,对外封装了连接细节。底层API提供的SVNRepository 类可以用来模拟Subversion资源库,开发者可以用它直接连接和操作版本资源库,但不能用来管理工作副本。后文会通过详细的例子进一步描述如何使用底层API操作管理Subversion版本资源库。

l  JavaHL API

SVNKit JavaHL API的接口类SVNClientInterface可以用来访问Subversion自带的JNI绑定。

SVNClientInterface的实现类为SVNClientImpl,开发者可以在运行时在JavaHL和SVNKit之间进行自由切换或直接使用SVNKit Jar文件替换标准的JavaHL Jar文件和其他二进制文件。

l  命令行客户端Command Line Client

SVNKit还提供了一套由Java语言实现的命令行客户端工具,支持全部的SVN客户端工具的功能特性。在没有安装SVN客户端的环境上,可以使用该命令行客户端工具来完成相应的工作。

 

通过上面对SVN和SVNKit的了解,我们来进一步研究如何建立SVNKit开发环境来使用SVNKit编写程序操作管理SVN。

 

建立SVNKit开发环境

首先,访问SVNKit官方站点下载SVNKit的最新二进制文件。目前,SVNKit的最新稳定版本为SVNKit 1.7.9,兼容于Subversion 1.7的工作副本和版本资源库。该版本的单机版本下载地址为:http://www.svnkit.com/org.tmatesoft.svn_1.7.9.standalone.zip。

 

把下载得到的ZIP文件解压,目录结构如清单1所示:

清单1.软件包目录结构
+---bin
 
+---conf
 
+---lib
 
+---licenses
 
\---src
 
\---svnkit-1.7.9-sources
 

其中,bin文件夹下是SVNKit提供的命令行客户端工具,支持Windows和Linux系统。以Windows系统下的工具为例,有以下几种主要工具jsvn.bat、jsvnadmin.bat、jsvndumpfilter.bat、jsvnlook.bat、jsvnsync.bat、jsvnversion.bat,和Subversion命令行客户端工具非常类似。Lib文件夹是SVNKit的Jar文件。conf文件夹下是日志属性配置文件,src文件夹是源代码文件等。

下载完毕,接着在Eclipse开发环境,创建新的Java项目。导入SVNKit lib文件夹下的Jar文件到构建路径,完成开发环境的准备工作,即可使用SVNKit开发程序来管理Subversion。

创建和访问Subversion资源库

Subversion资源库存储支持Berkley DB 数据库和普通文件系统,通常情况下,使用默认的普通文件系统即可。SVNKit自带的命令行工具可以用来手工创建版本资源库,方法很简单,在SVNKit分发包bin目录下可以找到名为jsvnadmin的工具,就可以用来手工创建资源库。使用清单2的命令创建一个资源库,创建的资源库在后文会使用到:

清单2.版本资源库
...> jsvnadmin.bat create C:\SVN_demo1
 

执行上述命令,会在你指定的目录下创建一个FSFS文件系统类型的资源库。SVNKit不支持Berkley DB类型的资源库的建立,如果需要建立该类型的资源库,不得不安装Subversion工具。清单3的命令通过指定资源库类型,来创建bdb类型资源库:

清单3.创建Berkley DB类型的版本资源库
...>svnadmin create --fs-type bdb C:\SVN_demo2
 

除了上述使用命令行创建版本资源库,还可以编写SVNKit程序代码来创建版本资源库。使用SVNKit编程,和命令行工具一样,只能创建FSFS类型的Subversion资源库,下面的代码演示如何创建一个版本资源库。

清单4.使用SVNRepositoryFactory方法创建资源库
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
 
import org.tmatesoft.svn.core.SVNURL;
 
import org.tmatesoft.svn.core.SVNException;
 
...
 
try {
 
String tgtPath = " C:\\SVN_demo3";
 
SVNURL tgtURL = SVNRepositoryFactory.createLocalRepository( new File( tgtPath ), true , false );
 
} catch ( SVNException e ) {
 
//处理异常
 
}
 

执行上述代码可以在C:\SVN_demo3目录下面创建一个FSFS类型的SVN版本资源库。第二个参数设置为true,允许修改创建的版本资源库的修订版本属性信息。如果修订版本属性没有纳入版本管理,可能会丢失修订版本属性信息。允许修改修订版本属性,创建资源库的时候,会自动在hooks目录下增加一个批处理文件pre-revprop-change.bat。如果第二个参数为false,则不自动创建该hook文件。如果有人想修改修改版本属性,SVN服务器会先调用pre-revprop-change.bat。如果该文件不存在,或者返回非零值,SVN服务器则不允许修改修订版本属性。在使用Subversion的svnadmin工具手工创建资源库时,资源库的hooks目录中只有模板,不包括hook文件。除非在hooks目录手工创建一个pre-revprop-change文件,否则不能修改修订版本的属性信息。第三个参数用来表示是否重写已经存在的资源库。如果设置为true,若指定的目录下存在SVN资源库,SSVNKit会覆盖重写现有的资源库,如果为false,保留存在的资源库,抛出指定路径已经存在资源库的SVNException。

 

若上述代码执行成功,会返回资源库的路径,如file:///C:/SVN_demo3。除了上述创建资源库的编程方法,还可以使用SVNKit顶层API的SVNAdminClient类来创建资源库,该类实际上也在后台调用上述SVNRepositoryFactory类的方法完成资源库的创建工作,如清单5所示:

清单5.使用SVNAdminClient的方法创建资源库
import org.tmatesoft.svn.core.wc.admin.SVNAdminClient;
 
import org.tmatesoft.svn.core.SVNURL;
 
import org.tmatesoft.svn.core.SVNException;
 
...
 
SVNAdminClient adminClient;
 
...
 
try {
 
String tgtPath = "C:/repos/root/path";
 
SVNURL tgtURL = adminClient.doCreateRepository( new File( tgtPath ),null , true ,false );
 
} catch ( SVNException e ) {
 
//处理异常
 
}
 

创建完毕资源库,下面来看一下访问资源库的方式。目前主要有两种方式访问Subversion资源库:通过网络远程访问和本地访问。SVNKit支持Subversion的资源库访问模式,如下表所示:

表1.Subversion资源库访问模式
协议	描述
file:///	直接访问本地磁盘上的资源库
http://	通过WebDAV 协议访问部署在apache服务器上的subversion资源库
https://	等同http://,传输经过 SSL 加密
svn://	通过定制协议访问svnserve服务
svn+ssh://	等同svn://,传输经过 SSL 加密
 

下面对各个协议进行简单介绍:

file:/// 访问方式
因为资源库在同一机器上,该协议下不需要设置账户信息来访问资源库。

svn://和svn+ssh:// 访问方式
为了使用svn:// 协议,管理员需配置账户和访问权限规则,svnserve程序用来认证访问用户。客户端ssh认证到Subversion 服务器,建立隧道式链接,然后像操作本地资源库一样操作远程资源库。

http://和 https:// 访问方式
为了使用http:// 协议,管理员配置使用WebDAV 协议扩展的Apache服务器。

 

在后文演示时,以svn://协议为例,需要预先使用svnserve启动Subversion服务。在配置相关的用户和权限后,使用命令svnserve.exe -d -r C:\SVN_demo1进行启动:

 

在完成创建版本资源库,并且启动完成后,我们继续研究如何使用SVNKit的顶层API和底层API编程管理Subversion版本资源库,所使用的示例资源库为上文所创建的C:\SVN_demo1。

使用SVNKit顶层 API管理工作副本

在本部分,继续研究如何使用SVNKit顶层API管理工作副本。通过上文,可以了解到所有工作副本的操作都在逻辑上组织在不同的SVN*Client类中,每一个SVN*Client类的方法都类似于Subversion命令行。通过SVNClientManager类可以获取SVN*Client类的实例,从而简化创建和维护SVN*Client实例的工作。以本部分用到的SVNUpdateClient、SVNWCClient和SVNCommitClient为例进行更深入的讲解,更多的SVN*Client的用法可以参考Javadoc文档。

 

SVNUpdateClient类对外提供的方法可以用来检出,更新,切换、重新定位工作副本,也可以从版本资源库中导出目录或文件。提供的方法及其对应的Subversion客户端命令主要有:

l  doCheckOut(…) 从版本资源库检出工作副本,对应“svn checkout”;

l  doUpdate(…)  把工作副本更新为最新版本或某个指定版本,对应“svn update”;

l  doSwitch(…)  更新工作副本至同一资源库中的不同 URL,对应“svn switch”;

l  doExport(..) 从版本资源库库中导出目无版本控制的工作副本,对应“svn export”;

l  doRelocate(…) 重新定位工作副本,指向不同的资源库根 URL,对应“svn relocate”。

 

SVNWCClient类主要提供和本地工作副本相关的操作方法,同时也提供一些需要访问版本资源库的方法。提供的方法及其对应的Subversion客户端命令主要有:

l  doAdd(…)  把文件和目录纳入版本控制,会在下一次提交时生效,对应“svn add”;

l  doDelete(…)   从工作副本中删除一个文件或目录,对应“svn delete”;

l  doCleanup(…)  清理工作副本,删除锁,继续未完成操作等,对应“svn cleanup”;

l  doInfo(…)   显示一个工作副本条目的信息,对应“svn info”;

l  doLock(…)  锁定资源库中的路径,使其他用户不能向其提交修改,对应“svn lock”;

l  doUnlock(…)  解除工作副本或URL的锁定,对应“svn unlock”。

 

SVNCommitClient类提供把变更提交到版本资源库上的一些相关操作。提供的方法及其对应的Subversion客户端命令主要有:

l  doCommit(…) 把工作副本的修改提交到资源库,对应“svn commit”;

l  doImport(…) 将未纳入版本控制的文件或目录树提交到资源库,对应“svn import”;

l  doDelete(…) 从资源库中删除文件和目录,对应“svn delete URL;

l  doMkDir(…) 创建纳入版本控制的新目录,对应“svn mkdir URL”。

 

接下来,就以实际工作应用中的一个例子来演示如何使用SVNKit管理工作副本。涉及到的操作包含:先从版本资源库检出一个工作副本,接着对其中的一个文本文件进行修改,最后利用提交操作把变更文件提交到版本资源库。如果不存在所述文本文件,则自动创建一个文件并纳入版本控制。 首先,初始化SVNClientManager对象,使用Subversion默认的配置选项,提供的用户名称和密码用于验证是否具有访问资源库的权限,如清单6所示:

清单6.初始化SVNClientManager对象
SVNClientManager ourClientManager=null;
 
DefaultSVNOptions options = SVNWCUtil.createDefaultOptions(true);
 
ourClientManager = SVNClientManager.newInstance(options, username,
 
password);
 

接着,通过对象ourClientManager,可以进一步获取SVNUpdateClient实例,完成对特定资源库URL的检出操作,如清单7所示,对方法的参数详细解释可以进一步参考Javadoc。

清单7.检出代码
System.out.println("正在从如下资源库地址检出工作副本:'" + repositoryURL + "'...");
 
String workCopyDir = System.getProperty("user.dir")       + File.separator + "WorkCopyDir";
 
File workCopy = new File(workCopyDir);
 
try {
 
SVNUpdateClient updateClient = urClientManager.getUpdateClient();
 
updateClient.setIgnoreExternals(false);
 
long revision = updateClient
 
.doCheckout(repositoryURL,workCopy, SVNRevision.HEAD, SVNRevision.HEAD,     SVNDepth.INFINITY, true);
 
logger.debug("检查的工作副本的修订版本号为" + revision);
 
} catch (SVNException svne) {
 
logger.error("从如下资源库地址检出工作副本时发生错误:'" +
 
repositoryURL + "'" + "\n"+ svne.getMessage(), svne);
 
}
 

然后,对检出的文件做些变更。如果检出的目录下不包括Demos.txt文件,则创建并把它纳入版本管理。对该文件的变更为新增一行,简单增加些内容如:“修改于*具体日期时间*”,代码见清单8:

清单8.对检出文件进行变更
String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
 
.format(new Date());
 
File localFile = new File(workCopy.getAbsolutePath()
 
+ File.separator + "Demos.txt");
 
String content = "\n  修改于" + now;
 
try {
 
if (!localFile.exists()) {
 
localFile.createNewFile();
 
// 把文件纳入版本管理
 
ourClientManager.getWCClient().doAdd(localFile, false,
 
false, false, SVNDepth.INFINITY, false, false);
 
}
 
RandomAccessFile randomFile = new RandomAccessFile(localFile,"rw");
 
randomFile.seek(randomFile.length());
 
randomFile.write(content.getBytes("UTF-8"));
 
randomFile.close();
 
} catch (Throwable t) {
 
logger.error(t.getMessage(), t);
 
}
 

最后,提交变更内容到版本资源库,保持工作副本与版本资源库的一致,见清单9。

清单9.执行提交操作
try {
 
String commitMessage = "提交内容为:" + content;
 
ourClientManager.getCommitClient().doCommit(
 
new File[] { workCopy }, false, commitMessage, null, null,
 
false, true, SVNDepth.INFINITY);
 
} catch (SVNException e) {
 
logger.error(e.getMessage(), e);
 
}
上文研究了如何利用SVNKit顶层API管理工作副本,在下一小节我们进一步研究如何使用SVNKit的底层API直接管理版本资源库。

使用SVNKit底层API直接管理版本资源库

已经了解底层API提供的SVNRepository 类可以用来模拟Subversion资源库,SVNRepository包含所有需要访问版本资源库的底层操作。顶层API操作需要访问版本资源库时,也会调用底层API来实现。在使用底层API之前,需要先做些连接协议设置,如清单10:

清单10.设置访问协议
//支持http:// 和 https://
 
DAVRepositoryFactory.setup();
 
//支持svn://和svn+ssh://
 
SVNRepositoryFactoryImpl.setup();
 
//支持file:///
 
FSRepositoryFactory.setup();
在完成设置之后,下面就来演示一下如何创建SVNRepository实例,并用该实例来直接管理版本资源库。在创建实例时,使用ISVNAuthenticationManager对访问用户进行验证,如清单11所示:

清单11.创建SVNRepository实例并对用户进行验证
String url="svn://127.0.0.1/demo1";
 
String name="ken";
 
String password="ken";
 
repository = null;
 
try {
 
repository = SVNRepositoryFactory.create(SVNURL.parseURIDecoded(url));
 
ISVNAuthenticationManager authManager =
 
SVNWCUtil.createDefaultAuthenticationManager(name, password);
 
repository.setAuthenticationManager(authManager);
 
...
 
} catch (SVNException e){
 
e.printStackTrace();
 
System.exit(1);
 
}
 
//进一步使用该实例管理版本资源库
 
...
 

下面就利用创建的SVNReposity实例来详细学习一下常用的方法,可以使用实例的getLatestRevision()方法来获取资源库的最新修订版本,如下面代码清单所示:

 

清单12.获取资源库的最新修订版本号
long latestRevision = -1;
 
try {
 
latestRevision = repository.getLatestRevision();
 
} catch (SVNException svne) {
 
System.err.println("获取资源库最新修订版本号时出现错误: " + svne.getMessage());
 
}
 

System.out.println(“Repository latest revision: ” + latestRevision);

 

可以使用SVNNodeKind checkPath(String path, long revision)来检验资源库管理的条目的类别,需要指定条目的路径和修订版本号作为参数输入,路径可以使用相对路径和绝对路径。如果是指定条目的路径在资源库中不存在,则返回SVNNodeKind.NONE;如果是文件或目录则分别返回SVNNodeKind.FILE和SVNNodeKind.DIR。代码如下所示:

清单13.校验路径
SVNNodeKind nodeKind = repository.checkPath(filePath,
 
SVNRevision.HEAD.getNumber());
 
if (nodeKind == SVNNodeKind.NONE) {
 
System.err.println("在指定的资源库位置不存在文件或目录条目,URL='" + url + "'.");
 
} else if (nodeKind == SVNNodeKind.FILE) {
 
System.out.println("在指定的资源库位置存在文件条目,URL='" + url + "'.");
 
} else if (nodeKind == SVNNodeKind.DIR) {
 
System.out.println("在指定的资源库位置存在目录条目,URL='" + url + "'.");
 
}
 

下面进一步来研究如何读取资源库中特定修订版本的文件的内容信息。在使用SVNNodeKind checkPath(String path, long revision)方法确保url对应的条目为文件后,先将该文件的内容读取到OutputStream对象,并收集它的属性信息到SVNProperties对象,接着使用循环将文件的属性依次输出到控制台。最后,通过利用文件的MIME类型属性判断文件是文本文件还是二进制文件,如果是文本文件,则将文件内容输出到控制台;如果是二进制文件,则不在控制台输出它的文件内容。详细代码见清单14:

清单14.获取资源库的文件属性及文件内容
try {
 
SVNProperties fileProperties = new SVNProperties();
 
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
 
repository.getFile(filePath, -1, fileProperties, outputStream);
 
// 打印文件属性信息
 
System.out.println("文件路径为:"+url);
 
System.out.println("文件属性信息为:");
 
for (Entry entry : (Set<Entry>) fileProperties.asMap().entrySet()) {
 
String propertyName = (String) entry.getKey();
 
String propertyValue = entry.getValue().toString();
 
System.out.println("文件属性 " + propertyName + " = "
 
+ propertyValue);
 
}
 
 
//获取文件的MIME类型
 
String mimeType = fileProperties
 
.getStringValue(SVNProperty.MIME_TYPE);
 
boolean isTextType = SVNProperty.isTextMimeType(mimeType);
 
 
 
//如果是文本文件则输出文本内容到控制台,否则不需要输出文件内容!
 
if (isTextType) {
 
System.out.println("文件内容为:");
 
try {
 
outputStream.writeTo(System.out);
 
} catch (IOException ioe) {
 
ioe.printStackTrace();
 
}
 
} else {
 
System.out.println("非文本文件类型,不能输出内容到控制台");
 
}
 
 
 
} catch (SVNException svne) {
 
System.err.println("获取文件属性信息及文件内容时发生错误: "
 
+ svne.getMessage());
 
}
 

运行程序,在控制台的输出类似如下:

清单15.控制台输出样例
在指定的资源库位置存在文件条目,URL='svn://127.0.0.1/demo1'.
 
文件路径为:svn://127.0.0.1/demo1
 
文件属性信息为:
 
文件属性 svn:entry:uuid = bf4c7da2-3f01-0010-b859-afe0b840d188
 
文件属性 svn:entry:revision = 87
 
文件属性 svn:entry:committed-date = 2013-07-29T08:31:30.527241Z
 
文件属性 svn:entry:checksum = 9d1d517438d913377ef3b9d5c700df44
 
文件属性 svn:entry:last-author = ken
 
文件属性 svn:entry:committed-rev = 86
 
文件内容为:
 
修改于2013-08-10 16:31:30
 

最后,再看一个使用底层API获取资源库历史记录的方法public Collection log(String[] targetPaths, Collection entries, long startRevision, long endRevision, boolean changedPath, boolean strictNode) throws SVNException。字符串数组指定要收集历史记录的路径,如果集合对象entries不为null,则把收集的历史记录保存在entries实例内。startRevision 和endRevision对起止修订版本号进行限定。布尔变量changedPath为true时,收集的历史记录里包括受影响的文件及目录信息,受影响的文件及目录信息可以使用SVNLogEntry.getChangedPaths()方法进行获取。布尔变量strictNode为true时,返回的历史记录包括复制操作的记录信息。

 

对指定路径和修订版本的历史记录进行遍历,返回一个包含历史记录信息SVNLogEntry对象信息的集合Collection<SVNLogEntry>。SVNLogEntry对象信息包括修订版本号、提交者、提交日期、注释信息和受影响的文件目录信息等等,如清单16所示,遍历相关信息并输出到控制台:

清单16.获取资源库的历史记录
long startRevision = 0;
 
long endRevision = -1;//最新修订版本
 
。。。
 
Collection<SVNLogEntry> logEntries = new LinkedList<SVNLogEntry>();
 
try {
 
repository.log(new String[] { "/" }, logEntries, startRevision,
 
endRevision, true, true);
 
 
 
} catch (SVNException svne) {
 
System.out.println("获取如下地址的资源库历史记录时出错:url= '"
 
+ url + "': " + svne.getMessage());
 
System.exit(1);
 
}
 
for (SVNLogEntry logEntry : logEntries) {
 
System.out.println("---------------------------------------------");
 
// 获取修改版本号
 
System.out.println("修订版本号: " + logEntry.getRevision());
 
// 获取提交者
 
System.out.println("提交者: " + logEntry.getAuthor());
 
// 获取提交时间
 
System.out.println("日期: " + logEntry.getDate());
 
// 获取注释信息
 
System.out.println("注释信息: " + logEntry.getMessage());
 
if (logEntry.getChangedPaths().size() > 0) {
 
System.out.println();
 
System.out.println("受影响的文件、目录:");
 
for (Entry<String, SVNLogEntryPath> entry : logEntry
 
.getChangedPaths().entrySet()) {
 
System.out.println(entry.getValue());
 
}
 
}
 
}
结束语

通过本文,可以了解到如何使用SVNKit编写程序代码来管理版本资源库Subversion,包括如何使用SVNKit顶层API管理Subversion工作副本和如何使用底层API直接管理版本资源库等,从而可以更自由的管理版本资源库。
除非注明,文章均为LoggingSelenium网站
原创,欢迎转载!转载请注明本文地址,谢谢。本文地址:http://loggingselenium.com/?p=483
.非常感谢!


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值