Subversion / Dump and loading

From WhyNotWiki
Jump to: navigation, search

How do I import part of repository A into repository B with full revision history intact?

Meet your new friends svnadmin dump and svnadmin load.

This must be done on the host that actually has the repository on it (it can't be done remotely like you can with normal svn commands).

  • Lock down old repositories to prevent commits while the migration is in progress.
    • I figured renaming them would be an effective way of doing this.
    • sudo mv /var/www/svn/reposA /var/www/svn/pre20060516-reposA

  • Dump the data from the old repository
svnadmin dump /var/www/svn/reposA/ > ~/reposA.svn_dump
* Dumped revision 18.
  • Load the data from the dump file into the new repository.
sudo svnadmin load /var/www/svn/reposB/ --parent-dir some_dir < ~/reposA.svn_dump
------- Committed new rev 494 (loaded from original rev 18) >>>

Question: Does the "parent-dir" have to already exist in the target repository?

Yes! So you may have to svn mkdir the directory first. Unless you want to get fun errors like this:

<<< Started new transaction, based on original revision 1
svnadmin: File not found: transaction '148-1', path 'parent_dir_that_was_expected_to_already_exist/lib'

A common pattern/use for this technique is when you want to import a smaller repository B into a larger repository A as a subdirectory called B... ([repository refactoring (category)]) You decided, for example, that you'd rather have one big repository that contains all of your projects instead of one repository per project.

> svnadmin dump ~/repositories/my_project_B/ > ~/my_project_B.svn_dump
> svn mkdir http://url/to/main_repository/my_project_B -m 'Creating directory into which my_project_B will be imported'
> sudo svnadmin load ~/repositories/main_repository/ --parent-dir my_project_B < ~/my_project_B.svn_dump

What if you only want to import part of repository A?

Meet your new friend svndumpfilter... It simply applies a directory filter to a dump file, letting you either exclude a certain directory from the dump file or include (only) the directories that you specify.


$ cat ~/svn_dumps/reposA.svn_dump   | svndumpfilter include frontend    > ~/svn_dumps/reposA-only_including_frontend_dir
$ cat ~/svn_dumps/reposA.svn_dump   | svndumpfilter exclude backend     > ~/svn_dumps/reposA-everything_except_backend_dir

Question: Can it also include/exclude files or does it only work for directories?

Caveat: svndumpfilter can't do both an exclude and an include in the same operation===

So you can'd do this, for example:

$ cat ~/svndumps/89glass | svndumpfilter --include: frontend --exclude: frontend/include > ~/svndumps/glass-89glass-web

But you can always do two consecutive svndumpfilter operations to achieve just about any combination you could want...

$ cat ~/svndumps/89glass          | svndumpfilter include frontend/ backend/ > ~/svndumps/89glass-frontend
$ cat ~/svndumps/89glass-frontend | svndumpfilter exclude frontend/include/  > ~/svndumps/89glass-frontend-without_include
$ ...

Caveat/Troubleshooting: svndumpfilter: Invalid copy source path '/dirA_old_name'

I think when this has happened to me before it is because I was using svndumpfilter include to include dirA, but dirA was a copy (or move) of dirA_old_name so it was unable to include dirA without including its ancestor from previously, which happened to have been called dirA_old_nameback in the day.

Solution (if dirA_old_name was moved/copied to dirA):

svndumpfilter include dirA_old_name dirA

instead of just:

svndumpfilter include dirA

I don't think you need to worry about the unwanted old directory svndumpfilter include ending up existing in your dump file (and thus your new repository). It simply needs to be able reference that old revision so that it can calculate what the later revisions look like -- but if dirA_old_name was deleted/moved, then it shouldn't end up existing in the current version. In other words, svndumpfilter needs to be able to look at that old directory to be able to figure stuff out, but that doesn't mean it will actually keep the directory in its final results (so you might argue that having to list it in the include option is misleading...).

Lesson learned: Even if a directory doesn't exist in the current revision of a repository, you may still need to include it in your svndumpfilter include command to avoid getting errors.

[Caveat (category)]Be sure to create any parent directories!

> cat dumps/everything | svndumpfilter include gemables/rake_command_completion/ > dumps/rake_command_completion

But now when I tried this...

> sudo svnadmin load /var/www/svn/code-copy/ < dumps/rake_command_completion

I got...

~file not found

So I tried it again, differently...

> sudo rm -rf /var/www/svn/code-copy
> sudo svnadmin create /var/www/svn/code-copy

> sudo svn mkdir file:///var/www/svn/code-copy/gemables//rake_command_completion -m 'Creating parent directories that svnadmin load might expect to be there'

Interestingly, I got the same error message here that I'd gotten when I tried to do the svnadmin load!

~file not found

... which is further evidence that all I need to do is create in the new repository all parent directories of the path (gemables/) that I originally dumped (gemables/rake_command_completion/)...

This is what finally worked for me...

> sudo svn mkdir file:///var/www/svn/code-copy/gemables/ -m 'Creating parent directories that svnadmin load might expect to be there'
> sudo svnadmin load /var/www/svn/code-copy/ < dumps/rake_command_completion > out &
> svn co file:///var/www/svn/code-copy/
A    code-copy/gemables
A    code-copy/gemables/rake_command_completion

Aliases: Subversion / Backup and restore, Subversion / Backing up your repository, Subversion / Restoring your repository from a dump file, svnadmin dump, svnadmin load, svndumpfilter

Personal tools