Patchwork [2,of,9] qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"

login
register
mail settings
Submitter Katsunori FUJIWARA
Date May 5, 2014, 12:33 p.m.
Message ID <77eaefecdb80052c9ca3.1399293182@feefifofum>
Download mbox | patch
Permalink /patch/4634/
State Accepted
Commit b9a16ed5acec8026191419acc27ccfbe32258f5e
Headers show

Comments

Katsunori FUJIWARA - May 5, 2014, 12:33 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1399292800 -32400
#      Mon May 05 21:26:40 2014 +0900
# Branch stable
# Node ID 77eaefecdb80052c9ca30ac0b3501532f2aefb44
# Parent  b683de8e06581ebb2a59120b118539a839bcfb06
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"

Before this patch, "hg qnew" invokes "ui.edit()" explicitly to get
commit message edited manually.

This requires explicit "localrepository.savecommitmessage()"
invocation to save edited commit message into ".hg/last-message.txt",
because unexpected exception raising may abort command execution
before saving it in "localrepository.commit()".

This patch uses "editor" argument of "localrepository.commit()"
instead of explicit "ui.edit()" invocation for "hg qnew".

"localrepository.commit()" will invoke "desceditor()" function newly
added by this patch, and save edited commit message into
".hg/last-message.txt" automatically.

This patch passes not "editor" but "desceditor" to "commit()", because
"hg qnew" requires editor function to return edited message if not
empty, or default message otherwise.

This patch applies "rstrip()" on "defaultmsg" at comparison between
"nctx.description()" and "defaultmsg", because the former should be
stripped by "changelog.stripdesc()" and the latter may have tail white
spaces inherited from "patchfn".

Patch

diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -1026,6 +1026,7 @@ 
            msg: a string or a no-argument function returning a string
         """
         msg = opts.get('msg')
+        editor = opts.get('editor')
         user = opts.get('user')
         date = opts.get('date')
         if date:
@@ -1078,12 +1079,23 @@ 
                         p.write("# User " + user + "\n")
                     if date:
                         p.write("# Date %s %s\n\n" % date)
-                if util.safehasattr(msg, '__call__'):
-                    msg = msg()
-                    repo.savecommitmessage(msg)
-                commitmsg = msg and msg or ("[mq]: %s" % patchfn)
+
+                defaultmsg = "[mq]: %s" % patchfn
+                if editor:
+                    origeditor = editor
+                    def desceditor(repo, ctx, subs):
+                        desc = origeditor(repo, ctx, subs)
+                        if desc.rstrip():
+                            return desc
+                        else:
+                            return defaultmsg
+                    commitmsg = msg
+                    editor = desceditor
+                else:
+                    commitmsg = msg or defaultmsg
+
                 n = newcommit(repo, None, commitmsg, user, date, match=match,
-                              force=True)
+                              force=True, editor=editor)
                 if n is None:
                     raise util.Abort(_("repo commit failed"))
                 try:
@@ -1092,8 +1104,9 @@ 
                     self.parseseries()
                     self.seriesdirty = True
                     self.applieddirty = True
-                    if msg:
-                        msg = msg + "\n\n"
+                    nctx = repo[n]
+                    if nctx.description() != defaultmsg.rstrip():
+                        msg = nctx.description() + "\n\n"
                         p.write(msg)
                     if commitfiles:
                         parent = self.qparents(repo, n)
@@ -2417,14 +2430,12 @@ 
     Returns 0 on successful creation of a new patch.
     """
     msg = cmdutil.logmessage(ui, opts)
-    def getmsg():
-        return ui.edit(msg, opts.get('user') or ui.username())
     q = repo.mq
     opts['msg'] = msg
     if opts.get('edit'):
-        opts['msg'] = getmsg
-    else:
-        opts['msg'] = msg
+        def editor(repo, ctx, subs):
+            return ui.edit(ctx.description() + "\n", ctx.user())
+        opts['editor'] = editor
     setupheaderopts(ui, opts)
     q.new(repo, patch, *args, **opts)
     q.savedirty()
diff --git a/tests/test-mq-qnew.t b/tests/test-mq-qnew.t
--- a/tests/test-mq-qnew.t
+++ b/tests/test-mq-qnew.t
@@ -247,8 +247,9 @@ 
   >             raise util.Abort('emulating unexpected abort')
   >     repo.__class__ = commitfailure
   > EOF
-  $ cat > .hg/hgrc <<EOF
+  $ cat >> .hg/hgrc <<EOF
   > [extensions]
+  > # this failure occurs before editor invocation
   > commitfailure = $TESTTMP/commitfailure.py
   > EOF
 
@@ -259,13 +260,62 @@ 
   > echo "test saving last-message.txt" >> \$1
   > EOF
 
+(test that editor is not invoked before transaction starting)
+
+  $ rm -f .hg/last-message.txt
+  $ HGEDITOR="sh $TESTTMP/editor.sh" hg qnew -e patch
+  abort: emulating unexpected abort
+  [255]
+  $ cat .hg/last-message.txt
+  cat: .hg/last-message.txt: No such file or directory
+  [1]
+
+(test that editor is invoked and commit message is saved into
+"last-message.txt")
+
+  $ cat >> .hg/hgrc <<EOF
+  > [extensions]
+  > commitfailure = !
+  > [hooks]
+  > # this failure occurs after editor invocation
+  > pretxncommit.unexpectedabort = false
+  > EOF
+
   $ rm -f .hg/last-message.txt
   $ HGEDITOR="sh $TESTTMP/editor.sh" hg qnew -e patch
   ==== before editing
+  
   ====
-  abort: emulating unexpected abort
+  transaction abort!
+  rollback completed
+  note: commit message saved in .hg/last-message.txt
+  abort: pretxncommit.unexpectedabort hook exited with status 1
   [255]
   $ cat .hg/last-message.txt
+  
   test saving last-message.txt
 
+  $ cat >> .hg/hgrc <<EOF
+  > [hooks]
+  > pretxncommit.unexpectedabort =
+  > EOF
+
+Test handling default message with the patch filename with tail whitespaces
+
+  $ cat > $TESTTMP/editor.sh << EOF
+  > echo "==== before editing"
+  > cat \$1
+  > echo "===="
+  > echo "[mq]: patch        " > \$1
+  > EOF
+
+  $ rm -f .hg/last-message.txt
+  $ HGEDITOR="sh $TESTTMP/editor.sh" hg qnew -e "patch "
+  ==== before editing
+  
+  ====
+  $ cat ".hg/patches/patch "
+  # HG changeset patch
+  # Parent 0000000000000000000000000000000000000000
+
   $ cd ..