[PATCH 3 of 3] cmdutil: make commit message shown in text editor customizable by template

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Tue Jul 15 09:42:20 CDT 2014


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1405434853 -32400
#      Tue Jul 15 23:34:13 2014 +0900
# Node ID cd229f9743ef08074a8d5b8f5449b01aa33ffded
# Parent  9cdacd1de1950586a11dc3b29b4940c563474318
cmdutil: make commit message shown in text editor customizable by template

This patch makes commit message shown in text editor customizable by
template. For example, this can advertise:

  - sample commit messages for routine works,
  - points to call attention before commit,
  - message of the day, and so on

To show commit message correctly even in problematic encoding, this
patch chooses the latter below:

  - replace "buildcommittext" with "buildcommittemplate" completely

  - invoke "buildcommittemplate" only if '[committemplate] changeset'
    is configured explicitly

For example, if multibyte character ending with backslash (0x5c) is
followed by ASCII character 'n' in the customized template, sequence
of backslash and 'n' is treated as line-feed unexpectedly (and
multibyte character is broken, too).

This corruption occurs in 'decode("string-escape")' while parsing
template string.

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2170,7 +2170,11 @@
     return commitforceeditor(repo, ctx, subs)
 
 def commitforceeditor(repo, ctx, subs, finishdesc=None, extramsg=None):
-    committext = buildcommittext(repo, ctx, subs, extramsg)
+    tmpl = repo.ui.config('committemplate', 'changeset', '').strip()
+    if tmpl:
+        committext = buildcommittemplate(repo, ctx, subs, extramsg, tmpl)
+    else:
+        committext = buildcommittext(repo, ctx, subs, extramsg)
 
     # run editor in the repository root
     olddir = os.getcwd()
@@ -2186,6 +2190,22 @@
 
     return text
 
+def buildcommittemplate(repo, ctx, subs, extramsg, tmpl):
+    ui = repo.ui
+    tmpl, mapfile = gettemplate(ui, tmpl, None)
+
+    try:
+        t = changeset_templater(ui, repo, None, {}, tmpl, mapfile, False)
+    except SyntaxError, inst:
+        raise util.Abort(inst.args[0])
+
+    if not extramsg:
+        extramsg = '' # ensure that extramsg is string
+
+    ui.pushbuffer()
+    t.show(ctx, extramsg=extramsg)
+    return ui.popbuffer()
+
 def buildcommittext(repo, ctx, subs, extramsg):
     edittext = []
     modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -330,6 +330,66 @@
 for credentials as usual if required by the remote.
 
 
+``committemplate``
+------------------
+
+``changeset`` configuration in this section is used as the template to
+customize the text shown in the editor when committing.
+
+In addition to pre-defined template keywords, commit log specific one
+below can be used for customization:
+
+``extramsg``
+    String: Extra message instead of 'Leave message empty to abort
+    commit.', if specified. This is specific for MQ commands, which
+    use default message (e.g. '[mq]: PATCHNAME') if commit message
+    is empty.
+
+For example, the template configuration below shows as same text as
+one shown by default::
+
+    [committemplate]
+    changeset = {desc}\n\n
+        HG: Enter commit message.  Lines beginning with 'HG:' are removed.
+        HG: {if(extramsg, extramsg, "Leave message empty to abort commit.")}
+        HG: --
+        HG: user: {author}\n{ifeq(p2rev, "-1", "",
+       "HG: branch merge\n")
+       }HG: branch '{branch}'\n{if(currentbookmark,
+       "HG: bookmark '{currentbookmark}'\n")  }{subrepos %
+       "HG: subrepo {subrepo}\n"              }{file_adds %
+       "HG: added {file}\n"                   }{file_mods %
+       "HG: changed {file}\n"                 }{file_dels %
+       "HG: removed {file}\n"                 }{if(files, "",
+       "HG: no files changed\n")}
+
+.. note::
+
+   For some problematic encodings (see :hg:`help win32mbcs` for
+   detail), this customization should be configured carefully, to
+   avoid showing broken characters.
+
+   For example, if multibyte character ending with backslash (0x5c) is
+   followed by ASCII character 'n' in the customized template,
+   sequence of backslash and 'n' is treated as line-feed unexpectedly
+   (and multibyte character is broken, too).
+
+Customized template is used for commands below (``--edit`` may be
+required):
+
+- :hg:`backout`
+- :hg:`commit`
+- :hg:`fetch` (for merge commit only)
+- :hg:`graft`
+- :hg:`histedit`
+- :hg:`import`
+- :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
+- :hg:`rebase`
+- :hg:`shelve`
+- :hg:`sign`
+- :hg:`tag`
+- :hg:`transplant`
+
 ``decode/encode``
 -----------------
 
