Alireza Fattahi Alireza Fattahi - 4 months ago 23
Bash Question

SVN comapre two folders and export differences in Command Prompt

How is possible to compare two folders in SVN and export the differences to another folder in windows command prompt?

With tortoise svn gui, we can compare two URLS select all and export selection files to a folder. As mentioned in export changed files using tortoise svn to another directory.

Is it possible to do it from command prompt ?!

I see list of commands at https://tortoisesvn.net/docs/nightly/TortoiseSVN_en/tsvn-automation.html but could not find any thing.

I find an script at https://www.electrictoolbox.com/subversion-export-changed-files-cli/ but it with was for the linux,

Answer Source

I changed the shell script for Linux you mentioned to work with Windows. The first variant (svn-export.bat) works with two different revisions in a repository. The second variant (svn-localexport.bat) will work with two local directories.

It uses the svn diff --summarize -r revision-from:revision-to repository as svn command to work. Create a batch file: svn-export.bat copy the following content into it and use it by:

svn-export revision-from revision-to repository target-directory

svn-export.bat:

@echo off
setlocal enabledelayedexpansion

set "INVPARAM="
if [%1] == [] set INVPARAM=1
if [%2] == [] set INVPARAM=1
if [%3] == [] set INVPARAM=1
if [%4] == [] set INVPARAM=1
if defined INVPARAM (
   echo "Please enter a revision from, revision to, SVN repository, and target directory"
   goto eof
)

rem set up nice names for the incoming parameters to make the script more readable
set "revision_from=%1"
set "revision_to=%2"
set "repository=%3"
set "target_directory=%4"

rem the findstr is needed so we only get added/modified files and not the deleted ones or anything else
set "svnCommand=svn diff --summarize -r%revision_from%:%revision_to% %repository% ^| findstr /B "[AM]""

if not exist "%target_directory%" ( mkdir "%target_directory%" )

rem go into target directory
pushd "%target_directory%"
for /f "delims=" %%L in ('%svnCommand%') do (
   rem convert line like: "A       http://..." to "http://..."
   set "filename=%%L"
   rem echo.before: ^<!filename!^>
   set "find=*%repository%/"
   call set filename=%%filename:!find!=%%
   rem echo.after:  ^<!filename!^>

   rem don't export if it's a directory we've already created
   if not exist "!filename!" (
      for %%F in ("!filename!") do set "directory=%%~dpF"
      if not exist "!directory!" ( mkdir "!directory!" )
      svn export -r %revision_to% %repository%/!filename! "%cd%\!filename!"
   )
)
popd

rem to summarize any deleted files or directories at the end of the script uncomment the following lines
rem echo.Deleted files:
rem svn diff --summarize -r%revision_from%:%revision_to% %repository% | findstr /B "[D]"

:eof

The next script is nearly the same but it compares two local directories that are managed by svn. Therefore it uses: svn diff --summarize --old folder-old --new folder-new as svn command. Use it via:

svn-localexport folder-old folder-new target-directory

svn_localexport.bat:

@echo off
setlocal enabledelayedexpansion

set "INVPARAM="
if [%1] == [] set INVPARAM=1
if [%2] == [] set INVPARAM=1
if [%3] == [] set INVPARAM=1
if defined INVPARAM (
   echo "Please enter a folder old, folder new, and target directory"
   goto eof
)

rem set up nice names for the incoming parameters to make the script more readable
set "folder_old=%1"
set "folder_new=%2"
set "target_directory=%3"

pushd "%folder_old%"
set "folder_old_abs=%cd%"
popd
pushd "%folder_new%"
set "folder_new_abs=%cd%"
popd

rem the findstr is needed so we only get added/modified files and not the deleted ones or anything else
set "svnCommand=svn diff --summarize --old "%folder_old_abs%" --new "%folder_new_abs%" ^| findstr /B "[AM]""

if not exist "%target_directory%" ( mkdir "%target_directory%" )

rem go into target directory
pushd "%target_directory%"
for /f "delims=" %%L in ('%svnCommand%') do (
   rem convert line like: "A       C:\Users\...\src.c" to "src.c"
   set "filename=%%L"
   rem echo.before: ^<!filename!^>
   set "find=*%folder_old_abs%\"
   call set filename=%%filename:!find!=%%
   rem echo.after:  ^<!filename!^>

   rem don't export if it's a directory we've already created
   if not exist "!filename!" (
      for %%F in ("!filename!") do set "directory=%%~dpF"
      if not exist "!directory!" ( mkdir "!directory!" )
      echo copy "%folder_new_abs%\!filename!" "%cd%\!filename!"
      copy "%folder_new_abs%\!filename!" "%cd%\!filename!"
   )
)
popd

rem to summarize any deleted files or directories at the end of the script uncomment the following lines
rem echo.Deleted files:
rem svn diff --summarize --old "%folder_old_abs%" --new "%folder_new_abs%" | findstr /B "[D]"

:eof

Note that both batch scripts doesn't overwrite target files if they are already exists. If you want to change that remove the corresponding if statement.