List all svn:externals recursively?

SvnTortoisesvn

Svn Problem Overview


How can I get a list of all svn:externals (recursively) in a directory? Is there any utility for this?

(I'm using Windows (and tortoise))

I have a bunch of svn:externals linking to different shared parts of my project and I when I branch it's usually quite error prone to find all externals and changed them so that the link to paths within the new branch.

Svn Solutions


Solution 1 - Svn

Do the following in the root of your working copy:

svn propget svn:externals -R

As discussed in the comments below, this does not list externals in externals.

Note for TortoiseSVN users: there is an option in the TortoiseSVN installer to also install the SVN command line client. This option is not enabled by default.

Solution 2 - Svn

Manually changing all of those external properties sounds tedious. Have you looked at the new functionality for externals added in Subversion 1.5?

> Subversion 1.5 takes a huge step in relieving these frustrations. As mentioned earlier, the URLs used in the new externals definition format can be relative, and Subversion provides syntax magic for specifying multiple flavors of URL relativity. > > ../ > >     Relative to the URL of the directory on which the svn:externals property is set > > ^/ > >     Relative to the root of the repository in which the svn:externals property is versioned > > // > >     Relative to the scheme of the URL of the directory on which the svn:externals property is set > > / > >     Relative to the root URL of the server on which the svn:externals property is versioned

Maybe one of those would help? I guess it depends on exactly how you are branching and what your repository structure looks like.

Solution 3 - Svn

My workaround for TortoiseSVN:

Open the "Branch/tag..." dialog from the SVN context menu. The lower dialog shows all externals including nested externals.

Solution 4 - Svn

Maybe, as a workaround, you could structure your project in such a way that all externals are set on the same folder, for example on the project folder just below Trunk. (This doesn't mean that all external folders have to be at the same depth by the way.) Then you can right-click on your project folder, then Properties..., then the tab Subversion, then Properties... then double-click svn:externals.

Solution 5 - Svn

I used the answer of Wim Coenen and wrote the following script to create a list of all revisions:

getSvnRevs() {
  cd "$1"
  wcver="$(svnversion)"
  [ -n "$wcver" ] || panic "Unable to get version for $wcdir"
  echo "$1: $wcver"
  svn propget svn:externals -R | while read a b c d e; do
    [ -n "$a" ] || continue
    if [ "$b" = "-" ]; then
      wcparent="$a"
      wcdir="$wcparent/$c"
      [ -z "$e" ] || panic "Invalid format #1"
    else
      [ -n "$wcparent" ] || panic "Invalid format #2"
      wcdir="$wcparent/$a"
      [ -z "$c" ] || panic "Invalid format #3"
    fi
    [ -d "$wcdir" ] || panic "Invalid directory: $wcdir"
    wcver="$(svnversion "$wcdir")"
    [ -n "$wcver" ] || panic "Unable to get version for $wcdir"
    echo "$1/$wcdir: $wcver"
  done
}

Fortunately, I don't have nested externals, so I didn't have to test this and I guess it wouldn't work. But if you need this, it's probably enough to just call this function recursively. Also, I never tested with filenames which need escaping. It likely won't work then.

DISCLAIMER: I know the original question was about windows, and shell script won't work there unless you're using cygwin or similar.

Solution 6 - Svn

I took Daniel Alder's answer, removed the svnversion calls, and made it recursive (NOTE: read a b c d e doesn't work if there's a space in either the source or destination). This is a bash script, so you'll either need something like Cygwin or use the Windows Subsystem for Linux.

getSvnExternals() {
  svnbase="$1"
  svnpath="$2"
  svn propget svn:externals -R "$svnbase/$svnpath" 2> /dev/null | while read a b c d e; do
    [ -n "$a" ] || continue
    if [ "$b" = "-" ]; then
      wcparent="$a"
      external="$c"
      wcdir=$(echo "$wcparent/$d" | sed s#^./##)
      [ -z "$e" ] || echo "WARNING: Invalid format #1. line='$a $b $c $d $e'"
    else
      [ -n "$wcparent" ] || echo "WARNING: Invalid format #2. wcparent=$wcparent"
      external="$a"
      wcdir=$(echo "$wcparent/$b" | sed s#^./##)
      [ -z "$c" ] || echo "WARNING: Invalid format #3. line='$a $b $c $d $e'"
    fi
    echo "$1/$wcdir: $external"
    ## recurse into external directory
    [ -d "$wcdir" ] && getSvnExternals "$1/$wcdir"
  done
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNiels BosmaView Question on Stackoverflow
Solution 1 - SvnWim CoenenView Answer on Stackoverflow
Solution 2 - SvnSebastian CelisView Answer on Stackoverflow
Solution 3 - SvnDrRobotNinjaView Answer on Stackoverflow
Solution 4 - SvnAnonymous CowardView Answer on Stackoverflow
Solution 5 - SvnDaniel AlderView Answer on Stackoverflow
Solution 6 - Svnpaulie4View Answer on Stackoverflow