net.wicp.tams.commons.apiext.SVNUtil Maven / Gradle / Ivy
package net.wicp.tams.commons.apiext;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNDepth;
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.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNDiffClient;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNStatus;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import net.wicp.tams.commons.Result;
import net.wicp.tams.commons.constant.DateFormatCase;
public class SVNUtil {
private final static Logger logger = LoggerFactory.getLogger(SVNUtil.class);
private static volatile SVNUtil INSTANCE;
private Map managerMap = new HashMap<>();
private String[] ignorefiles = new String[] { ".project", ".classpath" };
private String[] ignoreDirs = new String[] { "target", ".settings", ".svn", "bin" };
private SVNUtil() {
// 初始化版本库
DAVRepositoryFactory.setup();
SVNRepositoryFactoryImpl.setup();
FSRepositoryFactory.setup();
logger.info("创建SVNUtil实例成功");
}
/**
* 验证登录svn
*/
public SVNClientManager authSvn(String svnRoot, String username, String password) {
if (managerMap.get(svnRoot) != null) {
return managerMap.get(svnRoot);
}
// 创建库连接
SVNRepository repository = null;
try {
repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(svnRoot));
} catch (SVNException e) {
logger.error(e.getErrorMessage().getMessage(), e);
return null;
}
// 身份验证
ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(username,
password.toCharArray());
// 创建身份验证管理器
repository.setAuthenticationManager(authManager);
DefaultSVNOptions options = SVNWCUtil.createDefaultOptions(true);
SVNClientManager clientManager = SVNClientManager.newInstance(options, authManager);
managerMap.put(svnRoot, clientManager);
return clientManager;
}
public static final SVNUtil getInstance() {
if (INSTANCE == null) {
synchronized (SVNUtil.class) {
if (INSTANCE == null) {
INSTANCE = new SVNUtil();
}
}
}
return INSTANCE;
}
/**
* Make directory in svn repository
*
* @param clientManager
* @param url
* eg: http://svn.ambow.com/wlpt/bsp/trunk
* @param commitMessage
* @return
*/
public SVNCommitInfo makeDirectory(SVNClientManager clientManager, SVNURL url, String commitMessage) {
try {
return clientManager.getCommitClient().doMkDir(new SVNURL[] { url }, commitMessage);
} catch (SVNException e) {
logger.error(e.getErrorMessage().getMessage(), e);
}
return null;
}
/**
* Imports an unversioned directory into a repository location denoted by a
* destination URL
*
* @param clientManager
* @param localPath
* a local unversioned directory or singal file that will be
* imported into a repository;
* @param dstURL
* a repository location where the local unversioned
* directory/file will be imported into
* @param commitMessage
* @param isRecursive
* 递归
* @return
*/
public SVNCommitInfo importDirectory(SVNClientManager clientManager, File localPath, SVNURL dstURL,
String commitMessage, boolean isRecursive) {
try {
return clientManager.getCommitClient().doImport(localPath, dstURL, commitMessage, null, true, true,
SVNDepth.fromRecurse(isRecursive));
} catch (SVNException e) {
logger.error(e.getErrorMessage().getMessage(), e);
}
return null;
}
/**
* Puts directories and files under version control
*
* @param clientManager
* SVNClientManager
* @param wcPath
* work copy path
*/
public void addEntry(SVNClientManager clientManager, File wcPath) {
try {
clientManager.getWCClient().doAdd(new File[] { wcPath }, true, false, false, SVNDepth.INFINITY, false,
false, true);
} catch (SVNException e) {
logger.error(e.getErrorMessage().getMessage(), e);
}
}
/**
* Collects status information on a single Working Copy item
*
* @param clientManager
* @param wcPath
* local item's path
* @param remote
* true to check up the status of the item in the repository,
* that will tell if the local item is out-of-date (like '-u'
* option in the SVN client's 'svn status' command), otherwise
* false
* @return
*/
public SVNStatus showStatus(SVNClientManager clientManager, File wcPath, boolean remote) {
SVNStatus status = null;
try {
status = clientManager.getStatusClient().doStatus(wcPath, remote);
} catch (SVNException e) {
logger.error(e.getErrorMessage().getMessage(), e);
}
return status;
}
/***
* Commit work copy's change to svn
*
* @param clientManager
* @param wcPath
* @param keepLocks
* @param commitMessage
* @return
*/
public Result commit(SVNClientManager clientManager, File wcPath, boolean keepLocks, String commitMessage) {
try {
this.checkVersiondDirectory(clientManager, wcPath);
clientManager.getCommitClient().doCommit(new File[] { wcPath }, keepLocks, commitMessage, null, null, false,
false, SVNDepth.INFINITY);
return Result.getSuc();
} catch (SVNException e) {
return Result.getError(e.getMessage());
}
}
/**
* Updates a working copy (brings changes from the repository into the
* working copy).
*
* @param clientManager
* @param wcPath
* working copy path
* @param updateToRevision
* revision to update to
* @param depth
* update的深度:目录、子目录、文件
* @return
*/
public long update(SVNClientManager clientManager, File wcPath, SVNRevision updateToRevision, SVNDepth depth) {
SVNUpdateClient updateClient = clientManager.getUpdateClient();
/*
* sets externals not to be ignored during the update
*/
updateClient.setIgnoreExternals(false);
/*
* returns the number of the revision wcPath was updated to
*/
try {
return updateClient.doUpdate(wcPath, updateToRevision, depth, false, false);
} catch (SVNException e) {
logger.error(e.getErrorMessage().getMessage(), e);
}
return 0;
}
/**
* recursively checks out a working copy from url into wcDir
*
* @param clientManager
* @param svnPath
* a repository location from where a Working Copy will be
* checked out
* @param revision
* the desired revision of the Working Copy to be checked out
* @param destPath
* the local path where the Working Copy will be placed
* @param depth
* checkout的深度,目录、子目录、文件
* @return
*/
public long checkout(SVNClientManager clientManager, String svnPath, SVNRevision revision, File destPath,
SVNDepth depth) {
SVNUpdateClient updateClient = clientManager.getUpdateClient();
/*
* sets externals not to be ignored during the checkout
*/
updateClient.setIgnoreExternals(false);
/*
* returns the number of the revision at which the working copy is
*/
try {
return updateClient.doCheckout(packUrl(svnPath), destPath, revision, revision, depth, false);
} catch (SVNException e) {
logger.error(e.getErrorMessage().getMessage(), e);
}
return 0;
}
/***
* 把当前目录的文件强制更新到其它分支
*
* @param clientManager
* @param workDir
* @param svnUrl
* @return
*/
public Result overWrite(SVNClientManager clientManager, File workDir, String svnUrl) {
String workDirPath = System.getProperty("user.home");
File homeDir = new File(String.format("%s/%s/%s", workDirPath, "/.zhongan/", workDir.getName()));
try {
if (homeDir.exists()) {
FileUtils.forceDelete(homeDir);
}
// checkout
INSTANCE.checkout(clientManager, svnUrl, SVNRevision.HEAD, homeDir, SVNDepth.fromRecurse(true));
// 复制到home
FileUtils.copyDirectory(workDir, homeDir, new FileFilter() {
@Override
public boolean accept(File pathname) {
return !isIgnorefiles(pathname);
}
});
} catch (IOException e) {
logger.error("合并代码错误", e);
return Result.getError("合并代码错误");
}
Result retinfo = INSTANCE.commit(clientManager, homeDir, true,
"合并SVN,时间:" + DateFormatCase.yyyyMMddHHmmss.getInstanc().format(new Date()));
return retinfo;
// 不做新分支的切换 切换到新分支
// INSTANCE.doSwitch(clientManager, workDir, svnUrl);
}
/***
* 合并分支
*
* @param clientManager
* @param workDir
* @param svnUrl
* @return
*/
public Result merge(SVNClientManager clientManager, File workDir, String svnUrl, boolean commit) {
String workDirPath = System.getProperty("user.home");
File homeDir = new File(String.format("%s/%s/%s", workDirPath, "/.zhongan/", workDir.getName()));// trunk目录+
// "_"
// +
// UUIDGenerator.getUniqueLong()
try {
try {
FileUtils.forceDelete(homeDir);
} catch (Exception e) {
}
// checkout
INSTANCE.checkout(clientManager, svnUrl, SVNRevision.HEAD, homeDir, SVNDepth.fromRecurse(true));
SVNDiffClient diff = clientManager.getDiffClient();
diff.doMerge(homeDir, SVNRevision.HEAD, workDir, SVNRevision.HEAD, homeDir, SVNDepth.fromRecurse(true),
false, false, false, false);
} catch (Exception e) {
logger.error("合并代码错误", e);
return Result.getError("合并代码错误");
}
if (commit) {
Result retinfo = INSTANCE.commit(clientManager, homeDir, true,
"合并SVN,时间:" + DateFormatCase.yyyyMMddHHmmss.getInstanc().format(new Date()));
return retinfo.setRetObjs(homeDir);
} else {
return Result.getSuc().setRetObjs(homeDir);
}
}
/**
* 确定path是否是一个工作空间
*
* @param path
* @return
*/
public boolean isWorkingCopy(File path) {
if (!path.exists()) {
logger.warn("'" + path + "' not exist!");
return false;
}
try {
if (null == SVNWCUtil.getWorkingCopyRoot(path, false)) {
return false;
}
} catch (SVNException e) {
logger.error(e.getErrorMessage().getMessage(), e);
}
return true;
}
/***
* 确定一个URL在SVN上是否存在
*
* @param clientManager
* @param svnPath
* @return
*/
public boolean isURLExist(SVNClientManager clientManager, String svnPath) {
try {
SVNRepository svnRepository = clientManager.createRepository(packUrl(svnPath), true);
SVNNodeKind nodeKind = svnRepository.checkPath("", -1);
return nodeKind == SVNNodeKind.NONE ? false : true;
} catch (SVNException e) {
e.printStackTrace();
}
return false;
}
private SVNURL packUrl(String svn) throws SVNException {
return SVNURL.parseURIEncoded(svn);
}
public long doSwitch(SVNClientManager clientManager, File destPath, String svnUrlStr) {
SVNUpdateClient updateClient = clientManager.getUpdateClient();
updateClient.setIgnoreExternals(false);
try {
return updateClient.doSwitch(destPath, packUrl(svnUrlStr), SVNRevision.HEAD, SVNRevision.HEAD,
SVNDepth.fromRecurse(false), false, false);
} catch (SVNException e) {
return -1L;
}
}
public void checkVersiondDirectory(SVNClientManager clientManager, File wc) {
if (!SVNWCUtil.isVersionedDirectory(wc) && !isIgnorefiles(wc)) {
addEntry(clientManager, wc);
}
if (wc.isDirectory()) {
for (File sub : wc.listFiles()) {
if (sub.isDirectory() && sub.getName().equals(".svn")) {
continue;
}
checkVersiondDirectory(clientManager, sub);
}
}
}
/***
* 判断文件是否该忽略
*
* @param file
* @return
*/
public boolean isIgnorefiles(File file) {
if (file == null || !file.exists()) {
return true;
}
boolean isIgnore = false;
if (file.isDirectory()) {
String filePath = file.getPath().replace("\\", "/");
for (String dir : ignoreDirs) {
if (ArrayUtils.contains(filePath.split("/"), dir)) {
isIgnore = true;
break;
}
}
} else {
isIgnore = ArrayUtils.contains(ignorefiles, file.getName());
}
return isIgnore;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy