##// END OF EJS Templates
log: move log file walk to its own function...
Durham Goode -
r19290:f21f4a1b default
parent child Browse files
Show More
@@ -1005,6 +1005,107 b' def increasingwindows(start, end, window'
1005 if windowsize < sizelimit:
1005 if windowsize < sizelimit:
1006 windowsize *= 2
1006 windowsize *= 2
1007
1007
1008 class FileWalkError(Exception):
1009 pass
1010
1011 def walkfilerevs(repo, match, follow, revs, fncache):
1012 '''Walks the file history for the matched files.
1013
1014 Returns the changeset revs that are involved in the file history.
1015
1016 Throws FileWalkError if the file history can't be walked using
1017 filelogs alone.
1018 '''
1019 wanted = set()
1020 copies = []
1021 minrev, maxrev = min(revs), max(revs)
1022 def filerevgen(filelog, last):
1023 """
1024 Only files, no patterns. Check the history of each file.
1025
1026 Examines filelog entries within minrev, maxrev linkrev range
1027 Returns an iterator yielding (linkrev, parentlinkrevs, copied)
1028 tuples in backwards order
1029 """
1030 cl_count = len(repo)
1031 revs = []
1032 for j in xrange(0, last + 1):
1033 linkrev = filelog.linkrev(j)
1034 if linkrev < minrev:
1035 continue
1036 # only yield rev for which we have the changelog, it can
1037 # happen while doing "hg log" during a pull or commit
1038 if linkrev >= cl_count:
1039 break
1040
1041 parentlinkrevs = []
1042 for p in filelog.parentrevs(j):
1043 if p != nullrev:
1044 parentlinkrevs.append(filelog.linkrev(p))
1045 n = filelog.node(j)
1046 revs.append((linkrev, parentlinkrevs,
1047 follow and filelog.renamed(n)))
1048
1049 return reversed(revs)
1050 def iterfiles():
1051 pctx = repo['.']
1052 for filename in match.files():
1053 if follow:
1054 if filename not in pctx:
1055 raise util.Abort(_('cannot follow file not in parent '
1056 'revision: "%s"') % filename)
1057 yield filename, pctx[filename].filenode()
1058 else:
1059 yield filename, None
1060 for filename_node in copies:
1061 yield filename_node
1062
1063 for file_, node in iterfiles():
1064 filelog = repo.file(file_)
1065 if not len(filelog):
1066 if node is None:
1067 # A zero count may be a directory or deleted file, so
1068 # try to find matching entries on the slow path.
1069 if follow:
1070 raise util.Abort(
1071 _('cannot follow nonexistent file: "%s"') % file_)
1072 raise FileWalkError("Cannot walk via filelog")
1073 else:
1074 continue
1075
1076 if node is None:
1077 last = len(filelog) - 1
1078 else:
1079 last = filelog.rev(node)
1080
1081
1082 # keep track of all ancestors of the file
1083 ancestors = set([filelog.linkrev(last)])
1084
1085 # iterate from latest to oldest revision
1086 for rev, flparentlinkrevs, copied in filerevgen(filelog, last):
1087 if not follow:
1088 if rev > maxrev:
1089 continue
1090 else:
1091 # Note that last might not be the first interesting
1092 # rev to us:
1093 # if the file has been changed after maxrev, we'll
1094 # have linkrev(last) > maxrev, and we still need
1095 # to explore the file graph
1096 if rev not in ancestors:
1097 continue
1098 # XXX insert 1327 fix here
1099 if flparentlinkrevs:
1100 ancestors.update(flparentlinkrevs)
1101
1102 fncache.setdefault(rev, []).append(file_)
1103 wanted.add(rev)
1104 if copied:
1105 copies.append(copied)
1106
1107 return wanted
1108
1008 def walkchangerevs(repo, match, opts, prepare):
1109 def walkchangerevs(repo, match, opts, prepare):
1009 '''Iterate over files and the revs in which they changed.
1110 '''Iterate over files and the revs in which they changed.
1010
1111
@@ -1044,101 +1145,18 b' def walkchangerevs(repo, match, opts, pr'
1044 if not slowpath and not match.files():
1145 if not slowpath and not match.files():
1045 # No files, no patterns. Display all revs.
1146 # No files, no patterns. Display all revs.
1046 wanted = set(revs)
1147 wanted = set(revs)
1047 copies = []
1048
1148
1049 if not slowpath and match.files():
1149 if not slowpath and match.files():
1050 # We only have to read through the filelog to find wanted revisions
1150 # We only have to read through the filelog to find wanted revisions
1051
1151
1052 minrev, maxrev = min(revs), max(revs)
1152 try:
1053 def filerevgen(filelog, last):
1153 wanted = walkfilerevs(repo, match, follow, revs, fncache)
1054 """
1154 except FileWalkError:
1055 Only files, no patterns. Check the history of each file.
1155 slowpath = True
1056
1057 Examines filelog entries within minrev, maxrev linkrev range
1058 Returns an iterator yielding (linkrev, parentlinkrevs, copied)
1059 tuples in backwards order
1060 """
1061 cl_count = len(repo)
1062 revs = []
1063 for j in xrange(0, last + 1):
1064 linkrev = filelog.linkrev(j)
1065 if linkrev < minrev:
1066 continue
1067 # only yield rev for which we have the changelog, it can
1068 # happen while doing "hg log" during a pull or commit
1069 if linkrev >= cl_count:
1070 break
1071
1072 parentlinkrevs = []
1073 for p in filelog.parentrevs(j):
1074 if p != nullrev:
1075 parentlinkrevs.append(filelog.linkrev(p))
1076 n = filelog.node(j)
1077 revs.append((linkrev, parentlinkrevs,
1078 follow and filelog.renamed(n)))
1079
1156
1080 return reversed(revs)
1157 # We decided to fall back to the slowpath because at least one
1081 def iterfiles():
1158 # of the paths was not a file. Check to see if at least one of them
1082 pctx = repo['.']
1159 # existed in history, otherwise simply return
1083 for filename in match.files():
1084 if follow:
1085 if filename not in pctx:
1086 raise util.Abort(_('cannot follow file not in parent '
1087 'revision: "%s"') % filename)
1088 yield filename, pctx[filename].filenode()
1089 else:
1090 yield filename, None
1091 for filename_node in copies:
1092 yield filename_node
1093 for file_, node in iterfiles():
1094 filelog = repo.file(file_)
1095 if not len(filelog):
1096 if node is None:
1097 # A zero count may be a directory or deleted file, so
1098 # try to find matching entries on the slow path.
1099 if follow:
1100 raise util.Abort(
1101 _('cannot follow nonexistent file: "%s"') % file_)
1102 slowpath = True
1103 break
1104 else:
1105 continue
1106
1107 if node is None:
1108 last = len(filelog) - 1
1109 else:
1110 last = filelog.rev(node)
1111
1112
1113 # keep track of all ancestors of the file
1114 ancestors = set([filelog.linkrev(last)])
1115
1116 # iterate from latest to oldest revision
1117 for rev, flparentlinkrevs, copied in filerevgen(filelog, last):
1118 if not follow:
1119 if rev > maxrev:
1120 continue
1121 else:
1122 # Note that last might not be the first interesting
1123 # rev to us:
1124 # if the file has been changed after maxrev, we'll
1125 # have linkrev(last) > maxrev, and we still need
1126 # to explore the file graph
1127 if rev not in ancestors:
1128 continue
1129 # XXX insert 1327 fix here
1130 if flparentlinkrevs:
1131 ancestors.update(flparentlinkrevs)
1132
1133 fncache.setdefault(rev, []).append(file_)
1134 wanted.add(rev)
1135 if copied:
1136 copies.append(copied)
1137
1138 # We decided to fall back to the slowpath because at least one
1139 # of the paths was not a file. Check to see if at least one of them
1140 # existed in history, otherwise simply return
1141 if slowpath:
1142 for path in match.files():
1160 for path in match.files():
1143 if path == '.' or path in repo.store:
1161 if path == '.' or path in repo.store:
1144 break
1162 break
General Comments 0
You need to be logged in to leave comments. Login now