changeset 4950:30847b8af7ca

dirstate: add __contains__ and make __getitem__ more useful dirstate.state(f) == '?' -> f not in dirstate dirstate.state(f) -> dirstate[f]
author Matt Mackall <mpm@selenic.com>
date Sat, 21 Jul 2007 16:02:09 -0500
parents fc61495ea9cf
children 6a7659a0c07c
files hgext/convert/hg.py hgext/gpg.py hgext/mq.py mercurial/cmdutil.py mercurial/commands.py mercurial/dirstate.py mercurial/localrepo.py
diffstat 7 files changed, 38 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/convert/hg.py
+++ b/hgext/convert/hg.py
@@ -26,7 +26,7 @@ class convert_mercurial(converter_sink):
 
     def putfile(self, f, e, data):
         self.repo.wwrite(f, data, e)
-        if self.repo.dirstate.state(f) == '?':
+        if f not in self.repo.dirstate:
             self.repo.dirstate.add(f)
 
     def copyfile(self, source, dest):
@@ -58,7 +58,7 @@ class convert_mercurial(converter_sink):
             extra['branch'] = commit.branch
         if commit.rev:
             extra['convert_revision'] = commit.rev
-            
+
         while parents:
             p1 = p2
             p2 = parents.pop(0)
--- a/hgext/gpg.py
+++ b/hgext/gpg.py
@@ -240,7 +240,7 @@ def sign(ui, repo, *revs, **opts):
 
     repo.wfile(".hgsigs", "ab").write(sigmessage)
 
-    if repo.dirstate.state(".hgsigs") == '?':
+    if '.hgsigs' not in repo.dirstate:
         repo.add([".hgsigs"])
 
     if opts["no_commit"]:
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -1872,7 +1872,7 @@ def rename(ui, repo, patch, name=None, *
     r = q.qrepo()
     if r:
         wlock = r.wlock()
-        if r.dirstate.state(name) == 'r':
+        if r.dirstate[name] == 'r':
             r.undelete([name], wlock)
         r.copy(patch, name, wlock)
         r.remove([patch], False, wlock)
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -638,12 +638,12 @@ def addremove(repo, pats=[], opts={}, wl
     mapping = {}
     for src, abs, rel, exact in walk(repo, pats, opts):
         target = repo.wjoin(abs)
-        if src == 'f' and repo.dirstate.state(abs) == '?':
+        if src == 'f' and abs not in repo.dirstate:
             add.append(abs)
             mapping[abs] = rel, exact
             if repo.ui.verbose or not exact:
                 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
-        if repo.dirstate.state(abs) != 'r' and not util.lexists(target):
+        if repo.dirstate[abs] != 'r' and not util.lexists(target):
             remove.append(abs)
             mapping[abs] = rel, exact
             if repo.ui.verbose or not exact:
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -33,7 +33,7 @@ def add(ui, repo, *pats, **opts):
             if ui.verbose:
                 ui.status(_('adding %s\n') % rel)
             names.append(abs)
-        elif repo.dirstate.state(abs) == '?':
+        elif abs not in repo.dirstate:
             ui.status(_('adding %s\n') % rel)
             names.append(abs)
     if not opts.get('dry_run'):
@@ -456,7 +456,7 @@ def commit(ui, repo, *pats, **opts):
                 elif not (stat.S_ISREG(mode) or stat.S_ISLNK(mode)):
                     raise util.Abort(_("can't commit %s: "
                                        "unsupported file type!") % rf)
-                elif repo.dirstate.state(f) == '?':
+                elif f not in repo.dirstate:
                     raise util.Abort(_("file %s not tracked!") % rf)
     else:
         files = []
@@ -482,7 +482,7 @@ def docopy(ui, repo, pats, opts, wlock):
     def okaytocopy(abs, rel, exact):
         reasons = {'?': _('is not managed'),
                    'r': _('has been marked for remove')}
-        state = repo.dirstate.state(abs)
+        state = repo.dirstate[abs]
         reason = reasons.get(state)
         if reason:
             if exact:
@@ -510,7 +510,7 @@ def docopy(ui, repo, pats, opts, wlock):
                      repo.pathto(prevsrc, cwd)))
             return
         if (not opts['after'] and os.path.exists(target) or
-            opts['after'] and repo.dirstate.state(abstarget) not in '?ar'):
+            opts['after'] and repo.dirstate[abstarget] in 'mn'):
             if not opts['force']:
                 ui.warn(_('%s: not overwriting - file exists\n') %
                         reltarget)
