Cannot update to old revisions after converting a folder into a subrepo

Didly didlybom at gmail.com
Sat May 21 20:55:19 UTC 2011


We have recently discovered that after converting a folder into a
subrepo (with the same name) you are no longer able to update back to
a revision before the subrepo was created (or at least it is not
easy).

What happens is that mercurial does not remove the subrepo when it
updates to an old revision (as it does with any other file that it
tracks). Instead it leaves the subrepo there, but stops tracking it.
Thus it becomes a regular but nested repo contained inside the
original repo. Because of this, mercurial cannot update to old
revisions since it would need to create the files inside the nested
repo folder and (logically) it refuses to do so.

This is an example script that shows this issue:

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\Angel\Documents\Repositories>mkdir sub_issue

C:\Users\Angel\Documents\Repositories>cd sub_issue

C:\Users\Angel\Documents\Repositories\sub_issue>mkdir module

C:\Users\Angel\Documents\Repositories\sub_issue>cd module

C:\Users\Angel\Documents\Repositories\sub_issue\module>echo module
contents.txt > module.txt

C:\Users\Angel\Documents\Repositories\sub_issue\module>type module.txt
module contents.txt

C:\Users\Angel\Documents\Repositories\sub_issue\module>cd ..

C:\Users\Angel\Documents\Repositories\sub_issue>hg init

C:\Users\Angel\Documents\Repositories\sub_issue>hg addremove *
adding module\module.txt

C:\Users\Angel\Documents\Repositories\sub_issue>hg commit -m "added
module as folder"

C:\Users\Angel\Documents\Repositories\sub_issue>hg log
changeset:   0:ea9e5beb608a
tag:         tip
user:        Angel Ezquerra <angel.ezquerra at gmail.com>
date:        Sat May 21 21:48:23 2011 +0200
summary:     added module as folder

C:\Users\Angel\Documents\Repositories\sub_issue>del module\module.txt

C:\Users\Angel\Documents\Repositories\sub_issue>hg addremove *
removing module\module.txt

C:\Users\Angel\Documents\Repositories\sub_issue>hg commit -m "First step in conv
erting module folder into subrepo"

C:\Users\Angel\Documents\Repositories\sub_issue>cd module

C:\Users\Angel\Documents\Repositories\sub_issue\module>echo module
contents.txt > module.txt

C:\Users\Angel\Documents\Repositories\sub_issue\module>hg init

C:\Users\Angel\Documents\Repositories\sub_issue\module>hg addremove *

C:\Users\Angel\Documents\Repositories\sub_issue\module>hg commit -m
"First module subrepo version"

C:\Users\Angel\Documents\Repositories\sub_issue\module>cd ..

C:\Users\Angel\Documents\Repositories\sub_issue>echo module = module > .hgsub

C:\Users\Angel\Documents\Repositories\sub_issue>type .hgsub
module = module

C:\Users\Angel\Documents\Repositories\sub_issue>dir
 Volume in drive C has no label.
 Volume Serial Number is 1E3F-79E3

 Directory of C:\Users\Angel\Documents\Repositories\sub_issue

05/21/2011  09:52 PM    <DIR>          .
05/21/2011  09:52 PM    <DIR>          ..
05/21/2011  09:53 PM    <DIR>          .hg
05/21/2011  09:50 PM                20 .hgsub
05/21/2011  09:52 PM    <DIR>          module
               1 File(s)             20 bytes
               4 Dir(s)  39,858,356,224 bytes free

C:\Users\Angel\Documents\Repositories\sub_issue>hg status
? .hgsub

C:\Users\Angel\Documents\Repositories\sub_issue>hg addremove .hgsub

C:\Users\Angel\Documents\Repositories\sub_issue>hg status
A .hgsub

C:\Users\Angel\Documents\Repositories\sub_issue>hg commit -m "Second
step to convert module folder into subrepo"
committing subrepository module

C:\Users\Angel\Documents\Repositories\sub_issue>hg status

C:\Users\Angel\Documents\Repositories\sub_issue>hg glog
@  changeset:   2:b2c692ca58ac
|  tag:         tip
|  user:        Angel Ezquerra <angel.ezquerra at gmail.com>
|  date:        Sat May 21 21:57:35 2011 +0200
|  summary:     Second step to convert module folder into subrepo
|
o  changeset:   1:88b6556861c0
|  user:        Angel Ezquerra <angel.ezquerra at gmail.com>
|  date:        Sat May 21 21:49:36 2011 +0200
|  summary:     First step in converting module folder into subrepo
|
o  changeset:   0:ea9e5beb608a
   user:        Angel Ezquerra <angel.ezquerra at gmail.com>
   date:        Sat May 21 21:48:23 2011 +0200
   summary:     added module as folder


C:\Users\Angel\Documents\Repositories\sub_issue>hg update -r0
abort: path 'module/module.txt' is inside repo 'module'

C:\Users\Angel\Documents\Repositories\sub_issue>hg update -C -r0
abort: path 'module/module.txt' is inside repo 'module'

C:\Users\Angel\Documents\Repositories\sub_issue>

As you can see, it is no longer possible to go back the first
revision, even if you use the "-C"option!

As far as I can see you must first remove the subrepo (while on
revision 2) and then you can update to revision 0. However, then you
can no longer update to revision 2 because there is nowhere to pull
the subrepo revisions from (at least with the regular relative subrepo
definition).

I believe that this is quite an easy problem to hit. The only reason
we had not faced it ourselves so far is that when we converted some
folders to subrepos we took the chance to reorganize our code,
renaming some of the folders that were later converted into subrepos.

>From a regular (not too savvy) user point of view, this leaves the
repo on a "broken" state, since it is no longer possible to access
some repo revisions using just hg commands.

I think that a (possibly silly) solution to this problem would be that
mercurial "stored" a "copy" of the subrepo in its ".hg" folder (as it
does for any regular file). It could do so when updating to a version
of the repo that did not include the subrepo. Then, it would be safe
for mercurial to delete the subrepo upon update, making this issue go
away.

Angel



More information about the Mercurial mailing list