如何在两个SVN修订版之间导出已更改的文件

时间:2011-09-07 14:29:58

标签: svn

如何在SVN中导出已在两个修订版之间更改的已更改文件。我需要通过命令行或使用任何脚本(具有适当的文件夹结构)的解决方案。另外,我需要基于Windows的解决方案。

e.g。某事:

export {svn diff --summarize -r 50:HEAD}

我想要一个目录树,其中包含文件的副本,其中的任何修订版本都在50以上

6 个答案:

答案 0 :(得分:12)

这是一个很好的分步教程,使用TortoiseSVN的比较修订导出选择到... 功能:

http://www.electrictoolbox.com/tortoisesvn-exporting-changed-files/

答案 1 :(得分:10)

据我所知,svn没有提供这样的功能。但您可以使用SharpSVN编写一个简单的c#程序来执行此操作。这是您可以使用的示例。在此示例中,我将整个更改的文件从版本100更改为200。

using SharpSvn;
using System.IO;
using System.Collections.ObjectModel;
using Microsoft.VisualBasic;

namespace SvnDiffExporter
{
    class Program
    {
        static void Main(string[] args)
        {
            SvnClient client = new SvnClient();
            SvnRevisionRange range = new SvnRevisionRange(100, 200);
            MemoryStream result = new MemoryStream();

            Collection<SvnLogEventArgs> items;
            SvnLogArgs logargs = new SvnLogArgs(range);
            client.GetLog(@"e:\Artifacts", logargs, out items);

            int i = 0;
            string [] path = new string[255];
            foreach (SvnLogEventArgs ar in items)
            {
                foreach (SvnChangeItem changeitem in ar.ChangedPaths)
                {
                    if (changeitem.Action != SvnChangeAction.Delete)
                    {
                        path[i] = changeitem.Path;
                        i++;
                    }
                }
            }

            string localpath = @"c:\data";
            foreach (string str in path)
                client.Export(str, localpath);
        }
    }
}

答案 2 :(得分:4)

我创建了一个批处理文件,用于导出修订版之间更改的文件。

@echo off

FOR /F "tokens=1,2" %%I IN ('svn diff --summarize -r %1') DO (
    IF NOT %%I == D (
        IF NOT EXIST %2\%%J\.. mkdir %2\%%J\..

        svn export --depth empty -q --force %%J %2\%%J
        echo %2\%%J
    )
)

要使用它,您只需在命令行上指定修订版本或修订版本范围,并指定导出文件的目标位置。

C:\YourRepository>svnexport.bat 1:10 C:\Export

答案 3 :(得分:1)

这是用bash脚本编写的另一个选项:

#!/bin/bash

##############################
# settings and inicilization #
##############################

SVN_SOURCE="https://svn.example.com/trunk/"
REV_PATH="/var/www/revisions/example.com/"

TIME_SPENT=$(date +%s)
REV=$(svn info $SVN_SOURCE | grep Revision | cut -d ' ' -f 2)
PREV=0
VERBOSIVE=0

USAGE_INFO="$(basename "$0") [-r REVISION_NUM] [-i PREVIOUS_REVISION_NUM] -- make an incremental svn export

where:
  -i  previous revision (default: 0)
  -h  show this help text
  -r  revision to export (default: $REV)
  -v  verbosive mode. show fetched files

current settins:
  SVN_SOURCE: $SVN_SOURCE
  REV_PATH:   $REV_PATH
"

while getopts r:i:hv option; do
  case "$option" in
    i)  PREV=$OPTARG
        ;;
    h)  echo "$USAGE_INFO"
        exit
        ;;
    r)  REV=$OPTARG
        ;;
    v)  VERBOSIVE=1
        ;;
  esac
done

EV_PATH=$REV_PATH$REV"/"

##############################
#         functions          #
##############################

