[PATCH] subrepos: abort commit by default if a subrepo is dirty

Jason Harris jason at jasonfharris.com
Sat Oct 22 17:11:08 CDT 2011

On Oct 22, 2011, at 4:18 PM, Martin Geisler wrote:

> Jason Harris <jason at jasonfharris.com> writes:
>> On Oct 21, 2011, at 3:34 AM, Angel Ezquerra wrote:
>>> On Fri, Oct 21, 2011 at 9:53 AM, Martin Geisler <mg at aragost.com> wrote:
>>>> Angel Ezquerra <angel.ezquerra at gmail.com> writes:
>>>>> This may be a dumb question, but will clean but modified subrepos
>>>>> (i.e. those were the current revision has been changed) still be
>>>>> committed when commitsubrepo is set to False?
>>>> That's actually a great question... The answer is that subrepos that
>>>> have changed revision *will* be committed when commitsubrepos=False.
>>>> I must admit that I did not expect this, but now that I think about
>>>> it, it seems nice: commitsubrepos=False prevents you from
>>>> accidentally reusing a top-level commit message in subrepos. But
>>>> you're still allowed to arrange the subrepos like you want (update
>>>> to new versions) and then make a big top-level commit to bind
>>>> everything together.
>>>> --
>>>> Martin Geisler
>>> I'm glad that is the case! In my opinion this is the right behavior.
>>> The new behaviour is great because it avoids modifying the subrepos
>>> (by creating _new_ commits, often with a nonsensical commit message)
>>> unless you explicitly tell mercurial to do so.
>>> But changing the subrepo revision does not modify the subrepo itself.
>>> You are basically modifying the .hgsubstate file, which is part of the
>>> parent repo.
>>> So in my opinion this makes a lot of sense.
>> Is there an option to control this? It would be really nice to turn
>> this off in our workflow. If we could then people could still rebase in
>> unpushed subrepo's etc, without nuking the repo by accident.
> I'm not sure what you ask to control. There is indeed an (old) option to
> control the recursive behavior of commit and there is a new --subrepos
> flag that overrides the option to make commit recurse.

I want an option so that if the subrepos have been changed and committed then
committing in the parent repo will *not* change the .hgsubstate.

Ie I want the option

ui.commitsubstate = true | false

and I want to set this to false by default. Then maybe invoke setting the substrate by

hg commit --commitsubstate ...

>> It turns out for us that most of the time changes in the super-repo
>> and changes in the sub-repo are independent (Which should be the case
>> as long as you are not changing the API of whatever is contained in
>> the subrepo's.)
> So then the new behavior should work well for you: if you accidentally
> commit at the top-level, you'll get an abort. You can then go into the
> subrepos and commit them with a proper commit message.

No. I will have already committed the subrepos. The question is exactly like
Angel asked it but I want the option to *not* commit the .hgsubstate even if I
have all the changes committed in all the sub-repos. Why do I want this you ask?
See my next answer...

>> And so every so often we need to tie together the super-repo and
>> sub-repo revisions. At that time it would be nice to do a special
>> commit which updates the .hgsubstate.
> That is just a normal commit in the super-repo.

That's the problem. I want it to be a non-normal commit. Eg the normal workflow
we want is people pull some repository and sub repositories. Then
they work on these repos like normal. Ie they rebase stuff, moving things around
as the develop some changes, etc. like they normally would. They then want to
tie the revisions together at that one place when they know that it is coherent
to do so, and then push.

WIthout such an option it would be possible to Eg: commit a subrepo, then commit
the parent repo. Do a rebase / strip in the sub repo. Do more work in the
subrepo. Commit the subrepo. Do some work in the parent commit that. etc. And
try and push that. And well they have pushed a nuked repo that does not have
integrity since one of the substrates pointed to by the parent doesn't exist.

Ie it's more common to do rebasing and moving things around in the various
repo's and only require tying together of the repo's even so often. (since they
are subrepo's...)

This is basically the same as having the overarching thin repository and doing a
commit there. Ie with the thin overarching super repo, the user can control when
to tie the repo revisions together.

>> (Unfortunately we didn't set things up originally with a thin wrapper
>> super repository and all sub repositories at the main level. If we
>> had, then of course we could have controlled the tying together by
>> only committing the wrapper super repository whenever we needed to.)
>> Also is there a command to check the integrity of the repo .hgsubstate
>> to confirm that all the subrepo revisions actually exist. Sort of like
>> a "hg verify --subrepos" ? Ie if a user does a rebase in a subrepo and
>> the version in .hgsubstate no longer exists then we can get a warning
>> about it?
> Ehm, no -- you would have heard of such a command by now if it existed
> and it would be mentioned in 'hg help subrepos' and/or 'hg help verify'.

I didn't think I had missed something like this but wanted to check. It could be
buried or accessed through some debug xyz or something. It seems like a fairly
important command to verify the integrity of a repo with subrepo's.


More information about the Mercurial-devel mailing list