1170 if follow: |
1170 if follow: |
1171 raise util.Abort(_('can only follow copies/renames for explicit ' |
1171 raise util.Abort(_('can only follow copies/renames for explicit ' |
1172 'filenames')) |
1172 'filenames')) |
1173 |
1173 |
1174 # The slow path checks files modified in every changeset. |
1174 # The slow path checks files modified in every changeset. |
1175 for i in sorted(revs): |
1175 # This is really slow on large repos, so compute the set lazily. |
1176 ctx = change(i) |
1176 class lazywantedset(object): |
1177 matches = filter(match, ctx.files()) |
1177 def __init__(self): |
1178 if matches: |
1178 self.set = set() |
1179 fncache[i] = matches |
1179 self.revs = set(revs) |
1180 wanted.add(i) |
1180 |
|
1181 # No need to worry about locality here because it will be accessed |
|
1182 # in the same order as the increasing window below. |
|
1183 def __contains__(self, value): |
|
1184 if value in self.set: |
|
1185 return True |
|
1186 elif not value in self.revs: |
|
1187 return False |
|
1188 else: |
|
1189 self.revs.discard(value) |
|
1190 ctx = change(value) |
|
1191 matches = filter(match, ctx.files()) |
|
1192 if matches: |
|
1193 fncache[value] = matches |
|
1194 self.set.add(value) |
|
1195 return True |
|
1196 return False |
|
1197 |
|
1198 def discard(self, value): |
|
1199 self.revs.discard(value) |
|
1200 self.set.discard(value) |
|
1201 |
|
1202 wanted = lazywantedset() |
1181 |
1203 |
1182 class followfilter(object): |
1204 class followfilter(object): |
1183 def __init__(self, onlyfirst=False): |
1205 def __init__(self, onlyfirst=False): |
1184 self.startrev = nullrev |
1206 self.startrev = nullrev |
1185 self.roots = set() |
1207 self.roots = set() |