sharing secret changesets with friends

Angel Ezquerra angel.ezquerra at
Tue Feb 18 16:42:40 CST 2014

On Tue, Feb 18, 2014 at 10:56 PM, Pierre-Yves David
<pierre-yves.david at> wrote:
> On 02/16/2014 05:02 PM, Dov Feldstern wrote:
>> I like to keep changesets that are still in-development secret --
>> keeping them just as draft is risky, since I find that I am wont to
>> "push" without limiting what branch I'm pushing, with the result that
>> I push work that is not really ready to be published (this was not so
>> much of a problem with mq, since patches did not get pushed by
>> default, but now that I'm switching to evolve -- which I am generally
>> very happy with :) -- this is more of an issue).
> My usual solution to this is to have a different `default` and
> `default-push` path.
> eg:
>   default =
>   default-push =
> So any push to a publishing server are explicit.
>> OTOH, keeping the changesets secret means I can't share them with
>> *any* repositories, though often I would like to be able to share
>> among my different non-publishing repositories (this is one of the
>> main drivers for switching from mq to evolve -- that with evolve it
>> should be easier to share in-progress, still-mutating, work). This is
>> also similar to the questions asked at [1,2], the answers to which I
>> find not very satisfying (no offense, Martin!).
> The phase dedicated to -in-progress- changeset I want to
> -share-with-other-people- are -draft-.
> You issue here seems to be accidentaly publication of such draft changeset.
> So, maybe we should improve this aspect of the problem. This could includes:
> - hook warning you when you are pushing draft to secret changeset.
> - special configuration on the path to mark it as "no auto publish"
>   (more on that below)
> - `--no-publish` flag on push
> (I'll talk about valid case for secret exchange later)
>> But even this simple implementation has already raised some issues:
>> 1. The pushed secret changesets get promoted to "draft" in both the
>> local and remote repos. What's actually happening, I think, is that
>> the csets get pushed to the remote as "draft", and then the comparison
>> of the local with the remote finds that they are draft in the remote,
>> and so promotes them to draft locally as well. (It was easy enough to
>> prevent the promotion of the local csets, but I couldn't find where
>> the promotion of the remote ones was happening; and if they get
>> promoted, then preventing the promotion of the local ones is
>> meaningless or downright wrong.) So, any tips on where the promotion
>> of the remote changesets to "draft" is happening?
> This is expected. New changeset added to a repo are added as draft (or
> public if publishing). There is no concept of "new changeset pushed as
> secret" as the fact someone was able to push them imply there were
> non-secret.
> And they try draft locally because they have been seen as draft remotely so
> their phase is moved to the lowest known one (draft < secret).
>> 2. If the secret changesets in the remote are manually forced back to
>> secret, then subsequent 'outgoing -F' shows them again as outgoing!
> Yes, because secret mean "no advertised by server".
> (rest of the paragraph made my head hurt, ignoring it for now)
>> 3. Just a general observation after having looked at the code a bit:
>> it seems that the *current* semantics of secrets are pretty widely
>> assumed, so I'm a *little* worried about being able to cover all
>> edge-cases with a change like this...
> You are right, the secret semantic is well established and well enforced.
> A simplistic view of your current plan can be "attempt to make secret phase
> a sightly altered draft phase". And this way is not going to fly. Once you
> start thinking about various level of draft changeset you end up with:
> - really secret changeset
> - changeset you want to share with repo on you machine
> - changeset you want to share with you various machine
> - changeset you want to share with continuous integration
> - changeset you want to share with your close coworker
> - changeset you want to share with your team
> - changeset you want to share with your review system
> - changeset you want to share with all the company
> - changeset you want to share with the alpha version repo
> - changeset you want to share with the beta version repo
> - changeset you want to share with the production version repo
> - changeset you want to share with the old stable version repo
> - changeset you want to share with the open source product repo
> - etc...
> This is why we stick to very simple public / draft / secret model in the
> end. We can't build a sane model generic enough for all use case. We need
> another tools for that.

Very interesting discussion.

I agree with your point of view that specifying levels of secretness
with greater granularity does not make sense. However there is one
thing that I really miss when using phases which is that there is no
way to differentiate between unshared draft revisions and shared draft

The way things currently are you can either work with a publishing
repo, in which case you know that draft revisions are unshared because
you cannot share them, or you can work with a non publishing repo in
which case you can share draft revisions but you can't tell whether
you have shared them or not. You cannot have both (i.e. you cannot
share draft revisions and still be able to tell which ones you shared
and which ones you did not share yet).

I always thought that I'd be nice to have a "shared" phase between
draft and public, which meant that the revision has been shared to a
non publishing repo. These revisions would behave exactly the same as
draft revisions. The only difference would be that you would be able
to tell that they had been shared (and thus that they are in the

That being said, even though I still think that having a shared phase
would be nice, it would be even nicer to have some sort of "sharelog"
that could tell you which revisions you shared with which repositories
(and also which revisions you got from where).

>> Does this idea sound interesting/useful to anyone else? And if so, any
>> pointers on how to move ahead with this?
> Even if I do not believe in your current approach as is, You are definitely
> pointing interesting issue that need proper solution. I would advertise a
> different approach:
> 1) make it harder to publish//exchange thing by mistake with some repo.
> 2) build a small dedicated solution to allow secret changeset in bundle and
> `backup push`
> For (1) I think the MacHg developer wrote some interresting proposal on this
> list about one year ago.
> I think we need to introduce a "path attribute" concept somehow. Maybe
> something like this
>   [paths]
>   toto =
> = true
>   toto.filter = branch("default") and ::tagged()
> (not doable this way for backward compatibility reason but you get the idea)

I think this would be very cool and useful. An empty "filter"
attribute could mean that the repo is readonly and that you never want
to push to it. The filter attribute could split into a push-filter and
a pull-filter so that you could also specify what you want to pull
from where.

Going further, this would be specially useful if it could also apply
to subrepos. Having a way to make a subrepo "readonly" is something
that I've been asked more than a few times.



More information about the Mercurial-devel mailing list