java - 自动化 svn 进程的方法(使用 Java)

标签 java svn tortoisesvn commit

正如我们所知,我们可以使用 Tortoise svn 等工具执行 svn 操作,如 check out 、提交、更新。

现在我正在尝试使用 ant 脚本执行 svn 操作,如 svn check out 、提交、更新(这样 svn 进程会容易得多)。

我正在尝试使用 svnkit sdk 给定如下:

/*
 * ====================================================================
 * Copyright (c) 2004-2010 TMate Software Ltd.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://svnkit.com/license.html
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 * ====================================================================
 */
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNLogEntryPath;
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.io.ISVNEditor;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

/*
 * The following example program demonstrates how you can use SVNRepository to
 * obtain a history for a range of revisions including (for each revision): all
 * changed paths, log message, the author of the commit, the timestamp when the 
 * commit was made. It is similar to the "svn log" command supported by the 
 * Subversion client library.
 * 
 * As an example here's a part of one of the program layouts (for the default
 * values):
 * 
 * ---------------------------------------------
 * revision: 1240
 * author: alex
 * date: Tue Aug 02 19:52:49 NOVST 2005
 * log message: 0.9.0 is now trunk
 *
 * changed paths:
 *  A  /trunk (from /branches/0.9.0 revision 1239)
 * ---------------------------------------------
 * revision: 1263
 * author: sa
 * date: Wed Aug 03 21:19:55 NOVST 2005
 * log message: updated examples, javadoc files
 *
 * changed paths:
 *  M  /trunk/doc/javadoc-files/javadoc.css
 *  M  /trunk/doc/javadoc-files/overview.html
 *  M  /trunk/doc/examples/src/org/tmatesoft/svn/examples/wc/StatusHandler.java
 * ...
 * 
 */
