Search code examples
gitsvngit-rewrite-history

How to split SVN repo to multiple git repos with history of moved files


This is another story about the conversion of a Subversion repository into multiple git repositories. But the question is not about how to do that in general but instead, how to keep the history of the resulting git repository intact, when the files have been moved in Subversion.

The situation looks like this:

Repo/
  trunk/
     ProjectA
     ProjectB
     ....

Whereas the subfolders in trunk were created at some point in time - before the layout was like the following:

Repo/
  ProjectA
  ProjectB
  ....

Now I would like to:

  1. Convert the repository to git (git svn clone does this nicely).
  2. Extract all subfolders in trunk to separate repositories.

So I went ahead, did the git svn clone {http...} AllProjects and then cloned AllProjects to ProjectA and used git filter-repo --subdirectory-filter trunk/ProjectA within ProjectA.

Now, the following problem appears:

  • Within AllProjects I can follow the log for a file from trunk/ProjectA/... and I can see that the file was moved (a real move, not delete and add).
  • Within the Repository ProjectA that was created from AllProjects the history only contains all entries of commits that already went to the trunk subfolder.

So even though the files in ProjectA come from AllProjects where all the history is present, all the history of those files in ProjectA is lost for all entries that affected those files before the move to the trunk subfolder.

What am I doing wrong here? This behavior does not make sense to me, why does git cut the history? Is there a way to achieve my goal?


Solution

  • The problem was that I only took the particular subfolder where the relevant project resided at the end. In order to keep the entire history of all the files within that subfolder I needed to take all paths into account, where those files have been before. So if e.g. trunk/ProjectA was in ProjectA before, I need to track the folders trunk/ProjectA and ProjectA. So what I did at the end and what worked was something like:

    git filter-repo --path trunk/ProjectA --path-rename trunk/ProjectA/:./ --path ProjectA --path-rename ProjectA:ProjectA 
    

    At the end I got the entire history correctly preserved with the project structure wanted.