Committing changed file via SVNKit without local c

2019-05-14 12:37发布

I'm using SVNKit to get the contents of a file from our repository. I would like to change that contents within the code and commit the changes back without having to checkout the file first. I searched the web already and only found solutions that require a checkout to the local file system.

Does anyone know a way for doing that?

标签: java svnkit
4条回答
SAY GOODBYE
2楼-- · 2019-05-14 13:15

Theoretically this should be feasible, but practical it seems to be impossible using SVNKit.

As far as I can see all check-in operations base directly or indirectly on org.tmatesoft.svn.core.wc.SVNCommitItem and this class requires a working copy file path in it's constructor.

You may be able to override this class and try to implement your own version which does not require a working-copy but I have not checked that in detail.

查看更多
成全新的幸福
3楼-- · 2019-05-14 13:26

I talked to the folks at TMate Software, and it seems this is indeed possible. The way they explained it, yes, you can use a local file and generate checksums with the new content and send that to Subversion, but (if anything) this is only going to help Subversion verify you have the correct and latest in your local copy. At the end of the day, Subversion is going to do its own diffs and deltas anyway.

So if you don't have a local copy, you can just create a checksum as if the file were new. Here's the rough code, extracted from my larger project. Note that checking the SVNDirEntry ahead of time isn't required, if you already know whether the file exists; I'm providing it here for explanatory purposes.

SVNDirEntry dirEntry = svnRepository.info(filePath, -1);
ISVNEditor editor = svnRepository.getCommitEditor("example modification", null, true, null);
editor.openRoot(-1);
if(dirEntry.getKind() == SVNNodeKind.NONE)
{
    editor.addFile(filePath, null, -1);
}
else
{
    editor.openFile(filePath, -1);
}
editor.applyTextDelta(filePath, null);
final SVNDeltaGenerator deltaGenerator = new SVNDeltaGenerator();
final String checksum = deltaGenerator.sendDelta(filePath, inputStream, editor, true);
editor.closeFile(filePath, checksum);
editor.closeDir(); //close the root
editor.closeEdit();

Don't forget, after getting a commit editor, to wrap everything up to closeEdit() in a try...catch block so that you can abort the edit if something goes wrong.

I've tried this and it passes all my tests using SVNKIt 1.3.7 (e.g. from Maven):

<repositories>
    <repository>
        <id>svnkit-repository</id>
        <name>SVNKit Repository</name>
        <url>http://maven.tmatesoft.com/content/repositories/releases/</url>
    </repository>
</repositories>
...
<dependency>
    <groupId>org.tmatesoft.svnkit</groupId>
    <artifactId>svnkit</artifactId>
    <version>1.3.7</version>
</dependency>
查看更多
三岁会撩人
4楼-- · 2019-05-14 13:30

There isn't really a way. Fundamentally, SVN works on a checkout-edit-commit model. There may be apps that hide that away from you, but they'll still be performing a checkout to e.g. a temporary directory behind the scenes.

查看更多
爷、活的狠高调
5楼-- · 2019-05-14 13:39

I just tried. You can get the bytes of the file to be modified. Change the contents in memory. Last, check in the code. Here is the sniped:

byte[] in = checkOutPom(project+"/"+ destinationPathQualifier + tag+ "/pom.xml");
BufferedReader bin = new BufferedReader(new InputStreamReader(
                new ByteArrayInputStream(in)));
MyPomHandler h = new MyPomHandler(); //replaces strings in the file
ByteArrayOutputStream os = new ByteArrayOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                os));
h.replace(bin, writer, "1.0.0-SNAPSHOT", tag);
ISVNEditor editor = getRepository().getCommitEditor(
                "Patching POM with tag:"+tag, null);
modifyFile(editor, project + "/" +  destinationPathQualifier + tag, project + "/" +  destinationPathQualifier + tag+"/pom.xml",in, os.toByteArray());

===================================================

public byte[] checkOutPom(String filename)
            throws SVNException {
    SVNProperties fileProperties = new SVNProperties();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    getRepository().getFile(filename, -1, fileProperties, baos);
    return baos.toByteArray();
}

==================================================

from svnkit sample code:

public SVNCommitInfo modifyFile(ISVNEditor editor, String dirPath,
            String filePath, byte[] oldData, byte[] newData)
            throws SVNException {   
    editor.openRoot(-1);    
    editor.openDir(dirPath, -1);    
    editor.openFile(filePath, -1);  
    editor.applyTextDelta(filePath, null);  
    SVNDeltaGenerator deltaGenerator = new SVNDeltaGenerator(); 
    String checksum = deltaGenerator.sendDelta(filePath,
                new ByteArrayInputStream(oldData), 0, new ByteArrayInputStream(
                        newData), editor, true);    
    editor.closeFile(filePath, checksum);   
    editor.closeDir();  
    editor.closeDir();  
    return editor.closeEdit();
}
查看更多
登录 后发表回答