Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining multiple SVN repositories into one

Tags:

svn

After considering the answers to my previous question (One SVN Repository or many?), I've decided to take the 4 or so repositories I have and consolidate them into one. This of course leads to the question, what's the best way to do this?

Is there a way to combine two or more repositories maintaining the version history for both?

Edit: I should also point out that I'm using Assembla.com, which does not provide access to the svnadmin command, AFAIK

Another edit: Does this even matter? If svnadmin works on URLs, then it's no problem then.

like image 484
nickf Avatar asked Nov 06 '08 00:11

nickf


People also ask

How do I merge files from one branch to another in svn?

One simple way to do that is to run svn diff with the same arguments you plan to pass to svn merge, as we already showed in our first example of merging. Another method of previewing is to pass the --dry-run option to the merge command: $ svn merge --dry-run -c 344 http://svn.example.com/repos/calc/trunk U integer.

How do I move a svn project from one repo to another?

If you don't want history, you can use svn export to get a clean folder without the . svn folders and then svn import into your other repository. With history, you would need to use the svnadmin dump . You would then use svndumpfilter to filter for only the parts or paths you want to use before using svnadmin load .


6 Answers

Edit: Oh well, the question edit was made while I was typing. This is an answer to

Is there a way to combine two or more repositories maintaining the version history for both?


Assuming that

The existing repositories have a structure like:

  • repository root
    • branches
    • tags
    • trunk

and you want a structure something like:

  • repository root
    • projectA
      • branches
      • tags
      • trunk
    • projectB
      • branches
      • tags
      • trunk

Then for each of your project repositories:

svnadmin dump > project<n>.dmp

Then for each of the dump files:

svn mkdir "<repo url>/project<n>"
svnadmin load --parent-dir "project<n>" <filesystem path to repos>

More complex manipulations are possible, but this is the simplest, most straightforward. Changing the source repository structure during a dump/load is hazardous, but doable through a combination of svnadmin dump, svndumpfilter, hand-editing or additional text filters and svnadmin load


Dealing with a third party provider

  • Request svnadmin dump files for each of your repositories. The provider should be willing/able to provide this - it is your code!
  • Create an SVN repository locally.
  • Perform the actions listed above for the dump files.
  • Verify the repository structure is correct with your favorite client.
  • Create a dump file for the combined repositories.
  • Request that the provider populate a new repository from this dump file.

YMMV: This seems to be a reasonable approach, but I've never worked with a third party provider like this.

like image 184
Ken Gentle Avatar answered Sep 30 '22 08:09

Ken Gentle


With Subversion 1.7, you are now able to do dumps remotely. That is, without having access to the local file system and the svnadmin dump command.

You can use svnrdump to get a complete dump of a remote repository. See the documentation for syntax details.

Note that the server does not have to be running 1.7, only the client.

http://svnbook.red-bean.com/en/1.7/svn.ref.svnrdump.c.dump.html

like image 43
Scott Coldwell Avatar answered Sep 30 '22 09:09

Scott Coldwell


Yes, using svnadmin dump and svnadmin load.

Let's assume that you have to repositories, one with HEAD revision 100 and the other with HEAD revision 150.

You dump the first repository and load it in the new one: you end up with the full story of the first repository, from revision 0 to revision 150.

Then you dump the second repository and load it in the new one: it gets loaded with its full history, the only things that change are the actual revision numbers. The history of the second repository will be represented in the new repository from revision 151 to revision 250.

The full history of both repositories is preserver, only the revision numbers change for the repository that is imported for second.

The same of course applies for more than two repositories.

EDIT: I posted while you were editing, so I didn't see your note...

like image 25
Davide Gualano Avatar answered Sep 30 '22 09:09

Davide Gualano


You can load many dump files in one repository with the following steps.

Repository root:

 projectA
    branches 
    tags
    trunk
 projectB
    branches
    tags
    trunk

First you must create the directory (project A, project B) in your repository root like this:

$ svn mkdir -m "Initial project root" \
file:///var/svn/repository_root/Project_A\
file:///var/svn/repository_root/Project_B\
file:///var/svn/repository_root/Project_C\

Revision 1 committed.

And after that you can load your dump files:

