使用svnkit上传单个文件到svn仓库,可以不用先把svn仓库checkout到本地
在进行svn插件开发时,使用到了svnkit这个包,原来上传文件到svn仓库的流程是:先把svn仓库中所有文件checkout到本地,然后再向本地的workingcopy目录添加新文件,最后进行commit到svn仓库,虽然这样也行,但是如果svn仓库目录下的文件较多,而且比较大的时候,这个方式的提交速度就不理想了,可以看下方代码:
/**
* 提交项目到SVN
* 可以是一个文件也可以是一个目录
* @param needmerge true
*/
public static boolean commitProjectToSvn(SVNUtil su , File[] files,boolean needmerge)
throws SVNException {
su.getSVNClientManager().getCommitClient().setEventHandler(new ISVNEventHandler() {
@Override
public void handleEvent(SVNEvent event, double progress) throws SVNException {
System.out.println(progress);
}
@Override
public void checkCancelled() throws SVNCancelException {
}
});
if(files == null || files.length == 0) {
return false;
}
List<File> list = new ArrayList<>();
for (File file : files) {
if(file.exists()) {
list.add(file);
checkVersiondDirectory(su, file, needmerge);
}
}
if(list.size() > 0) {
commit(su, list.toArray(new File[0]), false, "jenkins svnkit:" + list);
return true;
}
return false;
}
/**
* 递归检查不在版本控制的文件,并add到svn
*/
private static void checkVersiondDirectory(SVNUtil su, File wc, boolean needmerge)
throws SVNException {
if (!SVNWCUtil.isVersionedDirectory(wc)) {
addEntry(su, wc, needmerge);
}
if (wc.isDirectory()) {
for (File sub : wc.listFiles()) {
if (sub.isDirectory() && sub.getName().equals(".svn")) {
continue;
}
checkVersiondDirectory(su, sub, needmerge);
}
}
}
/**
* Commit work copy's change to svn
*
* @param wcPath working copy paths which changes are to be committed
* @param keepLocks whether to unlock or not files in the repository
* @param commitMessage commit log message
*/
public static SVNCommitInfo commit(SVNUtil su, File[] files,
boolean keepLocks, String commitMessage) throws SVNException {
SVNCommitClient commitClient = su.getSVNClientManager().getCommitClient();
try {
return commitClient
.doCommit(files, keepLocks, commitMessage, null, null, false, true,
SVNDepth.INFINITY);
} catch (SVNException e) {
e.printStackTrace();
throw e;
}
}
/**
* Puts directories and files under version control
*
* @param clientManager SVNClientManager
* @param wcPath work copy path
*/
public static void addEntry(SVNUtil su, File wcPath, boolean needmerge) throws SVNException {
SVNClientManager svnClientManager = su.getSVNClientManager();
// DefaultSVNOptions defaultSVNOptions = new DefaultSVNOptions();
// defaultSVNOptions.setConflictHandler(new ConflictResolverHandler(SVNConflictChoice.THEIRS_CONFLICT));
// svnClientManager.setOptions(defaultSVNOptions);
SVNWCClient wcClient = svnClientManager.getWCClient();
try {
wcClient.doAdd(new File[]{wcPath}, true, false, false, SVNDepth.INFINITY, false, false, true);
} catch (SVNException e) {
e.printStackTrace();
if(e.getMessage().contains("E155015")) {
// 解决冲突
// SVNConflictChoice.MERGED 是把本地和远程仓库文件合并,以本地为主
// SVNConflictChoice.THEIRS_CONFLICT
// SVNConflictChoice.THEIRS_FULL
// SVNConflictChoice.MINE_CONFLICT
if(needmerge) {
wcClient.doResolve(wcPath, SVNDepth.INFINITY,SVNConflictChoice.MERGED);
} else {
throw e;
}
// SVNDiffClient diffClient = su.getSVNClientManager().getDiffClient();
// DefaultSVNOptions options = (DefaultSVNOptions) diffClient.getOptions();
// options.setConflictHandler(new ConflictResolverHandler(SVNConflictChoice.THEIRS_FULL));
// SVNRevisionRange rangeToMerge = new SVNRevisionRange(SVNRevision.create(1), SVNRevision.HEAD);
// diffClient.doMerge(SVNURL.parseURIEncoded(su.getStoreUrl()), SVNRevision.HEAD, Collections.singleton(rangeToMerge), new File("C:\\Users\\zxavi\\Desktop\\c"), SVNDepth.UNKNOWN, true, false, false, false);
} else {
throw e;
}
}
}
调用
boolean b1 = commitProjectToSvn(su, new File[]{new File("C:\\Users\\zxavi\\Desktop\\c\\1.txt"),new File("C:\\Users\\zxavi\\Desktop\\c\\5.txt")},true);
现换了一种方式,可以不用先把svn仓库checkout到本地,直接把单个文件上传,代码如下:
/**
* https://stackoverflow.com/questions/4711561/committing-changed-file-via-svnkit-without-local-checkout/8661636
* @param su
* @param files
* @param locSvnDirPath
* @throws SVNException
*/
public static void commitFilesToSVN(SVNUtil su,File[] files,String locSvnDirPath)
throws SVNException {
String storeUrl = su.getStoreUrl();
if(!storeUrl.endsWith("/") && !storeUrl.endsWith("\\")) {
storeUrl += "/";
}
SVNClientManager svnClientManager = su.getSVNClientManager();
for (File file : files) {
String absolutePath = file.getAbsolutePath();
String s = absolutePath.substring(locSvnDirPath.length() + 1);
if(isURLExist(SVNURL.parseURIEncoded(storeUrl + s),su.getUSERNAME(),su.getPASSWD())) {
svnClientManager.getCommitClient().doDelete(new SVNURL[]{SVNURL.parseURIEncoded(storeUrl + s)},"svnkit delete");
}
svnClientManager.getCommitClient( ).doImport( new File(locSvnDirPath + "/" + s) , SVNURL.parseURIEncoded(storeUrl + s) , "svnkit commit" , true );
}
}
主要代码其实是两行:
svnClientManager.getCommitClient().doDelete(new SVNURL[]{SVNURL.parseURIEncoded(storeUrl + s)},"svnkit delete"); // 先删除svn仓库上的文件,如果文件存在的话那么后面上传就会报错
svnClientManager.getCommitClient( ).doImport( new File(locSvnDirPath + "/" + s) , SVNURL.parseURIEncoded(storeUrl + s) , "svnkit commit" , true );
比如:
svnClientManager.getCommitClient().doDelete(new SVNURL[]{SVNURL.parseURIEncoded("svn://localhost/sources/3/demo-0.0.1-SNAPSHOT.war")},"svnkit delete");
svnClientManager.getCommitClient( ).doImport( new File("D:\\git_workspace\\ci_demo\\target\\demo-0.0.1-SNAPSHOT.war") , SVNURL.parseURIEncoded(storeUrl + s) , "svnkit commit" , true );
本文来自博客园,作者:margo,转载请注明原文链接:https://www.cnblogs.com/ZMargo/articles/11230517.html

浙公网安备 33010602011771号