SVN是当前最常用的版本控制工具。关于subversion、visualSVN server、TortoiseSVN Client、SVNKit的介绍网上有很多,可以到搜索引擎一搜一大把。
subversion官网
visualSVN server官网
tortoiseSVN Client官网
SVNKit官网
最近在寻思着做个版本控制的模块用到transdoc中,到深圳图书馆借了本
版本控制之道学习ing。
里面介绍的是svn安装和使用,没有具体说怎么在它基础上做开发。于是找到svnkit官网看API/Wiki,苦于英文太差,又到网上找了些资料,封装了下HighLevelAPI常用的一些方法,特定了transdoc的适用场景,简化了参数。
package cn.transdoc.svn;
import java.io.File;
import java.io.OutputStream;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
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.internal.wc.DefaultSVNOptions;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNCommitClient;
import org.tmatesoft.svn.core.wc.SVNCopyClient;
import org.tmatesoft.svn.core.wc.SVNCopySource;
import org.tmatesoft.svn.core.wc.SVNDiffClient;
import org.tmatesoft.svn.core.wc.SVNMoveClient;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import org.tmatesoft.svn.core.wc.SVNWCClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
/**
* svn客户端,包含一些常见的svn操作
*
* @author Administrator
*
*/
public class SvnClient {
private SVNClientManager svnClientManager;
static {
DAVRepositoryFactory.setup();
FSRepositoryFactory.setup();
SVNRepositoryFactoryImpl.setup();
}
/**
* 使用用户名与密码创建一个Svn客户端
*
* @param username
* @param password
*/
public SvnClient(String username, String password) {
DefaultSVNOptions options = SVNWCUtil.createDefaultOptions(false);
svnClientManager = SVNClientManager.newInstance(options, username, password);
}
/**
* 将指定版本库文件夹路径的最新版本检出到本地
*
* @param repoPath
* 仓库路径 url,必须是文件夹
* @param workingCopy
* 本地工作副本,必须是文件夹
* @param includeChildren
* 是否检出文件夹下的文件和子文件夹
* @throws SVNException
* 当repoPath或workingCopy不是文件夹时,或者repoPath不存在时,抛出该异常
*/
public void checkout(String repoPath, File workingCopy, boolean includeChildren) throws SVNException {
SVNUpdateClient client = svnClientManager.getUpdateClient();
SVNURL repositoryURL = SVNURL.parseURIEncoded(repoPath);
SVNDepth depth = includeChildren ? SVNDepth.INFINITY : SVNDepth.EMPTY;
client.doCheckout(repositoryURL, workingCopy, SVNRevision.HEAD, SVNRevision.HEAD, depth, true);
}
/**
* 更新版本化环境中的工作副本到最新版本
*
* @param workingCopy
* 本地工作副本,可以是文件或文件夹
* @param includeChildren
* 当workingCopy是文件夹时,是否检出文件夹下的文件和子文件夹
* @throws SVNException
*/
public void update(File workingCopy, boolean includeChildren) throws SVNException {
SVNUpdateClient client = svnClientManager.getUpdateClient();
SVNDepth depth = includeChildren ? SVNDepth.INFINITY : SVNDepth.EMPTY;
client.doUpdate(workingCopy, SVNRevision.HEAD, depth, true, true);
}
/**
* 添加工作副本到版本化环境中
*
* @param workingCopy
* 本地工作副本,可以是文件或文件夹
* @param includeChildren
* 是否添加文件夹下的文件和子文件夹
* @throws SVNException
*/
public void add(File workingCopy, boolean includeChildren) throws SVNException {
SVNWCClient client = svnClientManager.getWCClient();
SVNDepth depth = includeChildren ? SVNDepth.INFINITY : SVNDepth.EMPTY;
client.doAdd(workingCopy, true, false, true, depth, false, true);
}
/**
* 提交已添加到版本化环境中的工作副本到版本库
*
* @param includeChildren
* 是否添加文件夹下的文件和子文件夹
* @param commitMessage
* 提交附加消息
* @param workingCopy
* 本地工作副本,可以是文件或文件夹
* @throws SVNException
*/
public void commit(String commitMessage, boolean includeChildren, File... workingCopy) throws SVNException {
SVNCommitClient client = svnClientManager.getCommitClient();
SVNDepth depth = includeChildren ? SVNDepth.INFINITY : SVNDepth.EMPTY;
client.doCommit(workingCopy, false, commitMessage, null, null, false, true, depth);
}
/**
* 将文件或文件夹导入版本库而不创建版本化环境
*
* @param repoPath
* @param file
* @param commitMessage
* @param includeChildren
* @throws SVNException
*/
public void importTo(String repoPath, File file, String commitMessage, boolean includeChildren) throws SVNException {
SVNCommitClient client = svnClientManager.getCommitClient();
SVNDepth depth = includeChildren ? SVNDepth.INFINITY : SVNDepth.EMPTY;
SVNURL url = SVNURL.parseURIEncoded(repoPath);
client.doImport(file, url, commitMessage, null, true, false, depth);
}
/**
* 将工作副本中的条目移出版本化环境
*
* @param workingCopy
* 需要移出的条目
* @param deleteMessage
* 移出附加消息
* @param deleteFiles
* 是否从文件系统中删除条目对应的文件
* @throws SVNException
*/
public void delete(File workingCopy, String deleteMessage, boolean deleteFiles) throws SVNException {
SVNWCClient client = svnClientManager.getWCClient();
client.doDelete(workingCopy, true, deleteFiles, false);
}
/**
* 锁定工作副本和存储库中的文件条目
*
* @param workingCopy
* 需要锁定的文件条目的工作副本
* @param lockMessage
* 锁定附加消息
* @throws SVNException
*/
public void lock(String lockMessage, File... workingCopy) throws SVNException {
SVNWCClient client = svnClientManager.getWCClient();
client.doLock(workingCopy, false, lockMessage);
}
/**
* 解除工作副本和存储库中已锁定的文件条目的锁定状态
*
* @param workingCopy
* 需要解除锁定的文件条目的工作副本
* @throws SVNException
*/
public void unlock(File... workingCopy) throws SVNException {
SVNWCClient client = svnClientManager.getWCClient();
client.doUnlock(workingCopy, false);
}
/**
* 取消所有本地编辑
*
* @param workingCopy
* @throws SVNException
*/
public void revert(File... workingCopy) throws SVNException {
SVNWCClient client = svnClientManager.getWCClient();
client.doRevert(workingCopy, SVNDepth.INFINITY, null);
}
/**
* 移动/重命名
*
* @param src
* @param dst
* @throws SVNException
*/
public void move(File src, File dst) throws SVNException {
SVNMoveClient client = svnClientManager.getMoveClient();
client.doMove(src, dst);
}
/**
* 取消移动/重命名
*
* @param src
* @param dst
* @throws SVNException
*/
public void undoMove(File src, File dst) throws SVNException {
SVNMoveClient client = svnClientManager.getMoveClient();
client.undoMove(src, dst);
revert(src, dst);
}
/**
* 复制src到dst
*
* @param src
* @param dst
* @throws SVNException
*/
public void copy(File dst, File... src) throws SVNException {
SVNCopyClient client = svnClientManager.getCopyClient();
SVNCopySource[] sources = new SVNCopySource[src.length];
int i = 0;
for (File file : src) {
sources[i++] = new SVNCopySource(SVNRevision.HEAD, SVNRevision.HEAD, file);
}
client.doCopy(sources, dst, false, true, false);
}
/**
* 比较当前工作版本和版本库最新版本的不同,输出到out
*
* @param src
* @param out
* @throws SVNException
*/
public void diff(File src, OutputStream out) throws SVNException {
SVNDiffClient client = svnClientManager.getDiffClient();
client.doDiff(src, SVNRevision.WORKING, src, SVNRevision.HEAD, SVNDepth.INFINITY, false, out, null);
}
}
测试:
package cn.transdoc.svn;
import java.io.File;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class SvnClientTest {
public static String REPO_ROOT = "https://humphrey/svn/root/test";
private SvnClient svnClient;
@Before
public void setUp() throws Exception {
String name = "admin";
String password = "admin";
svnClient = new SvnClient(name, password);
}
@After
public void tearDown() throws Exception {
}
@Test
public void checkOut() throws Exception {
svnClient.checkout(REPO_ROOT, new File("F:\\transdoc"), false);
}
@Test
public void update() throws Exception {
svnClient.update(new File("F:\\transdoc"), true);
}
@Test
public void updateFile() throws Exception {
svnClient.update(new File("F:\\transdoc\\c.txt"), true);
}
@Test
public void add() throws Exception {
svnClient.add(new File("F:\\transdoc\\3"), true);
}
@Test
public void commit() throws Exception {
svnClient.commit("测试提交", true, new File("F:\\transdoc\\b.txt"));
}
@Test
public void delete() throws Exception {
svnClient.delete(new File("F:\\transdoc\\e.txt"), "deleteMessage", false);
}
@Test
public void lock() throws Exception {
svnClient.lock("lockMessage", new File("F:\\transdoc\\a.txt"), new File("F:\\transdoc\\b.txt"));
}
@Test
public void unlock() throws Exception {
svnClient.unlock(new File[] { new File("F:\\transdoc\\a.txt"), new File("F:\\transdoc\\b.txt"),
new File("F:\\transdoc\\e.txt") });
}
@Test
public void importTo() throws Exception {
svnClient.importTo(REPO_ROOT + "/e.txt", new File("F:\\transdoc\\e.txt"), "importTo", true);
}
@Test
public void move() throws Exception {
File src = new File("F:\\transdoc\\s.txt");
File dst = new File("F:\\transdoc\\a.txt");
svnClient.move(src, dst);
// svnClient.revert(src,dst);
svnClient.undoMove(dst, src);
// svnClient.commit("move", true, src, dst);
}
@Test
public void undoMove() throws Exception {
File src = new File("F:\\transdoc\\s.txt");
File dst = new File("F:\\transdoc\\a.txt");
svnClient.undoMove(src, dst);
// svnClient.commit("undoMove", true, src,dst);
}
@Test
public void revert() throws Exception {
svnClient.revert(new File("F:\\transdoc\\s.txt"));
svnClient.revert(new File("F:\\transdoc\\a.txt"));
}
@Test
public void copy() throws Exception {
svnClient.copy(new File("F:\\transdoc\\1"), new File("F:\\transdoc\\b.txt"));
}
@Test
public void diff() throws Exception {
svnClient.diff(new File("F:\\transdoc\\b.txt"), System.out);
}
}