splicemap to "inject" files?

Tom Udale tom at ionoptix.com
Thu Aug 18 20:12:59 UTC 2011


Hi All,

We have been using hg for some time on a very large repository created 
by cvs2hg.  We broke our original monolithic repo into subrepositories. 
  It was not long before we ran into the problem of going back in time. 
  Because of course, when you first set up the subrepos, you are adding 
your .hgsub and .hgsubstate files _now_ where in reality, those files 
should have been added at (or near) changeset 0.

The gist of the problem is described here:

http://stackoverflow.com/questions/4602452/how-to-convert-an-existing-mercurial-repository-to-use-subrepositories-and-keep-t

Since in my particular case the subrepos were pretty much read only, I 
was wondering if it might not be possible to manually inject the correct 
hgsub and hgsubstate files back into the history with

hg convert --splicemap.

For example, consider a repo with 2000 changesets and a subrepo with 
only 1 changeset.  Both came from the same CVS repository.

When I introduce the .hgsub and .hgsubstate file, that is going to go in 
as changeset 2001.  This will make the files in my sub show up now, but 
not if I update to before 2001.

Now assume that I know from looking at the commit comments that the 
subrepo was actually introduced at changeset 4.  I want to move my 2001 
changeset to there.

My hope therefore would be to run a hg convert --splicemap to "move" the 
commit that introduced the .hgsub and .hgsubstate files between 
changesets 4 and 5 by basically making 2001 the parent of 5 and 4 the 
parent of 2001 (by hash of course).

I hoped that this would make it look as if those files had been present 
from the beginning of the history and thus updating to any revision 
after that time would do the "right" thing and check out the expected 
revision of the subrepo.

Indeed, I hoped that might even do the right thing in subsequent 
branches as well since they would be in before the branch happened.

I created a toy test repo to try simply moving a changeset from the tip 
to be the parent of 0 and it failed with:

spliced in ['79d5b6aa16475ebd2453c17a777f9ef5ff665f51'] as parents of 
b5b9c5091dd4eaf08adce2f5e27ed1e8ba4b9361

abort: unknown revision '79d5b6aa16475ebd2453c17a777f9ef5ff665f51'!

 From searching the web, it appears the problem is that convert is 
looking for the parent revision in the destination repo (where it does 
not exist yet) rather than in the source repo.

I thought that the --splicemap would be applied after the conversion, 
but it appears that convert looks at splicemap as it processes each 
source changeset and if it sees the CS as a child, it tries to find the 
parent in the dest.  Of course, since the child CS in question is the 
first one, the parent is certainly not going to be found.


Is there a way to make this work?

Am I even on the right track here?





Best regards,

Tom Udale




More information about the Mercurial mailing list