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来实现的。或者是类似的产品实现的。对于我们更好的理解这些工具的使用提供了很大的帮助。

时间: 2024-08-28 15:25:14

java操作svn【svnkit】实操的相关文章

java操作svn【svnkit】入门

SVNKit整体认识: SVNKit 是一个100%纯java,用于在java应用程序中与Subversion版本控制系统一起工作的客户端库.它的结构可以表示为: SVNKit有两个层次的API: 一. 高级层用于管理工作拷贝.这一类API让你管理工作拷贝就像使用Subversion命令行客户端一样. 二. 低级层类似Subversion仓库访问层.它类似直接在Subversion仓库上工作的驱动器. 高级层API 高级API类似Subversion的命令行客户端的命令,所有管理工作拷贝的操作逻

分享3个JAVA实操项目视频

[JAVA] 实战高可用的JAVA微服务架构-Spring Cloud系列 小马哥JAVA微服务架构实践视频教程 百度网盘: https://pan.baidu.com/s/11dncR9yiOkyFL9avaf21rg 密码b8s5 [JAVA] 全力打造JAVA高性能项目 Netty+SpringBoot+Nginx+FastDFS技术聚合 JAVA高性能后台项目 百度网盘: https://pan.baidu.com/s/1XdC0wjEHRVWe8owYtmlzPg 密码7rqj [JA

SpringMVC_3_实操Binding

previous:SpringMVC_2_实操Controller  next:SpringMVC_4_实操FileUpload Binding:将请求中的字段按照名字匹配的原则填入模型对象. 1)@ModelAttribute on Method 2)redirect/forward ------------------------------------------------------ CourseController.java @RequestMapping(value="/admin

Docker 学习笔记【3】 Docker 仓库、数据卷、数据卷容器,网络基础实操。高级网络配置学习

Docker 学习笔记[4] 高级网络配置实操,实战案例实验 =========================================================================== Docker 学习笔记[2] Docker 仓库实操,创建私有仓库,实操数据卷.数据卷容器,记录开始 =========================================================================== 被格式化的脚本内容: #开头代表

容器平台自动化CI/CD流水线实操

CI/CD----(实操说明) CI/CD 持续集成(Continuous Integration, CI):  代码合并,构建,部署,测试都在一起,不断地执行这个过程,并对结果反馈. 持续部署(Continuous Deployment, CD): 部署到测试环境.预生产环境.生成环境. 持续部署(Continuous Delivery, CD):  将最终产品发布到生成环境.给用户使用. Jenkins与容器技术CI/CD实战 说明:这张图稍微更形象一点,上线之前先把代码git到版本仓库,然

性能测试工具 jmeter 分布式压力测试实操

性能测试工具 jmeter 分布式压力测试实操 本文在Non-GUI Mode下进行,准备好三台有jdk环境,linux操作系统,同一局域网测试机器,运行两台slave,一台master机器,进行分布式测试. slave-1/slave-2/master配置好jmeter环境(以下操作在jdk版本1.8环境下进行的) 1.下载jmeter3.2 wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-3.2.tgz 2

kettle安装部署基本操作及实操文档

一.kettle是什么? Kettle,简称ETL(Extract-Transform-Load的缩写,即数据抽取.转换.装载的过程),是一款国外开源的ETL工具,纯Java编写,可以在Window.Linux.Unix上运行,绿色无需安装,数据抽取高效稳定,对于企业或行业应用来说,我们经常会遇到各种数据的处理,转换,迁移,所以了解并掌握一种etl工具的使用,必不可少.kettle支持图形化的GUI设计界面,然后可以以工作流的形式流转,在做一些简单或复杂的数据抽取.质量检测.数据清洗.数据转换.

POSIX in Windows实操:Gentoo-prefix/interix

引子:无论是MingW还是Cygwin,包括最近冒起的MSYS2,都存在各种奇怪之处,一言蔽之,就是离不开Windows但又对POSIX心痒难搔.Gentoo prefix让你实实在在地操练POSIX,又不失Windows的优雅. 什么是Gentoo prefix? Gentoo是一种GNU/Linux发行版,就像Ubuntu是一种GNU/Linux发行版一样.Gentoo的特点就是好,真的好.其中的原理在于,Gentoo是基于POSIX标准的源代码发行版,而实现POSIX标准的二进制通常千奇百

打造网络营销利器-第1篇-TDK设置实操-网站优化进阶

网络营销如何做,才能从网络挖掘出大量的新业务?互联网时代你还停留于没业务就扩充销售队伍的思想,你就OUT了! 本系列文章将用通俗的语言介绍网站运营大牛们的惯用手法,网站SEO并没有你们想象那么难!重点是了解并坚持去做! 上一篇文章<中小企业网站优化技巧-1-网站的TDK>介绍了网站的TDK是什么(标题.描述.关键词),那么本文,将以具体产品为例介绍下TDK的实际操作. 首先,登录进网站系统后台,从左边菜单栏找到产品管理==>添加产品,点击打开添加产品的页面: 然后第一步,选择您产品对应的