[PATCH v2] histedit: add 'stop' verb

Pierre-Yves David pierre-yves.david at ens-lyon.org
Fri Sep 19 19:36:15 CDT 2014



On 09/16/2014 10:55 AM, David Soria Parra wrote:
> # HG changeset patch
> # User David Soria Parra <davidsp at fb.com>
> # Date 1410834154 25200
> #      Mon Sep 15 19:22:34 2014 -0700
> # Node ID 026b02a9b45b1c0c811822b2374c8b8f0c710cd4
> # Parent  2dd1cbee569db9c04c4be2e8342bba2c576a4337
> histedit: add 'stop' verb
>
> Add a stop verb to stop after a given revision and drop out to the shell. If
> obsolence markers aren't enabled, the user can only perform read operations.

There does not seems to be anything enforcing this read onlyness (but 
the fact that in a special case, hg commit --amend refuse to work)

What would happen if someone changes the hash of the parent (so that 
"stopped" changeset have a different hash) and then change the hash 
again using `hg commit --amend`



> diff --git a/hgext/histedit.py b/hgext/histedit.py
> --- a/hgext/histedit.py
> +++ b/hgext/histedit.py
[…]
> @@ -403,6 +406,26 @@
>   def drop(ui, repo, ctx, ha, opts):
>       return ctx, [(repo[ha].node(), ())]
>
> +def stop(ui, repo, ctx, ha, opts):
> +    oldctx = repo[ha]
> +    if oldctx.parents()[0] == ctx:
> +        ui.debug('node %s unchanged\n' % ha)
> +        hg.update(repo, oldctx.node())
> +        current = oldctx
> +    else:
> +        hg.update(repo, ctx.node())
> +        stats = applychanges(ui, repo, oldctx, opts)
> +        if stats and stats[3] > 0:
> +            raise error.InterventionRequired(_('Fix up the change and run '
> +                                               'hg histedit --continue'))
> +        # drop the second merge parent
> +        commit = commitfuncfor(repo, oldctx)
> +        n = commit(text=oldctx.description(), user=oldctx.user(),
> +                   date=oldctx.date(), extra=oldctx.extra())
> +        current = repo[n]
> +
> +    raise error.InterventionRequired(
> +        _('Stopped at %s. Run hg histedit --continue to resume.') % current)

Can't we just reuse the code from pick? sound like a pure code 
duplication to me.

Also, the documentation of histedit should be updated too.