public class History {
    /*
     * args parameter is used to obtain a repository location URL, a start
     * revision number, an end revision number, user's account name & password
     * to authenticate him to the server.
     */
    public static void main(String[] args) {
        /*
         * Default values:
         */
        String url = "svnUrl";
        String name = "username";
        String password = "password";
        long startRevision = 0;
        long endRevision = -1;//HEAD (the latest) revision
        /*
         * Initializes the library (it must be done before ever using the
         * library itself)
         */
        setupLibrary();

        if (args != null) {
            /*
             * Obtains a repository location URL
             */
            url = (args.length >= 1) ? args[0] : url;
            /*
             * Obtains the start point of the revisions range
             */
            startRevision = (args.length >= 2) ? Long.parseLong(args[1])
                    : startRevision;
            /*
             * Obtains the end point of the revisions range
             */
            endRevision = (args.length >= 3) ? Long.parseLong(args[2])
                    : endRevision;
            /*
             * Obtains an account name (will be used to authenticate the user to
             * the server)
             */
            name = (args.length >= 4) ? args[3] : name;
            /*
             * Obtains a password
             */
            password = (args.length >= 5) ? args[4] : password;
        }

        SVNRepository repository = null;

        try {
            /*
             * Creates an instance of SVNRepository to work with the repository.
             * All user's requests to the repository are relative to the
             * repository location used to create this SVNRepository.
             * SVNURL is a wrapper for URL strings that refer to repository locations.
             */
            repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url));
        } catch (SVNException svne) {
            /*
             * Perhaps a malformed URL is the cause of this exception.
             */
            System.err
                    .println("error while creating an SVNRepository for the location '"
                            + url + "': " + svne.getMessage());
            System.exit(1);
        }


        ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(name, password);
        repository.setAuthenticationManager(authManager);



        /*
         * Gets the latest revision number of the repository
         */
        try {
            endRevision = repository.getLatestRevision();
        } catch (SVNException svne) {
            System.err.println("error while fetching the latest repository revision: " + svne.getMessage());
            System.exit(1);
        }

        Collection logEntries = null;
        try {

            logEntries = repository.log(new String[] {""}, null,
                    startRevision, endRevision, true, true);

        } catch (SVNException svne) {
            System.out.println("error while collecting log information for '"
                    + url + "': " + svne.getMessage());
            System.exit(1);
        }
        for (Iterator entries = logEntries.iterator(); entries.hasNext();) {
            /*
             * gets a next SVNLogEntry
             */
            SVNLogEntry logEntry = (SVNLogEntry) entries.next();
            System.out.println("---------------------------------------------");
            /*
             * gets the revision number
             */
            System.out.println("revision: " + logEntry.getRevision());
            /*
             * gets the author of the changes made in that revision
             */
            System.out.println("author: " + logEntry.getAuthor());
            /*
             * gets the time moment when the changes were committed
             */
            System.out.println("date: " + logEntry.getDate());
            /*
             * gets the commit log message
             */
            System.out.println("log message: " + logEntry.getMessage());
            /*
             * displaying all paths that were changed in that revision; cahnged
             * path information is represented by SVNLogEntryPath.
             */
            String logMessage = "log message";

            try {
                 ISVNEditor editor = repository.getCommitEditor( logMessage , null /*locks*/ , true /*keepLocks*/ , null /*mediator*/ );

                History.copyDir(editor, "C:/svnCommitCode/src","svnurl/src", logEntry.getRevision());
            } catch (SVNException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


            if (logEntry.getChangedPaths().size() > 0) {
                System.out.println();
                System.out.println("changed paths:");
                /*
                 * keys are changed paths
                 */
                Set changedPathsSet = logEntry.getChangedPaths().keySet();

                for (Iterator changedPaths = changedPathsSet.iterator(); changedPaths
                        .hasNext();) {
                    /*
                     * obtains a next SVNLogEntryPath
                     */
                    SVNLogEntryPath entryPath = (SVNLogEntryPath) logEntry
                            .getChangedPaths().get(changedPaths.next());
                    /*
                     * SVNLogEntryPath.getPath returns the changed path itself;
                     * 
                     * SVNLogEntryPath.getType returns a charecter describing
                     * how the path was changed ('A' - added, 'D' - deleted or
                     * 'M' - modified);
                     * 
                     * If the path was copied from another one (branched) then
                     * SVNLogEntryPath.getCopyPath &
                     * SVNLogEntryPath.getCopyRevision tells where it was copied
                     * from and what revision the origin path was at.
                     */
                    System.out.println(" "
                            + entryPath.getType()
                            + " "
                            + entryPath.getPath()
                            + ((entryPath.getCopyPath() != null) ? " (from "
                                    + entryPath.getCopyPath() + " revision "
                                    + entryPath.getCopyRevision() + ")" : ""));
                }
            }
        }
    }

    /*
     * Initializes the library to work with a repository via 
     * different protocols.
     */
    private static void setupLibrary() {
        /*
         * For using over http:// and https://
         */
        DAVRepositoryFactory.setup();
        /*
         * For using over svn:// and svn+xxx://
         */
        SVNRepositoryFactoryImpl.setup();

        /*
         * For using over file:///
         */
        FSRepositoryFactory.setup();
    }


    private static SVNCommitInfo copyDir( ISVNEditor editor , String srcDirPath , String dstDirPath , long revision ) throws SVNException {
                    editor.openRoot( -1 );

                    editor.addDir( dstDirPath , srcDirPath , revision );
            System.out.println("done--------------------");
                    //Closes dstDirPath.
                    editor.closeDir( );

                    //Closes the root directory.
                   editor.closeDir( );

                   return editor.closeEdit( );
               }

}

我能够获得一些输出作为历史记录:

revision: 7
author: username
date: Wed Apr 23 15:47:58  2014
log message: testing

changed paths:
 A  /testCode/src

但是当我调用 SVNCommitInfo copyDir() 方法时出现以下错误:

