diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -1484,6 +1484,7 @@ class queue(object): self.ui.write(_("no patches applied\n")) return 1 msg = opts.get('msg', '').rstrip() + editor = opts.get('editor') newuser = opts.get('user') newdate = opts.get('date') if newdate: @@ -1652,9 +1653,20 @@ class queue(object): try: # might be nice to attempt to roll back strip after this - if not msg: + defaultmsg = "[mq]: %s" % patchfn + if editor: + origeditor = editor + def desceditor(repo, ctx, subs): + desc = origeditor(repo, ctx, subs) + if desc.rstrip(): + ph.setmessage(desc) + return desc + return defaultmsg + message = msg or "\n".join(ph.message) + editor = desceditor + elif not msg: if not ph.message: - message = "[mq]: %s\n" % patchfn + message = defaultmsg else: message = "\n".join(ph.message) else: @@ -1664,7 +1676,7 @@ class queue(object): # Ensure we create a new changeset in the same phase than # the old one. n = newcommit(repo, oldphase, message, user, ph.date, - match=match, force=True) + match=match, force=True, editor=editor) # only write patch after a successful commit c = [list(x) for x in refreshchanges] if inclsubs: @@ -2478,20 +2490,16 @@ def refresh(ui, repo, *pats, **opts): q = repo.mq message = cmdutil.logmessage(ui, opts) if opts.get('edit'): - if not q.applied: - ui.write(_("no patches applied\n")) - return 1 if message: raise util.Abort(_('option "-e" incompatible with "-m" or "-l"')) - patch = q.applied[-1].name - ph = patchheader(q.join(patch), q.plainmode) - message = ui.edit('\n'.join(ph.message), ph.user or ui.username()) - # We don't want to lose the patch message if qrefresh fails (issue2062) - repo.savecommitmessage(message) + def editor(repo, ctx, subs): + return ui.edit(ctx.description() + "\n", ctx.user()) + else: + editor = False setupheaderopts(ui, opts) wlock = repo.wlock() try: - ret = q.refresh(repo, pats, msg=message, **opts) + ret = q.refresh(repo, pats, msg=message, editor=editor, **opts) q.savedirty() return ret finally: @@ -2582,13 +2590,15 @@ def fold(ui, repo, *files, **opts): message = '\n'.join(message) if opts.get('edit'): - message = ui.edit(message, user or ui.username()) - repo.savecommitmessage(message) + def editor(repo, ctx, subs): + return ui.edit(ctx.description() + "\n", ctx.user()) + else: + editor = False diffopts = q.patchopts(q.diffopts(), *patches) wlock = repo.wlock() try: - q.refresh(repo, msg=message, git=diffopts.git) + q.refresh(repo, msg=message, git=diffopts.git, editor=editor) q.delete(repo, patches, opts) q.savedirty() finally: diff --git a/tests/test-mq-qfold.t b/tests/test-mq-qfold.t --- a/tests/test-mq-qfold.t +++ b/tests/test-mq-qfold.t @@ -153,8 +153,9 @@ Test saving last-message.txt: > repo.__class__ = commitfailure > EOF - $ cat > .hg/hgrc <> .hg/hgrc < [extensions] + > # this failure occurs before editor invocation > commitfailure = $TESTTMP/commitfailure.py > EOF @@ -165,15 +166,65 @@ Test saving last-message.txt: > (echo; echo "test saving last-message.txt") >> \$1 > EOF + $ hg qapplied + p1 + git + $ hg tip --template "{files}\n" + aa + +(test that editor is not invoked before transaction starting) + $ rm -f .hg/last-message.txt $ HGEDITOR="sh $TESTTMP/editor.sh" hg qfold -e p3 - ==== before editing - original message==== refresh interrupted while patch was popped! (revert --all, qpush to recover) abort: emulating unexpected abort [255] $ cat .hg/last-message.txt + cat: .hg/last-message.txt: No such file or directory + [1] + +(reset applied patches and directory status) + + $ cat >> .hg/hgrc < [extensions] + > # this failure occurs after editor invocation + > commitfailure = ! + > EOF + + $ hg qapplied + p1 + $ hg status -A aa + ? aa + $ rm aa + $ hg status -m + M a + $ hg revert --no-backup -q a + $ hg qpush -q git + now at: git + +(test that editor is invoked and commit message is saved into +"last-message.txt") + + $ cat >> .hg/hgrc < [hooks] + > # this failure occurs after editor invocation + > pretxncommit.unexpectedabort = false + > EOF + + $ rm -f .hg/last-message.txt + $ HGEDITOR="sh $TESTTMP/editor.sh" hg qfold -e p3 + ==== before editing original message + ==== + transaction abort! + rollback completed + note: commit message saved in .hg/last-message.txt + refresh interrupted while patch was popped! (revert --all, qpush to recover) + abort: pretxncommit.unexpectedabort hook exited with status 1 + [255] + $ cat .hg/last-message.txt + original message + test saving last-message.txt $ 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 @@ -59,3 +59,86 @@ Should display 'Fifth commit message\\\n $ hg log -l1 --template "{desc}\n" Fifth commit message This is the 5th log message + +Test saving last-message.txt: + + $ cat > $TESTTMP/editor.sh << EOF + > echo "==== before editing" + > cat \$1 + > echo "====" + > (echo; echo "test saving last-message.txt") >> \$1 + > EOF + + $ cat > $TESTTMP/commitfailure.py < from mercurial import util + > def reposetup(ui, repo): + > class commitfailure(repo.__class__): + > def commit(self, *args, **kwargs): + > raise util.Abort('emulating unexpected abort') + > repo.__class__ = commitfailure + > EOF + + $ cat >> .hg/hgrc < [extensions] + > # this failure occurs before editor invocation + > commitfailure = $TESTTMP/commitfailure.py + > EOF + + $ hg qapplied + first-patch + second-patch + $ hg tip --template "{files}\n" + file2 + +(test that editor is not invoked before transaction starting) + + $ rm -f .hg/last-message.txt + $ HGEDITOR="sh $TESTTMP/editor.sh" hg qrefresh -e + refresh interrupted while patch was popped! (revert --all, qpush to recover) + abort: emulating unexpected abort + [255] + $ cat .hg/last-message.txt + cat: .hg/last-message.txt: No such file or directory + [1] + +(reset applied patches and directory status) + + $ cat >> .hg/hgrc < [extensions] + > commitfailure = ! + > EOF + + $ hg qapplied + first-patch + $ hg status -A file2 + ? file2 + $ rm file2 + $ hg qpush -q second-patch + now at: second-patch + +(test that editor is invoked and commit message is saved into +"last-message.txt") + + $ cat >> .hg/hgrc < [hooks] + > # this failure occurs after editor invocation + > pretxncommit.unexpectedabort = false + > EOF + + $ rm -f .hg/last-message.txt + $ HGEDITOR="sh $TESTTMP/editor.sh" hg qrefresh -e + ==== before editing + Fifth commit message + This is the 5th log message + ==== + transaction abort! + rollback completed + note: commit message saved in .hg/last-message.txt + refresh interrupted while patch was popped! (revert --all, qpush to recover) + abort: pretxncommit.unexpectedabort hook exited with status 1 + [255] + $ cat .hg/last-message.txt + Fifth commit message + This is the 5th log message + + test saving last-message.txt