>   def message(ui, repo, ctx, ha, opts):
>       oldctx = repo[ha]
> @@ -459,6 +482,8 @@
>                  'drop': drop,
>                  'm': message,
>                  'mess': message,
> +               's': stop,
> +               'stop': stop,
>                  }
>
>   @command('histedit',
[…]
> diff --git a/tests/test-histedit-stop.t b/tests/test-histedit-stop.t
> new file mode 100644
> --- /dev/null
> +++ b/tests/test-histedit-stop.t
> @@ -0,0 +1,224 @@
> +  $ . "$TESTDIR/histedit-helpers.sh"
> +
> +  $ cat >> $HGRCPATH <<EOF
> +  > [extensions]
> +  > histedit=
> +  > EOF
> +
> +  $ initrepo ()
> +  > {
> +  >     hg init r
> +  >     cd r
> +  >     for x in a b c d e f ; do
> +  >         echo $x > $x
> +  >         hg add $x
> +  >         hg ci -m $x
> +  >     done
> +  > }
> +
> +  $ initrepo
> +
> +log before edit
> +
> +  $ hg log --graph
> +  @  changeset:   5:652413bf663e
> +  |  tag:         tip
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     f
> +  |
> +  o  changeset:   4:e860deea161a
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     e
> +  |
> +  o  changeset:   3:055a42cdd887
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     d
> +  |
> +  o  changeset:   2:177f92b77385
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     c
> +  |
> +  o  changeset:   1:d2ae7f538514
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     b
> +  |
> +  o  changeset:   0:cb9a9f314b8b
> +     user:        test
> +     date:        Thu Jan 01 00:00:00 1970 +0000
> +     summary:     a
> +
> +
> +stop & continue must preserve hashes
> +
> +  $ hg histedit 177f92b77385 --commands - 2>&1 << EOF| fixbundle
> +  > pick 177f92b77385 c
> +  > pick 055a42cdd887 d
> +  > stop e860deea161a e
> +  > pick 652413bf663e f
> +  > EOF
> +  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
> +  Stopped at e860deea161a. Run hg histedit --continue to resume.

I do not feel like the "Stopped at e860deea161a." is bringing any 
information here. What about the start of the changeset descriptioon.

Also, we should probably be a bit more verbose. Something like:

Run any operation you would like to then run `hg histedit --continue` to 
resume.

> +
> +  $ hg histedit --continue
> +  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +
> +  $ hg log --graph
> +  @  changeset:   5:652413bf663e
> +  |  tag:         tip
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     f
> +  |
> +  o  changeset:   4:e860deea161a
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     e
> +  |
> +  o  changeset:   3:055a42cdd887
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     d
> +  |
> +  o  changeset:   2:177f92b77385
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     c
> +  |
> +  o  changeset:   1:d2ae7f538514
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     b
> +  |
> +  o  changeset:   0:cb9a9f314b8b
> +     user:        test
> +     date:        Thu Jan 01 00:00:00 1970 +0000
> +     summary:     a
> +
> +abort should work
> +
> +  $ hg histedit 177f92b77385 --commands - 2>&1 << EOF| fixbundle
> +  > pick 177f92b77385 c
> +  > pick 055a42cdd887 d
> +  > stop e860deea161a e
> +  > pick 652413bf663e f
> +  > EOF
> +  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
> +  Stopped at e860deea161a. Run hg histedit --continue to resume.
> +
> +  $ hg id -r . -i
> +  e860deea161a
> +  $ echo added > added
> +  $ hg add added
> +  $ hg commit --amend
> +  abort: cannot amend changeset with children
> +  [255]

I expect confusion here, we should either:

- relief this restriction soon,
- improve the message.


> +
> +  $ hg histedit --abort
> +
> +  $ hg log --graph --template '{node|short} {desc} {files}\n'
> +  o  652413bf663e f f
> +  |
> +  @  e860deea161a e e
> +  |
> +  o  055a42cdd887 d d
> +  |
> +  o  177f92b77385 c c
> +  |
> +  o  d2ae7f538514 b b
> +  |
> +  o  cb9a9f314b8b a a
> +
> +  $ hg update --clean
> +  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +
> +continue will pickup a dirty working dir
> +
> +  $ hg histedit 177f92b77385 --commands - 2>&1 << EOF| fixbundle
> +  > pick 177f92b77385 c
> +  > pick 055a42cdd887 d
> +  > stop e860deea161a e
> +  > pick 652413bf663e f
> +  > EOF
> +  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
> +  Stopped at e860deea161a. Run hg histedit --continue to resume.
> +
> +  $ hg id -r . -i
> +  e860deea161a
> +  $ echo added > added
> +  $ hg add added
> +
> +  $ hg histedit --continue
> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  saved backup bundle to $TESTTMP/r/.hg/strip-backup/652413bf663e-backup.hg

Deeply confused about what happened to the changes here. They appeared 
to have been silently commited. how was the message selected?

Is this a side effect of the `edit` implementation?


> +
> +  $ hg log --graph --template '{node|short} {desc} {files}\n'
> +  @  77c6d5f5f6f9 f f
> +  |
> +  o  94e1741af639 e added
> +  |
> +  o  e860deea161a e e
> +  |
> +  o  055a42cdd887 d d
> +  |
> +  o  177f92b77385 c c
> +  |
> +  o  d2ae7f538514 b b
> +  |
> +  o  cb9a9f314b8b a a
> +
> +Enable obsolete

 From here, everything appears to have a bad identation, so nothing is 
run. Fixing the indentation reveal test error.

> +
> + $ cat > ${TESTTMP}/obs.py << EOF
> + > import mercurial.obsolete
> + > mercurial.obsolete._enabled = True
> + > EOF
> +
> + $ cat >> $HGRCPATH << EOF
> + > [extensions]
> + > histedit=
> + > rebase=
> + >
> + > obs=${TESTTMP}/obs.py
> + > EOF
> +
> +With obsolete enabled a stop should retain the hashes
> +
> + $ hg histedit 177f92b77385 --commands - 2>&1 << EOF| fixbundle
> + > pick 177f92b77385 c
> + > pick 055a42cdd887 d
> + > stop e860deea161a e
> + > pick 94e1741af639 e
> + > pick 77c6d5f5f6f9 f
> + > EOF
> + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
> + Changes commited as d51720eb7a13. You may amend the commit now.
> + When you are finished, run hg histedit --continue to resume.
> +
> + $ echo added > added
> + $ hg add added
> + $ hg commit --amend
> +
> + $ hg histedit --continue
> + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +
> + $ hg log --graph --template '{node|short} {desc} {files}\n'
> + @  099559071076 f f
> + |
> + o  e860deea161a e e
> + |
> + o  e860deea161a e added e
> + |
> + o  055a42cdd887 d d
> + |
> + o  177f92b77385 c c
> + |
> + o  d2ae7f538514 b b
> + |
> + o  cb9a9f314b8b a a
> +


What about testing what happen when multiple changeset are added during 
stop ? (I assume the edit logic quick in again?)


-- 
Pierre-Yves David


More information about the Mercurial-devel mailing list