Search code examples
gitsvngit-svn

How to convert to GIT an old SVN repository with trunk/branches created later


I'm trying to migrate a really old SVN repository to GIT maintaining history, but having in mind that the repository didn't have the trunk/branches/tags structure all the time, but instead it was created without them, and the repository was migrated to the trunk/branches/tags structure later.

I've tried with git-svn with the command:

git svn clone <repo_url> --stdlayout

but the problem is that history gets cut on the "trunk, branches and tags created" commit, so everything before that commit is lost. I've also tried with:

git svn clone <repo_url> -T/ -bbranches -ttags

which gets all the commits, but creates a real mesh in the commit graph because it duplicates commits in the branches and the trunk, and does not create any relation between master and branches. I tried cleaning it up with commands like:

git filter-branch -f --index-filter "git rm -rf --cached --ignore-unmatch branches tags" -- --all

which removes the branches folder form the trunk branch mostly right, (and removes a lot of duplicated commits) and also trying to move the trunk folder to the root with:

git filter-branch --tree-filter "if test -d 'trunk'; then  git mv trunk/\* .; fi" --tag-name-filter cat --prune-empty -- --all

but doesn't work. I'm working on windows, so the command in git-svn docs for moving all items is not working for me (missing sed):

git filter-branch --index-filter \
    'git ls-files -s | sed "s-\t\"*-&newsubdir/-" |
        GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
            git update-index --index-info &&
     mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD

(which I rewrote to :)

git filter-branch --index-filter \
    'git ls-files -s | sed "s-\t\"trunk/\(*\)-\1-" |
        GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
            git update-index --index-info &&
    mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD

Any idea if what I'm trying to do is possible or should I just quit and keep history only until creation of trunk/branches/tags?


Solution

  • I finally found a solution: using svn-all-fast-export (svn2git) I got to create a repository with all the history with the following script:

    create repository REPONAME
    end repository
    
    # Master branch
    
    match /
      repository REPONAME
      max revision REVISION_BEFORE_TRUNK_BRANCHES_TAGS_CREATION
      branch master
    end match
    
    match /trunk/
      repository REPONAME
      branch master
    end match
    
    # Common branches
    
    match /branches/([^/]+)/
      repository REPONAME
      branch \1
    end match
    
    # Ignore everything else
    match /
    end match
    

    As I was on windows, had to compile on Windows Substime for Linux, installing "build-essential subversion git qtchooser qt5-default libapr1 libapr1-dev libsvn-dev"; or cygwin with the following libs (as explained in this issue)

    gcc-g++ (v7.4.0-1)
    libQt5Core-devel (v5.9.4-2)
    libapr1 (v1.6.5-1)
    libapr1-devel (v1.6.5-1)
    make (v4.2.1-2)
    subversion (v1.11.1-1)
    subversion-devel (v1.11.1-1)