##// END OF EJS Templates
Make repo locks recursive, eliminate all passing of lock/wlock
Matt Mackall -
r4917:126f527b default
parent child Browse files
Show More
@@ -19,38 +19,38 b" def fetch(ui, repo, source='default', **"
19 merged, and the result of the merge is committed. Otherwise, the
19 merged, and the result of the merge is committed. Otherwise, the
20 working directory is updated.'''
20 working directory is updated.'''
21
21
22 def postincoming(other, modheads, lock, wlock):
22 def postincoming(other, modheads):
23 if modheads == 0:
23 if modheads == 0:
24 return 0
24 return 0
25 if modheads == 1:
25 if modheads == 1:
26 return hg.clean(repo, repo.changelog.tip(), wlock=wlock)
26 return hg.clean(repo, repo.changelog.tip())
27 newheads = repo.heads(parent)
27 newheads = repo.heads(parent)
28 newchildren = [n for n in repo.heads(parent) if n != parent]
28 newchildren = [n for n in repo.heads(parent) if n != parent]
29 newparent = parent
29 newparent = parent
30 if newchildren:
30 if newchildren:
31 newparent = newchildren[0]
31 newparent = newchildren[0]
32 hg.clean(repo, newparent, wlock=wlock)
32 hg.clean(repo, newparent)
33 newheads = [n for n in repo.heads() if n != newparent]
33 newheads = [n for n in repo.heads() if n != newparent]
34 err = False
34 err = False
35 if newheads:
35 if newheads:
36 ui.status(_('merging with new head %d:%s\n') %
36 ui.status(_('merging with new head %d:%s\n') %
37 (repo.changelog.rev(newheads[0]), short(newheads[0])))
37 (repo.changelog.rev(newheads[0]), short(newheads[0])))
38 err = hg.merge(repo, newheads[0], remind=False, wlock=wlock)
38 err = hg.merge(repo, newheads[0], remind=False)
39 if not err and len(newheads) > 1:
39 if not err and len(newheads) > 1:
40 ui.status(_('not merging with %d other new heads '
40 ui.status(_('not merging with %d other new heads '
41 '(use "hg heads" and "hg merge" to merge them)') %
41 '(use "hg heads" and "hg merge" to merge them)') %
42 (len(newheads) - 1))
42 (len(newheads) - 1))
43 if not err:
43 if not err:
44 mod, add, rem = repo.status(wlock=wlock)[:3]
44 mod, add, rem = repo.status()[:3]
45 message = (cmdutil.logmessage(opts) or
45 message = (cmdutil.logmessage(opts) or
46 (_('Automated merge with %s') % other.url()))
46 (_('Automated merge with %s') % other.url()))
47 n = repo.commit(mod + add + rem, message,
47 n = repo.commit(mod + add + rem, message,
48 opts['user'], opts['date'], lock=lock, wlock=wlock,
48 opts['user'], opts['date'],
49 force_editor=opts.get('force_editor'))
49 force_editor=opts.get('force_editor'))
50 ui.status(_('new changeset %d:%s merges remote changes '
50 ui.status(_('new changeset %d:%s merges remote changes '
51 'with local\n') % (repo.changelog.rev(n),
51 'with local\n') % (repo.changelog.rev(n),
52 short(n)))
52 short(n)))
53 def pull(lock, wlock):
53 def pull():
54 cmdutil.setremoteconfig(ui, opts)
54 cmdutil.setremoteconfig(ui, opts)
55
55
56 other = hg.repository(ui, ui.expandpath(source))
56 other = hg.repository(ui, ui.expandpath(source))
@@ -60,8 +60,8 b" def fetch(ui, repo, source='default', **"
60 raise util.Abort(_("fetch -r doesn't work for remote repositories yet"))
60 raise util.Abort(_("fetch -r doesn't work for remote repositories yet"))
61 elif opts['rev']:
61 elif opts['rev']:
62 revs = [other.lookup(rev) for rev in opts['rev']]
62 revs = [other.lookup(rev) for rev in opts['rev']]
63 modheads = repo.pull(other, heads=revs, lock=lock)
63 modheads = repo.pull(other, heads=revs)
64 return postincoming(other, modheads, lock, wlock)
64 return postincoming(other, modheads)
65
65
66 parent, p2 = repo.dirstate.parents()
66 parent, p2 = repo.dirstate.parents()
67 if parent != repo.changelog.tip():
67 if parent != repo.changelog.tip():
@@ -73,13 +73,13 b" def fetch(ui, repo, source='default', **"
73 try:
73 try:
74 wlock = repo.wlock()
74 wlock = repo.wlock()
75 lock = repo.lock()
75 lock = repo.lock()
76 mod, add, rem = repo.status(wlock=wlock)[:3]
76 mod, add, rem = repo.status()[:3]
77 if mod or add or rem:
77 if mod or add or rem:
78 raise util.Abort(_('outstanding uncommitted changes'))
78 raise util.Abort(_('outstanding uncommitted changes'))
79 if len(repo.heads()) > 1:
79 if len(repo.heads()) > 1:
80 raise util.Abort(_('multiple heads in this repository '
80 raise util.Abort(_('multiple heads in this repository '
81 '(use "hg heads" and "hg merge" to merge)'))
81 '(use "hg heads" and "hg merge" to merge)'))
82 return pull(lock, wlock)
82 return pull()
83 finally:
83 finally:
84 del lock, wlock
84 del lock, wlock
85
85
@@ -323,10 +323,10 b' class queue:'
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)
@@ -337,15 +337,14 b' class queue:'
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:
@@ -381,7 +380,7 b' class queue:'
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
@@ -390,8 +389,7 b' class queue:'
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
@@ -412,7 +410,7 b' class queue:'
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
@@ -437,18 +435,15 b' class queue:'
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
@@ -463,8 +458,7 b' class queue:'
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
@@ -511,9 +505,8 b' class queue:'
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"))
@@ -623,10 +616,9 b' class queue:'
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]
@@ -648,17 +640,16 b' class queue:'
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)
@@ -748,9 +739,8 b' class queue:'
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'
@@ -794,15 +784,14 b' class queue:'
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:
@@ -820,14 +809,12 b' class queue:'
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
@@ -899,7 +886,7 b' class queue:'
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)
@@ -1075,9 +1062,9 b' class queue:'
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)
@@ -1097,8 +1084,8 b' class queue:'
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
@@ -1898,9 +1885,9 b' def rename(ui, repo, patch, name=None, *'
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
@@ -119,9 +119,8 b' class transplanter:'
119 continue
119 continue
120 if pulls:
120 if pulls:
121 if source != repo:
121 if source != repo:
122 repo.pull(source, heads=pulls, lock=lock)
122 repo.pull(source, heads=pulls)
123 merge.update(repo, pulls[-1], False, False, None,
123 merge.update(repo, pulls[-1], False, False, None)
124 wlock=wlock)
125 p1, p2 = repo.dirstate.parents()
124 p1, p2 = repo.dirstate.parents()
126 pulls = []
125 pulls = []
127
126
@@ -132,7 +131,7 b' class transplanter:'
132 # fail.
131 # fail.
133 domerge = True
132 domerge = True
134 if not hasnode(repo, node):
133 if not hasnode(repo, node):
135 repo.pull(source, heads=[node], lock=lock)
134 repo.pull(source, heads=[node])
136
135
137 if parents[1] != revlog.nullid:
136 if parents[1] != revlog.nullid:
138 self.ui.note(_('skipping merge changeset %s:%s\n')
137 self.ui.note(_('skipping merge changeset %s:%s\n')
@@ -147,11 +146,11 b' class transplanter:'
147 del revmap[rev]
146 del revmap[rev]
148 if patchfile or domerge:
147 if patchfile or domerge:
149 try:
148 try:
150 n = self.applyone(repo, node, source.changelog.read(node),
149 n = self.applyone(repo, node,
150 source.changelog.read(node),
151 patchfile, merge=domerge,
151 patchfile, merge=domerge,
152 log=opts.get('log'),
152 log=opts.get('log'),
153 filter=opts.get('filter'),
153 filter=opts.get('filter'))
154 lock=lock, wlock=wlock)
155 if n and domerge:
154 if n and domerge:
156 self.ui.status(_('%s merged at %s\n') % (revstr,
155 self.ui.status(_('%s merged at %s\n') % (revstr,
157 revlog.short(n)))
156 revlog.short(n)))
@@ -162,8 +161,8 b' class transplanter:'
162 if patchfile:
161 if patchfile:
163 os.unlink(patchfile)
162 os.unlink(patchfile)
164 if pulls:
163 if pulls:
165 repo.pull(source, heads=pulls, lock=lock)
164 repo.pull(source, heads=pulls)
166 merge.update(repo, pulls[-1], False, False, None, wlock=wlock)
165 merge.update(repo, pulls[-1], False, False, None)
167 finally:
166 finally:
168 self.saveseries(revmap, merges)
167 self.saveseries(revmap, merges)
169 self.transplants.write()
168 self.transplants.write()
@@ -195,7 +194,7 b' class transplanter:'
195 return (user, date, msg)
194 return (user, date, msg)
196
195
197 def applyone(self, repo, node, cl, patchfile, merge=False, log=False,
196 def applyone(self, repo, node, cl, patchfile, merge=False, log=False,
198 filter=None, lock=None, wlock=None):
197 filter=None):
199 '''apply the patch in patchfile to the repository as a transplant'''
198 '''apply the patch in patchfile to the repository as a transplant'''
200 (manifest, user, (time, timezone), files, message) = cl[:5]
199 (manifest, user, (time, timezone), files, message) = cl[:5]
201 date = "%d %d" % (time, timezone)
200 date = "%d %d" % (time, timezone)
@@ -221,7 +220,7 b' class transplanter:'
221 self.ui.warn(_('%s: empty changeset') % revlog.hex(node))
220 self.ui.warn(_('%s: empty changeset') % revlog.hex(node))
222 return None
221 return None
223 finally:
222 finally:
224 files = patch.updatedir(self.ui, repo, files, wlock=wlock)
223 files = patch.updatedir(self.ui, repo, files)
225 except Exception, inst:
224 except Exception, inst:
226 if filter:
225 if filter:
227 os.unlink(patchfile)
226 os.unlink(patchfile)
@@ -239,8 +238,7 b' class transplanter:'
239 p1, p2 = repo.dirstate.parents()
238 p1, p2 = repo.dirstate.parents()
240 repo.dirstate.setparents(p1, node)
239 repo.dirstate.setparents(p1, node)
241
240
242 n = repo.commit(files, message, user, date, lock=lock, wlock=wlock,
241 n = repo.commit(files, message, user, date, extra=extra)
243 extra=extra)
244 if not merge:
242 if not merge:
245 self.transplants.set(n, node)
243 self.transplants.set(n, node)
246
244
@@ -282,8 +280,7 b' class transplanter:'
282 revlog.hex(parents[0]))
280 revlog.hex(parents[0]))
283 if merge:
281 if merge:
284 repo.dirstate.setparents(p1, parents[1])
282 repo.dirstate.setparents(p1, parents[1])
285 n = repo.commit(None, message, user, date, wlock=wlock,
283 n = repo.commit(None, message, user, date, extra=extra)
286 extra=extra)
287 if not n:
284 if not n:
288 raise util.Abort(_('commit failed'))
285 raise util.Abort(_('commit failed'))
289 if not merge:
286 if not merge:
@@ -628,8 +628,7 b' def findrenames(repo, added=None, remove'
628 if bestname:
628 if bestname:
629 yield bestname, a, bestscore
629 yield bestname, a, bestscore
630
630
631 def addremove(repo, pats=[], opts={}, wlock=None, dry_run=None,
631 def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None):
632 similarity=None):
633 if dry_run is None:
632 if dry_run is None:
634 dry_run = opts.get('dry_run')
633 dry_run = opts.get('dry_run')
635 if similarity is None:
634 if similarity is None:
@@ -649,8 +648,8 b' def addremove(repo, pats=[], opts={}, wl'
649 if repo.ui.verbose or not exact:
648 if repo.ui.verbose or not exact:
650 repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
649 repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
651 if not dry_run:
650 if not dry_run:
652 repo.add(add, wlock=wlock)
651 repo.add(add)
653 repo.remove(remove, wlock=wlock)
652 repo.remove(remove)
654 if similarity > 0:
653 if similarity > 0:
655 for old, new, score in findrenames(repo, add, remove, similarity):
654 for old, new, score in findrenames(repo, add, remove, similarity):
656 oldrel, oldexact = mapping[old]
655 oldrel, oldexact = mapping[old]
@@ -660,7 +659,7 b' def addremove(repo, pats=[], opts={}, wl'
660 '(%d%% similar)\n') %
659 '(%d%% similar)\n') %
661 (oldrel, newrel, score * 100))
660 (oldrel, newrel, score * 100))
662 if not dry_run:
661 if not dry_run:
663 repo.copy(old, new, wlock=wlock)
662 repo.copy(old, new)
664
663
665 def service(opts, parentfn=None, initfn=None, runfn=None):
664 def service(opts, parentfn=None, initfn=None, runfn=None):
666 '''Run a command as a service.'''
665 '''Run a command as a service.'''
@@ -466,7 +466,7 b' def commit(ui, repo, *pats, **opts):'
466 except ValueError, inst:
466 except ValueError, inst:
467 raise util.Abort(str(inst))
467 raise util.Abort(str(inst))
468
468
469 def docopy(ui, repo, pats, opts, wlock):
469 def docopy(ui, repo, pats, opts):
470 # called with the repo lock held
470 # called with the repo lock held
471 #
471 #
472 # hgsep => pathname that uses "/" to separate directories
472 # hgsep => pathname that uses "/" to separate directories
@@ -527,14 +527,14 b' def docopy(ui, repo, pats, opts, wlock):'
527 try:
527 try:
528 restore = repo.dirstate[abstarget] == 'r'
528 restore = repo.dirstate[abstarget] == 'r'
529 if restore and not opts.get('dry_run'):
529 if restore and not opts.get('dry_run'):
530 repo.undelete([abstarget], wlock)
530 repo.undelete([abstarget])
531 try:
531 try:
532 if not opts.get('dry_run'):
532 if not opts.get('dry_run'):
533 util.copyfile(src, target)
533 util.copyfile(src, target)
534 restore = False
534 restore = False
535 finally:
535 finally:
536 if restore:
536 if restore:
537 repo.remove([abstarget], wlock=wlock)
537 repo.remove([abstarget])
538 except IOError, inst:
538 except IOError, inst:
539 if inst.errno == errno.ENOENT:
539 if inst.errno == errno.ENOENT:
540 ui.warn(_('%s: deleted in working copy\n') % relsrc)
540 ui.warn(_('%s: deleted in working copy\n') % relsrc)
@@ -553,9 +553,9 b' def docopy(ui, repo, pats, opts, wlock):'
553 "data will be stored for %s.\n")
553 "data will be stored for %s.\n")
554 % (repo.pathto(origsrc, cwd), reltarget))
554 % (repo.pathto(origsrc, cwd), reltarget))
555 if abstarget not in repo.dirstate and not opts.get('dry_run'):
555 if abstarget not in repo.dirstate and not opts.get('dry_run'):
556 repo.add([abstarget], wlock)
556 repo.add([abstarget])
557 elif not opts.get('dry_run'):
557 elif not opts.get('dry_run'):
558 repo.copy(origsrc, abstarget, wlock)
558 repo.copy(origsrc, abstarget)
559 copied.append((abssrc, relsrc, exact))
559 copied.append((abssrc, relsrc, exact))
560
560
561 # pat: ossep
561 # pat: ossep
@@ -677,7 +677,7 b' def copy(ui, repo, *pats, **opts):'
677 """
677 """
678 wlock = repo.wlock(False)
678 wlock = repo.wlock(False)
679 try:
679 try:
680 errs, copied = docopy(ui, repo, pats, opts, wlock)
680 errs, copied = docopy(ui, repo, pats, opts)
681 finally:
681 finally:
682 del wlock
682 del wlock
683 return errs
683 return errs
@@ -1627,7 +1627,7 b' def import_(ui, repo, patch1, *patches, '
1627 p2 = repo.lookup(p2 or hex(nullid))
1627 p2 = repo.lookup(p2 or hex(nullid))
1628
1628
1629 if p1 != wp[0].node():
1629 if p1 != wp[0].node():
1630 hg.clean(repo, p1, wlock=wlock)
1630 hg.clean(repo, p1)
1631 repo.dirstate.setparents(p1, p2)
1631 repo.dirstate.setparents(p1, p2)
1632 elif p2:
1632 elif p2:
1633 try:
1633 try:
@@ -1645,12 +1645,11 b' def import_(ui, repo, patch1, *patches, '
1645 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1645 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1646 files=files)
1646 files=files)
1647 finally:
1647 finally:
1648 files = patch.updatedir(ui, repo, files, wlock=wlock)
1648 files = patch.updatedir(ui, repo, files)
1649 n = repo.commit(files, message, user, date, wlock=wlock,
1649 n = repo.commit(files, message, user, date)
1650 lock=lock)
1651 if opts.get('exact'):
1650 if opts.get('exact'):
1652 if hex(n) != nodeid:
1651 if hex(n) != nodeid:
1653 repo.rollback(wlock=wlock, lock=lock)
1652 repo.rollback()
1654 raise util.Abort(_('patch is damaged' +
1653 raise util.Abort(_('patch is damaged' +
1655 ' or loses information'))
1654 ' or loses information'))
1656 finally:
1655 finally:
@@ -2261,14 +2260,14 b' def rename(ui, repo, *pats, **opts):'
2261 """
2260 """
2262 wlock = repo.wlock(False)
2261 wlock = repo.wlock(False)
2263 try:
2262 try:
2264 errs, copied = docopy(ui, repo, pats, opts, wlock)
2263 errs, copied = docopy(ui, repo, pats, opts)
2265 names = []
2264 names = []
2266 for abs, rel, exact in copied:
2265 for abs, rel, exact in copied:
2267 if ui.verbose or not exact:
2266 if ui.verbose or not exact:
2268 ui.status(_('removing %s\n') % rel)
2267 ui.status(_('removing %s\n') % rel)
2269 names.append(abs)
2268 names.append(abs)
2270 if not opts.get('dry_run'):
2269 if not opts.get('dry_run'):
2271 repo.remove(names, True, wlock=wlock)
2270 repo.remove(names, True)
2272 return errs
2271 return errs
2273 finally:
2272 finally:
2274 del wlock
2273 del wlock
@@ -2359,7 +2358,7 b' def revert(ui, repo, *pats, **opts):'
2359 names[abs] = (rel, exact)
2358 names[abs] = (rel, exact)
2360 target_only[abs] = True
2359 target_only[abs] = True
2361
2360
2362 changes = repo.status(match=names.has_key, wlock=wlock)[:5]
2361 changes = repo.status(match=names.has_key)[:5]
2363 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
2362 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
2364
2363
2365 revert = ([], _('reverting %s\n'))
2364 revert = ([], _('reverting %s\n'))
@@ -2432,7 +2431,7 b' def revert(ui, repo, *pats, **opts):'
2432 if not opts.get('dry_run'):
2431 if not opts.get('dry_run'):
2433 for f in forget[0]:
2432 for f in forget[0]:
2434 repo.dirstate.forget(f)
2433 repo.dirstate.forget(f)
2435 r = hg.revert(repo, node, update.has_key, wlock)
2434 r = hg.revert(repo, node, update.has_key)
2436 for f in add[0]:
2435 for f in add[0]:
2437 repo.dirstate.add(f)
2436 repo.dirstate.add(f)
2438 for f in undelete[0]:
2437 for f in undelete[0]:
@@ -237,7 +237,7 b' def _update(repo, node): return update(r'
237 def update(repo, node):
237 def update(repo, node):
238 """update the working directory to node, merging linear changes"""
238 """update the working directory to node, merging linear changes"""
239 pl = repo.parents()
239 pl = repo.parents()
240 stats = _merge.update(repo, node, False, False, None, None)
240 stats = _merge.update(repo, node, False, False, None)
241 _showstats(repo, stats)
241 _showstats(repo, stats)
242 if stats[3]:
242 if stats[3]:
243 repo.ui.status(_("There are unresolved merges with"
243 repo.ui.status(_("There are unresolved merges with"
@@ -251,15 +251,15 b' def update(repo, node):'
251 % (pl[0].rev(), repo.changectx(node).rev()))
251 % (pl[0].rev(), repo.changectx(node).rev()))
252 return stats[3]
252 return stats[3]
253
253
254 def clean(repo, node, wlock=None, show_stats=True):
254 def clean(repo, node, show_stats=True):
255 """forcibly switch the working directory to node, clobbering changes"""
255 """forcibly switch the working directory to node, clobbering changes"""
256 stats = _merge.update(repo, node, False, True, None, wlock)
256 stats = _merge.update(repo, node, False, True, None)
257 if show_stats: _showstats(repo, stats)
257 if show_stats: _showstats(repo, stats)
258 return stats[3]
258 return stats[3]
259
259
260 def merge(repo, node, force=None, remind=True, wlock=None):
260 def merge(repo, node, force=None, remind=True):
261 """branch merge with node, resolving changes"""
261 """branch merge with node, resolving changes"""
262 stats = _merge.update(repo, node, True, force, False, wlock)
262 stats = _merge.update(repo, node, True, force, False)
263 _showstats(repo, stats)
263 _showstats(repo, stats)
264 if stats[3]:
264 if stats[3]:
265 pl = repo.parents()
265 pl = repo.parents()
@@ -272,9 +272,9 b' def merge(repo, node, force=None, remind'
272 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
272 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
273 return stats[3]
273 return stats[3]
274
274
275 def revert(repo, node, choose, wlock):
275 def revert(repo, node, choose):
276 """revert changes to revision in node without updating dirstate"""
276 """revert changes to revision in node without updating dirstate"""
277 return _merge.update(repo, node, False, True, choose, wlock)[3]
277 return _merge.update(repo, node, False, True, choose)[3]
278
278
279 def verify(repo):
279 def verify(repo):
280 """verify the consistency of a repository"""
280 """verify the consistency of a repository"""
@@ -530,12 +530,11 b' class localrepository(repo.repository):'
530 finally:
530 finally:
531 del l
531 del l
532
532
533 def rollback(self, wlock=None, lock=None):
533 def rollback(self):
534 wlock = lock = None
534 try:
535 try:
535 if not wlock:
536 wlock = self.wlock()
536 wlock = self.wlock()
537 lock = self.lock()
537 if not lock:
538 lock = self.lock()
539 if os.path.exists(self.sjoin("undo")):
538 if os.path.exists(self.sjoin("undo")):
540 self.ui.status(_("rolling back last transaction\n"))
539 self.ui.status(_("rolling back last transaction\n"))
541 transaction.rollback(self.sopener, self.sjoin("undo"))
540 transaction.rollback(self.sopener, self.sjoin("undo"))
@@ -570,13 +569,23 b' class localrepository(repo.repository):'
570 return l
569 return l
571
570
572 def lock(self, wait=True):
571 def lock(self, wait=True):
573 return self._lock(self.sjoin("lock"), wait, None, self.invalidate,
572 if self._lockref and self._lockref():
574 _('repository %s') % self.origroot)
573 return self._lockref()
574
575 l = self._lock(self.sjoin("lock"), wait, None, self.invalidate,
576 _('repository %s') % self.origroot)
577 self._lockref = weakref.ref(l)
578 return l
575
579
576 def wlock(self, wait=True):
580 def wlock(self, wait=True):
577 return self._lock(self.join("wlock"), wait, self.dirstate.write,
581 if self._wlockref and self._wlockref():
578 self.dirstate.invalidate,
582 return self._wlockref()
579 _('working directory of %s') % self.origroot)
583
584 l = self._lock(self.join("wlock"), wait, self.dirstate.write,
585 self.dirstate.invalidate, _('working directory of %s') %
586 self.origroot)
587 self._wlockref = weakref.ref(l)
588 return l
580
589
581 def filecommit(self, fn, manifest1, manifest2, linkrev, transaction, changelist):
590 def filecommit(self, fn, manifest1, manifest2, linkrev, transaction, changelist):
582 """
591 """
@@ -638,16 +647,16 b' class localrepository(repo.repository):'
638 changelist.append(fn)
647 changelist.append(fn)
639 return fl.add(t, meta, transaction, linkrev, fp1, fp2)
648 return fl.add(t, meta, transaction, linkrev, fp1, fp2)
640
649
641 def rawcommit(self, files, text, user, date, p1=None, p2=None, wlock=None, extra={}):
650 def rawcommit(self, files, text, user, date, p1=None, p2=None, extra={}):
642 if p1 is None:
651 if p1 is None:
643 p1, p2 = self.dirstate.parents()
652 p1, p2 = self.dirstate.parents()
644 return self.commit(files=files, text=text, user=user, date=date,
653 return self.commit(files=files, text=text, user=user, date=date,
645 p1=p1, p2=p2, wlock=wlock, extra=extra)
654 p1=p1, p2=p2, extra=extra)
646
655
647 def commit(self, files=None, text="", user=None, date=None,
656 def commit(self, files=None, text="", user=None, date=None,
648 match=util.always, force=False, lock=None, wlock=None,
657 match=util.always, force=False, force_editor=False,
649 force_editor=False, p1=None, p2=None, extra={}):
658 p1=None, p2=None, extra={}):
650 tr = None
659 wlock = lock = tr = None
651 try:
660 try:
652 commit = []
661 commit = []
653 remove = []
662 remove = []
@@ -707,10 +716,8 b' class localrepository(repo.repository):'
707
716
708 self.hook("precommit", throw=True, parent1=xp1, parent2=xp2)
717 self.hook("precommit", throw=True, parent1=xp1, parent2=xp2)
709
718
710 if not wlock:
719 wlock = self.wlock()
711 wlock = self.wlock()
720 lock = self.lock()
712 if not lock:
713 lock = self.lock()
714 tr = self.transaction()
721 tr = self.transaction()
715
722
716 # check in files
723 # check in files
@@ -854,7 +861,7 b' class localrepository(repo.repository):'
854 yield src, fn
861 yield src, fn
855
862
856 def status(self, node1=None, node2=None, files=[], match=util.always,
863 def status(self, node1=None, node2=None, files=[], match=util.always,
857 wlock=None, list_ignored=False, list_clean=False):
864 list_ignored=False, list_clean=False):
858 """return status of files between two nodes or node and working directory
865 """return status of files between two nodes or node and working directory
859
866
860 If node1 is None, use the first dirstate parent instead.
867 If node1 is None, use the first dirstate parent instead.
@@ -908,18 +915,17 b' class localrepository(repo.repository):'
908
915
909 # update dirstate for files that are actually clean
916 # update dirstate for files that are actually clean
910 if fixup:
917 if fixup:
911 fixlock = wlock
918 wlock = None
912 try:
919 try:
913 if not fixlock:
920 try:
914 try:
921 wlock = self.wlock(False)
915 fixlock = self.wlock(False)
922 except lock.LockException:
916 except lock.LockException:
923 pass
917 pass
924 if wlock:
918 if fixlock:
919 for f in fixup:
925 for f in fixup:
920 self.dirstate.normal(f)
926 self.dirstate.normal(f)
921 finally:
927 finally:
922 del fixlock
928 del wlock
923 else:
929 else:
924 # we are comparing working dir against non-parent
930 # we are comparing working dir against non-parent
925 # generate a pseudo-manifest for the working dir
931 # generate a pseudo-manifest for the working dir
@@ -966,10 +972,9 b' class localrepository(repo.repository):'
966 l.sort()
972 l.sort()
967 return (modified, added, removed, deleted, unknown, ignored, clean)
973 return (modified, added, removed, deleted, unknown, ignored, clean)
968
974
969 def add(self, list, wlock=None):
975 def add(self, list):
976 wlock = self.wlock()
970 try:
977 try:
971 if not wlock:
972 wlock = self.wlock()
973 for f in list:
978 for f in list:
974 p = self.wjoin(f)
979 p = self.wjoin(f)
975 try:
980 try:
@@ -992,10 +997,9 b' class localrepository(repo.repository):'
992 finally:
997 finally:
993 del wlock
998 del wlock
994
999
995 def forget(self, list, wlock=None):
1000 def forget(self, list):
1001 wlock = self.wlock()
996 try:
1002 try:
997 if not wlock:
998 wlock = self.wlock()
999 for f in list:
1003 for f in list:
1000 if self.dirstate[f] != 'a':
1004 if self.dirstate[f] != 'a':
1001 self.ui.warn(_("%s not added!\n") % f)
1005 self.ui.warn(_("%s not added!\n") % f)
@@ -1004,7 +1008,8 b' class localrepository(repo.repository):'
1004 finally:
1008 finally:
1005 del wlock
1009 del wlock
1006
1010
1007 def remove(self, list, unlink=False, wlock=None):
1011 def remove(self, list, unlink=False):
1012 wlock = None
1008 try:
1013 try:
1009 if unlink:
1014 if unlink:
1010 for f in list:
1015 for f in list:
@@ -1013,8 +1018,7 b' class localrepository(repo.repository):'
1013 except OSError, inst:
1018 except OSError, inst:
1014 if inst.errno != errno.ENOENT:
1019 if inst.errno != errno.ENOENT:
1015 raise
1020 raise
1016 if not wlock:
1021 wlock = self.wlock()
1017 wlock = self.wlock()
1018 for f in list:
1022 for f in list:
1019 if unlink and os.path.exists(self.wjoin(f)):
1023 if unlink and os.path.exists(self.wjoin(f)):
1020 self.ui.warn(_("%s still exists!\n") % f)
1024 self.ui.warn(_("%s still exists!\n") % f)
@@ -1027,13 +1031,13 b' class localrepository(repo.repository):'
1027 finally:
1031 finally:
1028 del wlock
1032 del wlock
1029
1033
1030 def undelete(self, list, wlock=None):
1034 def undelete(self, list):
1035 wlock = None
1031 try:
1036 try:
1032 p = self.dirstate.parents()[0]
1037 p = self.dirstate.parents()[0]
1033 mn = self.changelog.read(p)[0]
1038 mn = self.changelog.read(p)[0]
1034 m = self.manifest.read(mn)
1039 m = self.manifest.read(mn)
1035 if not wlock:
1040 wlock = self.wlock()
1036 wlock = self.wlock()
1037 for f in list:
1041 for f in list:
1038 if self.dirstate[f] != 'r':
1042 if self.dirstate[f] != 'r':
1039 self.ui.warn("%s not removed!\n" % f)
1043 self.ui.warn("%s not removed!\n" % f)
@@ -1044,7 +1048,8 b' class localrepository(repo.repository):'
1044 finally:
1048 finally:
1045 del wlock
1049 del wlock
1046
1050
1047 def copy(self, source, dest, wlock=None):
1051 def copy(self, source, dest):
1052 wlock = None
1048 try:
1053 try:
1049 p = self.wjoin(dest)
1054 p = self.wjoin(dest)
1050 if not (os.path.exists(p) or os.path.islink(p)):
1055 if not (os.path.exists(p) or os.path.islink(p)):
@@ -1053,8 +1058,7 b' class localrepository(repo.repository):'
1053 self.ui.warn(_("copy failed: %s is not a file or a "
1058 self.ui.warn(_("copy failed: %s is not a file or a "
1054 "symbolic link\n") % dest)
1059 "symbolic link\n") % dest)
1055 else:
1060 else:
1056 if not wlock:
1061 wlock = self.wlock()
1057 wlock = self.wlock()
1058 if dest not in self.dirstate:
1062 if dest not in self.dirstate:
1059 self.dirstate.add(dest)
1063 self.dirstate.add(dest)
1060 self.dirstate.copy(source, dest)
1064 self.dirstate.copy(source, dest)
@@ -1336,10 +1340,9 b' class localrepository(repo.repository):'
1336 else:
1340 else:
1337 return subset
1341 return subset
1338
1342
1339 def pull(self, remote, heads=None, force=False, lock=None):
1343 def pull(self, remote, heads=None, force=False):
1344 lock = self.lock()
1340 try:
1345 try:
1341 if not lock:
1342 lock = self.lock()
1343 fetch = self.findincoming(remote, force=force)
1346 fetch = self.findincoming(remote, force=force)
1344 if fetch == [nullid]:
1347 if fetch == [nullid]:
1345 self.ui.status(_("requesting all changes\n"))
1348 self.ui.status(_("requesting all changes\n"))
@@ -496,20 +496,17 b' def recordupdates(repo, action, branchme'
496 if f:
496 if f:
497 repo.dirstate.forget(f)
497 repo.dirstate.forget(f)
498
498
499 def update(repo, node, branchmerge, force, partial, wlock):
499 def update(repo, node, branchmerge, force, partial):
500 """
500 """
501 Perform a merge between the working directory and the given node
501 Perform a merge between the working directory and the given node
502
502
503 branchmerge = whether to merge between branches
503 branchmerge = whether to merge between branches
504 force = whether to force branch merging or file overwriting
504 force = whether to force branch merging or file overwriting
505 partial = a function to filter file lists (dirstate not updated)
505 partial = a function to filter file lists (dirstate not updated)
506 wlock = working dir lock, if already held
507 """
506 """
508
507
508 wlock = repo.wlock()
509 try:
509 try:
510 if not wlock:
511 wlock = repo.wlock()
512
513 wc = repo.workingctx()
510 wc = repo.workingctx()
514 if node is None:
511 if node is None:
515 # tip of current branch
512 # tip of current branch
@@ -1013,7 +1013,7 b' def diffopts(ui, opts={}, untrusted=Fals'
1013 ignorewsamount=get('ignore_space_change', 'ignorewsamount'),
1013 ignorewsamount=get('ignore_space_change', 'ignorewsamount'),
1014 ignoreblanklines=get('ignore_blank_lines', 'ignoreblanklines'))
1014 ignoreblanklines=get('ignore_blank_lines', 'ignoreblanklines'))
1015
1015
1016 def updatedir(ui, repo, patches, wlock=None):
1016 def updatedir(ui, repo, patches):
1017 '''Update dirstate after patch application according to metadata'''
1017 '''Update dirstate after patch application according to metadata'''
1018 if not patches:
1018 if not patches:
1019 return
1019 return
@@ -1035,11 +1035,11 b' def updatedir(ui, repo, patches, wlock=N'
1035 for src, dst, after in copies:
1035 for src, dst, after in copies:
1036 if not after:
1036 if not after:
1037 copyfile(src, dst, repo.root)
1037 copyfile(src, dst, repo.root)
1038 repo.copy(src, dst, wlock=wlock)
1038 repo.copy(src, dst)
1039 removes = removes.keys()
1039 removes = removes.keys()
1040 if removes:
1040 if removes:
1041 removes.sort()
1041 removes.sort()
1042 repo.remove(removes, True, wlock=wlock)
1042 repo.remove(removes, True)
1043 for f in patches:
1043 for f in patches:
1044 ctype, gp = patches[f]
1044 ctype, gp = patches[f]
1045 if gp and gp.mode:
1045 if gp and gp.mode:
@@ -1050,7 +1050,7 b' def updatedir(ui, repo, patches, wlock=N'
1050 repo.wwrite(gp.path, '', x and 'x' or '')
1050 repo.wwrite(gp.path, '', x and 'x' or '')
1051 else:
1051 else:
1052 util.set_exec(dst, x)
1052 util.set_exec(dst, x)
1053 cmdutil.addremove(repo, cfiles, wlock=wlock)
1053 cmdutil.addremove(repo, cfiles)
1054 files = patches.keys()
1054 files = patches.keys()
1055 files.extend([r for r in removes if r not in files])
1055 files.extend([r for r in removes if r not in files])
1056 files.sort()
1056 files.sort()
General Comments 0
You need to be logged in to leave comments. Login now