comparison mercurial/localrepo.py @ 1584:b3e94785ab69

merge with crew
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Sun, 11 Dec 2005 15:38:42 -0800
parents 63799b01985c
children 5c5aaaa9ab6f 11d12bd6e1dc
comparison
equal deleted inserted replaced
1583:32a4e6802864 1584:b3e94785ab69
10 from node import * 10 from node import *
11 from i18n import gettext as _ 11 from i18n import gettext as _
12 from demandload import * 12 from demandload import *
13 demandload(globals(), "re lock transaction tempfile stat mdiff errno") 13 demandload(globals(), "re lock transaction tempfile stat mdiff errno")
14 14
15 class localrepository: 15 class localrepository(object):
16 def __init__(self, ui, path=None, create=0): 16 def __init__(self, ui, path=None, create=0):
17 if not path: 17 if not path:
18 p = os.getcwd() 18 p = os.getcwd()
19 while not os.path.isdir(os.path.join(p, ".hg")): 19 while not os.path.isdir(os.path.join(p, ".hg")):
20 oldp = p 20 oldp = p
41 os.mkdir(self.path) 41 os.mkdir(self.path)
42 os.mkdir(self.join("data")) 42 os.mkdir(self.join("data"))
43 43
44 self.dirstate = dirstate.dirstate(self.opener, ui, self.root) 44 self.dirstate = dirstate.dirstate(self.opener, ui, self.root)
45 try: 45 try:
46 self.ui.readconfig(os.path.join(self.path, "hgrc")) 46 self.ui.readconfig(self.join("hgrc"))
47 except IOError: pass 47 except IOError: pass
48 48
49 def hook(self, name, **args): 49 def hook(self, name, **args):
50 def runhook(name, cmd): 50 def runhook(name, cmd):
51 self.ui.note(_("running hook %s: %s\n") % (name, cmd)) 51 self.ui.note(_("running hook %s: %s\n") % (name, cmd))
223 223
224 def recover(self): 224 def recover(self):
225 lock = self.lock() 225 lock = self.lock()
226 if os.path.exists(self.join("journal")): 226 if os.path.exists(self.join("journal")):
227 self.ui.status(_("rolling back interrupted transaction\n")) 227 self.ui.status(_("rolling back interrupted transaction\n"))
228 return transaction.rollback(self.opener, self.join("journal")) 228 transaction.rollback(self.opener, self.join("journal"))
229 return True
229 else: 230 else:
230 self.ui.warn(_("no interrupted transaction available\n")) 231 self.ui.warn(_("no interrupted transaction available\n"))
232 return False
231 233
232 def undo(self): 234 def undo(self):
235 wlock = self.wlock()
233 lock = self.lock() 236 lock = self.lock()
234 if os.path.exists(self.join("undo")): 237 if os.path.exists(self.join("undo")):
235 self.ui.status(_("rolling back last transaction\n")) 238 self.ui.status(_("rolling back last transaction\n"))
236 transaction.rollback(self.opener, self.join("undo")) 239 transaction.rollback(self.opener, self.join("undo"))
237 self.dirstate = None
238 util.rename(self.join("undo.dirstate"), self.join("dirstate")) 240 util.rename(self.join("undo.dirstate"), self.join("dirstate"))
239 self.dirstate = dirstate.dirstate(self.opener, self.ui, self.root) 241 self.dirstate.read()
240 else: 242 else:
241 self.ui.warn(_("no undo information available\n")) 243 self.ui.warn(_("no undo information available\n"))
242 244
243 def lock(self, wait=1): 245 def lock(self, wait=1):
244 try: 246 try:
246 except lock.LockHeld, inst: 248 except lock.LockHeld, inst:
247 if wait: 249 if wait:
248 self.ui.warn(_("waiting for lock held by %s\n") % inst.args[0]) 250 self.ui.warn(_("waiting for lock held by %s\n") % inst.args[0])
249 return lock.lock(self.join("lock"), wait) 251 return lock.lock(self.join("lock"), wait)
250 raise inst 252 raise inst
253
254 def wlock(self, wait=1):
255 try:
256 wlock = lock.lock(self.join("wlock"), 0, self.dirstate.write)
257 except lock.LockHeld, inst:
258 if not wait:
259 raise inst
260 self.ui.warn(_("waiting for lock held by %s\n") % inst.args[0])
261 wlock = lock.lock(self.join("wlock"), wait, self.dirstate.write)
262 self.dirstate.read()
263 return wlock
251 264
252 def rawcommit(self, files, text, user, date, p1=None, p2=None): 265 def rawcommit(self, files, text, user, date, p1=None, p2=None):
253 orig_parent = self.dirstate.parents()[0] or nullid 266 orig_parent = self.dirstate.parents()[0] or nullid
254 p1 = p1 or self.dirstate.parents()[0] or nullid 267 p1 = p1 or self.dirstate.parents()[0] or nullid
255 p2 = p2 or self.dirstate.parents()[1] or nullid 268 p2 = p2 or self.dirstate.parents()[1] or nullid
263 if orig_parent == p1: 276 if orig_parent == p1:
264 update_dirstate = 1 277 update_dirstate = 1
265 else: 278 else:
266 update_dirstate = 0 279 update_dirstate = 0
267 280
281 wlock = self.wlock()
282 lock = self.lock()
268 tr = self.transaction() 283 tr = self.transaction()
269 mm = m1.copy() 284 mm = m1.copy()
270 mfm = mf1.copy() 285 mfm = mf1.copy()
271 linkrev = self.changelog.count() 286 linkrev = self.changelog.count()
272 for f in files: 287 for f in files:
351 return None 366 return None
352 367
353 if not self.hook("precommit"): 368 if not self.hook("precommit"):
354 return None 369 return None
355 370
371 wlock = self.wlock()
356 lock = self.lock() 372 lock = self.lock()
357 tr = self.transaction() 373 tr = self.transaction()
358 374
359 # check in files 375 # check in files
360 new = {} 376 new = {}
444 return None 460 return None
445 return n 461 return n
446 462
447 def walk(self, node=None, files=[], match=util.always): 463 def walk(self, node=None, files=[], match=util.always):
448 if node: 464 if node:
465 fdict = dict.fromkeys(files)
449 for fn in self.manifest.read(self.changelog.read(node)[0]): 466 for fn in self.manifest.read(self.changelog.read(node)[0]):
450 if match(fn): yield 'm', fn 467 fdict.pop(fn, None)
468 if match(fn):
469 yield 'm', fn
470 for fn in fdict:
471 self.ui.warn(_('%s: No such file in rev %s\n') % (
472 util.pathto(self.getcwd(), fn), short(node)))
451 else: 473 else:
452 for src, fn in self.dirstate.walk(files, match): 474 for src, fn in self.dirstate.walk(files, match):
453 yield src, fn 475 yield src, fn
454 476
455 def changes(self, node1 = None, node2 = None, files = [], 477 def changes(self, node1 = None, node2 = None, files = [],
468 del mf[fn] 490 del mf[fn]
469 return mf 491 return mf
470 492
471 # are we comparing the working directory? 493 # are we comparing the working directory?
472 if not node2: 494 if not node2:
495 try:
496 wlock = self.wlock(wait=0)
497 except lock.LockHeld:
498 wlock = None
473 l, c, a, d, u = self.dirstate.changes(files, match) 499 l, c, a, d, u = self.dirstate.changes(files, match)
474 500
475 # are we comparing working dir against its parent? 501 # are we comparing working dir against its parent?
476 if not node1: 502 if not node1:
477 if l: 503 if l:
479 change = self.changelog.read(self.dirstate.parents()[0]) 505 change = self.changelog.read(self.dirstate.parents()[0])
480 mf2 = mfmatches(change[0]) 506 mf2 = mfmatches(change[0])
481 for f in l: 507 for f in l:
482 if fcmp(f, mf2): 508 if fcmp(f, mf2):
483 c.append(f) 509 c.append(f)
510 elif wlock is not None:
511 self.dirstate.update([f], "n")
484 512
485 for l in c, a, d, u: 513 for l in c, a, d, u:
486 l.sort() 514 l.sort()
487 515
488 return (c, a, d, u) 516 return (c, a, d, u)
522 l.sort() 550 l.sort()
523 551
524 return (c, a, d, u) 552 return (c, a, d, u)
525 553
526 def add(self, list): 554 def add(self, list):
555 wlock = self.wlock()
527 for f in list: 556 for f in list:
528 p = self.wjoin(f) 557 p = self.wjoin(f)
529 if not os.path.exists(p): 558 if not os.path.exists(p):
530 self.ui.warn(_("%s does not exist!\n") % f) 559 self.ui.warn(_("%s does not exist!\n") % f)
531 elif not os.path.isfile(p): 560 elif not os.path.isfile(p):
534 self.ui.warn(_("%s already tracked!\n") % f) 563 self.ui.warn(_("%s already tracked!\n") % f)
535 else: 564 else:
536 self.dirstate.update([f], "a") 565 self.dirstate.update([f], "a")
537 566
538 def forget(self, list): 567 def forget(self, list):
568 wlock = self.wlock()
539 for f in list: 569 for f in list:
540 if self.dirstate.state(f) not in 'ai': 570 if self.dirstate.state(f) not in 'ai':
541 self.ui.warn(_("%s not added!\n") % f) 571 self.ui.warn(_("%s not added!\n") % f)
542 else: 572 else:
543 self.dirstate.forget([f]) 573 self.dirstate.forget([f])
547 for f in list: 577 for f in list:
548 try: 578 try:
549 util.unlink(self.wjoin(f)) 579 util.unlink(self.wjoin(f))
550 except OSError, inst: 580 except OSError, inst:
551 if inst.errno != errno.ENOENT: raise 581 if inst.errno != errno.ENOENT: raise
582 wlock = self.wlock()
552 for f in list: 583 for f in list:
553 p = self.wjoin(f) 584 p = self.wjoin(f)
554 if os.path.exists(p): 585 if os.path.exists(p):
555 self.ui.warn(_("%s still exists!\n") % f) 586 self.ui.warn(_("%s still exists!\n") % f)
556 elif self.dirstate.state(f) == 'a': 587 elif self.dirstate.state(f) == 'a':
564 def undelete(self, list): 595 def undelete(self, list):
565 p = self.dirstate.parents()[0] 596 p = self.dirstate.parents()[0]
566 mn = self.changelog.read(p)[0] 597 mn = self.changelog.read(p)[0]
567 mf = self.manifest.readflags(mn) 598 mf = self.manifest.readflags(mn)
568 m = self.manifest.read(mn) 599 m = self.manifest.read(mn)
600 wlock = self.wlock()
569 for f in list: 601 for f in list:
570 if self.dirstate.state(f) not in "r": 602 if self.dirstate.state(f) not in "r":
571 self.ui.warn("%s not removed!\n" % f) 603 self.ui.warn("%s not removed!\n" % f)
572 else: 604 else:
573 t = self.file(f).read(m[f]) 605 t = self.file(f).read(m[f])
580 if not os.path.exists(p): 612 if not os.path.exists(p):
581 self.ui.warn(_("%s does not exist!\n") % dest) 613 self.ui.warn(_("%s does not exist!\n") % dest)
582 elif not os.path.isfile(p): 614 elif not os.path.isfile(p):
583 self.ui.warn(_("copy failed: %s is not a file\n") % dest) 615 self.ui.warn(_("copy failed: %s is not a file\n") % dest)
584 else: 616 else:
617 wlock = self.wlock()
585 if self.dirstate.state(dest) == '?': 618 if self.dirstate.state(dest) == '?':
586 self.dirstate.update([dest], "a") 619 self.dirstate.update([dest], "a")
587 self.dirstate.copy(source, dest) 620 self.dirstate.copy(source, dest)
588 621
589 def heads(self): 622 def heads(self, start=None):
590 return self.changelog.heads() 623 heads = self.changelog.heads(start)
624 # sort the output in rev descending order
625 heads = [(-self.changelog.rev(h), h) for h in heads]
626 heads.sort()
627 return [n for (r, n) in heads]
591 628
592 # branchlookup returns a dict giving a list of branches for 629 # branchlookup returns a dict giving a list of branches for
593 # each head. A branch is defined as the tag of a node or 630 # each head. A branch is defined as the tag of a node or
594 # the branch of the node's parents. If a node has multiple 631 # the branch of the node's parents. If a node has multiple
595 # branch tags, tags are eliminated if they are visible from other 632 # branch tags, tags are eliminated if they are visible from other
1370 1407
1371 for f in a + c + u: 1408 for f in a + c + u:
1372 mw[f] = "" 1409 mw[f] = ""
1373 mfw[f] = util.is_exec(self.wjoin(f), mfw.get(f, False)) 1410 mfw[f] = util.is_exec(self.wjoin(f), mfw.get(f, False))
1374 1411
1412 if moddirstate:
1413 wlock = self.wlock()
1414
1375 for f in d: 1415 for f in d:
1376 if f in mw: del mw[f] 1416 if f in mw: del mw[f]
1377 1417
1378 # If we're jumping between revisions (as opposed to merging), 1418 # If we're jumping between revisions (as opposed to merging),
1379 # and if neither the working directory nor the target rev has 1419 # and if neither the working directory nor the target rev has