Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Svn to Git of only one subdirectory

Tags:

git

svn

git-svn

I know about git-svn and have used it to migrate SVN repositories into Git.

With one repo I have a specific requirement, which I can't find a solution for. That SVN repo contains multiple actual projects as subdirectories:

trunk/
    project1/
    project2/
    project3/
branches/
    branch1/
        project1/
        project3/
        project2/
...

and so on...

What I want to do is import each of these "sub-projects" in its own repo in git - obviously, keeping revision history, branches, commit messages, tags, etc.

I can use --ignore-paths and --include-paths switches to only pull one of these sub-projects at a time, but they will still appear under the respective project1, etc. subdirectories. What I really want to end up with is the content of project being in the root in each branch (including trunk).

Is there a way to do this?

like image 606
Aleks G Avatar asked Jan 05 '16 10:01

Aleks G


1 Answers

I found the solution. It's not as simple as git svn clone, but not too difficult. So, here's what I did (say, for project1 in the scenario from the question):

  1. Create an empty repo on the git server for project1
  2. Clone the empty repo onto my local machine:
    git clone [email protected]:group/project1.git
  3. Go into that empty repo working directory:
    cd project1
  4. Init git svn repo:
    git svn init --stdlayout --no-metadata https://svn.server.com/group
  5. Now, here's where the magic comes. If at this point I run git config --local --list, I get the following (only relevant lines shown):

    svn-remote.svn.fetch=trunk:refs/remotes/trunk
    svn-remote.svn.branches=branches/*:refs/remotes/branches/*
    svn-remote.svn.tags=tags/*:refs/remotes/tags/*
    

    All that I need to do now is git config --local --edit and add project1 in the correct places:

    svn-remote.svn.fetch=trunk/project1:refs/remotes/trunk
    svn-remote.svn.branches=branches/*/project1:refs/remotes/branches/*
    svn-remote.svn.tags=tags/*/project1:refs/remotes/tags/*
    
  6. Now you can git svn fetch

  7. Set branches and tags:

    for branch in `git branch -r | grep "branches/" | sed 's/ branches\///'`; do
        git branch $branch refs/remotes/branches/$branch
    done
    
    for tag in `git branch -r | grep "tags/" | sed 's/ tags\///'`; do
        git tag -a -m"Converting SVN tags" $tag refs/remotes/tags/$tag
    done
    
  8. And finally push it all to the remote:

    git push --all origin
    git push --tags origin
    

Now if you clone your repo, you'll get the content of project1 in the root of your cloned repo - exactly what I was looking for.

like image 102
Aleks G Avatar answered Oct 14 '22 07:10

Aleks G