在没有 Atlassian Fisheye 的情况下以编程方式检索 SVN 提交

Retrieving SVN Commits programmatically, without Atlassian Fisheye

我们目前正在使用 Atlassian JIRA 来处理缺陷和定期开发周期。我们使用 SVN Repository 来维护代码。我们最近做的一件事是使用 SVNKit 1.7.4 和 Atlassian Fisheye 开发一个自定义实用程序,它给出了一个 JIRA id 列表,从 SVN 获取提交。这是通过使用 Atlassian Fisheye REST services.Once 我们得到这个文件路径列表,我们将工作副本与目标进行比较,并使用 SVNDeltaGenerator 的 applyTextDelta 方法修改文件,然后在目标分支中签入。我们需要的最重要的一件事情是来自 SVN 的特定 JIRA ID 的变更集。一旦我们将 JIRA ID 作为输入,Fisheye 就会从 SVN 获取详细信息并将其作为列表发回。

现在,如果我们需要绕过 Fisheye 并使用 SVN 内部功能来实现 Fisheye 为我们所做的同样的事情,我们需要做什么?我们遵循提交消息始终包含 JIRA ID 的 svn 钩子,是否有一种方法可以检索完整的更改集,包括文件名、路径、使用特定 JIRA 添加的目录,比如使用提交消息?我们的开发人员使用的示例提交消息之一是 "ND-9181: This file is related to ABC and has fix for DE119919"。这里的 ND-9181 是 JIRA ID。类似的,所有对 SVN 的提交都必须具有 JIRA ID。

我要的是在下面指定SVN:

从 SVN Files/File Paths/Directories 中查找所有 Commit_Msg ='ND-9817'

如果有人曾经实现过此操作或知道使用 SVNKit 以编程方式执行此操作的方法,请告诉我。

Subversion CLI 从 1.8 版本开始支持 svn log 命令的 --search 选项,因此如果可以使用 CLI,您可以简单地解析此命令的结果:

svn log -v --search ND-9817

奇怪的是,此功能在最新的 SVNKit API 中不可用(他们提供的 Javadocs 是针对 1.7 版本的,但我试验了最新的 1.8.11 版本)。因此,SVNKit 解决方案似乎需要手动过滤。为了简洁起见,我省略了包、导入和主要方法。

public class q34800380 {
    public void grepLogMessages(String url, String message) throws SVNException {
        SvnOperationFactory svnOperationFactory = new SvnOperationFactory();
        try {
            SvnLog log = svnOperationFactory.createLog();
            log.setSingleTarget(SvnTarget.fromURL(SVNURL.parseURIEncoded(url)));
            log.addRange(SvnRevisionRange.create(SVNRevision.create(0), SVNRevision.HEAD));
            log.setDiscoverChangedPaths(true);
            log.setReceiver(new GrepLogReceiver(message));
            log.run();
        } finally {
            svnOperationFactory.dispose();
        }
    }
    private class GrepLogReceiver implements ISvnObjectReceiver<SVNLogEntry> {
        private String message;
        public GrepLogReceiver(String message) {
            this.message = message; 
        }
        @Override
        public void receive(SvnTarget target, SVNLogEntry le) throws SVNException {
            if (le.getMessage() != null && le.getMessage().contains(message)) {
                System.out.println("rev #" + le.getRevision() + ": " + le.getMessage());
                Map<String, SVNLogEntryPath> cps = le.getChangedPaths();
                for (Map.Entry<String, SVNLogEntryPath> e : cps.entrySet()) {
                    SVNLogEntryPath lep = e.getValue();
                    System.out.println(lep.getType() + " " + lep.getPath());
                }
            }
        }
    }
}