【问题标题】:Committing changed file via SVNKit without local checkout?在没有本地结帐的情况下通过 SVNKit 提交更改的文件?
【发布时间】:2013-10-10 12:36:24
【问题描述】:

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

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

【问题讨论】:

    标签: java svnkit


    【解决方案1】:

    我与 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>
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我知道这本质上是 SVN 的工作方式。但我敢肯定,像 SVNKit 这样的库可以完美地解决这个问题。
      • 奥利,这不是真的。从最终用户的角度来看,确实存在一个 checkout/edit/commit 模型,但 Subversion 协议并没有将调用者限制为该模型。上面 Oscar 的示例演示了如何在不先检出文件的情况下执行提交 - 它将“oldData”传递给 delta 生成器,但这不是必需的,delta 可能不是指“以前的”版本。
      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-06-17
          • 1970-01-01
          • 2015-09-25
          • 2020-08-11
          • 2021-02-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多