How to add branches to a non-standard Subversion repository in a way that is compatible with git-svn

I found myself in the unusual situation of having a Subversion repository which was created initially without the usual trunk, branches, and tags folders, but where the team found later that, you know, this newfangled “branches” idea might just come in useful after all. If that's all there was to it, I could have just added those folders in a regular commit and continued on. The tricky part was that we also wanted git-svn compatibility, and for it to recognize branches, it needs the folder structure to be in place from the first commit onward.

Unfortunately, there ain't no easy way to achieve this which also preserves the revision numbers. But it is possible. What I had to do was rewrite the first commit manually:

  1. Checkout the original repo at revision 1.
  2. Copy all the files to a new repo, but this time place it under a trunk top-level folder, ensuring everything is otherwise identical inside.
  3. Also add tags and branches top-level folders.
  4. Commit all those using the same commit message as the original.

Now, this commit still doesn't have the same metadata, so I had to then take an svndump of the new repo, and edit that dump so that the 0 and 1 commits have the same metadata as revisions 0 and 1 of the original repo's dump. I had to use a hex editor for this to prevent automated reformatting which interfered with the file contents. I also had to keep an eye on any content-length properties (or numbers after K or V identifiers) as they need adjusting if the length of any properties change. It's a little fiddly to get right.

Once that modified dump file is prepared, I made a new destination repo to reconstruct the final repo, and loaded the dump into that new repo, e.g.: svnadmin load repo-new < repo-new.dump. At this point, the new repo will have the first few commits necessary to establish the top-level folder structure, and it's ready to load the remaining commits of the original repo while also specifying the new parent dir be /trunk. I did the following using a dump of the original repository (use svnadmin info repo to find the last revision number): svnadmin load --revision 2:LAST_REV_NO --parent-dir trunk/ < repo.dump

That takes a few minutes or longer, but once it's done the new repo is a copy of the old repo with all work being done under /trunk (and also possessing a new UUID). The old repo can now be moved out of the way and the new repo put in its place. Clients will see its different UUID and fail - they will, of course, all need to take a fresh checkout.


Comment to add? Send me a message: <brendon@quantumfurball.net>

← Previous | Next →