# HG changeset patch # User Brendan Cully # Date 1224391942 25200 # Node ID ce10a2f222588304129cd56d344d0670e70c7758 # Parent b420ef2c812b5b790d4982fc4edca06b8f4952f4 mq: heavy rearrangement of qnew to make it recover reliably from errors. Closes issue1269. diff -r b420ef2c812b -r ce10a2f22258 hgext/mq.py --- a/hgext/mq.py Sat Oct 18 20:45:53 2008 -0700 +++ b/hgext/mq.py Sat Oct 18 21:52:22 2008 -0700 @@ -640,7 +640,7 @@ raise util.Abort(_('"%s" cannot be used as the name of a patch') % name) - def new(self, repo, patch, *pats, **opts): + def new(self, repo, patchfn, *pats, **opts): """options: msg: a string or a no-argument function returning a string """ @@ -650,9 +650,9 @@ date = opts.get('date') if date: date = util.parsedate(date) - self.check_reserved_name(patch) - if os.path.exists(self.join(patch)): - raise util.Abort(_('patch "%s" already exists') % patch) + self.check_reserved_name(patchfn) + if os.path.exists(self.join(patchfn)): + raise util.Abort(_('patch "%s" already exists') % patchfn) if opts.get('include') or opts.get('exclude') or pats: match = cmdutil.match(repo, pats, opts) # detect missing files in pats @@ -665,39 +665,55 @@ match = cmdutil.match(repo, m + a + r) commitfiles = m + a + r self.check_toppatch(repo) + insert = self.full_series_end() wlock = repo.wlock() try: - insert = self.full_series_end() - if callable(msg): - msg = msg() - commitmsg = msg and msg or ("[mq]: %s" % patch) - n = repo.commit(commitfiles, commitmsg, user, date, match=match, force=True) - if n == None: - raise util.Abort(_("repo commit failed")) - self.full_series[insert:insert] = [patch] - self.applied.append(statusentry(revlog.hex(n), patch)) - self.parse_series() - self.series_dirty = 1 - self.applied_dirty = 1 - p = self.opener(patch, "w") - if date: - p.write("# HG changeset patch\n") - if user: - p.write("# User " + user + "\n") - p.write("# Date %d %d\n" % date) - p.write("\n") - elif user: - p.write("From: " + user + "\n") - p.write("\n") - if msg: - msg = msg + "\n" - p.write(msg) - p.close() - wlock = None - r = self.qrepo() - if r: r.add([patch]) - if commitfiles: - self.refresh(repo, short=True, git=opts.get('git')) + # if patch file write fails, abort early + p = self.opener(patchfn, "w") + try: + if date: + p.write("# HG changeset patch\n") + if user: + p.write("# User " + user + "\n") + p.write("# Date %d %d\n\n" % date) + elif user: + p.write("From: " + user + "\n\n") + + if callable(msg): + msg = msg() + commitmsg = msg and msg or ("[mq]: %s" % patchfn) + n = repo.commit(commitfiles, commitmsg, user, date, match=match, force=True) + if n == None: + raise util.Abort(_("repo commit failed")) + try: + self.full_series[insert:insert] = [patchfn] + self.applied.append(statusentry(revlog.hex(n), patchfn)) + self.parse_series() + self.series_dirty = 1 + self.applied_dirty = 1 + if msg: + msg = msg + "\n" + p.write(msg) + if commitfiles: + diffopts = self.diffopts() + if opts.get('git'): diffopts.git = True + parent = self.qparents(repo, n) + patch.diff(repo, node1=parent, node2=n, fp=p, + match=match, opts=diffopts) + p.close() + wlock = None + r = self.qrepo() + if r: r.add([patchfn]) + except: + repo.rollback() + raise + except Exception, inst: + patchpath = self.join(patchfn) + try: + os.unlink(patchpath) + except: + self.ui.warn(_('error unlinking %s\n') % patchpath) + raise self.removeundo(repo) finally: del wlock