@@ -525,7 +525,7 @@ def docopy(ui, repo, pats, opts, wlock):
             if not os.path.isdir(targetdir) and not opts.get('dry_run'):
                 os.makedirs(targetdir)
             try:
-                restore = repo.dirstate.state(abstarget) == 'r'
+                restore = repo.dirstate[abstarget] == 'r'
                 if restore and not opts.get('dry_run'):
                     repo.undelete([abstarget], wlock)
                 try:
@@ -547,7 +547,7 @@ def docopy(ui, repo, pats, opts, wlock):
             ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
         targets[abstarget] = abssrc
         if abstarget != origsrc:
-            if repo.dirstate.state(origsrc) == 'a':
+            if repo.dirstate[origsrc] == 'a':
                 if not ui.quiet:
                     ui.warn(_("%s has not been committed yet, so no copy "
                               "data will be stored for %s.\n")
@@ -718,12 +718,11 @@ def debugrebuildstate(ui, repo, rev=""):
 def debugcheckstate(ui, repo):
     """validate the correctness of the current dirstate"""
     parent1, parent2 = repo.dirstate.parents()
-    dc = repo.dirstate
     m1 = repo.changectx(parent1).manifest()
     m2 = repo.changectx(parent2).manifest()
     errors = 0
-    for f in dc:
-        state = repo.dirstate.state(f)
+    for f in repo.dirstate:
+        state = repo.dirstate[f]
         if state in "nr" and f not in m1:
             ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
             errors += 1
@@ -735,7 +734,7 @@ def debugcheckstate(ui, repo):
                     (f, state))
             errors += 1
     for f in m1:
-        state = repo.dirstate.state(f)
+        state = repo.dirstate[f]
         if state not in "nrm":
             ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
             errors += 1
@@ -787,8 +786,10 @@ def debugsetparents(ui, repo, rev1, rev2
 
 def debugstate(ui, repo):
     """show the contents of the current dirstate"""
-    dc = repo.dirstate
-    for file_ in dc:
+    dc = repo.dirstate._map
+    k = dc.keys()
+    k.sort()
+    for file_ in k:
         if dc[file_][3] == -1:
             # Pad or slice to locale representation
             locale_len = len(time.strftime("%x %X", time.localtime(0)))
@@ -1758,7 +1759,7 @@ def locate(ui, repo, *pats, **opts):
                                              default='relglob'):
         if src == 'b':
             continue
-        if not node and repo.dirstate.state(abs) == '?':
+        if not node and abs not in repo.dirstate:
             continue
         if opts['fullpath']:
             ui.write(os.path.join(repo.root, abs), end)
@@ -2216,7 +2217,7 @@ def remove(ui, repo, *pats, **opts):
                 forget.append(abs)
                 continue
             reason = _('has been marked for add (use -f to force removal)')
-        elif repo.dirstate.state(abs) == '?':
+        elif abs not in repo.dirstate:
             reason = _('is not managed')
         elif opts['after'] and not exact and abs not in deleted:
             continue
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -88,11 +88,14 @@ class dirstate(object):
             return path.replace(os.sep, '/')
         return path
 
-    def __del__(self):
-        self.write()
-
     def __getitem__(self, key):
-        return self._map[key]
+        ''' current states:
+        n  normal
+        m  needs merging
+        r  marked for removal
+        a  marked for addition
+        ?  not tracked'''
+        return self._map.get(key, ("?",))[0]
 
     def __contains__(self, key):
         return key in self._map
@@ -117,14 +120,6 @@ class dirstate(object):
         self._branch = branch
         self._opener("branch", "w").write(branch + '\n')
 
-    def state(self, key):
-        ''' current states:
-        n  normal
-        m  needs merging
-        r  marked for removal
-        a  marked for addition'''
-        return self._map.get(key, ("?",))[0]
-
     def _read(self):
         self._map = {}
         self._copymap = {}
@@ -460,7 +455,7 @@ class dirstate(object):
 
         for src, fn, st in self.statwalk(files, match, ignored=list_ignored):
             try:
-                type_, mode, size, time = self[fn]
+                type_, mode, size, time = self._map[fn]
             except KeyError:
                 if list_ignored and self._ignore(fn):
                     ignored.append(fn)
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -125,7 +125,7 @@ class localrepository(repo.repository):
             fp.write('%s %s\n' % (hex(node), munge and munge(name) or name))
             fp.close()
             self.hook('tag', node=hex(node), tag=name, local=local)
-            
+
         prevtags = ''
         if local:
             try:
@@ -156,7 +156,7 @@ class localrepository(repo.repository):
         # committed tags are stored in UTF-8
         writetag(fp, name, util.fromlocal, prevtags)
 
-        if use_dirstate and self.dirstate.state('.hgtags') == '?':
+        if use_dirstate and '.hgtags' not in self.dirstate:
             self.add(['.hgtags'])
 
         tagnode = self.commit(['.hgtags'], message, user, date, p1=parent,
@@ -651,8 +651,8 @@ class localrepository(repo.repository):
         if use_dirstate:
             if files:
                 for f in files:
-                    s = self.dirstate.state(f)
-                    if s in 'nmai':
+                    s = self.dirstate[f]
+                    if s in 'nma':
                         commit.append(f)
                     elif s == 'r':
                         remove.append(f)
@@ -970,7 +970,7 @@ class localrepository(repo.repository):
             if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)):
                 self.ui.warn(_("%s not added: only files and symlinks "
                                "supported currently\n") % f)
-            elif self.dirstate.state(f) in 'an':
+            elif self.dirstate[f] in 'an':
                 self.ui.warn(_("%s already tracked!\n") % f)
             else:
                 self.dirstate.add(f)
@@ -979,7 +979,7 @@ class localrepository(repo.repository):
         if not wlock:
             wlock = self.wlock()
         for f in list:
-            if self.dirstate.state(f) not in 'ai':
+            if self.dirstate[f] != 'a':
                 self.ui.warn(_("%s not added!\n") % f)
             else:
                 self.dirstate.forget(f)
@@ -997,7 +997,7 @@ class localrepository(repo.repository):
         for f in list:
             if unlink and os.path.exists(self.wjoin(f)):
                 self.ui.warn(_("%s still exists!\n") % f)
-            elif self.dirstate.state(f) == 'a':
+            elif self.dirstate[f] == 'a':
                 self.dirstate.forget(f)
             elif f not in self.dirstate:
                 self.ui.warn(_("%s not tracked!\n") % f)
@@ -1011,7 +1011,7 @@ class localrepository(repo.repository):
         if not wlock:
             wlock = self.wlock()
         for f in list:
-            if self.dirstate.state(f) not in  "r":
+            if self.dirstate[f] != 'r':
                 self.ui.warn("%s not removed!\n" % f)
             else:
                 t = self.file(f).read(m[f])
@@ -1028,7 +1028,7 @@ class localrepository(repo.repository):
         else:
             if not wlock:
                 wlock = self.wlock()
-            if self.dirstate.state(dest) == '?':
+            if dest not in self.dirstate:
                 self.dirstate.add(dest)
             self.dirstate.copy(source, dest)