D2679: [PoC] obsolete: config option to enable local only obsolescence mode

lothiraldan (Boris Feld) phabricator at mercurial-scm.org
Wed Oct 10 16:55:00 EDT 2018


lothiraldan added a comment.


  In https://phab.mercurial-scm.org/D2679#73347, @martinvonz wrote:
  
  > Here's a case I just ran into where I would have liked to de-obsolete a commit:
  >
  > 1. Someone queues a patch and pushes to central repo. Repo looks like this:
  
  
  You are using the words "Someone queues a patch", is your example taken from the current Mercurial project workflow? If so, keep in mind that this workflow is a bit unique. It is not what we refer as "distributed evolution" and diverges from it in various ways. In particular, we can highlight the following difference:
  
  - Contributions are exchanged through email or Phabricator. Both ways fail to transfers the associated obsmarkers (and therefore break the evolution chains). Instead people using distributed evolution exchanges changesets through mercurial repositories, fully taking advantage of the obsmarkers data. This makes it possible for them to collaborate on the same feature branch and other evolution benefits (eg: evolution data in code review tools).
  - The publication workflow is odds as hundreds of unrelated draft changeset can stack above each other before being published. This is not really the use-case that draft phase and evolution targets.
  
  > 
  > 
  >   o  B
  >   |
  >   o  A
  > 
  > 
  > 
  > 
  > 2. I fix a typo and and amend, but I forget to push.
  > 3. I build my own commit on top. My repo:
  > 
  >   ``` o  X | o  B' | o  A ```
  
  Small side question: Why are you building X on top of (draft) B', are they related?
  
  > 
  > 
  > 4. Someone pushes new patches to central repo. Central repo:
  > 
  >   ``` o  C | o  B | o  A ```
  
  Additional side question: Why is C on top of (draft) B. Are they related?
  
  > 
  > 
  > 5. I pull from central repo. My repo:
  > 
  >   ``` o  C | x B | | o  X | | | o  B' |/ o  A ```
  > 6. I move my change onto the new upstream and prune my local B' that's now unwanted:
  > 
  >   ``` o X' | o  C | x B | | x B' |/ o  A ```
  > 
  >   If upstream history was really just a single commit (`C` above), then the obvious thing to do is to just evolve that commit and push it. However, sometimes there is a long chain on top, and in my case there was a separate commit upstream that fixed the typo I fixed when I amended `B` and it would be a little confusing to explain why someone's fix was "lost".
  
  I can see two distinct arguments in that description:
  
  1. Someone else made a similar fix in an independent changeset, and you want to give them the priority.
  2. There are many drafts stacked above it and you don't want to rewrite B.
  
  Regarding the first argument, the case is easily handled by "rewinding" your amend's change and restoring the diff provided by 'B'. The `hg rewind` command deal with this case well: `hg rewind --to B`. The use of `hg prune` in your example is wrong. By using prune, you signal that the full line of change in B' (B' and it predecessors B) is something that is unwanted. So you are not just dropping the change introduced in your amend, but the other associated change.
  
  Regarding the second argument, the one I interpret as it would create too many orphans.
  It seems to be the consequence of the current Mercurial Project workflow where many unrelated drafts get stacked.
  The point of the draft phase is to signal that a changeset is safe to be rewritten. In other words that the consequences of such rewriting are acceptable. If you get to the point where rewriting draft no longer feel safe you seem to have a workflow issue.
  
  For the sake of the current argument, let's assume that the workflow would be fixed in a direction where B would be public. After your pull. In that case, B' would be "phase-divergent". Solving that phase-divergence will create a ΔB changeset with just the fix (you amend change). Rebasing that ΔB on top of the other fix will make it disappears, giving priority as you intended.
  
  > So I'd prefer to mark B as no longer obsolete. I know I can do that with `hg strip B'`, but that also strips `X`, which is probably not a big loss, but it's a weird side-effect.
  
  You cannot really strip the obsmarkers between B and B' without stripping B' itself. If B' end up being visible again it's Evolve that would be lost introducing confusion too.
  
  > Perhaps all I'm asking for is a way of dropping the obsmarker between `B` and `B'`. I don't know what the best UI for that would be, though. For now, I guess I'll use `hg strip`.
  
  Stripping obsmarkers (and changesets) gets tricky quickly as their might continue to exist elsewhere. issue5267 <https://bz.mercurial-scm.org/show_bug.cgi?id=5267> is a good example. There is already a couple of ways to do it (hg strip or hg debugobsolete) but it is currently confined into advanced commands. Before smoothing special case that could benefit stripping (or equivalent feature), it is important to deal with the UI for the main use-case. The use-case that solves both local and distributed evolution with the same command set. We want this commands set to comes first as we know it will be necessary. We can add more advanced commands and concept to deal with stripping afterward.
  
  Let me clarify that last part: imagine two commands (or command set, or concepts):
  
  1. Command-A handles cases for both local and distributed evolution,
  2. Command-B only handles local evolution, but deal with a corner case a bit later.
  
  If we introduce Command-A early, we can foster a good user experience that will be the same for local and distributed case. This makes the "step" to distributed usage simple and painless. The overall user experience and other commands will make sure they work smoothly with Command-A. Later, we can introduce Command-B that will deal with specialized cases were Command-A is lacking. Since Command-A is already covering the main use-cases well, Command-B can focus on dealing with the specialized cases only. Each command has clear responsibilities.
  
  On the other hand, introducing Command-B first will create a user experience that does not cover all of the main use-cases. The later arrival of Command-A will introduce an overlap in responsibilities confusing to users. In addition, it will create a problematic step to move from the local experience to the distributed one. Users will have to "forget" their previous usage to be able to get the better of Mercurial, this will create more confusion.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2679

To: indygreg, #hg-reviewers
Cc: martinvonz, markand, durin42, lothiraldan, pulkit, mercurial-devel


More information about the Mercurial-devel mailing list