【问题标题】:Process only changed files仅处理更改的文件
【发布时间】:2012-10-17 10:01:34
【问题描述】:

什么:
使用 jenkins,我只想定期处理来自 SVN 的更改文件,并将处理的输出提交回 SVN。

原因:
我们正在将二进制文件提交到 SVN(我们正在使用 Oracle Forms 并正在提交 fmb-Files)。我创建了一个将 fmb 导出为 xml 的脚本(使用 Oracle 的原始 Fmb2XML 工具),然后我将 XML 转换为我们也想要提交的纯源代码。这使我们能够 greping,查看更改,....

问题:
目前我只能检查所有内容,转换整个目录并将整个目录提交回 SVN。但由于所有纯文本文件都是新生成的,它们在 SVN 中似乎发生了变化。我只想提交已更改的。

谁能帮我解决这个问题?

【问题讨论】:

    标签: svn jenkins


    【解决方案1】:

    我安装了 Groovy 插件,配置了 Groovy 语言并创建了一个脚本,我将其作为“系统 Groovy 脚本”执行。脚本如下所示:

    import java.lang.ProcessBuilder.Redirect
    
    import hudson.model.*
    import hudson.util.*
    import hudson.scm.*
    import hudson.scm.SubversionChangeLogSet.LogEntry
    
    // uncomment one of the following def build = ... lines
    
    // work with current build
    def build = Thread.currentThread()?.executable
    
    // for testing, use last build or specific build number
    //def item = hudson.model.Hudson.instance.getItem("Update_SRC_Branch") 
    //def build = item.getLastBuild()   
    //def build = item.getBuildByNumber(35)   
    
    // get ChangesSets with all changed items
    def changeSet= build.getChangeSet()
    List<LogEntry> items = changeSet.getItems()
    
    def affectedFiles = items.collect { it.paths }
    
    // get filtered file names (only fmb) without path
    def fileNames = affectedFiles.flatten().findResults {
        if (it.path.substring(it.path.lastIndexOf(".") + 1) != "fmb") return null
        it.path.substring(it.path.lastIndexOf("/") + 1)
    }.sort().unique()
    
    // setup log files
    def stdOutFile = "${build.rootDir}\\stdout.txt"
    def stdErrFile = "${build.rootDir}\\stderr.txt"
    
    // now execute the external transforming
    fileNames.each {
        def params = [...]
        def processBuilder = new ProcessBuilder(params)
    
        // redirect stdout and stderr to log files
        processBuilder.redirectOutput(new File(stdOutFile))
        processBuilder.redirectError(new File(stdErrFile))
    
        def process = processBuilder.start()
        process.waitFor()
    
        // print log files
        println new File(stdOutFile).readLines()
        System.err.println new File(stdErrFile).readLines()
    }
    

    之后我使用带有“svn commit”的命令行来提交更新的文件。

    【讨论】:

      【解决方案2】:

      初步说明:在 SVN 行话中从 repo 获取文件是“checkout”,保存 到 repo - “commit”。不要混用 CVS 和 SVN 术语,这会导致误解

      为了获得修订(或修订集)中更改文件的列表,您可以使用

      • 简单的方法 - svn log 带有选项 -q -v。对于单个修订版,您还添加 -c REVNO,对于修订版范围:-r REVSTART:REVEND。可能额外的 --xml 会产生比纯文本更合适的输出

      您必须对日志的输出进行后处理才能获得纯列表,因为:日志包含一些对您无用的数据,如果日志为范围,您可以将同一文件包含在多个修订版中

      z:\>svn log -q -v -r 1190 https://subversion.assembla.com/svn/customlocations-greylink/
      ------------------------------------------------------------------------
      r1190 | lazybadger | 2012-09-20 13:19:45 +0600 (Чт, 20 сен 2012)
      Changed paths:
         M /trunk/Abrikos.ini
         M /trunk/ER-Telecom.ini
         M /trunk/GorNet.ini
         M /trunk/KrosLine.ini
         M /trunk/Rostelecom.ini
         M /trunk/Vladlink.ini
      ------------------------------------------------------------------------
      

      单个修订示例:您必须 log | grep trunk | sort -u,将 repo-base 添加到文件名

      • 更难的方法:使用额外的 SCM(即 - Mercurial)和 hgsubversion,您将获得更多(可能)带有 hg log --template "{files}\n" 的日志 - 仅 略微 因为您只会获得文件列表,但文件集在不同的修订版中以换行符分隔,修订版内的文件名以空格分隔

      【讨论】:

      • 好点!但是如果我遵循简单的路径,我将不得不编写一个脚本来解析 XML,然后我将不得不启动我的命令文件。所以我更容易从脚本中获取更改的信息。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      相关资源
      最近更新 更多