使用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 );

  

  

  

  

  

posted @ 2019-07-23 11:04  margo  阅读(1297)  评论(0)    收藏  举报