Use the parameter --parent-dir DIRECTORY

$ svnadmin load /var/svn/repository_root --parent-dir Project_A < file-dump-PRJA.dump
…
$ svnadmin load /var/svn/repository_root --parent-dir Project_B < file-dump-PRJB.dump

This way you'll have a repository which contains many dumped repositories.

like image 24
Hatim Avatar answered Sep 30 '22 07:09

Hatim


If you don't have access to svnadmin, it would be hard but doable. Let's say you have repositories A and B, and want to merge them into repository C. Here's the steps you would have to use to accomplish this.

  1. Check out revision 1 of repository A to your hard disk.

  2. Create a directory, called Repository_A on the root of your C repository, and check this out to your local hard disk.

  3. Copy the files from your check out of A (minus) the .svn files, to your checkout of C, in the Repository_A folder.

  4. Perform a Commit on C.

Update your working copy of repository A to revision 2 , and perform steps 3 and 4, and repeat with each successive revision until you reach the head.

Now do the same with B.

This would basically do the same as @Davide Gualano was suggesting, without requiring svnadmin. You could probably write a simple script to do this for your, of if there aren't a lot of revisions, you could just do it manually.

like image 35
Kibbee Avatar answered Sep 30 '22 08:09

Kibbee


The other answers for this question enabled me to make the script below. Adapt the REPOS map for your case. Also, you may want to move the tags and branches into a "preaggregate" directory in stead of directly into the new branches and trunk.

#!/bin/bash

NEWREPO=$(pwd)/newrepo
NEWREPOCO="${NEWREPO}_co"
DUMPS=repodumps
REV="0:HEAD"
REPOROOT=/data/svn/2.2.1/repositories/
TOOLDIR=/opt/svn/2.2.1/bin/
PATH=${PATH}:${TOOLDIR}

# Old Repository mapping 
declare -A REPOS=( 
    [BlaEntityBeans]='(
        [newname]="EntityBeans"
    )'
    [OldServletRepoServlet]='(
        [newname]="SpreadsheetImportServlet"
    )'
    [ExperimentalMappingXML]='(
        [newname]="SpreadsheetMappingXML"
    )'
    [NewImportProcess]='(
        [newname]="SpreadsheetImportProcess"
    )'    
)

dump() {
    rm -fr ${DUMPS}
    mkdir ${DUMPS}
    for repo in "${!REPOS[@]}"
    do
        local dumpfile=${DUMPS}/${repo}.dmp
    echo "Dumpimg Repo ${repo} to ${dumpfile}"
        svnadmin dump -r ${REV} ${REPOROOT}/${repo} > ${dumpfile}
    done
}

loadRepos() {
    # new big repo
    rm -fr ${NEWREPO}
    svnadmin create ${NEWREPO}
    svn mkdir file:///${NEWREPO}/trunk -m ""
    svn mkdir file:///${NEWREPO}/branches -m ""
    svn mkdir file:///${NEWREPO}/tags -m ""

    # add the old projects as modules
    for currentname in "${!REPOS[@]}"
    do  
        declare -A repo=${REPOS[$currentname]}
        local newname=${repo[newname]}
        echo "Loading repo ${currentname} soon to be ${newname}"
        dumpfile=${DUMPS}/${currentname}.dmp

        # import the current repo into a trmporary root position
        svn mkdir file:///${NEWREPO}/${currentname} -m "Made module ${currentname}"
        svnadmin load --parent-dir ${currentname} ${NEWREPO} < ${dumpfile}

        # now move stuff arround
        # first rename to new repo
        svn move file:///${NEWREPO}/${currentname} file:///${NEWREPO}/${newname} -m "Moved ${currentname} to ${newname}"
        # now move trunk, branches and tags
        for vc in {trunk,branches,tags}
        do
            echo "Moving the current content of $vc into ${NEWREPO}/${vc}/${newname}"
            svn move file:///${NEWREPO}/${newname}/${vc} file:///${NEWREPO}/${vc}/${newname} -m "Done by $0"
        done
    svn rm  file:///${NEWREPO}/${newname} -m "Removed old ${newname}"
    done
}

dump
loadRepos
like image 32
sthysel Avatar answered Sep 30 '22 09:09

sthysel