promtYesOrDie(){
  while true; do
    read -e -p "$1 (y/n): " -i "y" yn
    case $yn in
      [Yy] ) break;;
      [Nn] ) echo "spent: "$((`date +%s` - $TIME_SPENT))"s"
             echo "bye bye"
             exit
             ;;
         * ) echo "Please answer (y)es or (n)o.";;
    esac
  done
}

doIncrementalExport(){
  PREV_PATH=$REV_PATH$PREV"/"
  if [ -d $PREV_PATH ]; then
    echo "copying files from: $PREV_PATH"
    cp -f -r "$PREV_PATH." $EV_PATH
    echo "fetching added and modified files since revision $PREV..."
    for FILE_SRC in $(svn diff --summarize -r $PREV:$REV $SVN_SOURCE | awk '/[AM]/ {print $2}'); do
      FILE_PATH=$(echo $FILE_SRC | sed -e "s{$SVN_SOURCE{{");
      if [ ! -d "$EV_PATH$FILE_PATH" ]; then
        TRG_DIR="$EV_PATH$(dirname $FILE_PATH)"
        mkdir -p $TRG_DIR
        svn export -r$REV -q --force $FILE_SRC "$EV_PATH$FILE_PATH"
        if [ $VERBOSIVE -eq 1 ]; then
          echo "$EV_PATH$FILE_PATH"
        fi
      fi
    done
    echo "removing deleted files and folders since revision $PREV ..."
    for FILE_SRC in $(svn diff --summarize -r $PREV:$REV $SVN_SOURCE | awk '/D/ {print $2}'); do
      FILE_PATH=$(echo $FILE_SRC | sed -e "s{$SVN_SOURCE{{");
      rm -r "$EV_PATH$FILE_PATH"
      if [ $VERBOSIVE -eq 1 ]; then
        echo "$EV_PATH$FILE_PATH"
      fi
    done
  else
    echo "previous revision does not exist at: $PREV_PATH"
    exit;
  fi
}

##############################
#       main function        #
##############################

if [ $PREV -eq 0 ]; then
  promtYesOrDie "Do you want to do full export instead of incremental, for revision $REV of repo: [$SVN_SOURCE]"
  echo "fatching source ..."
  if [ $VERBOSIVE -eq 1 ]; then
    svn export -r$REV --force $SVN_SOURCE $EV_PATH
  else
    svn export -r$REV -q --force $SVN_SOURCE $EV_PATH
  fi
else
  promtYesOrDie "Do you want to do incremental export, for revision renge $PREV:$REV of repo: [$SVN_SOURCE]"
  doIncrementalExport
fi

echo "spent: "$((`date +%s` - $TIME_SPENT))"s"
echo [done]

我使用the complete scrip在LAMP生产环境中进行增量svn导出。

答案 4 :(得分:0)

如果我理解你的问题,你对修订之间的全局补丁不感兴趣。在这种情况下,您需要将每个修订导出到一个单独的目录中,然后使用Beyond Compare之类的工具(或类似WinMerge之类的任何东西)来识别修改过的文件。

但是,如果您的构建目录受版本控制,那么您最好创建一个补丁并将其应用于其中。

答案 5 :(得分:0)

尽管如果可以使用C#解决方案,@ hsalimi的帖子可能会起作用,但是@kicken的帖子作为Windows解决方案非常有效。

不幸的是,我找不到使用存储库的方法。我必须先检出所需目录的修订版本,然后在“工作副本”目录上运行脚本。

但是我无法使用它。 这个小的重写对我有用:

FOR /F "tokens=1,2,3" %%I IN ('svn diff --summarize -r %1 %3') DO (
    IF NOT %%I == D (
        IF NOT EXIST %2\ mkdir %2\
        svn export --depth empty -q --force %%J %2
        echo exported: %2
    )
)

要运行它,还需要SVN_URL:

C:\YourRepository>svnexport.bat 1:10 C:\Export <pathToWorkingDirectory>

(我知道这是一篇非常古老的文章,但是感谢您@kicken结束了我对解决方案的长期搜索)