55

I have a largish Mercurial repository that I've decided would be better as several smaller repositories. Is there a way that I can split the repository and have each piece retain its revision history?

James Sulak
  • 31,389
  • 11
  • 53
  • 57

3 Answers3

54

The best way to do this is using the 'convert' extension. You'll use mercurial and both source and destination type and then use a --filemap with entries like:

exclude path/you/do/not/want
rename path/you/do/want .

The rename is only necessary if you want to take the parts you're keeping and move them "higher" in the directory hierarchy.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Ry4an Brase
  • 78,112
  • 7
  • 148
  • 169
  • 4
    This wont work: rename path/you/do/want / This will: rename path/you/do/want . This only applies if you are moving a path to the root. – Nathan Lee Apr 08 '09 at 02:25
  • 8
    Even better: replace the `exclude ...` line with `include path/you/do/want` -- then only the named path(s) will make it into the converted repo. – Kevin Mar 14 '12 at 22:19
  • 2
    @Kevin that's definitely the way to do it if you want the projects to stay in their original, deep, paths. I figured that since splitting was the goal that each project should be raised to the top level of the new repo in which it's the sole project. – Ry4an Brase Mar 16 '12 at 02:10
  • 5
    I used this `convert` extension and was at first wondering why the destination path seems empty. Then I realized that there is no working copy by default in the new repo. If you need it, you should run `hg up` in the destination directory. Maybe it will help someone. – vadipp Aug 11 '14 at 12:15
0

I found a detailed guide here:

Create a file map new-repo.filemap such as

include vendor/FooBackend
rename vendor/FooBackend .

Create another file map rewrite-old-repo.filemap:

exclude vendor/FooBackend

Create the new repository:

hg convert /path/to/current/repo /path/to/new/repo --filemap new-repo.filemap

The new repository is now finished. The directory is empty, but a hg update will bring its contents up to speed.

Create the modified repository:

hg convert /path/to/current/repo /path/to/rewritten/repo --filemap rewrite-old-repo.filemap
KalenGi
  • 1,766
  • 4
  • 25
  • 40
  • This looks interesting for splitting a Mercurial repo in two, but it seems like it would get too complicated if for instance I have a project with over 200 sub-directories and I want to turn each sub-directory into its own project. (It's not entirely clear whether I would simply "include" and "rename" the directory I wanted to keep, and then exclude the other 200+, or if I would need to iterate each file in the sub-directory. – Michael May 21 '23 at 21:10
-5

Just clone it and delete the unwanted stuff out of each copy.

  • 2
    That doesn't help. Every close still has full history, so the "too much stuff" will always be there in the ".hg" directory taking up space. – Ry4an Brase Nov 03 '08 at 04:16
  • 14
    ah, you want the Stalinist revisionism form of version control. ;) http://en.wikipedia.org/wiki/Historical_revisionism_(negationism) – Jason S Jan 15 '09 at 21:46
  • @Ry4an But aren't the clones efficient copies of each other? Meaning yes, the revision history for the deleted items will be in both repositories but only stored once on disk right? So if I cloned a repository with several revs to files A - D and then deleted to give me an A/B and C/D repository, I'd only be storing one copy of all the revs of A-D along with an extra changeset in each one indicating C/D were removed in one and A/B in the other. Right? – Adam Wuerl Aug 30 '11 at 21:49
  • @adam yes, provided they all local clones storage will be efficient. It sounded like the original questioner wanted to be able to clone the subset repos to new (non-local) locations and have those clones be smaller. That's only possible by modifying history. – Ry4an Brase Aug 31 '11 at 05:51