org.tmatesoft.svn.core.SVNException: svn: E160013: '/testCode/!svn/bc/2/C:/svnCommitCode/src' path not found: 404 Not Found (http://svnUrl)

我同时提供源(我的本地系统目录路径)和目标路径(svn 目录路径),我在这里做错了什么? (意味着在 svn 上存在相同的“src”文件夹,我只想替换为当前本地目录。)

谁能在这方面指导我?

最佳答案

这个解决方案对我有用。

首先调用此方法getSVNClientManager 进行身份验证,它将返回clientManager,用于获取不同类型的svn 客户端实例以执行不同的 Activity 。

public SVNClientManager getSVNClientManager () throws IOException{
             SVNURL url = SVNURL
                  .parseURIDecoded("<path to the base svn repository>");                    
             SVNRepository repository = SVNRepositoryFactory.create(url, null);
             ISVNOptions myOptions = SVNWCUtil.createDefaultOptions(true);
            //provide svn username and password
            //username = name used to connect to svn
            //password = password used to connect to svn
            ISVNAuthenticationManager myAuthManager = SVNWCUtil
                .createDefaultAuthenticationManager("<username>", "<password>");
           repository.setAuthenticationManager(myAuthManager);
        //clientManager will be used to get different kind of svn clients instances to do different activities
       //like update, commit, view diff etc.
        SVNClientManager clientManager = SVNClientManager.newInstance(
                myOptions, myAuthManager);

return clientManager ;
} 

然后调用方法commitToSvn()

public void commitToSvn(SVNClientManager clientManager)
            throws SVNException {
        SVNCommitClient commitClient = clientManager.getCommitClient();
        File fileToCheckin = new File("LocalDir/SampleFileFolder/SampleFile1");
        boolean recursive = true;       
       SVNCommitInfo importInfo = commitClient
                .doImport(
                        fileToCheckin ,
                        SVNURL.parseURIDecoded("<path at which we want to check-in the file>"),
                        "testing svn kit integration", recursive);
        System.out.println(importInfo.getNewRevision());
    }

同样我们可以调用checkout方法exportFromSvn()

public void exportFromSvn(SVNClientManager clientManager) throws SVNException {
        SVNUpdateClient updateClient = clientManager.getUpdateClient();
        SVNURL url = SVNURL.parseURIDecoded("<svn url to export from>");
        //destination path
        File dstPath = new File("LocalDirNew");
        //the revision number which should be looked upon for the file path
        SVNRevision pegRevision = SVNRevision.create(<right svn revision number>);
        //the revision number which is required to be exported.
        SVNRevision revision = SVNRevision.create(<right svn revision number>);
        //if there is any special character for end of line (in the file) then it is required. For our use case, //it can be null, assuming there are no special characters. In this case the OS specific EoF style will //be assumed
        String eolStyle = null;
        //this would force the operation
        boolean force = true;
        //Till what extent under a directory, export is required, is determined by depth. INFINITY means the whole subtree of that directory will be exported
        SVNDepth recursive = SVNDepth.INFINITY;
        updateClient.doExport(url, dstPath, pegRevision, revision, eolStyle, force, recursive );
    }

关于java - 自动化 svn 进程的方法(使用 Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23245684/

相关文章:

java - 安卓谷歌地图 : Combine scrollBy with zoomBy for simultaneous pan & zoom

java - Sonarqube - 如何为 Kotlin 项目启用许可证检查器?

mysql - 如何体面地跟踪SVN对数据库结构的修改?

java - 在 Java 中针对特定情况停止 for 循环中的增量

java - 提取所有 TD 或 TH 列

svn - 这个 405 Method Not Allowed svn 错误是什么?

svn - 在 TortoiseSVN 中搁置和审查代码

svn - Subversion 工作流 : force update, 构建,提交前测试

svn - 获取之前的SVN更新日志

svn - Tortoise SVN 是否允许在存储库中搜索?