comparison mercurial/localrepo.py @ 6769:97c12b1ed1e0

status: use contexts
author Matt Mackall <mpm@selenic.com>
date Fri, 11 Jul 2008 18:46:02 -0500
parents 8db64464d136
children 854b907527e5
comparison
equal deleted inserted replaced
6768:e3bb005373b1 6769:97c12b1ed1e0
941 changeset, finding all files matched by the match 941 changeset, finding all files matched by the match
942 function 942 function
943 ''' 943 '''
944 return self[node].walk(match) 944 return self[node].walk(match)
945 945
946 def status(self, node1=None, node2=None, match=None, 946 def status(self, node1='.', node2=None, match=None,
947 ignored=False, clean=False, unknown=False): 947 ignored=False, clean=False, unknown=False):
948 """return status of files between two nodes or node and working directory 948 """return status of files between two nodes or node and working directory
949 949
950 If node1 is None, use the first dirstate parent instead. 950 If node1 is None, use the first dirstate parent instead.
951 If node2 is None, compare node1 with working directory. 951 If node2 is None, compare node1 with working directory.
952 """ 952 """
953 953
954 def fcmp(fn, getnode): 954 def mfmatches(ctx):
955 t1 = self.wread(fn) 955 mf = ctx.manifest().copy()
956 return self.file(fn).cmp(getnode(fn), t1) 956 for fn in mf:
957
958 def mfmatches(node):
959 change = self.changelog.read(node)
960 mf = self.manifest.read(change[0]).copy()
961 for fn in mf.keys():
962 if not match(fn): 957 if not match(fn):
963 del mf[fn] 958 del mf[fn]
964 return mf 959 return mf
965 960
966 if not match: 961 if not match:
967 match = match_.always(self.root, self.getcwd()) 962 match = match_.always(self.root, self.getcwd())
968 963
964 ctx1 = self[node1]
965 ctx2 = self[node2]
966 working = ctx2 == self[None]
967 parentworking = working and ctx1 == self['.']
968
969 listignored, listclean, listunknown = ignored, clean, unknown 969 listignored, listclean, listunknown = ignored, clean, unknown
970 modified, added, removed, deleted, unknown = [], [], [], [], [] 970 modified, added, removed, deleted, unknown = [], [], [], [], []
971 ignored, clean = [], [] 971 ignored, clean = [], []
972 972
973 compareworking = False 973 if not parentworking:
974 if not node1 or (not node2 and node1 == self.dirstate.parents()[0]):
975 compareworking = True
976
977 if not compareworking:
978 # read the manifest from node1 before the manifest from node2, 974 # read the manifest from node1 before the manifest from node2,
979 # so that we'll hit the manifest cache if we're going through 975 # so that we'll hit the manifest cache if we're going through
980 # all the revisions in parent->child order. 976 # all the revisions in parent->child order.
981 mf1 = mfmatches(node1) 977 mf1 = mfmatches(ctx1)
982 978
983 # are we comparing the working directory? 979 # are we comparing the working directory?
984 if not node2: 980 if working:
985 (lookup, modified, added, removed, deleted, unknown, 981 (lookup, modified, added, removed, deleted, unknown,
986 ignored, clean) = self.dirstate.status(match, listignored, 982 ignored, clean) = self.dirstate.status(match, listignored,
987 listclean, listunknown) 983 listclean, listunknown)
988 # are we comparing working dir against its parent? 984 # are we comparing working dir against its parent?
989 if compareworking: 985 if parentworking:
990 if lookup: 986 if lookup:
991 fixup = [] 987 fixup = []
992 # do a full compare of any files that might have changed 988 # do a full compare of any files that might have changed
993 ctx = self['.']
994 ff = self.dirstate.flagfunc(ctx.flags)
995 for f in lookup: 989 for f in lookup:
996 if (f not in ctx or ff(f) != ctx.flags(f) 990 if (f not in ctx1 or ctx2.flags(f) != ctx1.flags(f)
997 or ctx[f].cmp(self.wread(f))): 991 or ctx1[f].cmp(ctx2[f].read())):
998 modified.append(f) 992 modified.append(f)
999 else: 993 else:
1000 fixup.append(f) 994 fixup.append(f)
1001 if listclean: 995 if listclean:
1002 clean.append(f) 996 clean.append(f)
1016 del wlock 1010 del wlock
1017 else: 1011 else:
1018 # we are comparing working dir against non-parent 1012 # we are comparing working dir against non-parent
1019 # generate a pseudo-manifest for the working dir 1013 # generate a pseudo-manifest for the working dir
1020 # XXX: create it in dirstate.py ? 1014 # XXX: create it in dirstate.py ?
1021 mf2 = mfmatches(self.dirstate.parents()[0]) 1015 mf2 = mfmatches(self['.'])
1022 ff = self.dirstate.flagfunc(mf2.flags)
1023 for f in lookup + modified + added: 1016 for f in lookup + modified + added:
1024 mf2[f] = "" 1017 mf2[f] = None
1025 mf2.set(f, ff(f)) 1018 mf2.set(f, ctx2.flags(f))
1026 for f in removed: 1019 for f in removed:
1027 if f in mf2: 1020 if f in mf2:
1028 del mf2[f] 1021 del mf2[f]
1029
1030 else: 1022 else:
1031 # we are comparing two revisions 1023 # we are comparing two revisions
1032 mf2 = mfmatches(node2) 1024 mf2 = mfmatches(ctx2)
1033 1025
1034 if not compareworking: 1026 if not parentworking:
1035 # flush lists from dirstate before comparing manifests 1027 # flush lists from dirstate before comparing manifests
1036 modified, added, clean = [], [], [] 1028 modified, added, clean = [], [], []
1037 1029
1038 # make sure to sort the files so we talk to the disk in a 1030 # make sure to sort the files so we talk to the disk in a
1039 # reasonable order 1031 # reasonable order
1040 getnode = lambda fn: mf1.get(fn, nullid)
1041 for fn in util.sort(mf2): 1032 for fn in util.sort(mf2):
1042 if fn in mf1: 1033 if fn in mf1:
1043 if (mf1.flags(fn) != mf2.flags(fn) or 1034 if (mf1.flags(fn) != mf2.flags(fn) or
1044 (mf1[fn] != mf2[fn] and 1035 (mf1[fn] != mf2[fn] and
1045 (mf2[fn] != "" or fcmp(fn, getnode)))): 1036 (mf2[fn] or ctx1[f].cmp(ctx2[f].read())))):
1046 modified.append(fn) 1037 modified.append(fn)
1047 elif listclean: 1038 elif listclean:
1048 clean.append(fn) 1039 clean.append(fn)
1049 del mf1[fn] 1040 del mf1[fn]
1050 else: 1041 else: