comparison mercurial/hg.py @ 896:01215ad04283

Merge with BOS
author mpm@selenic.com
date Sat, 13 Aug 2005 19:43:42 -0800
parents 6d6095823b82 77b52b864249
children 3616c0d7ab88
comparison
equal deleted inserted replaced
867:0cd2ee61b10a 896:01215ad04283
8 import sys, struct, os 8 import sys, struct, os
9 import util 9 import util
10 from revlog import * 10 from revlog import *
11 from demandload import * 11 from demandload import *
12 demandload(globals(), "re lock urllib urllib2 transaction time socket") 12 demandload(globals(), "re lock urllib urllib2 transaction time socket")
13 demandload(globals(), "tempfile httprangereader bdiff urlparse stat") 13 demandload(globals(), "tempfile httprangereader bdiff urlparse")
14 demandload(globals(), "bisect select") 14 demandload(globals(), "bisect errno select stat")
15 15
16 class filelog(revlog): 16 class filelog(revlog):
17 def __init__(self, opener, path): 17 def __init__(self, opener, path):
18 revlog.__init__(self, opener, 18 revlog.__init__(self, opener,
19 os.path.join("data", self.encodedir(path + ".i")), 19 os.path.join("data", self.encodedir(path + ".i")),
298 self.ignorefunc = None 298 self.ignorefunc = None
299 299
300 def wjoin(self, f): 300 def wjoin(self, f):
301 return os.path.join(self.root, f) 301 return os.path.join(self.root, f)
302 302
303 def getcwd(self):
304 cwd = os.getcwd()
305 if cwd == self.root: return ''
306 return cwd[len(self.root) + 1:]
307
303 def ignore(self, f): 308 def ignore(self, f):
304 if not self.ignorefunc: 309 if not self.ignorefunc:
305 bigpat = [] 310 bigpat = []
306 try: 311 try:
307 l = file(self.wjoin(".hgignore")) 312 l = file(self.wjoin(".hgignore"))
308 for pat in l: 313 for pat in l:
309 if pat != "\n": 314 if pat != "\n":
310 p = util.pconvert(pat[:-1]) 315 p = pat[:-1]
311 try: 316 try:
312 r = re.compile(p) 317 re.compile(p)
313 except: 318 except:
314 self.ui.warn("ignoring invalid ignore" 319 self.ui.warn("ignoring invalid ignore"
315 + " regular expression '%s'\n" % p) 320 + " regular expression '%s'\n" % p)
316 else: 321 else:
317 bigpat.append(util.pconvert(pat[:-1])) 322 bigpat.append(p)
318 except IOError: pass 323 except IOError: pass
319 324
320 if bigpat: 325 if bigpat:
321 s = "(?:%s)" % (")|(?:".join(bigpat)) 326 s = "(?:%s)" % (")|(?:".join(bigpat))
322 r = re.compile(s) 327 r = re.compile(s)
435 f = f + "\0" + c 440 f = f + "\0" + c
436 e = struct.pack(">cllll", e[0], e[1], e[2], e[3], len(f)) 441 e = struct.pack(">cllll", e[0], e[1], e[2], e[3], len(f))
437 st.write(e + f) 442 st.write(e + f)
438 self.dirty = 0 443 self.dirty = 0
439 444
440 def walk(self, files = None, match = util.always): 445 def filterfiles(self, files):
446 ret = {}
447 unknown = []
448
449 for x in files:
450 if x is '.':
451 return self.map.copy()
452 if x not in self.map:
453 unknown.append(x)
454 else:
455 ret[x] = self.map[x]
456
457 if not unknown:
458 return ret
459
460 b = self.map.keys()
461 b.sort()
462 blen = len(b)
463
464 for x in unknown:
465 bs = bisect.bisect(b, x)
466 if bs != 0 and b[bs-1] == x:
467 ret[x] = self.map[x]
468 continue
469 while bs < blen:
470 s = b[bs]
471 if len(s) > len(x) and s.startswith(x) and s[len(x)] == '/':
472 ret[s] = self.map[s]
473 else:
474 break
475 bs += 1
476 return ret
477
478 def walk(self, files = None, match = util.always, dc=None):
441 self.read() 479 self.read()
442 dc = self.map.copy() 480
443 # walk all files by default 481 # walk all files by default
444 if not files: files = [self.root] 482 if not files:
483 files = [self.root]
484 if not dc:
485 dc = self.map.copy()
486 elif not dc:
487 dc = self.filterfiles(files)
488
445 known = {'.hg': 1} 489 known = {'.hg': 1}
446 def seen(fn): 490 def seen(fn):
447 if fn in known: return True 491 if fn in known: return True
448 known[fn] = 1 492 known[fn] = 1
449 def traverse(): 493 def traverse():
450 for f in util.unique(files): 494 for ff in util.unique(files):
451 f = os.path.join(self.root, f) 495 f = os.path.join(self.root, ff)
452 if os.path.isdir(f): 496 try:
497 st = os.stat(f)
498 except OSError, inst:
499 if ff not in dc: self.ui.warn('%s: %s\n' % (
500 util.pathto(self.getcwd(), ff),
501 inst.strerror))
502 continue
503 if stat.S_ISDIR(st.st_mode):
453 for dir, subdirs, fl in os.walk(f): 504 for dir, subdirs, fl in os.walk(f):
454 d = dir[len(self.root) + 1:] 505 d = dir[len(self.root) + 1:]
455 nd = os.path.normpath(d) 506 nd = util.normpath(d)
507 if nd == '.': nd = ''
456 if seen(nd): 508 if seen(nd):
457 subdirs[:] = [] 509 subdirs[:] = []
458 continue 510 continue
459 for sd in subdirs: 511 for sd in subdirs:
460 ds = os.path.join(nd, sd +'/') 512 ds = os.path.join(nd, sd +'/')
463 subdirs.sort() 515 subdirs.sort()
464 fl.sort() 516 fl.sort()
465 for fn in fl: 517 for fn in fl:
466 fn = util.pconvert(os.path.join(d, fn)) 518 fn = util.pconvert(os.path.join(d, fn))
467 yield 'f', fn 519 yield 'f', fn
520 elif stat.S_ISREG(st.st_mode):
521 yield 'f', ff
468 else: 522 else:
469 yield 'f', f[len(self.root) + 1:] 523 kind = 'unknown'
524 if stat.S_ISCHR(st.st_mode): kind = 'character device'
525 elif stat.S_ISBLK(st.st_mode): kind = 'block device'
526 elif stat.S_ISFIFO(st.st_mode): kind = 'fifo'
527 elif stat.S_ISLNK(st.st_mode): kind = 'symbolic link'
528 elif stat.S_ISSOCK(st.st_mode): kind = 'socket'
529 self.ui.warn('%s: unsupported file type (type is %s)\n' % (
530 util.pathto(self.getcwd(), ff),
531 kind))
470 532
471 ks = dc.keys() 533 ks = dc.keys()
472 ks.sort() 534 ks.sort()
473 for k in ks: 535 for k in ks:
474 yield 'm', k 536 yield 'm', k
475 537
476 # yield only files that match: all in dirstate, others only if 538 # yield only files that match: all in dirstate, others only if
477 # not in .hgignore 539 # not in .hgignore
478 540
479 for src, fn in util.unique(traverse()): 541 for src, fn in util.unique(traverse()):
480 fn = os.path.normpath(fn) 542 fn = util.normpath(fn)
481 if seen(fn): continue 543 if seen(fn): continue
482 if fn in dc: 544 if fn not in dc and self.ignore(fn):
483 del dc[fn]
484 elif self.ignore(fn):
485 continue 545 continue
486 if match(fn): 546 if match(fn):
487 yield src, fn 547 yield src, fn
488 548
489 def changes(self, files=None, match=util.always): 549 def changes(self, files=None, match=util.always):
490 self.read() 550 self.read()
491 dc = self.map.copy() 551 if not files:
552 dc = self.map.copy()
553 else:
554 dc = self.filterfiles(files)
492 lookup, modified, added, unknown = [], [], [], [] 555 lookup, modified, added, unknown = [], [], [], []
493 removed, deleted = [], [] 556 removed, deleted = [], []
494 557
495 for src, fn in self.walk(files, match): 558 for src, fn in self.walk(files, match, dc=dc):
496 try: 559 try:
497 s = os.stat(os.path.join(self.root, fn)) 560 s = os.stat(os.path.join(self.root, fn))
498 except OSError: 561 except OSError:
499 continue 562 continue
500 if not stat.S_ISREG(s.st_mode): 563 if not stat.S_ISREG(s.st_mode):
695 def file(self, f): 758 def file(self, f):
696 if f[0] == '/': f = f[1:] 759 if f[0] == '/': f = f[1:]
697 return filelog(self.opener, f) 760 return filelog(self.opener, f)
698 761
699 def getcwd(self): 762 def getcwd(self):
700 cwd = os.getcwd() 763 return self.dirstate.getcwd()
701 if cwd == self.root: return ''
702 return cwd[len(self.root) + 1:]
703 764
704 def wfile(self, f, mode='r'): 765 def wfile(self, f, mode='r'):
705 return self.wopener(f, mode) 766 return self.wopener(f, mode)
706 767
707 def transaction(self): 768 def transaction(self):