Rollback ate my commit message! (issue 1635)

Adrian Buehlmann adrian at cadifra.com
Wed Nov 18 02:27:50 CST 2009


On 18.11.2009 03:11, Greg Ward wrote:
> Hi all --
> 
> several months ago, I filed issue 1635 because the behaviour of "hg
> rollback" occasionally annoyed me a bit.  Now I have discovered a
> really killer use case for fixing issue 1635: pretxncommit hooks.
> 
> Imagine this: you prepare a beautiful patch and run "hg commit".  Type
> in a carefully handcrafted commit message that describes exactly what
> you did in clear, concise language.  (You know how hard that can be!)
> Then some jerk's pretxncommit hook barges in and tells you that your
> commit message is malformatted, or your code doesn't meet the style
> guideline, or you created a filename with spaces in it ... whatever
> your local hook is designed to enforce.
> 
> So Mercurial rolls back the transaction.  Your beautiful patch is
> still there in the working dir, of course.  But that carefully crafted
> commit message?  Gone.  Poof!
> 
> Granted, destroying the user's metadata is not as bad as destroying
> their data.  But it's still not nice.  And in this case, the user has
> no recourse.  They cannot run "hg tip -v" before rolling back the
> commit, because they don't get to decide that the commit gets rolled
> back.

Have you seen
http://mercurial.selenic.com/wiki/MessageExtension
?

> The good news is that a cheap and simple patch near the end of
> localrepository.commit() will make me happy:
> 
> """
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -839,6 +843,11 @@
>              self.dirstate.setparents(ret)
>              ms.reset()
> 
> +            # save commit message in case this gets rolled back
> +            f = self.opener('commit-msg.txt', 'wt')
> +            f.write(cctx._text.rstrip() + '\n')
> +            f.close()
> +
>              return ret
> 
>          finally:
> """

How about using the file '.hg/message' (MessageExtension uses that filename)?

(Would be nice to settle on a common file name. Maybe GUI tools could use that
same filename too.)

> Pros:
>   * dead simple and easy
>   * pretty much the behaviour that will be expected by anyone used to Subversion
> 
> Cons:
>   * opaque: no hint that the commit message was saved
> 
> I tried to address the opacity by patching localrepository.rollback():
> 
> """
> @@ -596,7 +596,12 @@
>              wlock = self.wlock()
>              lock = self.lock()
>              if os.path.exists(self.sjoin("undo")):
> -                self.ui.status(_("rolling back last transaction\n"))
> +                status = _("rolling back last transaction\n")
> +                if os.path.exists(self.join("commit-msg.txt")):
> +                    status = _(
> +                        "rolling back last transaction "
> +                        "(last commit message saved in .hg/commit-msg.txt)\n")
> +                self.ui.status(status)
>                  transaction.rollback(self.sopener,
> self.sjoin("undo"), self.ui.warn)
>                  util.rename(self.join("undo.dirstate"), self.join("dirstate"))
>                  try:
> """
> 
> but I'm not entirely thrilled with that.  The message is useless,
> bordering on misleading, if you rollback anything other than a commit.
> 
> Thoughts?
> 


More information about the Mercurial-devel mailing list