[PATCH 4 of 4 V4 evolve-ext] metaedit: add support for folding commits while editing their metadata

Siddharth Agarwal sid at less-broken.com
Mon May 2 13:21:52 EDT 2016


On 5/2/16 09:27, Pierre-Yves David wrote:
> I've pushed this series.

Thanks :)

>
> I made two minor followup changeset to adjust details I noted while 
> reading them.
>
> On 04/26/2016 06:14 PM, Simon Farnsworth wrote:
>> I like this - it's a safe subset of histedit for operations (like 
>> code review tools) that want to change metadata but don't want bugs 
>> to damage the diff.
>>
>> I can't see anything wrong with this version.
>>
>> Simon
>>
>> On 26/04/2016 00:34, Siddharth Agarwal wrote:
>>> # HG changeset patch
>>> # User Siddharth Agarwal <sid0 at fb.com>
>>> # Date 1461626682 25200
>>> #      Mon Apr 25 16:24:42 2016 -0700
>>> # Node ID 71e061aa0be879ad6477fbdb724a3a2e69e5af5b
>>> # Parent  ea19e5ccc442ac286d4244695365034475b4fa5c
>>> metaedit: add support for folding commits while editing their metadata
>>>
>>> This also allows us to accept multiple commits without dealing with 
>>> the thorny
>>> algorithmic and UI issues of editing multiple commits at once.
>>>
>>> Crucially, it is different from 'hg fold --exact' in that it also 
>>> allows
>>> 'folding' a single commit and rewriting its metadata. This is really 
>>> useful to
>>> have as a single logical operation, for example while preparing a 
>>> series of
>>> multiple local changesets that will need to be pushed as a single 
>>> changeset.
>>>
>>> diff --git a/hgext/evolve.py b/hgext/evolve.py
>>> --- a/hgext/evolve.py
>>> +++ b/hgext/evolve.py
>>> @@ -3151,14 +3151,18 @@ def fold(ui, repo, *revs, **opts):
>>>
>>>   @command('^metaedit',
>>>            [('r', 'rev', [], _("revision to edit")),
>>> +         ('', 'fold', None, _("also fold specified revisions into 
>>> one")),
>>>            ] + commitopts + commitopts2,
>>>            _('hg metaedit [OPTION]... [-r] [REV]'))
>>>   def metaedit(ui, repo, *revs, **opts):
>>>       """edit commit information
>>>
>>> -    Edits the commit information for the specified revision. By 
>>> default, edits
>>> +    Edits the commit information for the specified revisions. By 
>>> default, edits
>>>       commit information for the working directory parent.
>>>
>>> +    With --fold, also folds multiple revisions into one if 
>>> necessary. In this
>>> +    case, the given revisions must form a linear unbroken chain.
>>> +
>>>       .. container:: verbose
>>>
>>>        Some examples:
>>> @@ -3171,10 +3175,19 @@ def metaedit(ui, repo, *revs, **opts):
>>>
>>>            hg metaedit --user 'New User <new-email at example.com>'
>>>
>>> +     - Combine all draft revisions that are ancestors of foo but 
>>> not of @ into
>>> +       one::
>>> +
>>> +         hg metaedit --fold 'draft() and only(foo,@)'
>>> +
>>> +       See :hg:`help phases` for more about draft revisions, and
>>> +       :hg:`help revsets` for more about the `draft()` and `only()` 
>>> keywords.
>>>       """
>>>       revs = list(revs)
>>>       revs.extend(opts['rev'])
>>>       if not revs:
>>> +        if opts['fold']:
>>> +            raise error.Abort(_('revisions must be specified with 
>>> --fold'))
>>>           revs = ['.']
>>>
>>>       wlock = lock = None
>>> @@ -3183,7 +3196,7 @@ def metaedit(ui, repo, *revs, **opts):
>>>           lock = repo.lock()
>>>
>>>           revs = scmutil.revrange(repo, revs)
>>> -        if len(revs) > 1:
>>> +        if not opts['fold'] and len(revs) > 1:
>>>               # TODO: handle multiple revisions. This is somewhat 
>>> tricky because
>>>               # if we want to edit a series of commits:
>>>               #
>>> @@ -3192,18 +3205,21 @@ def metaedit(ui, repo, *revs, **opts):
>>>               # we need to rewrite a first, then directly rewrite b 
>>> on top of the
>>>               # new a, then rewrite c on top of the new b. So we 
>>> need to handle
>>>               # revisions in topological order.
>>> -            raise error.Abort(_('editing multiple revisions is not '
>>> -                                'currently supported'))
>>> -
>>> -        newunstable = _disallowednewunstable(repo, revs)
>>> -        if newunstable:
>>> -            raise error.Abort(
>>> -                _('cannot edit commit information in the middle of 
>>> a stack'),
>>> -                hint=_('%s will be affected') % 
>>> repo[newunstable.first()])
>>> -        if repo.revs("%ld and public()", revs):
>>> -            raise error.Abort(_('cannot edit commit information for 
>>> public '
>>> -                                'revisions'))
>>> -        root = head = repo[revs.first()]
>>> +            raise error.Abort(_('editing multiple revisions without 
>>> --fold is '
>>> +                                'not currently supported'))
>>> +
>>> +        if opts['fold']:
>>> +            root, head = _foldcheck(repo, revs)
>>> +        else:
>>> +            newunstable = _disallowednewunstable(repo, revs)
>>> +            if newunstable:
>>> +                raise error.Abort(
>>> +                    _('cannot edit commit information in the middle 
>>> of a stack'),
>>> +                    hint=_('%s will be affected') % 
>>> repo[newunstable.first()])
>>> +            if repo.revs("%ld and public()", revs):
>>> +                raise error.Abort(_('cannot edit commit information 
>>> for public '
>>> +                                    'revisions'))
>>> +            root = head = repo[revs.first()]
>>>
>>>           wctx = repo[None]
>>>           p1 = wctx.p1()
>>> @@ -3217,7 +3233,12 @@ def metaedit(ui, repo, *revs, **opts):
>>>               if commitopts.get('message') or 
>>> commitopts.get('logfile'):
>>>                   commitopts['edit'] = False
>>>               else:
>>> -                msgs = [head.description()]
>>> +                if opts['fold']:
>>> +                    msgs = ["HG: This is a fold of %d changesets." 
>>> % len(allctx)]
>>> +                    msgs += ["HG: Commit message of changeset 
>>> %s.\n\n%s\n" %
>>> +                             (c.rev(), c.description()) for c in 
>>> allctx]
>>> +                else:
>>> +                    msgs = [head.description()]
>>>                   commitopts['message'] =  "\n".join(msgs)
>>>                   commitopts['edit'] = True
>>>
>>> @@ -3239,6 +3260,8 @@ def metaedit(ui, repo, *revs, **opts):
>>>           finally:
>>>               tr.release()
>>>
>>> +        if opts['fold']:
>>> +            ui.status('%i changesets folded\n' % len(revs))
>>>           if newp1 is not None:
>>>               hg.update(repo, newp1)
>>>       finally:
>>> diff --git a/tests/test-evolve.t b/tests/test-evolve.t
>>> --- a/tests/test-evolve.t
>>> +++ b/tests/test-evolve.t
>>> @@ -1468,11 +1468,26 @@ hg metaedit
>>>     $ hg metaedit -r 0
>>>     abort: cannot edit commit information for public revisions
>>>     [255]
>>> +  $ hg metaedit --fold
>>> +  abort: revisions must be specified with --fold
>>> +  [255]
>>> +  $ hg metaedit -r 0 --fold
>>> +  abort: cannot fold public revisions
>>> +  [255]
>>> +  $ hg metaedit '36 + 42' --fold
>>> +  abort: cannot fold non-linear revisions (multiple roots given)
>>> +  [255]
>>> +  $ hg metaedit '36::39 + 41' --fold
>>> +  abort: cannot fold non-linear revisions (multiple heads given)
>>> +  [255]
>>>   check that metaedit respects allowunstable
>>>     $ hg metaedit '.^' --config 
>>> 'experimental.evolution=createmarkers, allnewcommands'
>>>     abort: cannot edit commit information in the middle of a stack
>>>     (c904da5245b0 will be affected)
>>>     [255]
>>> +  $ hg metaedit '18::20' --fold --config 
>>> 'experimental.evolution=createmarkers, allnewcommands'
>>> +  abort: cannot fold chain not ending with a head or with branching
>>> +  [255]
>>>     $ hg metaedit --user foobar
>>>     0 files updated, 0 files merged, 0 files removed, 0 files 
>>> unresolved
>>>     $ hg log --template '{rev}: {author}\n' -r '42:' --hidden
>>> @@ -1483,26 +1498,57 @@ check that metaedit respects allowunstab
>>>
>>>   TODO: support this
>>>     $ hg metaedit '.^::.'
>>> -  abort: editing multiple revisions is not currently supported
>>> +  abort: editing multiple revisions without --fold is not currently 
>>> supported
>>>     [255]
>>>
>>> -no new commit is created here because the date is the same
>>> -  $ HGEDITOR=cat hg metaedit
>>> +  $ HGEDITOR=cat hg metaedit '.^::.' --fold
>>> +  HG: This is a fold of 2 changesets.
>>> +  HG: Commit message of changeset 41.
>>> +
>>> +  amended
>>> +
>>> +  HG: Commit message of changeset 43.
>>> +
>>>     will be evolved safely
>>>
>>>
>>> +
>>>     HG: Enter commit message.  Lines beginning with 'HG:' are removed.
>>>     HG: Leave message empty to abort commit.
>>>     HG: --
>>> -  HG: user: foobar
>>> +  HG: user: test
>>>     HG: branch 'default'
>>>     HG: changed a
>>> +  HG: changed newfile
>>> +  2 changesets folded
>>> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
>>> +
>>> +  $ glog -r .
>>> +  @  44:41bf1183869c at default(draft) amended
>>> +  |
>>> +  ~
>>> +
>>> +no new commit is created here because the date is the same
>>> +  $ HGEDITOR=cat hg metaedit
>>> +  amended
>>> +
>>> +
>>> +  will be evolved safely
>>> +
>>> +
>>> +  HG: Enter commit message.  Lines beginning with 'HG:' are removed.
>>> +  HG: Leave message empty to abort commit.
>>> +  HG: --
>>> +  HG: user: test
>>> +  HG: branch 'default'
>>> +  HG: changed a
>>> +  HG: changed newfile
>>>     nothing changed
>>>
>>>     $ glog -r '.^::.'
>>> -  @  43:62353add3dfb at default(draft) will be evolved safely
>>> +  @  44:41bf1183869c at default(draft) amended
>>>     |
>>> -  o  41:34ae045ec400 at default(draft) amended
>>> +  o  36:43c3f5ef149f at default(draft) add uu
>>>     |
>>>     ~
>>>
>>> @@ -1510,15 +1556,22 @@ TODO: don't create a new commit in this
>>>     $ hg metaedit --config defaults.metaedit=
>>>     0 files updated, 0 files merged, 0 files removed, 0 files 
>>> unresolved
>>>     $ hg log -r '.^::.' --template '{rev}: {desc|firstline}\n'
>>> -  41: amended
>>> -  44: will be evolved safely
>>> +  36: add uu
>>> +  45: amended
>>>
>>>     $ hg up .^
>>> -  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
>>> -  $ hg metaedit --user foobar2 44
>>> +  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
>>> +  $ hg metaedit --user foobar2 45
>>>     $ hg log --template '{rev}: {author}\n' -r '42:' --hidden
>>>     42: test
>>>     43: foobar
>>> -  44: foobar
>>> -  45: foobar2
>>> -  $ hg diff -r 44 -r 45 --hidden
>>> +  44: test
>>> +  45: test
>>> +  46: foobar2
>>> +  $ hg diff -r 45 -r 46 --hidden
>>> +
>>> +'fold' one commit
>>> +  $ hg metaedit 39 --fold --user foobar3
>>> +  1 changesets folded
>>> +  $ hg log -r 47 --template '{rev}: {author}\n'
>>> +  47: foobar3
>>> _______________________________________________
>>> Mercurial-devel mailing list
>>> Mercurial-devel at mercurial-scm.org
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mercurial-2Dscm.org_mailman_listinfo_mercurial-2Ddevel&d=CwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=mEgSWILcY4c4W3zjApBQLA&m=UHn3lAnPn2BRfDMVSc9_wLI4N4sjJYZax4FtWUqUWJY&s=nM0aEVfbyAV1jJibZ_K_QhF2VL1XOSRF1FdcDsmXi_k&e= 
>>>
>>>
>>
>
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel




More information about the Mercurial-devel mailing list