使用svnkit api,純java操作svn,實現svn提交,更新等操作(修正版)

來源:互聯網
上載者:User

此篇是在上一篇基礎上修改了bug。


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 copyif(!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);// 提交到SVNcommitProjectToSvn(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.componentDocument 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. 修改.projecttry {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/bsprepositoryURL = 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;// trunktry {// eg: http://svn.ambow.com/wlpt/bsprepositoryURL = 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;// projectNametry {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操作





相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.