41
41
42
42
import argparse
43
43
import collections
44
+ import itertools
44
45
import logging
45
46
import re
46
47
import subprocess
@@ -246,7 +247,11 @@ def _load_pr_commit_mappings(
246
247
# enough for the 99% case of reverts: rarely should someone land a cleanish
247
248
# revert of a >6 month old change...
248
249
def find_reverts (
249
- git_dir : str , across_ref : str , root : str , max_pr_lookback : int = 20000
250
+ git_dir : str ,
251
+ across_ref : str ,
252
+ root : str ,
253
+ max_pr_lookback : int = 20000 ,
254
+ stop_at_sha : Optional [str ] = None ,
250
255
) -> List [Revert ]:
251
256
"""Finds reverts across `across_ref` in `git_dir`, starting from `root`.
252
257
@@ -260,6 +265,9 @@ def find_reverts(
260
265
SHAs. These heuristics require that commit history from `root` to
261
266
`some_parent_of_root` is loaded in memory. `max_pr_lookback` is how
262
267
many commits behind `across_ref` should be loaded in memory.
268
+ stop_at_sha: If non-None and `stop_at_sha` is encountered while walking
269
+ to `across_ref` from `root`, stop checking for reverts. This allows for
270
+ faster incremental checking between `find_reverts` calls.
263
271
"""
264
272
across_sha = _rev_parse (git_dir , across_ref )
265
273
root_sha = _rev_parse (git_dir , root )
@@ -281,10 +289,16 @@ def find_reverts(
281
289
root_sha ,
282
290
)
283
291
292
+ commit_log_stream : Iterable [_LogEntry ] = _log_stream (git_dir , root_sha , across_sha )
293
+ if stop_at_sha :
294
+ commit_log_stream = itertools .takewhile (
295
+ lambda x : x .sha != stop_at_sha , commit_log_stream
296
+ )
297
+
284
298
all_reverts = []
285
299
# Lazily load PR <-> commit mappings, since it can be expensive.
286
300
pr_commit_mappings = None
287
- for sha , commit_message in _log_stream ( git_dir , root_sha , across_sha ) :
301
+ for sha , commit_message in commit_log_stream :
288
302
reverts , pr_reverts = _try_parse_reverts_from_commit_message (
289
303
commit_message ,
290
304
)
0 commit comments