Hidden Commits in 4.3

Pierre-Yves David pierre-yves.david at ens-lyon.org
Tue Apr 11 16:29:15 EDT 2017

On 04/11/2017 12:43 AM, Augie Fackler wrote:
> On Fri, Apr 07, 2017 at 12:20:44PM +0200, Pierre-Yves David wrote:
>> On 04/06/2017 02:46 AM, Jun Wu wrote:
>>> obsstore-based hidden is broken by design, since it cannot unhide commits:
>>>  $ hg export . > patch.txt
>>>  $ hg prune . # could also be done by pulling obsmarkers from a remote
>>>               # peer, or it could be amend / metaedit etc.
>>>  $ hg import --exact --bypass patch.txt # cannot really import the patch
>> The case you describe above work as intended.
> I know it's the original intent, but I'm not sure that the original intent is actually a desirable set of outcomes. I've actually tripped over this usability wart a decent number of times, usually some variation on this theme:
> hg pull marmoute-wip -r some-feature
> hg co some-feature
> hg rebase -d @
> <poke a bit>
> hg strip 'ancestors(some-feature) and not ancestors(@)'
> <time passes>
> hg pull marmoute-wip -r some-feature # which has not moved since the last time I pulled
> <it appears nothing happens>

The issue you face here is related to known limitation of `hg strip`. 
When it removes the changesets, strip should also remove the 
obsolescence markers leading to them.

That will be fixed soon. Having strip able to remove obsmarker has been 
close to the top of the evolve roadmap[1] for some times and it is on 
the funded path.

Once Strip is fixed, we'll be back in a world without natural way to 
locally have an obsmarkers chain ending on a latest successors we do not 
have locally. In other words, if a changset is obsolete in your repo, it 
either has a visible latest successors or it is pruned.

[1] https://www.mercurial-scm.org/wiki/CEDRoadMap

> This briefly confuses *me* when I trip over it,
> and I've helped work out some of the design of the feature,

I'm sorry, but no. you did not helped work out some of the design of the 
feature. You have barely contributed code touching evolution and not 
contributed to its concept. You attended some meeting and discussion, 
that does not automatically makes you an evolution expert.

> which strongly suggests to me that the "is listed as a precursor in an
> obsmarker means its always hidden" behavior is suboptimal in the real world.
> As a rough cut of how we might reconcile usability and theory, I wonder if
> the correct path is to have obsmarkers immediately hide things (if possible)
> only when they're first introduced (likely through pull), but if the user
> takes an action that unhides, we just do that and then there's some advisory
> mechanism by which they can be told that things have been obsoleted.

I'm going to repeat myself here: hiding is an important feature of 
changeset-evolution and part of the global state it allows people to 

Mixing it with local only elements will not work. They are tons of 
simple case where we won't be able to determine a simple and consistent 
behavior for it. Even the local case can quickly raise shortcoming to 
the above proposal:

   When an orphan changeset gets hidden by evolution, what should we do
   with its obsolete parent? Was it visible because of the orphan or
   because the user actively "unhide" it some time ago?

Looking at the distributed case is worse, the global state is a critical 
part of changeset evolution. This proposal is not getting through the 
basic example[3] (pulling the markers before the changesets). It also 
break the branch replacement code[4], a bit we have concrete data that 
users cares a lot about.

The issue with mixing local data with the global state is at the 
theoretical level. This we can probably keep finding new problematic 
cases over and over.

[2] https://www.mercurial-scm.org/wiki/CEDConcept#Global_State
[3] https://www.mercurial-scm.org/wiki/CEDConcept#concrete_examples

>> By using "hg prune ." you globally marks the changeset as an undesirable
>> dead-end (obsolete-pruned)[1]. re-obtaining the same changesets in this
>> repository or in another will not affect this global state. We are just
>> adding global informations together:
>>  The changeset exists + a prune marker exists == this changeset is
>> obsolete.
>> This global state is a critical part of changeset evolution, and the
>> visibility rules computed from obsolescence are fully parts of this
>> state[2].
> I'm starting to get nervous about the "global state" business, because it's starting to remind me of bookmarks.

Can you elaborate? bookmarks are a very different concept, without 
history, I do not see what relation you see between the two.

> Sometimes (often?) user-local state is super important. I think it's feasible to have a global obsolescence state as an advisory mechanism for hiding

I've already written multiple documents pointing at why allowing local 
data to permanently mud with hidden-ness from obsolescence is 
problematic. Please go back to them and if needed point out precises 
elements that needs clarification.

> (for example "caution: the revision you've checked out has been rebased by $user to $revision - you may not want to do any work here",

Note: We are already doing half of this and have the data to do the 
other half.

> or the automatic hiding I mentioned above that's easy to undo) and still retain enough of the "magic" that evolution is still a huge win over the status quo in other history editing tooling.
> It sounds like there are no objections to the immediate 'hg hide' proposal, and the only points of contention are around the expected future interactions between hiding and exchanged obsolete markers. Is that an accurate assessment?

¿I'm quite confused? how do you end up interpreting:

    "this kills our ability to complete and ship changeset-evolution
     to all Mercurial user in the next year or two."


    "there are no objections"?

Regarding purely local hiding, an alternative to "hg strip" fully 
independent of obsolescence is a good idea. I do not think we can call 
it `hg hide` and `hg unhide`. As explained before, 'hidden' can comes 
from multiple sources and using such command name would be confusing. I 
like 'hg archive' from Jun proposal at the sprint, it would do a good 

>> So far, I'm not seen a rational for hash-preservation been a -requirement-
>> nor a group of people agreeing it is a -requirement-.
>> Sure it would be nice, but "nice" is different from -required-.
>> This is probably a core point we need to iron out in this discussion.
> I'm starting (based on the above rough edges that I've tripped on more than once)

I know two rough edges you have met:

1) dropping queued patch → from an issue with the current community 

2) the strip case above → from current lacking implementation of strip.

Are there other case you have tripped on ?

> to be of the opinion that supporting hash preservation is effectively non-optional because of workflows people already have in their brains.

Can you elaborate on these workflow?

> It also makes a bunch of cases in tools like histedit and commit --amend easier to write (and harder for future extension authors to screw up!) to get that working in a sensible way.

The code that ensure monotonic rewrite in amend and histedit is very 
small (couple of line) and has been working smoothly since their 

I'm very surprised one would consider to postpone evolution release to 
unforeseeable future because of such small code changes.


Pierre-Yves David

More information about the Mercurial-devel mailing list