Patchwork amend: new extension providing the amend command

login
register
mail settings
Submitter Jun Wu
Date July 12, 2017, 4:01 a.m.
Message ID <906655cf953a84750642.1499832116@x1c>
Download mbox | patch
Permalink /patch/22249/
State Superseded
Headers show

Comments

Jun Wu - July 12, 2017, 4:01 a.m.
# HG changeset patch
# User Jun Wu <quark@fb.com>
# Date 1499831635 25200
#      Tue Jul 11 20:53:55 2017 -0700
# Node ID 906655cf953a84750642abd93d8c42663e808561
# Parent  26e4ba058215e536d3827befbea99ff6203d35f8
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 906655cf953a
amend: new extension providing the amend command

Various third parties have implemented the `amend` command, which is in high
demand. This patch adds it as an experimental extension so its interface
could be formalized in core directly.

Since `commit --amend` is basically what `amend` should do. The command is
just a thin wrapper around `commit --amend` and just prevent the editor from
popping up by passing `--message`.
via Mercurial-devel - July 12, 2017, 6:18 a.m.
On Tue, Jul 11, 2017 at 9:01 PM, Jun Wu <quark@fb.com> wrote:
> # HG changeset patch
> # User Jun Wu <quark@fb.com>
> # Date 1499831635 25200
> #      Tue Jul 11 20:53:55 2017 -0700
> # Node ID 906655cf953a84750642abd93d8c42663e808561
> # Parent  26e4ba058215e536d3827befbea99ff6203d35f8
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #              hg pull https://bitbucket.org/quark-zju/hg-draft -r 906655cf953a
> amend: new extension providing the amend command
>
> Various third parties have implemented the `amend` command, which is in high
> demand. This patch adds it as an experimental extension so its interface
> could be formalized in core directly.
>
> Since `commit --amend` is basically what `amend` should do. The command is
> just a thin wrapper around `commit --amend` and just prevent the editor from
> popping up by passing `--message`.

I use "hg amend -e" quite often. Would be nice to have that too.

>
> diff --git a/hgext/amend.py b/hgext/amend.py
> new file mode 100644
> --- /dev/null
> +++ b/hgext/amend.py
> @@ -0,0 +1,49 @@
> +# amend.py - provide the amend command
> +#
> +# Copyright 2017 Facebook, Inc.
> +#
> +# This software may be used and distributed according to the terms of the
> +# GNU General Public License version 2 or any later version.
> +"""provide the amend command (EXPERIMENTAL)
> +
> +This extension provides an ``amend`` command that is similar to
> +``commit --amend`` but does not prompt an editor.
> +"""
> +
> +from __future__ import absolute_import
> +
> +from mercurial.i18n import _
> +from mercurial import (
> +    cmdutil,
> +    commands,
> +    registrar,
> +)
> +
> +# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
> +# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
> +# be specifying the version(s) of Mercurial they are tested with, or
> +# leave the attribute unspecified.
> +testedwith = 'ships-with-hg-core'
> +
> +cmdtable = {}
> +command = registrar.command(cmdtable)
> +
> +@command('amend',
> +    [('A', 'addremove', None,
> +      _('mark new/missing files as added/removed before committing')),
> +     ('i', 'interactive', None, _('use interactive mode')),
> +    ] + cmdutil.walkopts + cmdutil.commitopts + cmdutil.commitopts2,
> +    _('[OPTION]... [FILE]...'),
> +    inferrepo=True)
> +def amend(ui, repo, *pats, **opts):
> +    """amend the working copy parent with all or specified outstanding changes
> +
> +    Similar to :hg:`commit --amend`, but reuse the commit message without
> +    invoking editor.
> +
> +    See :hg:`help commit` for more details.
> +    """
> +    with repo.wlock(), repo.lock():
> +        opts['message'] = opts.get('message') or repo['.'].description()
> +        opts['amend'] = True
> +        return commands._docommit(ui, repo, *pats, **opts)

Comparing this to evolve's version, there are a few differences:

