Fix svn:externals cached in working copy

The goal was to change an external reference and make it a part of the repository.  So from this:

repo
\-foo -> external: https://....

To this:

repo
\-foo (included in repo directly)

The procedure for this would be:

  1. Removing the externals reference
    repo$ svn pd svn:externals .
  2. Adding the content
    svn add foo
  3. And committing it
    svn ci -m 'Include foo in repo instead of external reference'

However there’s actually an additional step needed after step 1: committing the removal of the externals definition. Otherwise the working copy can get corrupted. I managed to get the working copy in a reasonable state except the foo directory was still recognised as an external.

As it turns out the list of externals in a working copy is stored in .svn/wc.db. Since the update around the removal of the externals reference failed halfway the entries from this database were not removed. Luckily it’s a standard, sqlite database so using the sqlite3 tool it’s possible to remove entries from the EXTERNALS table.

repo$ sqlite3 .svn/wc.db
SQLite version 3.8.2 2013-12-06 14:53:30
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
ACTUAL_NODE    NODES          PRISTINE       WC_LOCK
EXTERNALS      NODES_BASE     REPOSITORY     WORK_QUEUE
LOCK           NODES_CURRENT  WCROOT
sqlite> select * from EXTERNALS;
1|foo||2|normal|dir||||
sqlite> delete from externals where local_relpath = 'foo';
sqlite> .quit
repo$

So far it seems that it didn’t do any damage.
Of course if the working copy is small and clean then checking it out might be a simpler and faster solution. In my case it was a 20G working copy so I was trying to find a way around it.