6

I'm trying to migrate a mercurial repository to git, but the problem is that the mercurial repository has subrepositories (some with branches), and lots of merges and branches itself. I'd like the final git repository to keep all this history and be correct and complete when checking out earlier parts of the repository or other branches. I don't need the new repository to have submodules or subtrees, although I would accept a solution using that as well. Some methods I've seen merge all the subrepos at the top of the new repo as branches, which means that checking out in the past doesn't contain all the files that were in subrepos. I've also tried importing everything as branches, resetting the head into the past, merging, and rebasing upwards, but there are too many merges and many conflicts arise, even with --preserve-merges, so I'd rather avoid this. I also couldn't find any way of replicating the mercurial subrepository update history in git as submodule update history. Does anyone have any ideas? Thank you.

user397114
  • 321
  • 2
  • 4

3 Answers3

1

Perhaps one thing you could do (but I'm not sure if this would work), is to use hg-git to push to an empty git repository.

Alternatively, you could also look to extend git-cinnabar to support subrepo conversion into submodules.

Mathiasdm
  • 1,791
  • 14
  • 26
  • 1
    I can get the commits over using hg-git, but that completely ignores the subrepos. I looked at git-cinnabar, but it doesn't have subrepo support either. I've already converted the base repo and all subrepos before, but haven't found a good way yet to combine them while being able to see the historical state of all files including subrepos. – user397114 May 28 '15 at 18:23
1

Having a similar problem (moving a Mercurial project with subrepositories to Git with a unified layout) I intend to follow a 2-fold approach:

  1. convert your subrepositories into a unified project layout in Mercurial - this is covered here: Join multiple subrepos into one and preserve history in Mercurial
  2. now you can migrate to Git easily, I found the official docs the best resource, with a good note on how to clean up commit history (authors): https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git#Mercurial

I'm just about to test this myself and will update this answer according to the results...

Community
  • 1
  • 1
Gregor
  • 1,297
  • 1
  • 19
  • 31
0

Disclaimer: the following solution only works if you are willing to fold the subrepos into the main repository, which may or may not be acceptable to you.


In short: convert each subrepo to git, convert the main repo to git, and have git merge the repos.

  1. Set up fast-export. It requires Python 2.7 and Mercurial 4.6.

  2. For each subrepo:

    1. Convert using fast-export
      1. Create a new directory to house your temporary subrepo
      2. Initialize git: git init; git config core.ignoreCase false;
      3. Run fast-export with config options as desired
    2. Run git reset --hard HEAD to repopulate the directory
    3. Remove any traces of hg from the repo as desired
    4. Configure folders to prepare for migration1
    5. Commit changes on the subrepo.
  3. Convert the primary repo from hg to git, using the steps 2.1-2.3.
  4. Convert the .hgignore file to .gitignore as required
  5. Commit the changes to the main repo
  6. Merge in each subrepo, using the steps from this post
git remote add subrepo1 path/to/subrepo1
git fetch subrepo1 --tags
git merge subrepo1/master --allow-unrelated-histories
git remote remove subrepo1

1For instance, in my case, the initial folder structure was like:

Main Repo
 |- SubRepo1
    L SubRepo1-Data
 |- SubRepo2
 L  OtherStuff

And after conversion, the new repo was configured as:

SubRepo1 (master)
 L SubRepo1-Data

So we needed to add a folder level to the the subrepos so that they were like:

SubRepo1 (master)
 L SubRepo1
   L SubRepo1-Data
user6456942
  • 11
  • 1
  • 1