SVNKit:提交锁定文件时的SVNException

时间:2013-11-08 12:12:56

标签: svn commit svnkit

我想提交修改后的单个文件。根据{{​​3}},我使用以下代码:

public static SVNCommitInfo modifyFile(ISVNEditor editor, String dirPath, String filePath, InputStream is, long size) throws SVNException {
    try {
       SVNDeltaGenerator deltaGenerator = new SVNDeltaGenerator(); 

        editor.openRoot(-1);
        editor.openDir(dirPath, -1);
        editor.openFile(filePath, -1);
        editor.applyTextDelta(filePath, null);

        String chksm = deltaGenerator.sendDelta(filePath, is, editor, true);

        editor.textDeltaEnd(filePath);
        editor.closeFile(filePath, chksm);                                    

        /*
         * Closes the directory.
         */
        editor.closeDir();
        /*
         * Closes the root directory.
         */
        editor.closeDir();
        return editor.closeEdit();
    } catch (SVNException e) {
        if (editor != null) {
            try {
                editor.abortEdit();
            } catch (Exception ex) {
            }
        }    
        throw e;
    }
}

但不幸的是,我得到了一个异常,尽管提交是由拥有该外观的用户完成的:

org.tmatesoft.svn.core.SVNException: svn: E175002: PUT of '/spielwiese/!svn/wrk/e9019037-4201-0010-b534-277444c0b279/postcommittesten.txt': 423 Locked (http://localhost:8081)
svn: E175002: PUT request failed on '/spielwiese/!svn/wrk/e9019037-4201-0010-b534-277444c0b279/postcommittesten.txt'
at org.tmatesoft.svn.core.internal.wc.SVNErrorManager.error(SVNErrorManager.java:106)
at org.tmatesoft.svn.core.internal.wc.SVNErrorManager.error(SVNErrorManager.java:90)
at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:739)
at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:369)
at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.performHttpRequest(DAVConnection.java:728)
at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.doPutDiff(DAVConnection.java:514)
at org.tmatesoft.svn.core.internal.io.dav.DAVCommitEditor.closeFile(DAVCommitEditor.java:335)

我错了什么?什么是正确的方法?

我尝试使用http://wiki.svnkit.com/Committing_To_A_Repository。但是SVNCommitClient需要一个lokal工作副本来提交单个文件,我不想创建一个lokal工作副本。所以我想直接将文件提交到给定位置的存储库。

如何提交由当前用户锁定的文件?

2 个答案:

答案 0 :(得分:2)

Subversion和DAV不仅需要拥有锁的用户才能更改锁定的文件。您还必须拥有该文件的lock tokenreasoning for that用于防止一个程序持有锁而另一个程序修改同一用户运行的文件时出现问题。通常,锁令牌存储在工作副本上,在该工作副本上进行锁定,代码将在那里检索它。但是,您似乎尝试在没有工作副本的情况下提交对文件的更改。

如果您要提交锁定的文件,则需要在获得ISVNEditor时提供锁定令牌,而getCommitEditor不在您提供的代码中。在您提供的链接上的示例代码中,通过调用SVNRepository类上的Map方法来完成。有几个signatures of the getCommitEditor会将force带到您可以使用的锁定令牌。

为了拥有锁定令牌,您必须在创建锁定时存储它们。如果您没有锁定令牌,则可以简单地窃取锁定。您可以通过在SVNRepository参数设置为True的情况下调用lock method on the SVNRepository class来做到这一点(假设您有权在服务器上窃取锁)。 {{1}}上有一个getLockgetLocks方法,但我不记得你是否可以通过这种方式检索锁定令牌,可能值得一试。

答案 1 :(得分:0)

谢谢@Ben Reser。你击中了靶心。我使用了SVNRepository#getCommitEditor(String,ISVNWorkspaceMediator)。但确实是签名错误的方法。

现在我的代码读取并且一切正常:

// Discover lock on the file
SVNLock lockedItem = this.repository.getLock(fileUrl);
Map<String, String> locks = new HashMap<String, String>();
if (lockedItem != null) {
    locks.put(lockedItem.getPath(), lockedItem.getID());
}

// Retrieve a commiteditor and provide the lock tokens
ISVNEditor editor = this.repository.getCommitEditor(
    comment, locks, true, new WorkspaceMediator());
SVNCommitInfo commitInfo = SVNUtils.modifyFile(editor,
    dirUrl, fileUrl, fileReader, size);