Patchwork [1,of,4] obsolete: add an `ui.prevent-unstable` option and related function

login
register
mail settings
Submitter Pierre-Yves David
Date Dec. 28, 2012, 10:44 p.m.
Message ID <84a2e3e8a7123f6d2593.1356734694@yamac.lan>
Download mbox | patch
Permalink /patch/320/
State Superseded, archived
Headers show

Comments

Pierre-Yves David - Dec. 28, 2012, 10:44 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
# Date 1356728772 -3600
# Node ID 84a2e3e8a7123f6d2593a4c78cca4399d77538b8
# Parent  8019f96ec4ce96f97dde775fe6f45007f29dabc3
obsolete: add an `ui.prevent-unstable` option and related function

This option controls if operation like `commit --amend`, `rebase` or `histedit`
can rewrite changeset without taking care of they descendant. In such case the
descendant become "unstable" and the user needs to take care of them later.

We always prevent creation of instability if the obsolescence feature is
disable. We would have no way to express the rewritting and the unstability
without them.

Rationale:

With obsolescence marker it is technically possible to rewrite a changeset
without taking care of its descendants. Advanced user want to benefit from that
but it seems a bad idea to expose that to new user. Therefor we need a way for
advanced user to enable is explicitly. The option introduced by this changeset
is our proposed solution. Rewriting operation is forbidden by default but there
a new UI option to make it possible.

As an alternative we could had a dedicated flag on all history rewriting
operation but it seems less convenient. In particular such flag for commit would
seems odd.
Matt Mackall - Dec. 29, 2012, midnight
On Fri, 2012-12-28 at 23:44 +0100, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
> # Date 1356728772 -3600
> # Node ID 84a2e3e8a7123f6d2593a4c78cca4399d77538b8
> # Parent  8019f96ec4ce96f97dde775fe6f45007f29dabc3
> obsolete: add an `ui.prevent-unstable` option and related function
...
> Rationale:
> 
> With obsolescence marker it is technically possible to rewrite a changeset
> without taking care of its descendants. Advanced user want to benefit from that
> but it seems a bad idea to expose that to new user.

And what's the rationale for an advanced user wanting to do that?
Pierre-Yves David - Dec. 29, 2012, 12:28 a.m.
On 29 d?c. 2012, at 01:00, Matt Mackall wrote:

> On Fri, 2012-12-28 at 23:44 +0100, Pierre-Yves David wrote:
>> # HG changeset patch
>> # User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
>> # Date 1356728772 -3600
>> # Node ID 84a2e3e8a7123f6d2593a4c78cca4399d77538b8
>> # Parent  8019f96ec4ce96f97dde775fe6f45007f29dabc3
>> obsolete: add an `ui.prevent-unstable` option and related function
> ...
>> Rationale:
>> 
>> With obsolescence marker it is technically possible to rewrite a changeset
>> without taking care of its descendants. Advanced user want to benefit from that
>> but it seems a bad idea to expose that to new user.
> 
> And what's the rationale for an advanced user wanting to do that?

Advanced user want to focus on what they are current rewriting and handle the consequence on descendant later. When they have a better understanding of what they changed.
Such workflow is similar to the one MQ use. You qrefresh you current patch only and care about consequences later.

Eg: refactoring branchmap have consequences on filtering related changesets. I have no willingness to handle consequence on them until I'm done refactoring.

Other useful usecase is `hg rebase -r` that allows you to extract a changeset from a series.

Other early user of evolve can testify they do that all the time.
Pierre-Yves David - Dec. 29, 2012, 3:33 a.m.
On 29 d?c. 2012, at 01:28, Pierre-Yves David wrote:

> 
> On 29 d?c. 2012, at 01:00, Matt Mackall wrote:
> 
>> On Fri, 2012-12-28 at 23:44 +0100, Pierre-Yves David wrote:
>>> # HG changeset patch
>>> # User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
>>> # Date 1356728772 -3600
>>> # Node ID 84a2e3e8a7123f6d2593a4c78cca4399d77538b8
>>> # Parent  8019f96ec4ce96f97dde775fe6f45007f29dabc3
>>> obsolete: add an `ui.prevent-unstable` option and related function
>> ...
>>> Rationale:
>>> 
>>> With obsolescence marker it is technically possible to rewrite a changeset
>>> without taking care of its descendants. Advanced user want to benefit from that
>>> but it seems a bad idea to expose that to new user.
>> 
>> And what's the rationale for an advanced user wanting to do that?
> 
> Advanced user want to focus on what they are current rewriting and handle the consequence on descendant later. When they have a better understanding of what they changed.
> Such workflow is similar to the one MQ use. You qrefresh you current patch only and care about consequences later.
> 
> Eg: refactoring branchmap have consequences on filtering related changesets. I have no willingness to handle consequence on them until I'm done refactoring.
> 
> Other useful usecase is `hg rebase -r` that allows you to extract a changeset from a series.
> 
> Other early user of evolve can testify they do that all the time.


After discussion with Matt and Siddhart I'll drop the option.

If obsolete is enabled we allow unstability creation.

The proper default will be discussed at the sprint.

Patch

diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -131,10 +131,24 @@  from i18n import _
 # as bumped too, we add the `bumpedfix` flag to the marker. <A', (Ad,)>.
 # This flag mean that the successors are an interdiff that fix the bumped
 # situation, breaking the transitivity of "bumped" here.
 bumpedfix = 1
 
+def preventunstable(ui):
+    '''Shall we actively prevent creation of instability locally?
+
+    Always True if the obsolete feature is not enabled. Without obsolescence
+    markers, history rewriting operations strip rewritten changeset... and their
+    children.
+
+    It use the `ui.prevent-unstable` option.
+    '''
+    if not _enabled:
+        return True
+    return ui.configbool('ui', 'prevent-unstable', True)
+
+
 def _readmarkers(data):
     """Read and enumerate markers from raw data"""
     off = 0
     diskversion = _unpack('>B', data[off:off + 1])[0]
     off += 1