diff --git a/tests/test-commit.t b/tests/test-commit.t
--- a/tests/test-commit.t
+++ b/tests/test-commit.t
@@ -354,6 +354,50 @@
   
   test saving last-message.txt
 
+test that '[committemplate] changeset' definition and commit log
+specific template keywords work well
+
+  $ cat >> .hg/hgrc <<EOF
+  > [committemplate]
+  > changeset = HG: this is customized commit template
+  >     HG: 'extramsg' should be empty
+  >     {extramsg}\n{if(currentbookmark,
+  >    "HG: bookmark '{currentbookmark}' is activated\n",
+  >    "HG: no bookmark is activated\n")}{subrepos %
+  >    "HG: subrepo '{subrepo}' is changed\n"}
+  > EOF
+
+  $ hg init sub2
+  $ echo a > sub2/a
+  $ hg -R sub2 add sub2/a
+  $ echo 'sub2 = sub2' >> .hgsub
+
+  $ HGEDITOR=cat hg commit -S -q
+  HG: this is customized commit template
+  HG: 'extramsg' should be empty
+  
+  HG: bookmark 'currentbookmark' is activated
+  HG: subrepo 'sub' is changed
+  HG: subrepo 'sub2' is changed
+  abort: empty commit message
+  [255]
+
+  $ hg bookmark --inactive currentbookmark
+  $ hg forget .hgsub
+  $ HGEDITOR=cat hg commit -q
+  HG: this is customized commit template
+  HG: 'extramsg' should be empty
+  
+  HG: no bookmark is activated
+  abort: empty commit message
+  [255]
+
+  $ cat >> .hg/hgrc <<EOF
+  > # disable customizing for subsequent tests
+  > [committemplate]
+  > changeset =
+  > EOF
+
   $ cd ..
 
 
diff --git a/tests/test-mq-qrefresh-replace-log-message.t b/tests/test-mq-qrefresh-replace-log-message.t
--- a/tests/test-mq-qrefresh-replace-log-message.t
+++ b/tests/test-mq-qrefresh-replace-log-message.t
@@ -26,10 +26,28 @@
   First commit message
 
 Testing changing message with -m
-(this tests also that '--edit' can be used with '--message')
+(this tests also that '--edit' can be used with '--message', and
+that '[committemplate] changeset' definition and commit log specific
+template keyword 'extramsg' work well)
+
+  $ cat >> .hg/hgrc <<EOF
+  > [committemplate]
+  > changeset = HG: this is customized commit template
+  >     {desc}\n\n
+  >     HG: Enter commit message.  Lines beginning with 'HG:' are removed.
+  >     HG: {extramsg}
+  >     HG: --
+  >     HG: user: {author}
+  >     HG: branch '{branch}'\n{file_adds %
+  >    "HG: added {file}\n"     }{file_mods %
+  >    "HG: changed {file}\n"   }{file_dels %
+  >    "HG: removed {file}\n"   }{if(files, "",
+  >    "HG: no files changed\n")}
+  > EOF
 
   $ echo bbbb > file
   $ HGEDITOR=cat hg qrefresh -m "Second commit message" -e
+  HG: this is customized commit template
   Second commit message
   
   
@@ -40,6 +58,12 @@
   HG: branch 'default'
   HG: added file
 
+  $ cat >> .hg/hgrc <<EOF
+  > # disable customizing for subsequent tests
+  > [committemplate]
+  > changeset =
+  > EOF
+
 Should display 'Second commit message'
 
   $ hg log -l1 --template "{desc}\n"


More information about the Mercurial-devel mailing list