3

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

有谁知道这样做的方法?

4

4 回答 4

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>
于 2011-12-28T21:44:09.743 回答
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();
}
于 2011-04-06T19:06:32.497 回答
0

真的没有办法。从根本上说,SVN 工作在 checkout-edit-commit 模型上。可能有一些应用程序会将其隐藏起来,但它们仍会执行结帐,例如在幕后的临时目录。

于 2011-01-17T09:24:55.353 回答
-2

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

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

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

于 2011-01-17T12:20:14.897 回答