Mercurial > hg > mercurial-crew-with-dirclash
comparison hgext/mq.py @ 4961:126f527b3ba3
Make repo locks recursive, eliminate all passing of lock/wlock
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sat, 21 Jul 2007 16:02:10 -0500 |
parents | 97b734fb9c6f |
children | 30d4d8985dd8 |
comparison
equal
deleted
inserted
replaced
4960:5c5d23d93447 | 4961:126f527b3ba3 |
---|---|
321 fns, matchfn, anypats = cmdutil.matchpats(repo, files, opts) | 321 fns, matchfn, anypats = cmdutil.matchpats(repo, files, opts) |
322 | 322 |
323 patch.diff(repo, node1, node2, fns, match=matchfn, | 323 patch.diff(repo, node1, node2, fns, match=matchfn, |
324 fp=fp, changes=changes, opts=self.diffopts()) | 324 fp=fp, changes=changes, opts=self.diffopts()) |
325 | 325 |
326 def mergeone(self, repo, mergeq, head, patch, rev, wlock): | 326 def mergeone(self, repo, mergeq, head, patch, rev): |
327 # first try just applying the patch | 327 # first try just applying the patch |
328 (err, n) = self.apply(repo, [ patch ], update_status=False, | 328 (err, n) = self.apply(repo, [ patch ], update_status=False, |
329 strict=True, merge=rev, wlock=wlock) | 329 strict=True, merge=rev) |
330 | 330 |
331 if err == 0: | 331 if err == 0: |
332 return (err, n) | 332 return (err, n) |
333 | 333 |
334 if n is None: | 334 if n is None: |
335 raise util.Abort(_("apply failed for patch %s") % patch) | 335 raise util.Abort(_("apply failed for patch %s") % patch) |
336 | 336 |
337 self.ui.warn("patch didn't work out, merging %s\n" % patch) | 337 self.ui.warn("patch didn't work out, merging %s\n" % patch) |
338 | 338 |
339 # apply failed, strip away that rev and merge. | 339 # apply failed, strip away that rev and merge. |
340 hg.clean(repo, head, wlock=wlock) | 340 hg.clean(repo, head) |
341 self.strip(repo, n, update=False, backup='strip', wlock=wlock) | 341 self.strip(repo, n, update=False, backup='strip') |
342 | 342 |
343 ctx = repo.changectx(rev) | 343 ctx = repo.changectx(rev) |
344 ret = hg.merge(repo, rev, wlock=wlock) | 344 ret = hg.merge(repo, rev) |
345 if ret: | 345 if ret: |
346 raise util.Abort(_("update returned %d") % ret) | 346 raise util.Abort(_("update returned %d") % ret) |
347 n = repo.commit(None, ctx.description(), ctx.user(), | 347 n = repo.commit(None, ctx.description(), ctx.user(), force=1) |
348 force=1, wlock=wlock) | |
349 if n == None: | 348 if n == None: |
350 raise util.Abort(_("repo commit failed")) | 349 raise util.Abort(_("repo commit failed")) |
351 try: | 350 try: |
352 message, comments, user, date, patchfound = mergeq.readheaders(patch) | 351 message, comments, user, date, patchfound = mergeq.readheaders(patch) |
353 except: | 352 except: |
379 return pp[0] | 378 return pp[0] |
380 if p1 in arevs: | 379 if p1 in arevs: |
381 return pp[1] | 380 return pp[1] |
382 return pp[0] | 381 return pp[0] |
383 | 382 |
384 def mergepatch(self, repo, mergeq, series, wlock): | 383 def mergepatch(self, repo, mergeq, series): |
385 if len(self.applied) == 0: | 384 if len(self.applied) == 0: |
386 # each of the patches merged in will have two parents. This | 385 # each of the patches merged in will have two parents. This |
387 # can confuse the qrefresh, qdiff, and strip code because it | 386 # can confuse the qrefresh, qdiff, and strip code because it |
388 # needs to know which parent is actually in the patch queue. | 387 # needs to know which parent is actually in the patch queue. |
389 # so, we insert a merge marker with only one parent. This way | 388 # so, we insert a merge marker with only one parent. This way |
390 # the first patch in the queue is never a merge patch | 389 # the first patch in the queue is never a merge patch |
391 # | 390 # |
392 pname = ".hg.patches.merge.marker" | 391 pname = ".hg.patches.merge.marker" |
393 n = repo.commit(None, '[mq]: merge marker', user=None, force=1, | 392 n = repo.commit(None, '[mq]: merge marker', user=None, force=1) |
394 wlock=wlock) | |
395 self.removeundo(repo) | 393 self.removeundo(repo) |
396 self.applied.append(statusentry(revlog.hex(n), pname)) | 394 self.applied.append(statusentry(revlog.hex(n), pname)) |
397 self.applied_dirty = 1 | 395 self.applied_dirty = 1 |
398 | 396 |
399 head = self.qparents(repo) | 397 head = self.qparents(repo) |
410 info = mergeq.isapplied(patch) | 408 info = mergeq.isapplied(patch) |
411 if not info: | 409 if not info: |
412 self.ui.warn("patch %s is not applied\n" % patch) | 410 self.ui.warn("patch %s is not applied\n" % patch) |
413 return (1, None) | 411 return (1, None) |
414 rev = revlog.bin(info[1]) | 412 rev = revlog.bin(info[1]) |
415 (err, head) = self.mergeone(repo, mergeq, head, patch, rev, wlock) | 413 (err, head) = self.mergeone(repo, mergeq, head, patch, rev) |
416 if head: | 414 if head: |
417 self.applied.append(statusentry(revlog.hex(head), patch)) | 415 self.applied.append(statusentry(revlog.hex(head), patch)) |
418 self.applied_dirty = 1 | 416 self.applied_dirty = 1 |
419 if err: | 417 if err: |
420 return (err, head) | 418 return (err, head) |
435 return (False, files, False) | 433 return (False, files, False) |
436 | 434 |
437 return (True, files, fuzz) | 435 return (True, files, fuzz) |
438 | 436 |
439 def apply(self, repo, series, list=False, update_status=True, | 437 def apply(self, repo, series, list=False, update_status=True, |
440 strict=False, patchdir=None, merge=None, wlock=None, | 438 strict=False, patchdir=None, merge=None, all_files={}): |
441 all_files={}): | 439 wlock = lock = tr = None |
442 lock = tr = None | |
443 try: | 440 try: |
444 if not wlock: | 441 wlock = repo.wlock() |
445 wlock = repo.wlock() | |
446 lock = repo.lock() | 442 lock = repo.lock() |
447 tr = repo.transaction() | 443 tr = repo.transaction() |
448 try: | 444 try: |
449 ret = self._apply(tr, repo, series, list, update_status, | 445 ret = self._apply(tr, repo, series, list, update_status, |
450 strict, patchdir, merge, wlock, | 446 strict, patchdir, merge, all_files=all_files) |
451 lock=lock, all_files=all_files) | |
452 tr.close() | 447 tr.close() |
453 self.save_dirty() | 448 self.save_dirty() |
454 return ret | 449 return ret |
455 except: | 450 except: |
456 try: | 451 try: |
461 raise | 456 raise |
462 finally: | 457 finally: |
463 del lock, wlock, tr | 458 del lock, wlock, tr |
464 | 459 |
465 def _apply(self, tr, repo, series, list=False, update_status=True, | 460 def _apply(self, tr, repo, series, list=False, update_status=True, |
466 strict=False, patchdir=None, merge=None, wlock=None, | 461 strict=False, patchdir=None, merge=None, all_files={}): |
467 lock=None, all_files={}): | |
468 # TODO unify with commands.py | 462 # TODO unify with commands.py |
469 if not patchdir: | 463 if not patchdir: |
470 patchdir = self.path | 464 patchdir = self.path |
471 err = 0 | 465 err = 0 |
472 n = None | 466 n = None |
509 repo.dirstate.remove(f) | 503 repo.dirstate.remove(f) |
510 for f in merged: | 504 for f in merged: |
511 repo.dirstate.merge(f) | 505 repo.dirstate.merge(f) |
512 p1, p2 = repo.dirstate.parents() | 506 p1, p2 = repo.dirstate.parents() |
513 repo.dirstate.setparents(p1, merge) | 507 repo.dirstate.setparents(p1, merge) |
514 files = patch.updatedir(self.ui, repo, files, wlock=wlock) | 508 files = patch.updatedir(self.ui, repo, files) |
515 n = repo.commit(files, message, user, date, force=1, lock=lock, | 509 n = repo.commit(files, message, user, date, force=1) |
516 wlock=wlock) | |
517 | 510 |
518 if n == None: | 511 if n == None: |
519 raise util.Abort(_("repo commit failed")) | 512 raise util.Abort(_("repo commit failed")) |
520 | 513 |
521 if update_status: | 514 if update_status: |
621 self.check_toppatch(repo) | 614 self.check_toppatch(repo) |
622 wlock = repo.wlock() | 615 wlock = repo.wlock() |
623 try: | 616 try: |
624 insert = self.full_series_end() | 617 insert = self.full_series_end() |
625 if msg: | 618 if msg: |
626 n = repo.commit(commitfiles, msg, force=True, wlock=wlock) | 619 n = repo.commit(commitfiles, msg, force=True) |
627 else: | 620 else: |
628 n = repo.commit(commitfiles, | 621 n = repo.commit(commitfiles, "[mq]: %s" % patch, force=True) |
629 "[mq]: %s" % patch, force=True, wlock=wlock) | |
630 if n == None: | 622 if n == None: |
631 raise util.Abort(_("repo commit failed")) | 623 raise util.Abort(_("repo commit failed")) |
632 self.full_series[insert:insert] = [patch] | 624 self.full_series[insert:insert] = [patch] |
633 self.applied.append(statusentry(revlog.hex(n), patch)) | 625 self.applied.append(statusentry(revlog.hex(n), patch)) |
634 self.parse_series() | 626 self.parse_series() |
646 self.refresh(repo, short=True) | 638 self.refresh(repo, short=True) |
647 self.removeundo(repo) | 639 self.removeundo(repo) |
648 finally: | 640 finally: |
649 del wlock | 641 del wlock |
650 | 642 |
651 def strip(self, repo, rev, update=True, backup="all", wlock=None): | 643 def strip(self, repo, rev, update=True, backup="all"): |
652 lock = None | 644 wlock = lock = None |
653 try: | 645 try: |
654 if not wlock: | 646 wlock = repo.wlock() |
655 wlock = repo.wlock() | |
656 lock = repo.lock() | 647 lock = repo.lock() |
657 | 648 |
658 if update: | 649 if update: |
659 self.check_localchanges(repo, refresh=False) | 650 self.check_localchanges(repo, refresh=False) |
660 urev = self.qparents(repo, rev) | 651 urev = self.qparents(repo, rev) |
661 hg.clean(repo, urev, wlock=wlock) | 652 hg.clean(repo, urev) |
662 repo.dirstate.write() | 653 repo.dirstate.write() |
663 | 654 |
664 self.removeundo(repo) | 655 self.removeundo(repo) |
665 repair.strip(self.ui, repo, rev, backup) | 656 repair.strip(self.ui, repo, rev, backup) |
666 finally: | 657 finally: |
746 if i + off < len(self.series): | 737 if i + off < len(self.series): |
747 return self.series[i + off] | 738 return self.series[i + off] |
748 raise util.Abort(_("patch %s not in series") % patch) | 739 raise util.Abort(_("patch %s not in series") % patch) |
749 | 740 |
750 def push(self, repo, patch=None, force=False, list=False, | 741 def push(self, repo, patch=None, force=False, list=False, |
751 mergeq=None, wlock=None): | 742 mergeq=None): |
752 if not wlock: | 743 wlock = repo.wlock() |
753 wlock = repo.wlock() | |
754 try: | 744 try: |
755 patch = self.lookup(patch) | 745 patch = self.lookup(patch) |
756 # Suppose our series file is: A B C and the current 'top' | 746 # Suppose our series file is: A B C and the current 'top' |
757 # patch is B. qpush C should be performed (moving forward) | 747 # patch is B. qpush C should be performed (moving forward) |
758 # qpush B is a NOP (no change) qpush A is an error (can't | 748 # qpush B is a NOP (no change) qpush A is an error (can't |
792 end = self.series.index(patch, start) + 1 | 782 end = self.series.index(patch, start) + 1 |
793 s = self.series[start:end] | 783 s = self.series[start:end] |
794 all_files = {} | 784 all_files = {} |
795 try: | 785 try: |
796 if mergeq: | 786 if mergeq: |
797 ret = self.mergepatch(repo, mergeq, s, wlock) | 787 ret = self.mergepatch(repo, mergeq, s) |
798 else: | 788 else: |
799 ret = self.apply(repo, s, list, wlock=wlock, | 789 ret = self.apply(repo, s, list, all_files=all_files) |
800 all_files=all_files) | |
801 except: | 790 except: |
802 self.ui.warn(_('cleaning up working directory...')) | 791 self.ui.warn(_('cleaning up working directory...')) |
803 node = repo.dirstate.parents()[0] | 792 node = repo.dirstate.parents()[0] |
804 hg.revert(repo, node, None, wlock) | 793 hg.revert(repo, node, None) |
805 unknown = repo.status(wlock=wlock)[4] | 794 unknown = repo.status()[4] |
806 # only remove unknown files that we know we touched or | 795 # only remove unknown files that we know we touched or |
807 # created while patching | 796 # created while patching |
808 for f in unknown: | 797 for f in unknown: |
809 if f in all_files: | 798 if f in all_files: |
810 util.unlink(repo.wjoin(f)) | 799 util.unlink(repo.wjoin(f)) |
818 self.ui.write("Now at: %s\n" % top) | 807 self.ui.write("Now at: %s\n" % top) |
819 return ret[0] | 808 return ret[0] |
820 finally: | 809 finally: |
821 del wlock | 810 del wlock |
822 | 811 |
823 def pop(self, repo, patch=None, force=False, update=True, all=False, | 812 def pop(self, repo, patch=None, force=False, update=True, all=False): |
824 wlock=None): | |
825 def getfile(f, rev): | 813 def getfile(f, rev): |
826 t = repo.file(f).read(rev) | 814 t = repo.file(f).read(rev) |
827 repo.wfile(f, "w").write(t) | 815 repo.wfile(f, "w").write(t) |
828 | 816 |
829 if not wlock: | 817 wlock = repo.wlock() |
830 wlock = repo.wlock() | |
831 try: | 818 try: |
832 if patch: | 819 if patch: |
833 # index, rev, patch | 820 # index, rev, patch |
834 info = self.isapplied(patch) | 821 info = self.isapplied(patch) |
835 if not info: | 822 if not info: |
897 raise | 884 raise |
898 try: os.removedirs(os.path.dirname(repo.wjoin(f))) | 885 try: os.removedirs(os.path.dirname(repo.wjoin(f))) |
899 except: pass | 886 except: pass |
900 repo.dirstate.forget(f) | 887 repo.dirstate.forget(f) |
901 repo.dirstate.setparents(qp, revlog.nullid) | 888 repo.dirstate.setparents(qp, revlog.nullid) |
902 self.strip(repo, rev, update=False, backup='strip', wlock=wlock) | 889 self.strip(repo, rev, update=False, backup='strip') |
903 del self.applied[start:end] | 890 del self.applied[start:end] |
904 if len(self.applied): | 891 if len(self.applied): |
905 self.ui.write("Now at: %s\n" % self.applied[-1].name) | 892 self.ui.write("Now at: %s\n" % self.applied[-1].name) |
906 else: | 893 else: |
907 self.ui.write("Patch queue now empty\n") | 894 self.ui.write("Patch queue now empty\n") |
1073 message = "\n".join(message) | 1060 message = "\n".join(message) |
1074 else: | 1061 else: |
1075 message = msg | 1062 message = msg |
1076 | 1063 |
1077 self.strip(repo, top, update=False, | 1064 self.strip(repo, top, update=False, |
1078 backup='strip', wlock=wlock) | 1065 backup='strip') |
1079 n = repo.commit(filelist, message, changes[1], match=matchfn, | 1066 n = repo.commit(filelist, message, changes[1], match=matchfn, |
1080 force=1, wlock=wlock) | 1067 force=1) |
1081 self.applied[-1] = statusentry(revlog.hex(n), patchfn) | 1068 self.applied[-1] = statusentry(revlog.hex(n), patchfn) |
1082 self.applied_dirty = 1 | 1069 self.applied_dirty = 1 |
1083 self.removeundo(repo) | 1070 self.removeundo(repo) |
1084 else: | 1071 else: |
1085 self.printdiff(repo, patchparent, fp=patchf) | 1072 self.printdiff(repo, patchparent, fp=patchf) |
1095 try: os.removedirs(os.path.dirname(f)) | 1082 try: os.removedirs(os.path.dirname(f)) |
1096 except: pass | 1083 except: pass |
1097 # forget the file copies in the dirstate | 1084 # forget the file copies in the dirstate |
1098 # push should readd the files later on | 1085 # push should readd the files later on |
1099 repo.dirstate.forget(a) | 1086 repo.dirstate.forget(a) |
1100 self.pop(repo, force=True, wlock=wlock) | 1087 self.pop(repo, force=True) |
1101 self.push(repo, force=True, wlock=wlock) | 1088 self.push(repo, force=True) |
1102 finally: | 1089 finally: |
1103 del wlock | 1090 del wlock |
1104 | 1091 |
1105 def init(self, repo, create=False): | 1092 def init(self, repo, create=False): |
1106 if not create and os.path.isdir(self.path): | 1093 if not create and os.path.isdir(self.path): |
1896 r = q.qrepo() | 1883 r = q.qrepo() |
1897 if r: | 1884 if r: |
1898 wlock = r.wlock() | 1885 wlock = r.wlock() |
1899 try: | 1886 try: |
1900 if r.dirstate[name] == 'r': | 1887 if r.dirstate[name] == 'r': |
1901 r.undelete([name], wlock) | 1888 r.undelete([name]) |
1902 r.copy(patch, name, wlock) | 1889 r.copy(patch, name) |
1903 r.remove([patch], False, wlock) | 1890 r.remove([patch], False) |
1904 finally: | 1891 finally: |
1905 del wlock | 1892 del wlock |
1906 | 1893 |
1907 q.save_dirty() | 1894 q.save_dirty() |
1908 | 1895 |