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