comparison mercurial/hg.py @ 866:6d6095823b82

Merge with TAH
author mpm@selenic.com
date Fri, 12 Aug 2005 23:54:09 -0800
parents 6390c377a9e6 2d2fee33ec68
children 62ec665759f2 01215ad04283
comparison
equal deleted inserted replaced
859:6390c377a9e6 866:6d6095823b82
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") 13 demandload(globals(), "tempfile httprangereader bdiff urlparse stat")
14 demandload(globals(), "bisect select") 14 demandload(globals(), "bisect select")
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,
390 self.copies[dest] = source 390 self.copies[dest] = source
391 391
392 def copied(self, file): 392 def copied(self, file):
393 return self.copies.get(file, None) 393 return self.copies.get(file, None)
394 394
395 def update(self, files, state): 395 def update(self, files, state, **kw):
396 ''' current states: 396 ''' current states:
397 n normal 397 n normal
398 m needs merging 398 m needs merging
399 r marked for removal 399 r marked for removal
400 a marked for addition''' 400 a marked for addition'''
405 for f in files: 405 for f in files:
406 if state == "r": 406 if state == "r":
407 self.map[f] = ('r', 0, 0, 0) 407 self.map[f] = ('r', 0, 0, 0)
408 else: 408 else:
409 s = os.stat(os.path.join(self.root, f)) 409 s = os.stat(os.path.join(self.root, f))
410 self.map[f] = (state, s.st_mode, s.st_size, s.st_mtime) 410 st_size = kw.get('st_size', s.st_size)
411 st_mtime = kw.get('st_mtime', s.st_mtime)
412 self.map[f] = (state, s.st_mode, st_size, st_mtime)
411 413
412 def forget(self, files): 414 def forget(self, files):
413 if not files: return 415 if not files: return
414 self.read() 416 self.read()
415 self.markdirty() 417 self.markdirty()
482 elif self.ignore(fn): 484 elif self.ignore(fn):
483 continue 485 continue
484 if match(fn): 486 if match(fn):
485 yield src, fn 487 yield src, fn
486 488
487 def changes(self, files = None, match = util.always): 489 def changes(self, files=None, match=util.always):
488 self.read() 490 self.read()
489 dc = self.map.copy() 491 dc = self.map.copy()
490 lookup, changed, added, unknown = [], [], [], [] 492 lookup, modified, added, unknown = [], [], [], []
493 removed, deleted = [], []
491 494
492 for src, fn in self.walk(files, match): 495 for src, fn in self.walk(files, match):
493 try: s = os.stat(os.path.join(self.root, fn)) 496 try:
494 except: continue 497 s = os.stat(os.path.join(self.root, fn))
495 498 except OSError:
496 if fn in dc: 499 continue
497 c = dc[fn] 500 if not stat.S_ISREG(s.st_mode):
501 continue
502 c = dc.get(fn)
503 if c:
498 del dc[fn] 504 del dc[fn]
499
500 if c[0] == 'm': 505 if c[0] == 'm':
501 changed.append(fn) 506 modified.append(fn)
502 elif c[0] == 'a': 507 elif c[0] == 'a':
503 added.append(fn) 508 added.append(fn)
504 elif c[0] == 'r': 509 elif c[0] == 'r':
505 unknown.append(fn) 510 unknown.append(fn)
506 elif c[2] != s.st_size or (c[1] ^ s.st_mode) & 0100: 511 elif c[2] != s.st_size or (c[1] ^ s.st_mode) & 0100:
507 changed.append(fn) 512 modified.append(fn)
508 elif c[1] != s.st_mode or c[3] != s.st_mtime: 513 elif c[3] != s.st_mtime:
509 lookup.append(fn) 514 lookup.append(fn)
510 else: 515 else:
511 if match(fn): unknown.append(fn) 516 unknown.append(fn)
512 517
513 return (lookup, changed, added, filter(match, dc.keys()), unknown) 518 for fn, c in [(fn, c) for fn, c in dc.items() if match(fn)]:
519 if c[0] == 'r':
520 removed.append(fn)
521 else:
522 deleted.append(fn)
523 return (lookup, modified, added, removed + deleted, unknown)
514 524
515 # used to avoid circular references so destructors work 525 # used to avoid circular references so destructors work
516 def opener(base): 526 def opener(base):
517 p = base 527 p = base
518 def o(path, mode="r"): 528 def o(path, mode="r"):
1561 for f in files: 1571 for f in files:
1562 self.ui.status("merging %s\n" % f) 1572 self.ui.status("merging %s\n" % f)
1563 m, o, flag = merge[f] 1573 m, o, flag = merge[f]
1564 self.merge3(f, m, o) 1574 self.merge3(f, m, o)
1565 util.set_exec(self.wjoin(f), flag) 1575 util.set_exec(self.wjoin(f), flag)
1566 if moddirstate and mode == 'm': 1576 if moddirstate:
1567 # only update dirstate on branch merge, otherwise we 1577 if mode == 'm':
1568 # could mark files with changes as unchanged 1578 # only update dirstate on branch merge, otherwise we
1569 self.dirstate.update([f], mode) 1579 # could mark files with changes as unchanged
1580 self.dirstate.update([f], mode)
1581 elif p2 == nullid:
1582 # update dirstate from parent1's manifest
1583 m1n = self.changelog.read(p1)[0]
1584 m1 = self.manifest.read(m1n)
1585 f_len = len(self.file(f).read(m1[f]))
1586 self.dirstate.update([f], mode, st_size=f_len, st_mtime=0)
1587 else:
1588 self.ui.warn("Second parent without branch merge!?\n"
1589 "Dirstate for file %s may be wrong.\n" % f)
1570 1590
1571 remove.sort() 1591 remove.sort()
1572 for f in remove: 1592 for f in remove:
1573 self.ui.note("removing %s\n" % f) 1593 self.ui.note("removing %s\n" % f)
1574 try: 1594 try: