phases and subrepos

Angel Ezquerra angel.ezquerra at
Fri Feb 3 07:36:55 CST 2012

On Fri, Feb 3, 2012 at 2:12 PM, Pierre-Yves David
<pierre-yves.david at> wrote:
> On Fri, Feb 03, 2012 at 12:16:07PM +0100, Angel Ezquerra wrote:
>> On Fri, Feb 3, 2012 at 11:00 AM, Pierre-Yves David
>> <pierre-yves.david at> wrote:
>> > On Fri, Feb 03, 2012 at 08:44:42AM +0100, Angel Ezquerra Moreu wrote:
>> >> Hi,
>> >>
>> >> I've been thinking about the interaction between subrepos and phases.
>> >>
>> >> One thing that has occurred to me is that there is as common case
>> >> where rewriting history causes problems, which is when you try to
>> >> rewrite the history of a subrepo.
>> >>
>> >> So, wouldn't it make sense to consider the selection of a subrepo
>> >> revision on its parent repo a publishing event? That is, committing a
>> >> change to the hgsubstate file on a parent repo should automatically
>> >> change the phase of the corresponding subrepo revision (and its
>> >> ancestors) to public.
>> >>
>> >> This would make it really hard to mess up your parent repo by
>> >> modifying one of its subrepos (with mq, for example).
>> >>
>> >> What do you guys think?
>> >
>> > I think we better fix subrepo than mark s immutable changeset that have no real
>> > reason to be immutable (other than rewriting extensions does not handle
>> > subrepo)
>> >
>> >
>> > --
>> > Pierre-Yves David
>> The thing is, how would we fix the subrepos? The problem is that the
>> parent repo-subrepo relationship is asymmetric, in the sense that the
>> parent repo is aware of the subrepo, but the subrepo is not aware of
>> its parent repo. This is a very basic assumption that I doubt will
>> ever change. Because of this, how can mercurial know that modifying a
>> draft revision in a subrepo (e.g. using mq from within the subrepo)
>> will break the parent repo, of which it is totally unaware? IMHO the
>> only solution is to have mercurial change the subrepo revision phases
>> as needed when updating the .hgsubstate file.
> What I see here is that making a revision public should make revision
> referenced in .hgsubstate public (a simple extension of phase compatibility
> rules)
> Moving boundary backward requires a --force option. Okay, People can be in
> trouble if they abuse --force option to mutate public changeset. This seem
> perfectly fine to me.
> There is still no valid semantic reason to make commit *public* by default if
> you use subrepo.

What I meant is that if you make a commit on the parent repo that
selects a different subrepo revision, the corresponding _subrepo_
revision should be made public. The parent repo revision created by
the commit should of course be draft.

>> Even if we "fixed subrepos" as you say, if a revision in the parent
>> repo is marked as public, then the corresponding subrepo revisions
>> should be marked as public as well. If the parent repo revision is
>> immutable, the subrepo history it depends on must be immutable as
>> well. It does not make sense to have immutable parent repo revisions
>> depending on draft or secret subrepo revisions.
> I Perfectly agree on this point


>> A trickier case is when a parent repo revision is still in its draft
>> or its secret phase. Theoretically it could be possible to edit the
>> subrepo history and then update the parent repo's .hgsubstate file to
>> reflect that change. But doing so automatically... well, it seems hard
>> and complex. If a user wants to do it manually, it'd be safer to have
>> them move the subrepo revision back to draft to prove that they really
>> know what they are doing.
> This semantically wrong. If repository rewriting extension does not handle
> subrepo properly they should abort. Misusing phase for this purpose would be
> and error imho.

But how can it do so? Let's say that I have a repo P and a subrepo S.
I commit revision A on P, which refers to revision B in the subrepo.
Both are in draft state.

Now I go into S and use mq modify S's subrepo revision B, getting B',
which I can do because it is in draft state. I just broke P's revision

How can mq protect me from that? How can it abort? It does not know
nor care that S is a subrepo! Maybe it should, but to do so it would
need to break a pretty basic principle of how subrepos work, which is
that a subrepo is just a repo.

Personally I would not mind if the parent repo to subrepo relationship
was a bit more bidirectional. It could make fixing these sort of
issues way easier, but I think that opens a whole different


More information about the Mercurial-devel mailing list