开发者

How to export changed files between two SVN revisions

How can I export changed files in SVN that have changed between two revisions. I need a solution either via command line or by using any scripts (with proper folder structure). In a开发者_Python百科ddition, I need windows based solution.

e.g. sth like:

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

I want a directory tree with a copy of the files that where changed in any revision from 50 on


As far as I know, svn does not provide such a feature. But you may write a simple c# program using SharpSVN to do it. Here is a sample that you can use. In this sample, I am getting the whole changed file from revision 100 to 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);
        }
    }
}


Here is a great step by step tutorial which do this with TortoiseSVN's Compare revisions and Export selection to... functions:

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


I created a batch file that will work to export the files changed between revisions.

@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
    )
)

To use it you just specify the revision or revision range on the command line and a destination for exported files.

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


Here is an other option written in bash script:

#!/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]

I use the complete scrip to do an incremental svn export on a LAMP production environment.


Although the post by @Hoodi may work if one is able to us a C# solution, the post by @kicken is extremely efficient as a windows solution.

Unfortunately I found no way to use the repository. I had to check out the revision I need to a directory first, then run the script on the "working copy" directory.

I was unable to use it as posted however. This little re-write worked for me:

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
    )
)

To run it needs the SVN_URL as well:

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

(I know this was a very old post, but THANK YOU @kicken for ending my LONG search for solution)


If I understand your question properly, you are not interested in a global patch between revisions. In this case, you need to export each revision in a separate directory, then use a tool like Beyond Compare (or anything equivalent like WinMerge) to identify modified files.

But, if your build directory is under version control, then you would be better off creating a patch and apply it on it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