105

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.

daveb
  • 74,111
  • 6
  • 45
  • 51
Niels Bosma
  • 11,758
  • 29
  • 89
  • 148
  • This question is also present at http://stackoverflow.com/questions/5118320/find-paths-with-svnexternal-properties-with-certain-string – Thiago Burgos Sep 02 '13 at 10:00

6 Answers6

167

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.

Wim Coenen
  • 66,094
  • 13
  • 157
  • 251
  • that just gives me a list of all the externals and where they point.. but not the 'location' of the external.. ie if i have lib\my_ex as an external i only get my_ex http:/svnlinkhere – ShoeLace Jun 17 '09 at 15:47
  • 4
    @ShoeLace: you must be working with an older SVN because in 1.6.1 the output *does* contain this information. – Wim Coenen Jun 18 '09 at 09:35
  • Good answer... but how can I do this in windows with TortoiseSVN? -- I don't have an 'svn.exe' on my computer, but I do have TortoiseSVN installed. – Eddified Jul 06 '10 at 19:15
  • @Eddified: there isn't really a command to do this with Tortoise, but I believe all externals are shown in the progress dialog at the end of an update. – Wim Coenen Jul 07 '10 at 10:05
  • This should work, but for me (pretty big repository) the task does not seem to come to an end - I aborted it after 3 hours without any feedback. Is there a way to make it faster by not going to full depth for example? – panschk Nov 29 '10 at 15:55
  • @panschk: No, there isn't. (There is a `--depth` option but this does not allow you to specify an arbitrary numeric depth.) – Wim Coenen Nov 29 '10 at 17:17
  • 1
    Sorry but I have to down-vote it since a) this will not output _all_ externals; fx, if we have external to folder and there is an external somewhere inside this folder - this won't show up b) the question is tagged tortoise svn, but answer is related to command line client – pmod Dec 08 '11 at 12:45
  • 3
    @pmod: a) I didn't know that, but it seems like an SVN bug to me rather than an error on my part. b) The TortoiseSVN 1.7 installer *includes* the command line client! – Wim Coenen Dec 08 '11 at 14:28
  • @Wim a) will check if that this is a real bug or limitation - you may correct your answer b) yes, but not by default (just updated on my PC) – pmod Dec 08 '11 at 15:26
  • 1
    The recursiveness is with respect to the folder structure of the working copy where you invoke the command. It is not with respect to externals nested inside externals. So I don't think it is a bug. Otherwise, this would make the operation even more unusable in terms of duration. – Frank Rem Aug 24 '14 at 11:08
15

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.

Sebastian Celis
  • 12,185
  • 6
  • 36
  • 44
10

My workaround for TortoiseSVN:

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

DrRobotNinja
  • 1,381
  • 12
  • 14
  • It looks like TortoiseSVN does not recursively look for svn:externals within svn:externals, so this is the same as doing `svn propget svn:externals -R`. – paulie4 Jun 16 '17 at 15:09
0

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.

Anonymous Coward
  • 596
  • 1
  • 5
  • 5
0

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.

Daniel Alder
  • 5,031
  • 2
  • 45
  • 55
0

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
}
paulie4
  • 457
  • 3
  • 10