Converting a subversion repository created by svn-buildpackage to git (with all history intact), is more difficult than it seems. While git has 2 tools for working with subversion repositories, the structure of the svn-buildpackage repository is problematic. The typical repository created by svn-buildpackage has a structure like this:
package/trunk/ tags/ tags/1.0-1/ branches/ branches/mybranch/ upstream/ upstream/current/ 1.0/
Both git-svn and git-svnimport will have problems with this setup due to the subdirectories of upstream in the branches directory. If you need to keep the svn repository and want to continue to work with it (using git to push changes back to the svn repository), then you'll have to use git-svn and live with the strange setup.
However, if you're migrating to git and plan on never using the svn repository again, you can simply use the sbp2git script, which will convert repositories in the format described above without much hassle.
Alternatively, you can manually use git-svnimport. To avoid the problems described above with the upstream subdirectories, the following AWK script can be used to reassign upstream to a single branch directory:
# print_status = 0 => print normally # 1 => skip the current block (look for PROPS-END) # 2 => end of block found, now just skip empty lines /.+/ { # Ready to print data again (non-empty line) if (print_status == 2) { print_status = 0 } } /^PROPS-END$/ { # End of not printing, skip the empty lines though if (print_status == 1) { print_status = 2 } } /^Node-path:( |.*\/)tags$/ { # Make sure the tags directory is not created twice if (tags_created == 1) { print_status = 1 } tags_created = 1 } /^Node-path:( |.*\/)branches\/upstream\/current/ { # Remove the current from the upstream directory sub("/current", "", $2) if ($2 ~ /branches\/upstream$/) { # Would create the upstream directory again, instead use it # to create the tags directory, if necessary, otherwise skip it if (tags_created == 1) { print_status = 1 } tags_created = 1 sub("branches/upstream","tags",$2) } if (print_status == 0) print $1, $2 next } /^Node-path:( |.*\/)branches\/upstream\// { # Switch all upstream tags to the tags directory sub("branches/upstream/", "tags/upstream-", $2) if (print_status == 0) print $1, $2 next } /^Node-copyfrom-path:( |.*\/)branches\/upstream\/current/ { # Make sure all copies from current now come from upstream sub("/current", "", $2) if (print_status == 0) print $1, $2 next } /^Node-copyfrom-path:( |.*\/)branches\/upstream\// { # Make sure all copies from upstream tags come from the tags directory sub("branches/upstream/", "tags/upstream-", $2) if (print_status == 0) print $1, $2 next } { if (print_status == 0) print }
To use this script, first dump the entire repository to a file using the "svnadmin dump" command. Then, run this script on the file, which will change branches/upsteam/current to just branches/upstream, and move branches/upstream/<version> to tags/upstream-<version>. Then use "svnadmin create" and "svnadmin load" on the result to load the modified repository structure into a temporary svn repository. Finally, run git-svnimport on the temporary repository. For the structure shown above, this results in branches of origin and master (both point to the trunk), mybranch, and upstream. There should also be tags, in this case upstream-1.0 and 1.0-1.
If your repository contains more than one package you'll need to filter the dump produced by "svnadmin dump" to just include information about this package. Indeed the awk script above only works with one package (actually only one "tags" directory) in the dump. To filter use something like "svndumpfilter include package < full-svn.dump > filtered-svn.dump" -- ?NicolasDuboc 2008-10-24