sharing secret changesets with friends

Dov Feldstern dovdevel at
Sun Feb 16 19:02:00 CST 2014


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).

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!).

So, my idea is something like this: it would be nice if I could
configure "friend" repositories -- say, by adding a "friends" key
under the [phases] config, with the value being a list of "paths" from
[ui]. Then, I would like any operations relative to "non-publishing
friends" to also include secret changesets, and to not promote the
phase of the changesets simply by virtue of this sharing.

In order to play around with this, I've just created a few patches
which add a '-F, --friend' flag to 'outgoing' and to 'push'; where, if
set, these operations will not exclude secret csets. The patches
actually work for me, though I've only tested two local repositories
at the moment. And in any case, I think the interface I describe above
(configuring friends) would be better than adding a per-command flag.

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?

2. If the secret changesets in the remote are manually forced back to
secret, then subsequent 'outgoing -F' shows them again as outgoing!
This may simply be because I haven't implemented "friend" support for
the incoming commands, yet; but regardless, it raises the question of
what happens, under the scheme proposed above, if the "friendship"
configuration is not symmetrical -- i.e., if repo1 defines repo2 as
its friend, but not vice versa, then repo1 can't see repo2's secrets,
and so secrets from repo1 will always appear to be outgoing to repo2.
To be sure, it really only makes sense to define as friends repos over
which you have control (either directly, or via a "real" friend that
you are sharing with) -- so just fixing the relations to be symmetric
should not be much of a problem; and in any case, at the worst, a
subsequent push will attempt to push the secrets again, and then they
don't get pushed because they already exist (mercurial outputs, e.g.,
"added 0 changesets with 0 changes to 11 files.")

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...

So --

Does this idea sound interesting/useful to anyone else? And if so, any
pointers on how to move ahead with this?


I'll send the patches I mentioned above as a patchbomb, just for reference.


More information about the Mercurial-devel mailing list