user111156
user111156

Reputation:

Multiple svn projects into one git repository?

I have started to use git-svn for some of my work to be able to do local commits. This works great for projects that use standard svn layout. Recently I started working on a Java project that is split into multiple connected modules (20-25), and each module have its own root folder in the same svn repo with its own trunk/branches/tags.

svnrepo/    
  module-1
    trunk
    branches
    tags
  module-N
    trunk
    branches
    tags

I have cloned each and every module with git svn clone -s /path/to/svnrepo/module[1-N]. The "problem" is that when I want to do git svn rebase on all modules i have to do it N times.

I have tried to do git svn clone /path/to/svnrepo/ do avoid doing the rebase operation N times, but that leaves me with a directory layout that is the same as in the svn repo.

Is there a way that I can track all the trunks of all modules in one git repo? So that I get a directory layout like this within my git repository:

module-1
module-2
module-N

Upvotes: 7

Views: 4350

Answers (2)

Francisco Noriega
Francisco Noriega

Reputation: 14574

I found myself in the same issue as you, and found out that there is no standard way to do this. However, looking around I found out about a strategy to help do this, and I created a power shell script based on that. I can't remember the source, or I would give them credit. I would explain it, but I its easier to just see the script and the comments.

You could use this script, or if not using windows/powershell, make on based on it. The good thing is that once you have your individual git repos for each submodule, if something fails, its really fast/easy to just delete the new "master" git repo, make changes to the script and just run it again, since its all local.

Beware that there are some cases that are not handled, like having when a sub module has folder that is called the same as another sub module (so if you have a sub module called BIN and then your other sub modules have sub a BIN sub folder, it will fail). Also be sure that all of your sub Modules git repos are up to date before you begin!

You can check out the script in this gist: Gist Script

if for some reason the gist is down, I've also added it here (albeit a lot less readable)

$GitReposLocation = "path\to\individual\git\repos"; #1 git repo for each module (you svn cloned each one using std layout)
$MasterGitRepoLocation = "path\to\masterRepo"; #the path where you want your main repo that contains all the modules
git reset --hard;

write-host Creating folder $MasterGitRepoLocation -foregroundcolor "green";
mkdir $MasterGitRepoLocation;

write-host Moving to folder $MasterGitRepoLocation -foregroundcolor "green";
cd $MasterGitRepoLocation;

write-host Creating Git Repository -foregroundcolor "cyan";
git init;

#this is hacky, but we need to have an initial commit
"" > root;
git add root;
write-host Creating root node -foregroundcolor "cyan";
git commit -m "Initial commit to create parent root.";

#we are going to be moving files around, and don't want to move the files we already got in our MasterRepo root/workspace
$NotMoveThesFiles = @();
dir |%{$NotMoveThesFiles+=@($_.FullName) };

$repos = @();
# you should add a repo here if for some reasong you don't want to process that one.
# $repos+=@("SomeRepo");

dir -Path $GitReposLocation -Directory |Where-object{ $repos -NotContains $_.Name }|%{$repos+=@($_.Name) };

# for-each repo....
$repos|%{ 
        $SubRepoName = $_;
        write-host Processing GitRepo $SubRepoName -foregroundcolor "green";        
        $Remote = "remote"+$SubRepoName;        

        #add this git repo (of a module) as a remote of our main repo
        write-host Adding reference to $SubRepoName as remote repo -foregroundcolor  "cyan";
        git remote add -f $Remote $GitReposLocation\$SubRepoName;

        #Merge that sub repo into the main repo. The only problem? It will copy that repo's workspace
        #directly into our main repo Root folder
        write-host Merging remote$SubRepoName/master into master -foregroundcolor  "cyan";
        git merge remote$SubRepoName/master;

        #so now we are going to create a folder with  the name of this module (subRepo)
        #and move everything that is in the Master's root folder to that folder, except of course
        #things that we already had in the root folder before the merge. (in the NotMoveTheseFiles array)

        write-host Moving files got from $SubRepoName to a subdir called $SubRepoName -foregroundcolor  "green";

        #create folder folr the module
        mkdir $SubRepoName;
        #add these new folde to the list of things we don't want to move into it.
        $NotMoveThesFiles+=@($SubRepoName);

        #copy all files not in the NotMoveTheseFiles array into the newly created folder.
        dir |where-object {$NotMoveThesFiles -NotContains $_} |%{git mv $_ $SubRepoName};

        #commit the change where we moved all these files around.
        $CommitMessage = "Moving files got from " + $SubRepoName + " to a subdir called $SubRepoName"
        git commit -m $CommitMessage;
    }

Upvotes: 0

Dan Moulding
Dan Moulding

Reputation: 220453

Unfortunately, no, there is no way to do this. One problem is that there is nothing preventing two or more modules from having a branch with the same name. Then, in git-svn, when you give it the branch name, how would it know which module you are talking about?

This problem really stems from the fact that in Subversion branches are not a first-class concept, whereas in git they are. git-svn is able to use more-or-less a kludge to work around this fact, but the kludge breaks down if the repo has a "non-standard" layout (such as the one you are working with).

My suggestion: write a script to git-svn rebase them all.

Upvotes: 2

Related Questions