Show More
@@ -1005,6 +1005,107 b' def increasingwindows(start, end, window' | |||
|
1005 | 1005 | if windowsize < sizelimit: |
|
1006 | 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 | 1109 | def walkchangerevs(repo, match, opts, prepare): |
|
1009 | 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 | 1145 | if not slowpath and not match.files(): |
|
1045 | 1146 | # No files, no patterns. Display all revs. |
|
1046 | 1147 | wanted = set(revs) |
|
1047 | copies = [] | |
|
1048 | 1148 | |
|
1049 | 1149 | if not slowpath and match.files(): |
|
1050 | 1150 | # We only have to read through the filelog to find wanted revisions |
|
1051 | 1151 | |
|
1052 | minrev, maxrev = min(revs), max(revs) | |
|
1053 | def filerevgen(filelog, last): | |
|
1054 | """ | |
|
1055 | Only files, no patterns. Check the history of each file. | |
|
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))) | |
|
1152 | try: | |
|
1153 | wanted = walkfilerevs(repo, match, follow, revs, fncache) | |
|
1154 | except FileWalkError: | |
|
1155 | slowpath = True | |
|
1079 | 1156 | |
|
1080 | return reversed(revs) | |
|
1081 | def iterfiles(): | |
|
1082 | pctx = repo['.'] | |
|
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: | |
|
1157 | # We decided to fall back to the slowpath because at least one | |
|
1158 | # of the paths was not a file. Check to see if at least one of them | |
|
1159 | # existed in history, otherwise simply return | |
|
1142 | 1160 | for path in match.files(): |
|
1143 | 1161 | if path == '.' or path in repo.store: |
|
1144 | 1162 | break |
General Comments 0
You need to be logged in to leave comments.
Login now