0

I want to commit a modified single file. According to http://wiki.svnkit.com/Committing_To_A_Repository I use the following code:

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

But unfortunatly I get an exception despite the the commit is done by the user who owns the look:

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)

What do I wrong? Whats the correct way?

I tried to use the SVNCommitClient. But the SVNCommitClient needs a lokal working copy to commit single files and I don't want to create a lokal working copy. So i want to directly commit the file into the Repository at a given location.

How do I commit a file, that is locked by the current user?

shylynx
  • 597
  • 1
  • 7
  • 25
  • What version is SVNKit? What is the version of the SVN server? What is the version of the SVN working copy format? Was the lock in the working copy acquired via SVNKit? – Chad Nouis Nov 08 '13 at 15:29
  • SVNKit 1.7.9.There is no working copy because we directly commit to the remote repository. – shylynx Nov 22 '13 at 14:54

2 Answers2

2

Subversion and DAV require more than just being the user who owns the lock in order to make changes to a locked file. You must also be in possession of the lock token for that file. The reasoning for that is to prevent an issue when one program holds the lock and another program modifies the file that are both being run by the same user. Typically the lock token is stored on a working copy where the lock is made and the code would retrieve it there. However, it seems that you're trying to commit changes to a file without a working copy.

If you want to commit to locked files you will need to provide the lock tokens when you get the ISVNEditor which is not in the code you've provided. In the example code on the link you provided, it's done by calling the getCommitEditor method on a SVNRepository class. There are a couple of signatures of the getCommitEditor that take a Map to the lock tokens that you can use.

In order to have the lock tokens you'll have to store them from when you created the lock. If you don't have the lock tokens you might be able to simply steal the lock. You can do that by calling the lock method on the SVNRepository class with the force argument set to True (assuming you have the permissions to steal locks on the server). There is a getLock and getLocks method on SVNRepository but I don't remember if you can retrieve the lock tokens that way, might be worth a try.

Ben Reser
  • 5,695
  • 1
  • 21
  • 29
0

Thanks @ Ben Reser. You hit the bullseye. I used SVNRepository#getCommitEditor(String, ISVNWorkspaceMediator). But indeed its the method with the wrong signature.

Now my code reads and all works fine:

// 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);
shylynx
  • 597
  • 1
  • 7
  • 25