Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert an existing Mercurial repository to use subrepositories and keep the history intact?

I've been reading about subrepositories and how to extract an existing folder from a Mercurial repository to a subrepository using the convert extension and a filemap. I can successfully do this. If I have the following folder structure:

C:\Project
---Project\root.txt
---Project\SubFolder
---Project\SubFolder\fileinsubfolder.txt

I can make a subrepository of SubFolder. In much the same way I can extract everything else a seperate repositorie (in this example the second repository would just have the root.txt file). Afterwards I can add the SubFolder repository as a subrepository to the second repository. But although both repositories have the complete history, these histories aren't linked => updating the root repository to an earlier state won't put the subrepository in the state it should be at that point. Updating to a consistent older revision (both root and subrepo updated automatically) will only work when updating to a revision that already knows about the subrepository and has .hgsubstate file.

And alternative I thought about was just forgetting the files in SubFolder in the current repository and initing a new repository in SubFolder and at the same time add a .hgsub file. What I hope to achieve here is work from this point on with a subrepository but still have a way to update to an older revision (before separating the subrepo) because the files of SubFolder are still in the history of the current repository.

This doesn't work though: When I have forgotten the files in mercurial, inited a new repo and linked it as a subrepo in the current repo and I update to an older revision before the subrepo existed I get this error:

C:\Project>hg update 1
abort: path 'SubFolder\fileinsubfolder.txt' is inside repo 'SubFolder'

The problem here is that when updating to an older revision which wasn't aware of the subrepo, this update wants to put files in the SubFolder. But this SubFolder is still another repo (has a .hg directory) and although the main repo has no recollection about it, the update doesn't want to put files in the SubFolder as it is a repo.

Is there anyway to get around this error or is there a better method to switch to using a subrepo for a certain folder in an existing Mercurial repository and keep the history intact (and both histories linked)?

like image 871
Christophe Avatar asked Jan 05 '11 09:01

Christophe


1 Answers

Nope, I'm afraid there are no tools that will allow you to split a repository in the way you ask for.

Just to clarify your question, then let us imagine you have a repository where the content of root.txt and sub/file.txt evolve like this

   root.txt  sub/file.txt`
0: root 0    file 0
1: root 1    file 1
2: root 2    file 2

for the first three changesets. What you ask for is an option for hg convert that would turn this into two repositories (easy, we can do that today) and where the convert extension injects .hgsub and .hgsubstate files so that the three changesets contain

   root.txt  .hgsub     .hgsubstate  |       file.txt
0: root 0    sub = sub  <X> sub      |  <X>: file 0
1: root 1    sub = sub  <Y> sub      |  <Y>: file 1
2: root 2    sub = sub  <Z> sub      |  <Z>: file 2

where the <X>, <Y>, and <Z> hashes are the one corresponding to the first three commits in the subrepository.

There is no such option for hg convert today, but based on the above it sounds feasible to write one. That would give you a great way to convert back and forth between a combined and a split repository.

like image 58
Martin Geisler Avatar answered Sep 21 '22 00:09

Martin Geisler