java操作svn【svnkit】实操
SVNKit中怎样使用不同的仓库访问协议?
当你下载了最新版的SVNKit二进制文件并且准备使用它时,一个问题出现了,要创建一个库需要做哪些初始化的步骤?直接与Subversion仓库交互已经在低级层API中实现,主要的仓库访问驱动的接口就是SVNRepository抽象类。这个驱动实现了一些协议,一个协议一个实现。每个驱动由一个抽象工厂类-SVNRepositoryFactory 创建,抽象工厂类也有每一种协议的实现。下面的表格将一种协议和工厂类的实现类一一对应:
svn://(svns://) |
SVNRepositoryFactoryImpl |
http://(https://) |
DAVRepositoryFactory |
file:/// |
FSRepositoryFactory |
SVNKit初始化的操作
在使用SVNKit库前,你必须为某一特定的协议创建一个合适的SVNRepositryFactory对象。例如,如果你想使用 svn:// 协议来和仓库交互,你必须注册一下SVNRepositoryFactoryImpl工厂:
- try {
- SVNRepositoryFactoryImpl.setup();
- ...
- } catch (SVNException e) {
- //handle exception
- }
这一步之后,由于SVNKit包含了注册的工厂对象,SVNRepositoryFactory知道了怎样给svn:// 协议创建SVNRepository驱动。接下来你就可以为它创建一个驱动了:
- try {
- ...
- SVNURL url = SVNURL.parseURIDecoded( "svn://host/path_to_repository_root/inner_path" );
- SVNRepository repository = SVNRepositoryFactory.create( url, null );
- ...
- } catch ( SVNException e ) {
- //handle exception
- }
在SVNKit中,所有的仓库url由SVNURL类来表示,如果一个路径字符串不是UTF-8编码的,可以使用SVNURL的parseURIDecoded()方法来创建一个新的url(如果需要编码,它会重新编码)。然后你可以通过这个url来在SVNRepositoryFactory中创建一个新的SVNRepository驱动。这样,你可以绑定驱动到任何一个你想访问的仓库地址。
使用高级层API
当你使用SVNKit管理工作拷贝时,由于高级层API使用低级层API来与仓库交互,你也需要创建合适的工厂类,如果你遗漏了这一初始化步骤,可能会抛出一个SVNKit不能给提供的url创建SVNRepository对象的异常。
当然就想我们使用其他svn客户端或者是svn插件一样。我们对Repository进行操作的时候是需要身份验证的,使用SVNKit也是一样。我们需要提供身份信息:
- <span style="white-space:pre"> </span>/*
- * 对版本库设置认证信息。
- */
- ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(name, password);
- repository.setAuthenticationManager(authManager);
实现DisplayFile:
- <span style="font-size:18px;">import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import org.tmatesoft.svn.core.SVNException;
- import org.tmatesoft.svn.core.SVNLogEntry;
- import org.tmatesoft.svn.core.SVNNodeKind;
- import org.tmatesoft.svn.core.SVNProperties;
- import org.tmatesoft.svn.core.SVNProperty;
- import org.tmatesoft.svn.core.SVNURL;
- import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
- import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
- import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
- import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
- import org.tmatesoft.svn.core.io.SVNRepository;
- import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
- import org.tmatesoft.svn.core.wc.SVNWCUtil;
- public class DisplayFile {
- /**
- * @param args
- */
- public static void main(String[] args) {
- //初始化库。 必须先执行此操作。具体操作封装在setupLibrary方法中。
- setupLibrary();
- /*
- * 相关变量赋值
- */
- String url = "https://hy/svn/svnkittest/branches";
- String name = "hanyi";
- String password = "hanyi";
- String filePath = "doImport.txt";
- //定义svn版本库的URL。
- SVNURL repositoryURL = null;
- //定义版本库。
- SVNRepository repository = null;
- try {
- //获取SVN的URL。
- repositoryURL=SVNURL.parseURIEncoded(url);
- //根据URL实例化SVN版本库。
- repository = SVNRepositoryFactory.create(repositoryURL);
- } catch (SVNException svne) {
- /*
- * 打印版本库实例创建失败的异常。
- */
- System.err
- .println("创建版本库实例时失败,版本库的URL是 '"
- + url + "': " + svne.getMessage());
- System.exit(1);
- }
- /*
- * 对版本库设置认证信息。
- */
- ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(name, password);
- repository.setAuthenticationManager(authManager);
- //此变量用来存放要查看的文件的属性名/属性值列表。
- SVNProperties fileProperties = new SVNProperties();
- //此输出流用来存放要查看的文件的内容。
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
- //获得版本库中文件的类型状态(是否存在、是目录还是文件),参数-1表示是版本库中的最新版本。
- SVNNodeKind nodeKind = repository.checkPath(filePath, -1);
- if (nodeKind == SVNNodeKind.NONE) {
- System.err.println("要查看的文件在 '" + url + "'中不存在.");
- System.exit(1);
- } else if (nodeKind == SVNNodeKind.DIR) {
- System.err.println("要查看对应版本的条目在 '" + url
- + "'中是一个目录.");
- System.exit(1);
- }
- //获取要查看文件的内容和属性,结果保存在baos和fileProperties变量中。
- repository.getFile(filePath, -1, fileProperties, baos);
- } catch (SVNException svne) {
- System.err.println("在获取文件内容和属性时发生错误: " + svne.getMessage());
- System.exit(1);
- }
- //获取文件的mime-type
- String mimeType = fileProperties.getStringValue(SVNProperty.MIME_TYPE);
- //判断此文件是否是文本文件
- boolean isTextType = SVNProperty.isTextMimeType(mimeType);
- /*
- * 显示文件的所有属性
- */
- Iterator iterator = fileProperties.nameSet().iterator();
- while (iterator.hasNext()) {
- String propertyName = (String) iterator.next();
- String propertyValue = fileProperties.getStringValue(propertyName);
- System.out.println("文件的属性: " + propertyName + "="
- + propertyValue);
- }
- /*
- * 如果文件是文本类型,则把文件的内容显示到控制台。
- */
- if (isTextType) {
- System.out.println("File contents:");
- System.out.println();
- try {
- baos.writeTo(System.out);
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- } else {
- System.out
- .println("因为文件不是文本文件,无法显示!");
- }
- System.out.println("");
- /*
- * 获得版本库的最新版本号。
- */
- long latestRevision = -1;
- try {
- latestRevision = repository.getLatestRevision();
- List<SVNLogEntry> entries = new ArrayList<SVNLogEntry>();
- try
- {
- repository.log(new String[]{""},//为过滤的文件路径前缀,为空表示不进行过滤
- entries,
- -1,//-1代表最新的版本号,初始版本号为0
- -1,
- true,
- true);
- }
- catch (SVNException e)
- {
- e.printStackTrace();
- }
- System.out.println("当前log信息数量:"+entries.size());
- String message=entries.get(0).getMessage().toString();
- System.out.println("提交的message信息:"+message);
- } catch (SVNException svne) {
- System.err.println("获取最新版本号时出错: " + svne.getMessage());
- System.exit(1);
- }
- System.out.println("");
- System.out.println("---------------------------------------------");
- System.out.println("版本库的最新版本号: " + latestRevision);
- System.exit(0);
- }
- /*
- * 初始化库
- */
- private static void setupLibrary() {
- /*
- * For using over http:// and https://
- */
- DAVRepositoryFactory.setup();
- /*
- * For using over svn:// and svn+xxx://
- */
- SVNRepositoryFactoryImpl.setup();
- /*
- * For using over file:///
- */
- FSRepositoryFactory.setup();
- }
- }</span><span style="font-weight: bold; font-size: 16pt;">
- </span>
打印的结果:
文件的属性: svn:entry:uuid=bf3500c6-b8a2-f84e-86b3-86d6154c1411
文件的属性: svn:entry:revision=2
文件的属性: svn:entry:committed-date=2015-04-29T15:53:24.910060Z
文件的属性: svn:wc:ra_dav:version-url=/svn/svnkittest/!svn/ver/2/branches/doImport.txt
文件的属性: svn:entry:checksum=1a3f6dc35be7edaba541a5a5053a2e03
文件的属性: svn:entry:committed-rev=2
文件的属性: svn:entry:last-author=hanyi
File contents:
hello the first svnkit demo
当前log信息数量:1
提交的message信息:韩义:svnkit demo test
---------------------------------------------
版本库的最新版本号: 2
实现DisplayRepositoryTree:
- import java.util.Collection;
- import java.util.Iterator;
- import org.tmatesoft.svn.core.SVNDirEntry;
- import org.tmatesoft.svn.core.SVNException;
- import org.tmatesoft.svn.core.SVNNodeKind;
- import org.tmatesoft.svn.core.SVNURL;
- import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
- import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
- import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
- import org.tmatesoft.svn.core.io.SVNRepository;
- import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
- import org.tmatesoft.svn.core.wc.SVNWCUtil;
- public class DisplayRepositoryTree {
- /**
- * @param args
- */
- public static void main(String[] args) {
- /*
- * For using over http:// and https://
- */
- DAVRepositoryFactory.setup();
- /*
- * 相关变量赋值
- */
- String url = "https://hy/svn/svnkittest";
- String name = "hanyi";
- String password = "hanyi";
- //定义svn版本库的URL。
- SVNURL repositoryURL = null;
- //定义版本库。
- SVNRepository repository = null;
- /*
- * 实例化版本库类
- * */
- try {
- //获取SVN的URL。
- repositoryURL=SVNURL.parseURIEncoded(url);
- //根据URL实例化SVN版本库。
- repository = SVNRepositoryFactory.create(repositoryURL);
- } catch (SVNException svne) {
- /*
- * 打印版本库实例创建失败的异常。
- */
- System.err
- .println("创建版本库实例时失败,版本库的URL是 '"
- + url + "': " + svne.getMessage());
- System.exit(1);
- }
- /*
- * 对版本库设置认证信息。
- */
- ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(name, password);
- repository.setAuthenticationManager(authManager);
- /*
- * 上面的代码基本上是固定的操作。
- * 下面的部分根据任务不同,执行不同的操作。
- * */
- try {
- //打印版本库的根
- System.out.println("Repository Root: " + repository.getRepositoryRoot(true));
- //打印出版本库的UUID
- System.out.println("Repository UUID: " + repository.getRepositoryUUID(true));
- System.out.println("");
- //打印版本库的目录树结构
- listEntries(repository, "");
- } catch (SVNException svne) {
- System.err.println("打印版本树时发生错误: "
- + svne.getMessage());
- System.exit(1);
- }
- /*
- * 获得版本库的最新版本树
- */
- long latestRevision = -1;
- try {
- latestRevision = repository.getLatestRevision();
- } catch (SVNException svne) {
- System.err
- .println("获取最新版本号时出错: "
- + svne.getMessage());
- System.exit(1);
- }
- System.out.println("");
- System.out.println("---------------------------------------------");
- System.out.println("版本库的最新版本是: " + latestRevision);
- System.exit(0);
- }
- /*
- * 此函数递归的获取版本库中某一目录下的所有条目。
- */
- public static void listEntries(SVNRepository repository, String path)
- throws SVNException {
- //获取版本库的path目录下的所有条目。参数-1表示是最新版本。
- Collection entries = repository.getDir(path, -1, null,
- (Collection) null);
- Iterator iterator = entries.iterator();
- while (iterator.hasNext()) {
- SVNDirEntry entry = (SVNDirEntry) iterator.next();
- System.out.println("/" + (path.equals("") ? "" : path + "/")
- + entry.getName() + " (author: '" + entry.getAuthor()
- + "'; revision: " + entry.getRevision() + "; date: " + entry.getDate() + ")");
- /*
- * 检查此条目是否为目录,如果为目录递归执行
- */
- if (entry.getKind() == SVNNodeKind.DIR) {
- listEntries(repository, (path.equals("")) ? entry.getName()
- : path + "/" + entry.getName());
- }
- }
- }
- }
打印的结果:
Repository Root: https://hy/svn/svnkittest
Repository UUID: bf3500c6-b8a2-f84e-86b3-86d6154c1411
/branches (author: 'hanyi'; revision: 2; date: Wed Apr 29 23:53:24 CST 2015)
/branches/doImport.txt (author: 'hanyi'; revision: 2; date: Wed Apr 29 23:53:24 CST 2015)
/tags (author: 'VisualSVN Server'; revision: 1; date: Wed Apr 29 14:14:01 CST 2015)
/trunk (author: 'VisualSVN Server'; revision: 1; date: Wed Apr 29 14:14:01 CST 2015)
---------------------------------------------
版本库的最新版本是: 2
其他的操作包括CheckOut,DoCommit,DoDiff,DoImport,DoUpdate我就不一一的写出了。上传一个包含所有操作的小例子,方便大家在以后的工作中学习使用:SVNKitTest(猛戳这里)
总结:
在学习SVNKit的过程中让我想起了我使用过的一些成型的产品,包括fisheye,Jenkins他们的底层与svn的集成或许就是通过SVNKit来实现的。或者是类似的产品实现的。对于我们更好的理解这些工具的使用提供了很大的帮助。
java操作svn【svnkit】实操的更多相关文章
- 利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解
本文转载自利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解 导语 由于最近工作需要利用 Jenkins 远程 API 操作 Jenkins 来完成一些列操作,就抽空研究 ...
- svnkit 用java 操作 svn
官网 https://svnkit.com/ https://blog.csdn.net/Hui_hai/article/details/80318518 https://blog.csdn.net/ ...
- java操作svn工具类SvnUtil
直接上代码,工作中使用的版本,记录下. public class SvnUtil { private static Logger logger = Logger.getLogger(SvnUtil.c ...
- .net基础学java系列(四)Console实操
上一篇文章 .net基础学java系列(三)徘徊反思 本章节没啥营养,请绕路! 看视频,不实操,对于上了年龄的人来说,是记不住的!我已经看了几遍IDEA的教学视频: https://edu.51cto ...
- Java初学者作业——编写JAVA程序,要求输入技术部门5位员工的理论成绩和实操成绩,计算并输出各位员工的最终评测成绩。
返回本章节 返回作业目录 需求说明: 某软件公司要求对技术部门的所有员工进行技能评测,技术评测分为两个部分:理论部分以及实操部分,最终评测成绩=理论成绩×0.4+实操成绩×0.6,要求输入技术部门5位 ...
- SBT实操指南
参考资料:1.英文官方文档2.中文官方文档,内容翻译的不全 SBT是类似maven和gradle的自动构建和包依赖管理工具,SBT是Scala技术体系下的包管理工具,都是Lightbend公司开发的, ...
- 第十章 Fisco Bcos 权限控制下的数据上链实操演练
一.目的 前面已经完成fisco bcos 相关底层搭建.sdk使用.控制台.webase中间件平台等系列实战开发, 本次进行最后一个部分,体系化管理区块链底层,建立有序的底层控管制度,实现权限化管理 ...
- kettle安装部署基本操作及实操文档
一.kettle是什么? Kettle,简称ETL(Extract-Transform-Load的缩写,即数据抽取.转换.装载的过程),是一款国外开源的ETL工具,纯Java编写,可以在Window. ...
- 性能测试工具 jmeter 分布式压力测试实操
性能测试工具 jmeter 分布式压力测试实操 本文在Non-GUI Mode下进行,准备好三台有jdk环境,linux操作系统,同一局域网测试机器,运行两台slave,一台master机器,进行分布 ...
随机推荐
- Intel GPA 抓取3d模型
原文链接在这里 http://dev.cra0kalo.com/?p=213 背景信息 Intel的GPA本身是一款图形分析软件,并没有设计从3D程序里抓取模型资源的功能,但这里作者是通过hook G ...
- Python机器学习库sklearn的安装
Python机器学习库sklearn的安装 scikit-learn是Python的一个开源机器学习模块,它建立在NumPy,SciPy和matplotlib模块之上能够为用户提供各种机器学习算法接口 ...
- 一站式机器学习平台TI-ONE是什么?——云+未来峰会开发者专场回顾
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 背景:5月23-24日,以“焕启”为主题的腾讯“云+未来”峰会在广州召开,广东省各级政府机构领导.海内外业内学术专家.行业大咖及技术大牛等在 ...
- mongodb配置文件与启动
数据库配置文件 mongo.cnf #日志文件位置 logpath=/data/db/journal/mongodb.log (这些都是可以自定义修改的) # 以追加方式写入日志 logappend= ...
- bzoj 4709: [Jsoi2011]柠檬
Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上.为了方便,我们从 ...
- 虚拟机centos笔记整理,持续更新~~
远程拷贝文件:scp -r 文件名 主机名:完整路径名(冒号不能少)拷贝当前windows系统的文件到当前目录:rz -y 查找文件:updatedb 修改数据库locate 文件名 即可查找文件
- 项目管理系列--从零开始Code Review[转]
从零开始Code Review 这篇帖子不是通篇介绍Code Review的方法论, 而是前大段记录了我们团队怎么从没有这个习惯到每天都进行review的过程, 后小段给出了我的一些建议. 希望能对诸 ...
- Iterator和for...of循环
Iterator和for...of循环 Iterator(遍历器)的概念 数据结构的默认Iterator接口 调用Iterator接口的场合 字符串的Iterator接口 Iterator接口与Gen ...
- PostgreSQL Entity Framework 自动迁移
1.依次添加NuGet包 EntityFramework.Npgsql.EntityFramework6.Npgsql,会自动生成一些配置文件,不过缺少数据库驱动的配置节点: <system.d ...
- 第四章使用java实现面向对象-接口
一.接口 1.接口可以看作是一种特殊的“抽象类”. 2.接口有比抽象类更好的特性 3.可以被多继承 4.设计和实现完全分离 5.更自然的使用多态 二.接口约定 1.接口表示一种约定:体现在接口名称和注 ...