在没有本地结账的情况下通过SVNKit提交更改的文件?

时间:2011-01-17 09:18:18

标签: java svnkit

我正在使用SVNKit从我们的存储库中获取文件的内容。我想在代码中更改内容并提交更改,而不必先检出文件。我已经搜索过网络,只找到了需要结账到本地文件系统的解决方案。

有没有人知道这样做的方法?

4 个答案:

答案 0 :(得分:6)

我和TMate Software的人们谈过,看来这确实是可能的。他们解释它的方式,是的,您可以使用本地文件并使用新内容生成校验和并将其发送到Subversion,但是(如果有的话)这只会帮助Subversion验证您的本地副本中是否有正确和最新的内容。在一天结束时,无论如何,Subversion将会做自己的差异和增量。

因此,如果您没有本地副本,则可以创建校验和,就像文件是新的一样。这是从我的大项目中提取的粗略代码。请注意,如果您已经知道该文件是否存在,则不需要提前检查SVNDirEntry;我在这里提供它是出于解释目的。

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

在获取提交编辑器后,请不要忘记在closeEdit()块中将所有内容包装到try...catch,以便在出现问题时可以中止编辑。

我试过这个并且它使用SVNKIt 1.3.7(例如来自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>

答案 1 :(得分:0)

没有办法。从根本上说,SVN适用于checkout-edit-commit模型。可能有应用程序隐藏了远离您的应用程序,但他们仍然会执行结帐,例如幕后的临时目录。

答案 2 :(得分:0)

我刚试过。您可以获取要修改的文件的字节。更改内存中的内容。最后,检查代码。这是狙击:

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

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

来自svnkit示例代码:

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

答案 3 :(得分:-2)

理论上这应该是可行的,但实际上似乎不可能使用SVNKit。

据我所知,所有签入操作都直接或间接地基于org.tmatesoft.svn.core.wc.SVNCommitItem,并且此类需要在其构造函数中使用工作副本文件路径。

您可以覆盖此类并尝试实现您自己的版本,该版本不需要工作副本,但我没有详细检查过。