255 for mi in self.message: |
255 for mi in self.message: |
256 while mi != self.comments[ci]: |
256 while mi != self.comments[ci]: |
257 ci += 1 |
257 ci += 1 |
258 del self.comments[ci] |
258 del self.comments[ci] |
259 |
259 |
260 def newcommit(repo, *args, **kwargs): |
260 def newcommit(repo, phase, *args, **kwargs): |
261 """helper dedicated to ensure a commit respect mq.secret setting |
261 """helper dedicated to ensure a commit respect mq.secret setting |
262 |
262 |
263 It should be used instead of repo.commit inside the mq source for operation |
263 It should be used instead of repo.commit inside the mq source for operation |
264 creating new changeset. |
264 creating new changeset. |
265 """ |
265 """ |
266 if not repo.ui.configbool('mq', 'secret', False): |
266 if phase is None: |
267 return repo.commit(*args, **kwargs) |
267 if repo.ui.configbool('mq', 'secret', False): |
268 |
268 phase = phases.secret |
269 backup = repo.ui.backupconfig('phases', 'new-commit') |
269 if phase is not None: |
|
270 backup = repo.ui.backupconfig('phases', 'new-commit') |
|
271 # Marking the repository as committing an mq patch can be used |
|
272 # to optimize operations like _branchtags(). |
|
273 repo._committingpatch = True |
270 try: |
274 try: |
271 # ensure we create a secret changeset |
275 if phase is not None: |
272 repo.ui.setconfig('phases', 'new-commit', phases.secret) |
276 repo.ui.setconfig('phases', 'new-commit', phase) |
273 return repo.commit(*args, **kwargs) |
277 return repo.commit(*args, **kwargs) |
274 finally: |
278 finally: |
275 repo.ui.restoreconfig(backup) |
279 repo._committingpatch = False |
|
280 if phase is not None: |
|
281 repo.ui.restoreconfig(backup) |
276 |
282 |
277 class queue(object): |
283 class queue(object): |
278 def __init__(self, ui, path, patchdir=None): |
284 def __init__(self, ui, path, patchdir=None): |
279 self.basepath = path |
285 self.basepath = path |
280 try: |
286 try: |
574 |
580 |
575 ctx = repo[rev] |
581 ctx = repo[rev] |
576 ret = hg.merge(repo, rev) |
582 ret = hg.merge(repo, rev) |
577 if ret: |
583 if ret: |
578 raise util.Abort(_("update returned %d") % ret) |
584 raise util.Abort(_("update returned %d") % ret) |
579 n = newcommit(repo, ctx.description(), ctx.user(), force=True) |
585 n = newcommit(repo, None, ctx.description(), ctx.user(), force=True) |
580 if n is None: |
586 if n is None: |
581 raise util.Abort(_("repo commit failed")) |
587 raise util.Abort(_("repo commit failed")) |
582 try: |
588 try: |
583 ph = patchheader(mergeq.join(patch), self.plainmode) |
589 ph = patchheader(mergeq.join(patch), self.plainmode) |
584 except: |
590 except: |
614 # needs to know which parent is actually in the patch queue. |
620 # needs to know which parent is actually in the patch queue. |
615 # so, we insert a merge marker with only one parent. This way |
621 # so, we insert a merge marker with only one parent. This way |
616 # the first patch in the queue is never a merge patch |
622 # the first patch in the queue is never a merge patch |
617 # |
623 # |
618 pname = ".hg.patches.merge.marker" |
624 pname = ".hg.patches.merge.marker" |
619 n = repo.commit('[mq]: merge marker', force=True) |
625 n = newcommit(repo, None, '[mq]: merge marker', force=True) |
620 self.removeundo(repo) |
626 self.removeundo(repo) |
621 self.applied.append(statusentry(n, pname)) |
627 self.applied.append(statusentry(n, pname)) |
622 self.applieddirty = True |
628 self.applieddirty = True |
623 |
629 |
624 head = self.qparents(repo) |
630 head = self.qparents(repo) |
745 p1, p2 = repo.dirstate.parents() |
751 p1, p2 = repo.dirstate.parents() |
746 repo.dirstate.setparents(p1, merge) |
752 repo.dirstate.setparents(p1, merge) |
747 |
753 |
748 match = scmutil.matchfiles(repo, files or []) |
754 match = scmutil.matchfiles(repo, files or []) |
749 oldtip = repo['tip'] |
755 oldtip = repo['tip'] |
750 n = newcommit(repo, message, ph.user, ph.date, match=match, |
756 n = newcommit(repo, None, message, ph.user, ph.date, match=match, |
751 force=True) |
757 force=True) |
752 if repo['tip'] == oldtip: |
758 if repo['tip'] == oldtip: |
753 raise util.Abort(_("qpush exactly duplicates child changeset")) |
759 raise util.Abort(_("qpush exactly duplicates child changeset")) |
754 if n is None: |
760 if n is None: |
755 raise util.Abort(_("repository commit failed")) |
761 raise util.Abort(_("repository commit failed")) |
756 |
762 |
986 if date: |
992 if date: |
987 p.write("# Date %s %s\n\n" % date) |
993 p.write("# Date %s %s\n\n" % date) |
988 if util.safehasattr(msg, '__call__'): |
994 if util.safehasattr(msg, '__call__'): |
989 msg = msg() |
995 msg = msg() |
990 commitmsg = msg and msg or ("[mq]: %s" % patchfn) |
996 commitmsg = msg and msg or ("[mq]: %s" % patchfn) |
991 n = newcommit(repo, commitmsg, user, date, match=match, |
997 n = newcommit(repo, None, commitmsg, user, date, match=match, |
992 force=True) |
998 force=True) |
993 if n is None: |
999 if n is None: |
994 raise util.Abort(_("repo commit failed")) |
1000 raise util.Abort(_("repo commit failed")) |
995 try: |
1001 try: |
996 self.fullseries[insert:insert] = [patchfn] |
1002 self.fullseries[insert:insert] = [patchfn] |
997 self.applied.append(statusentry(n, patchfn)) |
1003 self.applied.append(statusentry(n, patchfn)) |
1538 repo.dirstate.invalidate() |
1544 repo.dirstate.invalidate() |
1539 raise |
1545 raise |
1540 |
1546 |
1541 try: |
1547 try: |
1542 # might be nice to attempt to roll back strip after this |
1548 # might be nice to attempt to roll back strip after this |
1543 backup = repo.ui.backupconfig('phases', 'new-commit') |
1549 |
1544 try: |
1550 # Ensure we create a new changeset in the same phase than |
1545 # Ensure we create a new changeset in the same phase than |
1551 # the old one. |
1546 # the old one. |
1552 n = newcommit(repo, oldphase, message, user, ph.date, |
1547 repo.ui.setconfig('phases', 'new-commit', oldphase) |
1553 match=match, force=True) |
1548 n = repo.commit(message, user, ph.date, match=match, |
|
1549 force=True) |
|
1550 finally: |
|
1551 repo.ui.restoreconfig(backup) |
|
1552 # only write patch after a successful commit |
1554 # only write patch after a successful commit |
1553 patchf.close() |
1555 patchf.close() |
1554 self.applied.append(statusentry(n, patchfn)) |
1556 self.applied.append(statusentry(n, patchfn)) |
1555 except: |
1557 except: |
1556 ctx = repo[cparents[0]] |
1558 ctx = repo[cparents[0]] |
3255 |
3257 |
3256 return result |
3258 return result |
3257 |
3259 |
3258 def _branchtags(self, partial, lrev): |
3260 def _branchtags(self, partial, lrev): |
3259 q = self.mq |
3261 q = self.mq |
|
3262 cl = self.changelog |
|
3263 qbase = None |
3260 if not q.applied: |
3264 if not q.applied: |
3261 return super(mqrepo, self)._branchtags(partial, lrev) |
3265 if getattr(self, '_committingpatch', False): |
3262 |
3266 # Committing a new patch, must be tip |
3263 cl = self.changelog |
3267 qbase = len(cl) - 1 |
3264 qbasenode = q.applied[0].node |
3268 else: |
3265 try: |
3269 qbasenode = q.applied[0].node |
3266 qbase = cl.rev(qbasenode) |
3270 try: |
3267 except error.LookupError: |
3271 qbase = cl.rev(qbasenode) |
3268 self.ui.warn(_('mq status file refers to unknown node %s\n') |
3272 except error.LookupError: |
3269 % short(qbasenode)) |
3273 self.ui.warn(_('mq status file refers to unknown node %s\n') |
|
3274 % short(qbasenode)) |
|
3275 if qbase is None: |
3270 return super(mqrepo, self)._branchtags(partial, lrev) |
3276 return super(mqrepo, self)._branchtags(partial, lrev) |
3271 |
3277 |
3272 start = lrev + 1 |
3278 start = lrev + 1 |
3273 if start < qbase: |
3279 if start < qbase: |
3274 # update the cache (excluding the patches) and save it |
3280 # update the cache (excluding the patches) and save it |