5

I am trying to convert a Subversion repository to Git. The problem I am facing is how to preserve the full complete history. The SVN repository has quite convoluted history and then git-svn works, it starts only from particular revision, ignoring all earlier history.

More details: I want to import a project which is now located as per std-layout http://svn.../projects/myProject/trunk. However the trunk is not created in SVN as it is now. It was originally created as some custom path like /my_project, then renamed in SVN into myProject/trunk, then several more moves and renames and it has finally ended up with standard layout.

So, if I just import the repo as-is pointing to the SVN project folder I need, the git-svn result starts history from the revision where the standard layout was introduced, ignoring the fact that the projects/myProject/trunk was moved in the repository multiple times earlier.

Technically I need to import a history of an SVN folder if it was moved/copied into the trunk from some other location (outside the trunk) of the same repository.

Does anybody have any ideas how to recover the history from such repository? Maybe somehow use multiple imports, then git grafts, or some other magic? Is there any easy way?

Rory O'Kane
  • 29,210
  • 11
  • 96
  • 131
kan
  • 28,279
  • 7
  • 71
  • 101
  • 1
    Does [this answer](http://stackoverflow.com/a/15169641/1698557) fall short? If so, how? – Patrick Quirk Dec 15 '14 at 17:56
  • possible duplicate of [Git-svn - import full history](http://stackoverflow.com/questions/15163916/git-svn-import-full-history) – 1615903 Dec 16 '14 at 08:37
  • @ Probably I am doing something wrong, but it doesn't work for me. The linked answer assume a project has defined structure of branches and tags, my project had the structure changed several times. So, the git doesn't follow the history in the past before the current layout was introduced. – kan Dec 16 '14 at 10:17

2 Answers2

0

reposurgeon, which has successfully converted some hairy old SVN repositories, can probably handle this. See its man page, especially the “Working with Subversion” section.

From the documentation, it looks like the branchify option should contain a list of the paths that your trunk has been at:

Here are the rules used for mapping subdirectories in a Subversion repository to branches:

  1. At any given time there is a set of eligible paths and path wildcards which declare potential branches. See the documentation of the branchify option for how to alter this set, which initially consists of {trunk, tags/*, branches/*, and '*'}.

  1. If an element of the branchify set ends with *, each immediate subdirectory of it is considered a potential branch. If '*' is in the branchify set (which is true by default) all top-level directories other than /trunk, /tags, and /branches are also considered potential branches.

branchify [path-set]

Specify the list of directories to be treated as potential branches (to become tags if there are no modifications after the creation copies) when analyzing a Subversion repo. This list is ignored when the --nobranch read option is used. It defaults to the 'standard layout' set of directories, plus any unrecognized directories in the repository root.

The branchify option’s default value contains *, and this might already detect your old branches for you. If it doesn’t you can try setting branchify to contain my_project, myProject/trunk, and trunk, in addition to the default paths tags/* and branches/*.

You may end up with multiple Git branches after this – one for my_project, one for trunk, etc. If that happens, reposurgeon’s unite or graft commands may be able to combine them; I’m not sure. If those commands only work with repositories and not branches, you can instead create a Git graft and run git filter-branch as described in this answer.

Rory O'Kane
  • 29,210
  • 11
  • 96
  • 131
0

Same problem here, and I have struggled a lot. Finally, inspired by this question, I summarize following steps to achieve the goal.

  1. Clone svn-root-directory with initial layout
  2. git svn reset -r <revision that add layout folders>
  3. In /.git/config, set remote.svn.fetch/branches/tags to corresponding layout
  4. git svn fetch -r <revisions in this layout, A:B(included) > [--ignore- path=branches\/] (Need to delete remote branch reference with same name (if any) in advance, otherwise it skipping the branching step)
  5. Repeat last 2 steps if there is more layout change
  6. Check if all branches history correct gitk -- all
Grant Chen
  • 16
  • 2