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

时间:2014-04-23 13:21:47

标签: java svn tortoisesvn commit

我们知道我们可以使用像Tortoise svn等工具执行svn操作,例如checkout,commit,update。

现在我正在尝试使用ant脚本执行svn checkout,commit,update等svn操作(因此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'文件夹中,我只想替换当前的本地目录。)

在这种情况下,任何人都可以指导我吗?

1 个答案:

答案 0 :(得分:1)

这个解决方案对我有用。

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

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 );
    }