sharing secret changesets with friends

Pierre-Yves David pierre-yves.david at
Tue Feb 18 20:03:55 CST 2014

On 02/18/2014 04:40 PM, Dov Feldstern wrote:
> Thanks, all, for your comments!
> A few random thoughts, I don't think I have a coherent direction in
> which to take this, yet:
> What is the use case for "secret", as it currently stands?

Initial motivation for secret are:

- prevent other people from pulling non-ready change from your repo.
- prevent push of local only change (local only config, nuclear secret etc).

One of the main aims was to prevent a simple and safe way to exclude MQ 
managed changeset from all exchange.

> I can't
> really think of any situation in which I would want to have something
> that *can't* be cloned to my *personal* clones.

Can't be clone by -you- from -your- personal clones is a special case. 
And this special case does not mean we should break the current 
semantic. We can improve this use case, but this should be seen as a 
special case with special solution we do not encourage for multiple 
people workflow.

> The way I see it, I
> want to always be able to clone my repo in order to branch out in some
> new experimental direction without affecting the original repo and its
> working directory -- and I want that clone to be, well, a *clone* --
> an exact copy -- of the original repo, including all of the
> experimental work or "pbranches" that it contained. Essentially,
> "secret" in its current form means keeping secrets from *myself* -- I
> don't see how that's useful...

Keeping it secret from yourself is a side effect of all the other 
usefullness of secret

> And again, just to explain the background: Now that I'm switching from
> mq to evolve, I have many csets in the repo that are not yet ready to
> be published -- what used to be *unapplied* patches in mq, or, in
> essence, "pbranches". (This is the expected state to be in with
> evolve, right?) Now, when I want to push one piece of work, I want to
> be able to guard against all the other "pbranches" from being
> accidentally pushed. With mq, as long as they were still patches they
> would not get accidentally pushed;

MQ has a simple security that say if the is mq patchs in outgoing rev, 
abort. Nothing prevent you to build the very same check with draft.

> and when I *did* intend to push, I
> would "qfinish" those patches I intended to push, and thus make them
> "pushable".

And when you did intend to push you would `hg phase --public` thoses 
patches you intended to push, and this make then pushable.

> So now I am looking for an equivalent way to differentiate
> between the work that I intend to push, and all the other work that I
> don't intend to push. Marking them as "secret" seems like the perfect
> solution -- except that, as explained above, then I can't even share
> them with myself -- and *that's* what I am hoping to solve.
> The solutions suggested here of making the default-push point to a
> non-public repo, or of somehow allowing for a "non-publishing" push
> command, or of specifying certain peers as "no auto-publish" are all
> addressing a problem which is subtly different than the problem I am
> trying to solve: my problem is not so much that of pushing to the
> wrong repo when I don't intend to, but rather that when I *do* intend
> to publish, I accidentally publish *more* than I intended to.

If you have to explicitly specify you are doing a publishing push, you 
should be able to also take the extra step to check your outgoing set 
and change it if needed. (I'm doing that all the time, Logilab people 
are doing that all the time)

> In other
> words, the focus is not on how to mark *who* I am or am not willing to
> share with, but rather on *what* I want to or don't want to share.

You have multiple way to mark *what* you intend to push:

You could use the workflow described above (explicitlyu publishing 
thing) and issue `hg push default -r 'public()'` command.

You could also use `ready` bookmark locally and use:
`hg push default -r ready`

> One way to think of this is as "tagging" the various draft csets --
> some of them being tagged as "don't push yet" and others as "ok, this
> is ready for pushing". But it's not exactly *tags* -- I want them to
> be shared, and movable, kind of like bookmarks. But it's not
> bookmarks, either; it's kind of *reverse* bookmarks: it's a movable
> pointer to the *base* of a branch rather than to its head. Those are
> exactly the semantics of phases...!

I not totally confused.

> Perhaps a solution like that suggested by Kaz, of having a
> 'non-publishing' option to push, could work: I would personally set
> that option to always be on, and that would provide the protection I
> am used to from mq; and the equivalent to "qfinish" would be to change
> the phase of the work that I'm ready to publish to be public. And
> "secret" is not part of the scheme at all...

That is the solution I explained earlier in this email. Its very close 
to what you have been using so far. And it seems that you have been 
happy with what you have been using so far.

Writing a small hook//extension that enforce is trivial. Moving this 
kind of logic in core with an option may be discussed.

> The idea of specifying filters for paths is interesting; it sounds
> very powerful, and a little complicated ;) ... But for the specific
> problem I am raising here, I don't see how exactly it would help...

I was just explaining we could add attribute to path, using filter as an 
example. The other attribute in the example is "no-autopublish" that 
help your use case, and we could probably define an appropriate 
attribute and semantic

default.draft-behavior = [push, no-auto-publish, exclude]

On 02/18/2014 04:54 PM, Dov Feldstern wrote:
> On Wed, Feb 19, 2014 at 2:40 AM, Dov Feldstern <dovdevel at> wrote:
>> ...
>> Perhaps a solution like that suggested by Kaz, of having a
>> 'non-publishing' option to push, could work: I would personally set
>> that option to always be on, and that would provide the protection I
>> am used to from mq; and the equivalent to "qfinish" would be to change
>> the phase of the work that I'm ready to publish to be public. And
>> "secret" is not part of the scheme at all...
> Actually, it's not a 'non-publishing' option to *push* that would be
> needed, but rather an option that would affect all of the commands
> that share with peers, whether push or pull or clone, saying that they
> should not share anything that would cause drafts to become public...

Yeah, global or path-level config option would be the way to go in my 

> And also, actually, if I'm going to rely on this behavior as a guard,
> then using a repo's "publish=no" is not good enough, either: I don't
> want to share my half-baked patches with anyone, even if they *did*
> define their repo as non-publishing. So in addition to this setting,
> I'd *still* need a way of specifying who my "friends" are -- with whom
> I'm willing to share my drafts.
> Essentially, the scheme I'm describing now is actually changing the
> semantics of *drafts*... I'd rather stick with changing the semantics
> of "secrets", I think...

The scheme your describing now it, I'm trying to stick the "I want 
control over that I push where" into phases. Phases are not meant for that.

The primary intend of phase are "Track what it is safe to rewrite and 
what is not safe to rewrite". I just happen that this property "safe to 
rewrite" is usually tightly related to "did I exchanged this changeset 
with a public repo".

The secret phase came later as a "Things that are involved in magic that 
make them dangerous to share with even non publishing repo" For example 
MQ changeset. It was also quite simple to implement with the name 
mechanism than phase.

So one more time, adding more mechanisme to control what you want to 
exchange where is perfectly ok. The fact in you case it is strongly 
related to draft changesets does not change the semantic of draft 
changeset ("may be rewritten"). And you may imagine people have the very 
same problem than you with "we do not want to push the proprietary 
branch of our software (full of public changeset) to the open-source repo.".
To rephrase, that is not changing the semantic of draft, its adding new 
semantic that happen to apply to draft.

One last reminder:
- public: will exist forever,
- draft:  May be disappear in the future,
- secret: Will stick to this repo only (may disappear)


More information about the Mercurial-devel mailing list