* Missing support for --edit and --logfile (as noted above, I
personally often use the former). Looks like this patch still allows
--logfile, but will perhaps result in a 'options --message and
--logfile are mutually exclusive' message?
* Missing support for evolve's experimental --current-{date,user}
options. Not sure if we care
* Added locking, which seems like a good idea to do before
repo['.'].description(). In fact, that probably fixes
https://bz.mercurial-scm.org/show_bug.cgi?id=5266
* Calls into _docommit() instead of commit(), which makes sense given
the item above (commit() just takes the locks and then calls
_docommit())
Jun Wu - July 12, 2017, 7:40 a.m.
Excerpts from Martin von Zweigbergk's message of 2017-07-11 23:18:21 -0700:
> I use "hg amend -e" quite often. Would be nice to have that too.
>
> Comparing this to evolve's version, there are a few differences:
> 
> * Missing support for --edit and --logfile (as noted above, I
> personally often use the former). Looks like this patch still allows
> --logfile, but will perhaps result in a 'options --message and
> --logfile are mutually exclusive' message?

Good point. I missed "-l".

> * Missing support for evolve's experimental --current-{date,user}
> options. Not sure if we care

That sounds like "-d now" or "-u SOMETHING".

> * Added locking, which seems like a good idea to do before
> repo['.'].description(). In fact, that probably fixes
> https://bz.mercurial-scm.org/show_bug.cgi?id=5266 

Nice mention of the bug. I did consider the race but wasn't aware we had a
bug already.

> * Calls into _docommit() instead of commit(), which makes sense given
> the item above (commit() just takes the locks and then calls
> _docommit())

V2 will address the "-l" and "-e" issue, plus a bit simplification in the
test.

Patch

