mercurial/hg.py
changeset 866 6d6095823b82
parent 859 6390c377a9e6
parent 865 2d2fee33ec68
child 894 62ec665759f2
child 896 01215ad04283
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: