一、简介

SVNKit是一个纯Java版本控制(SVN)工具库(library)。

二、下载

在官网下载Standalone版本并解压,将解压后的svnkit-1.10.1\lib下的jar添加到Build Path中。

三、样例

1、打印SVN库历史记录

  • 源码
package com.svnkit;

import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;

import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNLogEntryPath;
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.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

public class History {

	public static void main(String[] args) {
		// http协议对应的SVNRepositoryFactory实现
		DAVRepositoryFactory.setup();

		String url = "http://acer/svn/myrepository/myproject";
		String name = "albert";
		char[] password = { 'w', 'z', 'k' };
		long startRevision = 0;
		long endRevision = -1; // HEAD (the latest) revision

		SVNRepository repository = null;
		try {
			// 创建基于特定协议的SVNRepository驱动程序
			repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url));
			// 创建身份验证管理器
			ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(name, password);
			// 设置一个提供用户凭据的身份验证管理器
			repository.setAuthenticationManager(authManager);

			// 不指定具体路径,获取所有被修改的文件
			String[] targetPaths = new String[] { "" };
			Collection<SVNLogEntry> logEntries = repository.log(targetPaths, null, startRevision, endRevision, true,
					true);
			for (SVNLogEntry logEntry : logEntries) {
				System.out.println("---------------------------------------------");
				System.out.println(String.format("revision: %s", logEntry.getRevision()));
				System.out.println(String.format("author: %s", logEntry.getAuthor()));
				System.out.println(String.format("date: %s", logEntry.getDate()));
				System.out.println(String.format("message: %s", logEntry.getMessage()));
				// 修改的文件路径
				Map<String, SVNLogEntryPath> changedPaths = logEntry.getChangedPaths();
				if (!changedPaths.isEmpty()) {
					System.out.println();
					System.out.println("changed paths:");
					for (Entry<String, SVNLogEntryPath> changedPath : changedPaths.entrySet()) {
						SVNLogEntryPath entryPath = changedPath.getValue();
						System.out.println(String.format("%s  %s  %s", entryPath.getType(), entryPath.getKind(),
								entryPath.getPath()));
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
  • 输出
---------------------------------------------
revision: 7
author: VisualSVN Server
date: Sun May 12 23:18:52 CST 2019
message: Created folder 'myproject'.

changed paths:
A  dir  /myproject
---------------------------------------------
revision: 8
author: albert
date: Sun May 12 23:20:53 CST 2019
message: 

changed paths:
A  file  /myproject/HelloWorld.java
---------------------------------------------
revision: 9
author: albert
date: Sun May 12 23:23:44 CST 2019
message: I love Java 

changed paths:
M  file  /myproject/HelloWorld.java
---------------------------------------------
revision: 43
author: tom
date: Fri Jan 31 20:56:56 CST 2020
message: 

changed paths:
A  file  /myproject/images/1541911065583.jpg
A  dir  /myproject/images
A  file  /myproject/images/1541911065545.jpg
A  file  /myproject/images/1541911065579.jpg
---------------------------------------------
revision: 44
author: tom
date: Fri Jan 31 20:58:13 CST 2020
message: 调整图片

changed paths:
D  file  /myproject/images/1541911065583.jpg
A  file  /myproject/images/agent-01.png
A  file  /myproject/images/agent-02.png
---------------------------------------------
revision: 45
author: tom
date: Fri Jan 31 20:58:41 CST 2020
message: 逻辑调整

changed paths:
M  file  /myproject/HelloWorld.java

2、统计修改情况

统计修改了指定路径的人员及修改次数:

  • 源码
package com.svnkit;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.tmatesoft.svn.core.ISVNLogEntryHandler;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
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.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

public class AnalysisHistory {

	public static void main(String[] args) {
		// http协议对应的SVNRepositoryFactory实现
		DAVRepositoryFactory.setup();

		String url = "http://acer/svn/myrepository/myproject";
		String name = "albert";
		char[] password = { 'w', 'z', 'k' };

		SVNRepository repository = null;
		try {
			// 创建基于特定协议的SVNRepository驱动程序
			repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url));
			// 创建身份验证管理器
			ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(name, password);
			// 设置一个提供用户凭据的身份验证管理器
			repository.setAuthenticationManager(authManager);

			// 统计指定路径的修改记录
			String[] paths = new String[] { "HelloWorld.java", "images/agent-01.png" };
			for (String path : paths) {
				analysis(repository, path);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void analysis(SVNRepository repository, String path) throws SVNException {
		long startRevision = 0;
		// HEAD (the latest) revision
		long endRevision = -1;
		// 人员与修改次数的map
		Map<String, Integer> countMap = new HashMap<>();

		// 不获取changedPath
		repository.log(new String[] { path }, startRevision, endRevision, false, true, 10, new ISVNLogEntryHandler() {
			@Override
			public void handleLogEntry(SVNLogEntry logEntry) throws SVNException {
				String author = logEntry.getAuthor();
				Integer count = countMap.get(author);
				if (count == null) {
					count = 0;
				}
				countMap.put(author, count + 1);
			}
		});

		System.out.println(String.format("The file %s: ", path));
		for (Entry<String, Integer> entry : countMap.entrySet()) {
			System.out.println(String.format("%s\t%stimes", entry.getKey(), entry.getValue()));
		}
		System.out.println();
	}
}
  • 输出
The file HelloWorld.java: 
tom	1times
albert	2times

The file images/agent-01.png: 
tom	1times
参考资料: