diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -943,7 +943,7 @@ class localrepository(repo.repository): ''' return self[node].walk(match) - def status(self, node1=None, node2=None, match=None, + def status(self, node1='.', node2=None, match=None, ignored=False, clean=False, unknown=False): """return status of files between two nodes or node and working directory @@ -951,14 +951,9 @@ class localrepository(repo.repository): If node2 is None, compare node1 with working directory. """ - def fcmp(fn, getnode): - t1 = self.wread(fn) - return self.file(fn).cmp(getnode(fn), t1) - - def mfmatches(node): - change = self.changelog.read(node) - mf = self.manifest.read(change[0]).copy() - for fn in mf.keys(): + def mfmatches(ctx): + mf = ctx.manifest().copy() + for fn in mf: if not match(fn): del mf[fn] return mf @@ -966,35 +961,34 @@ class localrepository(repo.repository): if not match: match = match_.always(self.root, self.getcwd()) + ctx1 = self[node1] + ctx2 = self[node2] + working = ctx2 == self[None] + parentworking = working and ctx1 == self['.'] + listignored, listclean, listunknown = ignored, clean, unknown modified, added, removed, deleted, unknown = [], [], [], [], [] ignored, clean = [], [] - compareworking = False - if not node1 or (not node2 and node1 == self.dirstate.parents()[0]): - compareworking = True - - if not compareworking: + if not parentworking: # read the manifest from node1 before the manifest from node2, # so that we'll hit the manifest cache if we're going through # all the revisions in parent->child order. - mf1 = mfmatches(node1) + mf1 = mfmatches(ctx1) # are we comparing the working directory? - if not node2: + if working: (lookup, modified, added, removed, deleted, unknown, ignored, clean) = self.dirstate.status(match, listignored, listclean, listunknown) # are we comparing working dir against its parent? - if compareworking: + if parentworking: if lookup: fixup = [] # do a full compare of any files that might have changed - ctx = self['.'] - ff = self.dirstate.flagfunc(ctx.flags) for f in lookup: - if (f not in ctx or ff(f) != ctx.flags(f) - or ctx[f].cmp(self.wread(f))): + if (f not in ctx1 or ctx2.flags(f) != ctx1.flags(f) + or ctx1[f].cmp(ctx2[f].read())): modified.append(f) else: fixup.append(f) @@ -1018,31 +1012,28 @@ class localrepository(repo.repository): # we are comparing working dir against non-parent # generate a pseudo-manifest for the working dir # XXX: create it in dirstate.py ? - mf2 = mfmatches(self.dirstate.parents()[0]) - ff = self.dirstate.flagfunc(mf2.flags) + mf2 = mfmatches(self['.']) for f in lookup + modified + added: - mf2[f] = "" - mf2.set(f, ff(f)) + mf2[f] = None + mf2.set(f, ctx2.flags(f)) for f in removed: if f in mf2: del mf2[f] - else: # we are comparing two revisions - mf2 = mfmatches(node2) + mf2 = mfmatches(ctx2) - if not compareworking: + if not parentworking: # flush lists from dirstate before comparing manifests modified, added, clean = [], [], [] # make sure to sort the files so we talk to the disk in a # reasonable order - getnode = lambda fn: mf1.get(fn, nullid) for fn in util.sort(mf2): if fn in mf1: if (mf1.flags(fn) != mf2.flags(fn) or (mf1[fn] != mf2[fn] and - (mf2[fn] != "" or fcmp(fn, getnode)))): + (mf2[fn] or ctx1[f].cmp(ctx2[f].read())))): modified.append(fn) elif listclean: clean.append(fn)