diff --git a/hgext/amend.py b/hgext/amend.py
new file mode 100644
--- /dev/null
+++ b/hgext/amend.py
@@ -0,0 +1,49 @@ 
+# amend.py - provide the amend command
+#
+# Copyright 2017 Facebook, Inc.
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+"""provide the amend command (EXPERIMENTAL)
+
+This extension provides an ``amend`` command that is similar to
+``commit --amend`` but does not prompt an editor.
+"""
+
+from __future__ import absolute_import
+
+from mercurial.i18n import _
+from mercurial import (
+    cmdutil,
+    commands,
+    registrar,
+)
+
+# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
+# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
+# be specifying the version(s) of Mercurial they are tested with, or
+# leave the attribute unspecified.
+testedwith = 'ships-with-hg-core'
+
+cmdtable = {}
+command = registrar.command(cmdtable)
+
+@command('amend',
+    [('A', 'addremove', None,
+      _('mark new/missing files as added/removed before committing')),
+     ('i', 'interactive', None, _('use interactive mode')),
+    ] + cmdutil.walkopts + cmdutil.commitopts + cmdutil.commitopts2,
+    _('[OPTION]... [FILE]...'),
+    inferrepo=True)
+def amend(ui, repo, *pats, **opts):
+    """amend the working copy parent with all or specified outstanding changes
+
+    Similar to :hg:`commit --amend`, but reuse the commit message without
+    invoking editor.
+
+    See :hg:`help commit` for more details.
+    """
+    with repo.wlock(), repo.lock():
+        opts['message'] = opts.get('message') or repo['.'].description()
+        opts['amend'] = True
+        return commands._docommit(ui, repo, *pats, **opts)
diff --git a/tests/test-amend.t b/tests/test-amend.t
new file mode 100644
--- /dev/null
+++ b/tests/test-amend.t
@@ -0,0 +1,194 @@ 
+#testcases obsstore-off obsstore-on
+
+  $ cat << EOF >> $HGRCPATH
+  > [extensions]
+  > amend=
+  > debugdrawdag=$TESTDIR/drawdag.py
+  > [diff]
+  > git=1
+  > EOF
+
+#if obsstore-on
+  $ cat << EOF >> $HGRCPATH
+  > [experimental]
+  > evolution=createmarkers
+  > EOF
+#endif
+
+Basic amend
+
+  $ hg init repo1
+  $ cd repo1
+  $ hg debugdrawdag <<'EOS'
+  > B
+  > |
+  > A
+  > EOS
+
+  $ hg update B -q
+  $ echo 2 >> B
+
+#if obsstore-off
+  $ hg amend
+  saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/112478962961-af2c0941-amend.hg (glob)
+#else
+  $ hg amend
+#endif
+
+#if obsstore-off
+  $ hg log -p -G --hidden -T '{rev} {node|short} {desc}\n'
+  @  1 be169c7e8dbe B
+  |  diff --git a/B b/B
+  |  new file mode 100644
+  |  --- /dev/null
+  |  +++ b/B
+  |  @@ -0,0 +1,1 @@
+  |  +B2
+  |
+  o  0 426bada5c675 A
+     diff --git a/A b/A
+     new file mode 100644
+     --- /dev/null
+     +++ b/A
+     @@ -0,0 +1,1 @@
+     +A
+     \ No newline at end of file
+  
+#else
+  $ hg log -p -G --hidden -T '{rev} {node|short} {desc}\n'
+  @  3 be169c7e8dbe B
+  |  diff --git a/B b/B
+  |  new file mode 100644
+  |  --- /dev/null
+  |  +++ b/B
+  |  @@ -0,0 +1,1 @@
+  |  +B2
+  |
+  | x  2 edf08988b141 temporary amend commit for 112478962961
+  | |  diff --git a/B b/B
+  | |  --- a/B
+  | |  +++ b/B
+  | |  @@ -1,1 +1,1 @@
+  | |  -B
+  | |  \ No newline at end of file
+  | |  +B2
+  | |
+  | x  1 112478962961 B
+  |/   diff --git a/B b/B
+  |    new file mode 100644
+  |    --- /dev/null
+  |    +++ b/B
+  |    @@ -0,0 +1,1 @@
+  |    +B
+  |    \ No newline at end of file
+  |
+  o  0 426bada5c675 A
+     diff --git a/A b/A
+     new file mode 100644
+     --- /dev/null
+     +++ b/A
+     @@ -0,0 +1,1 @@
+     +A
+     \ No newline at end of file
+  
+#endif
+
+Amend with options
+
+  $ echo 3 > c
+  $ hg amend -m OVERRIDE -A c -q
+  $ hg log -r . -T '{node|short} {desc} {files}\n'
+  890b8e0bbed5 OVERRIDE B c
+
+Amend does not support --editor
+
+  $ hg amend --editor | head -1
+  hg amend: option --editor not recognized
+  hg amend [OPTION]... [FILE]...
+
+Nothing changed
+
+  $ hg amend
+  nothing changed
+  [1]
+
+Metadata only changed
+
+  $ hg amend -d '2000 1000' -q
+  $ hg log -r . -T '{node|short} {date} {desc} {author}\n'
+  06e65c62fb8d 2000.01000 OVERRIDE test
+
+  $ hg amend -m NEWMESSAGE -q
+  $ hg log -r . -T '{node|short} {date} {desc} {author}\n'
+  70590a98f4ff 2000.01000 NEWMESSAGE test
+
+  $ hg amend -u 'Foo <foo@example.com>' -q
+  $ hg log -r . -T '{node|short} {date} {desc} {author}\n'
+  d893134640f0 2000.01000 NEWMESSAGE Foo <foo@example.com>
+
+Amend in the middle of a stack
+
+  $ hg init $TESTTMP/repo2
+  $ cd $TESTTMP/repo2
+  $ hg debugdrawdag <<'EOS'
+  > C
+  > |
+  > B
+  > |
+  > A
+  > EOS
+
+  $ hg update -q B
+  $ echo 2 >> B
+  $ hg amend
+  abort: cannot amend changeset with children
+  [255]
+
+#if obsstore-on
+
+With allowunstable, amend could work in the middle of a stack
+
+  $ cat >> $HGRCPATH <<EOF
+  > [experimental]
+  > evolution=createmarkers, allowunstable
+  > EOF
+
+  $ hg amend
+  $ hg log -T '{rev} {node|short} {desc}\n' -G
+  @  4 be169c7e8dbe B
+  |
+  | o  2 26805aba1e60 C
+  | |
+  | x  1 112478962961 B
+  |/
+  o  0 426bada5c675 A
+  
+#endif
+
+Cannot amend public changeset
+
+  $ hg phase -r A --public
+  $ hg update -C -q A
+  $ hg amend -m AMEND -q
+  abort: cannot amend public changesets
+  [255]
+
+Amend a merge changeset
+
+  $ hg init $TESTTMP/repo3
+  $ cd $TESTTMP/repo3
+  $ hg debugdrawdag <<'EOS'
+  >   C
+  >  /|
+  > A B
+  > EOS
+  $ hg update -q C
+  $ hg amend -m FOO -q
+  $ rm .hg/localtags
+  $ hg log -G -T '{desc}\n'
+  @    FOO
+  |\
+  | o  B
+  |
+  o  A
+