[PATCH 1 of 4 V2] obsolete: track node versions

Durham Goode durham at fb.com
Thu Mar 30 14:28:32 EDT 2017


Let's step back a moment and think about what obsmarkers are used for. 
They are used to hide commits, and to automatically perform rebases. The 
concerns around obscycles is that allowing cycles (without a perfect 
version scheme) could affect those two uses.  For hiding, it could 
result in hiding commits from the user that they didn't mean to be 
hidden. For rebasing, it means we could rebase onto the wrong successor.

I think the underlying issue is that we're trying to do too much magic 
for the user, and we're unable to find a perfect design to make that 
magic safe and understandable. I think finding the right answer here may 
be impossible.

Proposal
===

I propose a series of changes to reduce the magic and remove the need 
for obs versioning, while maintaining the power and increasing the 
understandability of these workflows. It has two parts:


1. Never hide a commit during hg pull. Only hide commits when the user 
does an action (strip/rebase/amend/histedit/evolve)
---

One of the recurring issues with obsmarkers is that commits may 
magically disappear when you pull from another repo. This has two 
issues: A) we have no good way of explaining it to the user, and B) we 
can't even be sure the user wants those commits to disappear.

I propose we *never* hide a commit when doing hg pull. When the user 
pulls, we download the obsmarkers like normal, but the commits don't 
disappear. Instead, we show the "[amended|rebased] to HASH" text in a 
log/smartlog output so the user can know the old commits are dead, then 
they can strip them at their leisure. This has the added benefit of 
making it user visible what obsmarker changes the pull brought in.

This proposal has two optional side features:

1a. *Do* hide commits during pull if the pulled version is public.
1b. Add an option to strip/prune to auto hide any visible commits that 
have visible successors and don't have visible descendants. So "hg pull 
&& hg strip/prune --obsolete-commits" would be roughly equivalent to hg 
pull today.

This proposal requires a notable change to core:

- Hidden must be separated from obsmarkers storage and mutable outside 
obsmarkers. This is possible with Jun's proposed phaseroot-esque hidden 
storage.


2. Auto rebase uses "visible successors" instead of "latest successor"
---

Today auto rebase (i.e. evolve) uses the latest successor as the 
destination of the rebases. I propose we change that to "visible 
successor" instead, where visible successor is defined as "any successor 
commit that is not hidden". This means, regardless of the current 
obsmarkers setup, the destination of the auto rebase is whatever 
successor is currently visible. Which is probably what the user wanted 
anyway.

If there are multiple visible successors, auto rebase fails and shows a 
list of the potential visible successors. Each item in the list can have 
the "[amended|rebased] to HASH" string next to it so users can 
understand at a glance the ordering and make a decision. They can either 
use -d on rebase to specify a solution to the conflict, or they  can use 
the normal visibility commands (hg strip/prune) to remove any 
undesirable commits.

The presence of cycles does not affect this at all, and there is no need 
for marker versioning. Auto rebase still uses whatever successors are 
visible, even if the successor is "older" than it, because of a cycle. 
The user can use the same rebase -d or strip/prune resolutions to 
resolve the conflict.

Summary of what these two changes achieve
===

 From a single, non-exchanging user's perspective the above proposal 
does not affect current UX around when things are hidden (like during 
rebase/amend/etc), but does allows all the benefits of the obscycle 
discussion (allowing unhiding) without the need for obsmarker versioning.

 From an exchange user's perspective, this makes exchange much more 
deterministic for the user (nothing is magically removed from the repo, 
and what new obs information from the pull is explained via smartlog), 
while still enabling auto rebase workflows. It also makes obsmarker 
conflict (divergence/etc) easier to understand and resolve by allowing 
users to resolve obsmarker conflicts using tools they're already 
familiar with (rebase -d, strip/prune).


More information about the Mercurial-devel mailing list