原文:http://blog.csdn.net/hardwin/article/details/7963318
import java.io.File; import org.apache.log4j.Logger; 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.SVNRevision; import org.tmatesoft.svn.core.wc.SVNStatus; import org.tmatesoft.svn.core.wc.SVNUpdateClient; import org.tmatesoft.svn.core.wc.SVNWCUtil; /** * SVNKit Utility * @author lena yang * */ public class SVNUtil { private static Logger logger = Logger.getLogger(SVNUtil.class); /** * 通过不同的协议初始化版本库 */ public static void setupLibrary() { DAVRepositoryFactory.setup(); SVNRepositoryFactoryImpl.setup(); FSRepositoryFactory.setup(); } /** * 验证登录svn */ public static SVNClientManager authSvn(String svnRoot, String username, String password) { // 初始化版本库 setupLibrary(); // 创建库连接 SVNRepository repository = null; try { repository = SVNRepositoryFactory.create(SVNURL .parseURIEncoded(svnRoot)); } catch (SVNException e) { logger.error(e.getErrorMessage(), e); return null; } // 身份验证 ISVNAuthenticationManager authManager = SVNWCUtil .createDefaultAuthenticationManager(username, password); // 创建身份验证管理器 repository.setAuthenticationManager(authManager); DefaultSVNOptions options = SVNWCUtil.createDefaultOptions(true); SVNClientManager clientManager = SVNClientManager.newInstance(options, authManager); return clientManager; } /** * Make directory in svn repository * @param clientManager * @param url * eg: http://svn.ambow.com/wlpt/bsp/trunk * @param commitMessage * @return * @throws SVNException */ public static SVNCommitInfo makeDirectory(SVNClientManager clientManager, SVNURL url, String commitMessage) { try { return clientManager.getCommitClient().doMkDir( new SVNURL[] { url }, commitMessage); } catch (SVNException e) { logger.error(e.getErrorMessage(), 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 static 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(), e); } return null; } /** * Puts directories and files under version control * @param clientManager * SVNClientManager * @param wcPath * work copy path */ public static 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(), 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 * @throws SVNException */ public static 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(), e); } return status; } /** * Commit work copy's change to svn * @param clientManager * @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 * @return * @throws SVNException */ public static SVNCommitInfo commit(SVNClientManager clientManager, File wcPath, boolean keepLocks, String commitMessage) { try { return clientManager.getCommitClient().doCommit( new File[] { wcPath }, keepLocks, commitMessage, null, null, false, false, SVNDepth.INFINITY); } catch (SVNException e) { logger.error(e.getErrorMessage(), e); } return null; } /** * 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 * @throws SVNException */ public static 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(), e); } return 0; } /** * recursively checks out a working copy from url into wcDir * @param clientManager * @param url * 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 * @throws SVNException */ public static long checkout(SVNClientManager clientManager, SVNURL url, 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(url, destPath, revision, revision,depth, false); } catch (SVNException e) { logger.error(e.getErrorMessage(), e); } return 0; } /** * 确定path是否是一个工作空间 * @param path * @return */ public static 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(), e); } return true; } /** * 确定一个URL在SVN上是否存在 * @param url * @return */ public static boolean isURLExist(SVNURL url,String username,String password){ try { SVNRepository svnRepository = SVNRepositoryFactory.create(url); ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(username, password); svnRepository.setAuthenticationManager(authManager); SVNNodeKind nodeKind = svnRepository.checkPath("", -1); return nodeKind == SVNNodeKind.NONE ? false : true; } catch (SVNException e) { e.printStackTrace(); } return false; } }
/** * 创建项目框架,SVN提交、更新 * @author lena yang * */ @Service("svnProjectService") public class SvnProjectService { private Logger logger = Logger.getLogger(SvnProjectService.class); // 项目的存放位置 private String workspace = null; private ResourceBundle rb = ResourceBundle.getBundle("application"); // SVN的用户名、密码 private String username = null; private String password = null; private String templete = null; @Resource(name="xcodeService") private XcodeService xcodeService; private void init(){ String webapp = System.getProperty("webapp.root"); if(null!=webapp&&!webapp.endsWith("/") && !webapp.endsWith("\\")){ webapp = webapp + "/"; } // 发布到web服务器以后,有可能WebContent没了 if(new File(webapp + "WebContent").exists()){ webapp = webapp + "WebContent"; } username = rb.getString("svn.username"); password = rb.getString("svn.password"); workspace = rb.getString("project.svn.path"); templete = webapp + "templete"; } public SvnProjectService(){ super(); init(); } /** * 创建项目框架 * @param project * Project * @return */ public boolean createProjectFrame(Project project,List<String> tableNames) { if(project == null){ return false; } File src = new File(templete); // 模板项目的位置 File ws = new File(workspace); // work copy if(!ws.exists()){ ws.mkdirs(); } File dest = new File(workspace + "/" + project.getName()); if(!dest.exists()){ dest.mkdirs(); } checkWorkCopy(project); // 确定工作空间 // 复制模板项目到工作空间 try { FileUtils.copyDirectory(src, dest); } catch (IOException e) { logger.error(e.getMessage(), e); return false; } //修改.project文件中的内容 editProjectFile(project); // 生成框架代码 xcodeService.createBaseFrameWithDatasource(project,tableNames); // 提交到SVN commitProjectToSvn(project); return true; } /** * 修改项目文件 * @param project * @throws DocumentException * @throws IOException */ @SuppressWarnings("unchecked") private void editProjectFile(Project project) { String pro = workspace + "/" + project.getName() + "/"; String settings = pro + ".settings/"; // 1. 修改.settings/org.eclipse.wst.common.component Document document = null; try { document = XmlReaderUtil.getDocument(new File(settings + "org.eclipse.wst.common.component")); } catch (DocumentException e) { e.printStackTrace(); } Element root = document.getRootElement(); root.element("wb-module").attribute("deploy-name") .setValue(project.getName()); if (root.element("wb-module").element("property").attribute("name") .getValue().equals("java-output-path")) { root.element("wb-module").element("property").attribute("value") .setValue("/" + project.getName() + "/build/classes"); } Iterator<Element> itr = (Iterator<Element>) XmlReaderUtil.getElements( document, "//wb-module//property").iterator(); while (itr.hasNext()) { Element element = itr.next(); if ("context-root".equals(element.attribute("name").getValue())) { element.attribute("value").setValue("/" + project.getName()); } } // 将修改后的值写入 XmlReaderUtil.writerXml(document, settings + "org.eclipse.wst.common.component"); // 2. 修改.project try { document = XmlReaderUtil.getDocument(new File(pro + ".project")); XmlReaderUtil.setElementText(document, "//projectDescription", "name", project.getName()); XmlReaderUtil.writerXml(document, pro + ".project"); } catch (DocumentException e) { e.printStackTrace(); } } /** * 从SVN更新项目到work copy * @param project * Project * @return */ public boolean updateProjectFromSvn(Project project) { if(null == project || null == rb.getString("svn.url")){ return false; } project.setSvnUrl(rb.getString("svn.url")); SVNClientManager clientManager = SVNUtil.authSvn(project.getSvnUrl(), username, password); if (null == clientManager) { logger.error("SVN login error! >>> url:" + project.getSvnUrl() + " username:" + username + " password:" + password); return false; } // 注册一个更新事件处理器 clientManager.getCommitClient().setEventHandler(new UpdateEventHandler()); SVNURL repositoryURL = null; try { // eg: http://svn.ambow.com/wlpt/bsp repositoryURL = SVNURL.parseURIEncoded(project.getSvnUrl()).appendPath("trunk/"+project.getName(), false); } catch (SVNException e) { logger.error(e.getMessage(),e); return false; } File ws = new File(new File(workspace), project.getName()); if(!SVNWCUtil.isVersionedDirectory(ws)){ SVNUtil.checkout(clientManager, repositoryURL, SVNRevision.HEAD, new File(workspace), SVNDepth.INFINITY); }else{ SVNUtil.update(clientManager, ws, SVNRevision.HEAD, SVNDepth.INFINITY); } return true; } /** * 提交项目到SVN * @param project * Project * @return */ public boolean commitProjectToSvn(Project project) { SVNClientManager clientManager = SVNUtil.authSvn(project.getSvnUrl(), username, password); clientManager.getCommitClient().setEventHandler(new CommitEventHandler()); File wc_project = new File( workspace + "/" + project.getName()); checkVersiondDirectory(clientManager,wc_project); SVNUtil.commit(clientManager, wc_project, false, "svnkit"); return true; } /** * 递归检查不在版本控制的文件,并add到svn * @param clientManager * @param wc */ private void checkVersiondDirectory(SVNClientManager clientManager,File wc){ if(!SVNWCUtil.isVersionedDirectory(wc)){ SVNUtil.addEntry(clientManager, wc); } if(wc.isDirectory()){ for(File sub:wc.listFiles()){ if(sub.isDirectory() && sub.getName().equals(".svn")){ continue; } checkVersiondDirectory(clientManager,sub); } } } private void checkWorkCopy(Project project){ project.setSvnUrl(rb.getString("svn.url")); SVNClientManager clientManager = SVNUtil.authSvn(project.getSvnUrl(), username, password); SVNURL repositoryURL = null; // trunk try { // eg: http://svn.ambow.com/wlpt/bsp repositoryURL = SVNURL.parseURIEncoded(project.getSvnUrl()) .appendPath("trunk", false); } catch (SVNException e) { logger.error(e.getMessage(),e); } File wc = new File(workspace); File wc_project = new File( workspace + "/" + project.getName()); SVNURL projectURL = null; // projectName try { projectURL = repositoryURL.appendPath(project.getName(), false); } catch (SVNException e) { logger.error(e.getMessage(),e); } if(!SVNUtil.isWorkingCopy(wc)){ if(!SVNUtil.isURLExist(projectURL,username,password)){ SVNUtil.checkout(clientManager, repositoryURL, SVNRevision.HEAD, wc, SVNDepth.EMPTY); }else{ SVNUtil.checkout(clientManager, projectURL, SVNRevision.HEAD, wc_project, SVNDepth.INFINITY); } }else{ SVNUtil.update(clientManager, wc, SVNRevision.HEAD, SVNDepth.INFINITY); } } }
文章主题是svnkit的api操作。所以涉及到其它类的,可以忽略。svnkit有两套api,high level和low level 。high level是操作工作拷贝即working copy的。
我这儿用的就是high level。
checkWorkCopy方法里面,先检查当前指定的路径是否是一个working copy。如果是,执行update操作;
如果不是的话,分两种情况:
1. svn上已经有以此project命名的项目,可能svn上有了,但working copy被删了什么的。就将该project checkout下来;
2. svn上没有该project。此时checkout一个空的东西。SVNDepth.EMPTY,只是让我们的路径成为一个working copy,路径下出现一个.svn目录,svn上面的文件不会被checkout下来。因为我们的svn上可能项目很多。如果把整个上级目录checkout下来会很慢也浪费硬盘空间。
用 svnkit 执行commit操作,概况来说,流程如下:
1. 保证本地path是一个working copy。 即checkWorkCopy方法
2. woking copy可能发生添加,更新,删除等变化操作
3. 检查working copy里面的文件是否under version control。即checkVersiondDirectory方法
4. 执行commit操作
相关推荐
### 纯Java操作SVN——SVNKit API详解 #### 概述 在软件开发过程中,版本控制系统如Subversion(SVN)是必不可少的工具之一。为了更好地集成SVN功能到Java应用中,SVNKit提供了一套全面且强大的API。本文将详细...
本文将详细介绍如何使用SVNKit进行SVN的基本操作,包括上传、下载、提交、更新及版本控制等。 ##### 软件下载与安装 1. **下载Subversion服务器程序** 访问Subversion官方网站下载适合Windows系统的二进制安装...
SVNKit提供了丰富的API,覆盖了SVN的大多数功能,包括但不限于创建、检查、更新、提交、合并、分支、标记等操作。它通过模拟SVN命令行工具的行为,使得在Java环境中进行版本控制变得简单易行。SVNKit支持多种SVN数据...
SVNKit 是一个纯 Java 的 SVN 客户端库,它提供了与 SVN 服务器交互的全面功能,包括但不限于创建、更新、提交、分支、合并等操作。而 SVNKit-CLI 是 SVNKit 的命令行接口,允许通过 Java 程序调用 SVN 命令行工具。...
SVNKit不仅提供了命令行工具的功能,还支持通过编程接口(API)进行复杂操作,如创建、更新、提交、回滚、分支和合并等。 二、基础操作 1. **初始化仓库**:使用SVNKit可以创建新的Subversion仓库,这涉及到设置...
此外,除了直接检出(Checkout),SVNKit还支持其他操作,如更新(Update)、提交(Commit)、差异比较(Diff)等,可以根据实际需求灵活使用。对于大型项目,可能需要更复杂的逻辑,例如处理锁、冲突解决以及增量...
利用svnkit操作svn,实现对版本修改文件的导出,可以导出多个版本,.java文件将会在本地取出.class文件,导出后压缩成压缩包,主要用于服务器上的资源更新,不需要开发人员去找到对应的.class文件或其他文件压缩然后...
SVNKit是一个纯Java实现的Subversion库,允许开发者在Java应用中执行各种SVN操作,如检出、提交、更新、回滚等。以下是对标题和描述中所述知识点的详细解释: 1. **SVNKit**: SVNKit是一个强大的开源库,它提供了...
此外,SVNKit还可以用来执行其他SVN操作,如检出(Checkout)、提交(Commit)、更新(Update)、合并(Merge)等。对于更复杂的场景,如遍历仓库的文件历史、查看差异(Diff)等,SVNKit也提供了相应的API。 在实际应用中,...
SVNKit是一个强大的Java库,它实现了Subversion(SVN)客户端的功能,允许开发者在Java应用程序中集成版本控制系统。SVNKit提供了丰富的API,使得开发者能够执行诸如版本控制、提交、更新、比较、合并等SVN操作。在...
svnkit 1.8.11- javadoc(svn java编程文档)
svnkit是纯java实现的操作subversion的类库,使用起来非常的方便。官方文档提到,svnkit提供了三种类型的api:high level api、low level api和java hl api。本文简单介绍一下svnkit的high level api和low level api...
需要svnkit 使用方法 SVNUtil.getHistoryByDate("https://127.0.0.1:8443/svn/Test/mytestprotect/", "username", "password"); 如果jar 在我的其它资源里
SVNKit是一个纯Java实现的SVN客户端库,提供了丰富的API,可以实现对SVN的各种操作,如添加、删除、提交、更新等。 - 首先,需要在项目中引入SVNKit依赖,然后创建SVNClientManager实例,这是所有SVN操作的基础。 ...
Java操作SVN(Subversion)是一项...总之,Java操作SVN主要依赖于像SVNKit这样的库,通过它们提供的API接口实现版本控制的各种功能。通过熟练掌握这些库的使用,你可以轻松地在Java应用中整合SVN,实现版本管理的需求。
用java代码下载svn上的项目,包含svnkit的jar包,可以根据版本号下载项目,同路径下会删除原来下载过的项目。
SVNKit是一个强大的Java库,它允许开发人员在纯Java环境中与Subversion(SVN)版本控制系统进行交互。Subversion是一种广泛使用的版本控制系统,用于跟踪文件和目录的更改,便于团队协作。本案例中,我们关注的是...
SVNKit是一个强大的Java库,它实现了Subversion(SVN)客户端功能,允许开发者在Java应用程序中集成版本控制系统。这个“svnkit帮助文档API”是一个离线版的资源,提供了详细的信息来帮助开发者理解和使用SVNKit库。...
其他SVNKit的操作包括CheckOut,DoCommit,DoDiff,DoImport,DoUpdate,查看上次备注信息(message/log),DisplayFile(查看svn文件属性)DisplayRepositoryTree(查看某路径下的所有文件)
这个Java实现的工具首先会与SVN服务器进行交互,使用SVNKit或JIRA等Java库来访问SVN的API。这些库提供了与SVN仓库通信的功能,包括获取提交记录、差异信息等。然后,它会对每个提交进行迭代,获取该提交涉及的所有...