comparison mercurial/localrepo.py @ 6142:50a277e6ceae

merge backout
author Thomas Arendsen Hein <thomas@intevation.de>
date Mon, 18 Feb 2008 19:21:33 +0100
parents 989467e8e3a9
children 23ffe82615d8
comparison
equal deleted inserted replaced
6141:90e5c82a3859 6142:50a277e6ceae
66 self.spath = os.path.join(self.path, "store") 66 self.spath = os.path.join(self.path, "store")
67 else: 67 else:
68 self.encodefn = lambda x: x 68 self.encodefn = lambda x: x
69 self.decodefn = lambda x: x 69 self.decodefn = lambda x: x
70 self.spath = self.path 70 self.spath = self.path
71 self.sopener = util.encodedopener(util.opener(self.spath), 71
72 self.encodefn) 72 try:
73 # files in .hg/ will be created using this mode
74 mode = os.stat(self.spath).st_mode
75 # avoid some useless chmods
76 if (0777 & ~util._umask) == (0777 & mode):
77 mode = None
78 except OSError:
79 mode = None
80
81 self._createmode = mode
82 self.opener.createmode = mode
83 sopener = util.opener(self.spath)
84 sopener.createmode = mode
85 self.sopener = util.encodedopener(sopener, self.encodefn)
73 86
74 self.ui = ui.ui(parentui=parentui) 87 self.ui = ui.ui(parentui=parentui)
75 try: 88 try:
76 self.ui.readconfig(self.join("hgrc"), self.root) 89 self.ui.readconfig(self.join("hgrc"), self.root)
77 extensions.loadall(self.ui) 90 extensions.loadall(self.ui)
79 pass 92 pass
80 93
81 self.tagscache = None 94 self.tagscache = None
82 self._tagstypecache = None 95 self._tagstypecache = None
83 self.branchcache = None 96 self.branchcache = None
97 self._ubranchcache = None # UTF-8 version of branchcache
98 self._branchcachetip = None
84 self.nodetagscache = None 99 self.nodetagscache = None
85 self.filterpats = {} 100 self.filterpats = {}
86 self._datafilters = {} 101 self._datafilters = {}
87 self._transref = self._lockref = self._wlockref = None 102 self._transref = self._lockref = self._wlockref = None
88 103
118 raise util.Abort(_('%r cannot be used in a tag name') % c) 133 raise util.Abort(_('%r cannot be used in a tag name') % c)
119 134
120 self.hook('pretag', throw=True, node=hex(node), tag=name, local=local) 135 self.hook('pretag', throw=True, node=hex(node), tag=name, local=local)
121 136
122 def writetag(fp, name, munge, prevtags): 137 def writetag(fp, name, munge, prevtags):
138 fp.seek(0, 2)
123 if prevtags and prevtags[-1] != '\n': 139 if prevtags and prevtags[-1] != '\n':
124 fp.write('\n') 140 fp.write('\n')
125 fp.write('%s %s\n' % (hex(node), munge and munge(name) or name)) 141 fp.write('%s %s\n' % (hex(node), munge and munge(name) or name))
126 fp.close() 142 fp.close()
127 143
184 200
185 user: name of user to use if committing 201 user: name of user to use if committing
186 202
187 date: date tuple to use if committing''' 203 date: date tuple to use if committing'''
188 204
205 date = util.parsedate(date)
189 for x in self.status()[:5]: 206 for x in self.status()[:5]:
190 if '.hgtags' in x: 207 if '.hgtags' in x:
191 raise util.Abort(_('working copy of .hgtags is changed ' 208 raise util.Abort(_('working copy of .hgtags is changed '
192 '(please commit .hgtags manually)')) 209 '(please commit .hgtags manually)'))
193 210
328 self.nodetagscache = {} 345 self.nodetagscache = {}
329 for t, n in self.tags().items(): 346 for t, n in self.tags().items():
330 self.nodetagscache.setdefault(n, []).append(t) 347 self.nodetagscache.setdefault(n, []).append(t)
331 return self.nodetagscache.get(node, []) 348 return self.nodetagscache.get(node, [])
332 349
333 def _branchtags(self): 350 def _branchtags(self, partial, lrev):
334 partial, last, lrev = self._readbranchcache()
335
336 tiprev = self.changelog.count() - 1 351 tiprev = self.changelog.count() - 1
337 if lrev != tiprev: 352 if lrev != tiprev:
338 self._updatebranchcache(partial, lrev+1, tiprev+1) 353 self._updatebranchcache(partial, lrev+1, tiprev+1)
339 self._writebranchcache(partial, self.changelog.tip(), tiprev) 354 self._writebranchcache(partial, self.changelog.tip(), tiprev)
340 355
341 return partial 356 return partial
342 357
343 def branchtags(self): 358 def branchtags(self):
344 if self.branchcache is not None: 359 tip = self.changelog.tip()
360 if self.branchcache is not None and self._branchcachetip == tip:
345 return self.branchcache 361 return self.branchcache
346 362
347 self.branchcache = {} # avoid recursion in changectx 363 oldtip = self._branchcachetip
348 partial = self._branchtags() 364 self._branchcachetip = tip
365 if self.branchcache is None:
366 self.branchcache = {} # avoid recursion in changectx
367 else:
368 self.branchcache.clear() # keep using the same dict
369 if oldtip is None or oldtip not in self.changelog.nodemap:
370 partial, last, lrev = self._readbranchcache()
371 else:
372 lrev = self.changelog.rev(oldtip)
373 partial = self._ubranchcache
374
375 self._branchtags(partial, lrev)
349 376
350 # the branch cache is stored on disk as UTF-8, but in the local 377 # the branch cache is stored on disk as UTF-8, but in the local
351 # charset internally 378 # charset internally
352 for k, v in partial.items(): 379 for k, v in partial.items():
353 self.branchcache[util.tolocal(k)] = v 380 self.branchcache[util.tolocal(k)] = v
381 self._ubranchcache = partial
354 return self.branchcache 382 return self.branchcache
355 383
356 def _readbranchcache(self): 384 def _readbranchcache(self):
357 partial = {} 385 partial = {}
358 try: 386 try:
366 last, lrev = lines.pop(0).split(" ", 1) 394 last, lrev = lines.pop(0).split(" ", 1)
367 last, lrev = bin(last), int(lrev) 395 last, lrev = bin(last), int(lrev)
368 if not (lrev < self.changelog.count() and 396 if not (lrev < self.changelog.count() and
369 self.changelog.node(lrev) == last): # sanity check 397 self.changelog.node(lrev) == last): # sanity check
370 # invalidate the cache 398 # invalidate the cache
371 raise ValueError('Invalid branch cache: unknown tip') 399 raise ValueError('invalidating branch cache (tip differs)')
372 for l in lines: 400 for l in lines:
373 if not l: continue 401 if not l: continue
374 node, label = l.split(" ", 1) 402 node, label = l.split(" ", 1)
375 partial[label.strip()] = bin(node) 403 partial[label.strip()] = bin(node)
376 except (KeyboardInterrupt, util.SignalInterrupt): 404 except (KeyboardInterrupt, util.SignalInterrupt):
485 if filter not in self.filterpats: 513 if filter not in self.filterpats:
486 l = [] 514 l = []
487 for pat, cmd in self.ui.configitems(filter): 515 for pat, cmd in self.ui.configitems(filter):
488 mf = util.matcher(self.root, "", [pat], [], [])[1] 516 mf = util.matcher(self.root, "", [pat], [], [])[1]
489 fn = None 517 fn = None
518 params = cmd
490 for name, filterfn in self._datafilters.iteritems(): 519 for name, filterfn in self._datafilters.iteritems():
491 if cmd.startswith(name): 520 if cmd.startswith(name):
492 fn = filterfn 521 fn = filterfn
522 params = cmd[len(name):].lstrip()
493 break 523 break
494 if not fn: 524 if not fn:
495 fn = lambda s, c, **kwargs: util.filter(s, c) 525 fn = lambda s, c, **kwargs: util.filter(s, c)
496 # Wrap old filters not supporting keyword arguments 526 # Wrap old filters not supporting keyword arguments
497 if not inspect.getargspec(fn)[2]: 527 if not inspect.getargspec(fn)[2]:
498 oldfn = fn 528 oldfn = fn
499 fn = lambda s, c, **kwargs: oldfn(s, c) 529 fn = lambda s, c, **kwargs: oldfn(s, c)
500 l.append((mf, fn, cmd)) 530 l.append((mf, fn, params))
501 self.filterpats[filter] = l 531 self.filterpats[filter] = l
502 532
503 for mf, fn, cmd in self.filterpats[filter]: 533 for mf, fn, cmd in self.filterpats[filter]:
504 if mf(filename): 534 if mf(filename):
505 self.ui.debug(_("filtering %s through %s\n") % (filename, cmd)) 535 self.ui.debug(_("filtering %s through %s\n") % (filename, cmd))
548 578
549 renames = [(self.sjoin("journal"), self.sjoin("undo")), 579 renames = [(self.sjoin("journal"), self.sjoin("undo")),
550 (self.join("journal.dirstate"), self.join("undo.dirstate")), 580 (self.join("journal.dirstate"), self.join("undo.dirstate")),
551 (self.join("journal.branch"), self.join("undo.branch"))] 581 (self.join("journal.branch"), self.join("undo.branch"))]
552 tr = transaction.transaction(self.ui.warn, self.sopener, 582 tr = transaction.transaction(self.ui.warn, self.sopener,
553 self.sjoin("journal"), 583 self.sjoin("journal"),
554 aftertrans(renames)) 584 aftertrans(renames),
585 self._createmode)
555 self._transref = weakref.ref(tr) 586 self._transref = weakref.ref(tr)
556 return tr 587 return tr
557 588
558 def recover(self): 589 def recover(self):
559 l = self.lock() 590 l = self.lock()
576 lock = self.lock() 607 lock = self.lock()
577 if os.path.exists(self.sjoin("undo")): 608 if os.path.exists(self.sjoin("undo")):
578 self.ui.status(_("rolling back last transaction\n")) 609 self.ui.status(_("rolling back last transaction\n"))
579 transaction.rollback(self.sopener, self.sjoin("undo")) 610 transaction.rollback(self.sopener, self.sjoin("undo"))
580 util.rename(self.join("undo.dirstate"), self.join("dirstate")) 611 util.rename(self.join("undo.dirstate"), self.join("dirstate"))
581 branch = self.opener("undo.branch").read() 612 try:
582 self.dirstate.setbranch(branch) 613 branch = self.opener("undo.branch").read()
614 self.dirstate.setbranch(branch)
615 except IOError:
616 self.ui.warn(_("Named branch could not be reset, "
617 "current branch still is: %s\n")
618 % util.tolocal(self.dirstate.branch()))
583 self.invalidate() 619 self.invalidate()
584 self.dirstate.invalidate() 620 self.dirstate.invalidate()
585 else: 621 else:
586 self.ui.warn(_("no rollback information available\n")) 622 self.ui.warn(_("no rollback information available\n"))
587 finally: 623 finally:
592 if hasattr(self, a): 628 if hasattr(self, a):
593 self.__delattr__(a) 629 self.__delattr__(a)
594 self.tagscache = None 630 self.tagscache = None
595 self._tagstypecache = None 631 self._tagstypecache = None
596 self.nodetagscache = None 632 self.nodetagscache = None
633 self.branchcache = None
634 self._ubranchcache = None
635 self._branchcachetip = None
597 636
598 def _lock(self, lockname, wait, releasefn, acquirefn, desc): 637 def _lock(self, lockname, wait, releasefn, acquirefn, desc):
599 try: 638 try:
600 l = lock.lock(lockname, 0, releasefn, desc=desc) 639 l = lock.lock(lockname, 0, releasefn, desc=desc)
601 except lock.LockHeld, inst: 640 except lock.LockHeld, inst:
858 user, date, extra) 897 user, date, extra)
859 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1, 898 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
860 parent2=xp2) 899 parent2=xp2)
861 tr.close() 900 tr.close()
862 901
863 if self.branchcache and "branch" in extra: 902 if self.branchcache:
864 self.branchcache[util.tolocal(extra["branch"])] = n 903 self.branchtags()
865 904
866 if use_dirstate or update_dirstate: 905 if use_dirstate or update_dirstate:
867 self.dirstate.setparents(n) 906 self.dirstate.setparents(n)
868 if use_dirstate: 907 if use_dirstate:
869 for f in removed: 908 for f in removed:
1482 1521
1483 if warn: 1522 if warn:
1484 self.ui.warn(_("abort: push creates new remote branches!\n")) 1523 self.ui.warn(_("abort: push creates new remote branches!\n"))
1485 self.ui.status(_("(did you forget to merge?" 1524 self.ui.status(_("(did you forget to merge?"
1486 " use push -f to force)\n")) 1525 " use push -f to force)\n"))
1487 return None, 1 1526 return None, 0
1488 elif inc: 1527 elif inc:
1489 self.ui.warn(_("note: unsynced remote changes!\n")) 1528 self.ui.warn(_("note: unsynced remote changes!\n"))
1490 1529
1491 1530
1492 if revs is None: 1531 if revs is None:
1979 tr.close() 2018 tr.close()
1980 finally: 2019 finally:
1981 del tr 2020 del tr
1982 2021
1983 if changesets > 0: 2022 if changesets > 0:
2023 # forcefully update the on-disk branch cache
2024 self.ui.debug(_("updating the branch cache\n"))
2025 self.branchtags()
1984 self.hook("changegroup", node=hex(self.changelog.node(cor+1)), 2026 self.hook("changegroup", node=hex(self.changelog.node(cor+1)),
1985 source=srctype, url=url) 2027 source=srctype, url=url)
1986 2028
1987 for i in xrange(cor + 1, cnr + 1): 2029 for i in xrange(cor + 1, cnr + 1):
1988 self.hook("incoming", node=hex(self.changelog.node(i)), 2030 self.hook("incoming", node=hex(self.changelog.node(i)),