SVN: Partial Checkouts

It is often useful to be able to partially checkout a project or a subset of related projects from a repository. Having such a partial working copy may be helpful to allow the joint commit of related changes to more than one project. Thus helps to “tie” the changes in the projects’ histories.

Here are a couple of scripts to assist that process: one Bash shell script, and the equivalent DOS Batch file.

The bash:

#!/bin/bash

### location (path) for the WORKING COPY
### [Cygwin (on Windows) / Linux path]
LOCAL="c:/path/to/dir/"

### location (URL) of the REPOSITORY
REPOS="http://server/svn_repos/"

### which BRANCH NAME within the repository to use
#BRANCH="trunk/"
BRANCH="branches/branch_name/"

### ===========================================================================

function main
{
 if [ ! -e "${LOCAL}" ]
 then
  ### checkout into existing working copy would perform a delete
  echo svn checkout --depth=empty "${REPOS}" "${LOCAL}"
  svn checkout --depth=empty "${REPOS}" "${LOCAL}" \
    || { echo "svn co fail" ; exit 1 ; }
 fi

 ### use these for very sparse checkouts, e.g.
 #svn_up_component project1/ doc/
 #svn_up_component project1/ src/
 #svn_up_component project2/ src/
 ### etc.

 ### use these for 'normal' partial checkouts
 svn_up_component project1/
 svn_up_component project2/
}

### ===========================================================================

function svn_up_component
{
 ### $1 = project (the bit before the branch name)
 ### $2 = sub-component (optional; the bit after the branch name)

 svn_up_rec_empty "${LOCAL}" "${1}${BRANCH}${2}"

 echo svn update --set-depth=infinity "${LOCAL}${1}${BRANCH}${2}"
 svn update --set-depth=infinity "${LOCAL}${1}${BRANCH}${2}" \
   || { echo "svn up infinity [${1}] [${2}] fail" ; exit 1 ; }
}

### ===========================================================================

function svn_up_rec_empty
{
 ### $1 = existing part of path
 ### $2 = path fragment to create

 _whole=$2
 _left=${2/\/*\//\/}
 _right=${2#*/}

 if [ ! -e "${1}" ]
 then
  echo svn update --set-depth=empty "${1}"
  svn update --set-depth=empty "${1}" \
    || { echo "svn up empty [${1}] fail" ; exit 1 ; }
 fi

 ### recursive call
 if [ "${_whole}" != "" ]
 then
  svn_up_rec_empty "${1}${_left}" "${_right}"
 fi
}

### ===========================================================================

main

The batch:

@echo off

setlocal

REM *** location (path) for the WORKING COPY
set LOCAL=C:/path/to/dir/

REM *** location (URL) of the REPOSITORY
set REPOS=http://server/svn_repos/

REM *** which BRANCH NAME within the repository to use
rem set BRANCH=trunk/
set BRANCH=branches/branch_name/

goto :main

REM *** =======================================================================

:main

if not exist %LOCAL% (
 REM *** checkout into existing working copy would perform a delete
 echo svn checkout --depth=empty %REPOS% %LOCAL%
 svn checkout --depth=empty %REPOS% %LOCAL% ^
   || (echo "svn co fail" & goto :EOF)
)

REM *** use these for very sparse checkouts, e.g.
rem call :svn_up_component project1/ doc/
rem call :svn_up_component project1/ src/
rem call :svn_up_component project2/ src/
REM *** etc.

REM *** use these for 'normal' partial checkouts
call :svn_up_component project1/
call :svn_up_component project2/

goto :EOF

REM *** =======================================================================

:svn_up_component
REM *** %1 = project (the bit before the branch name)
REM *** %2 = sub-component (optional; the bit after the branch name)

call :svn_up_rec_empty %LOCAL% %1%BRANCH%%2

echo svn update --set-depth=infinity %LOCAL%%1%BRANCH%%2
svn update --set-depth=infinity %LOCAL%%1%BRANCH%%2 ^
 || (echo "svn up infinity [%1] [%2] fail" & goto :EOF)

goto :EOF

REM *** =======================================================================

:svn_up_rec_empty

REM *** %1 = existing part of path
REM *** %2 = path fragment to create

set _whole=%2
set _right=%_whole:*/=%
if not "%_right%" == "" (
 call set _left=%%_whole:%_right%=%%
) else (
 set _left=%_whole%
)

if not exist "%1" (
 echo svn update --set-depth=empty %1
 svn update --set-depth=empty %1 ^
   || (echo "svn up empty [%1] fail" & goto :EOF)
)

REM *** recursive call
if not "%_whole%" == "" (
 call :svn_up_rec_empty %1%_left% %_right%
)

goto :EOF

REM *** =======================================================================

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.