4141
4242import argparse
4343import collections
44+ import itertools
4445import logging
4546import re
4647import subprocess
@@ -246,7 +247,11 @@ def _load_pr_commit_mappings(
246247# enough for the 99% case of reverts: rarely should someone land a cleanish
247248# revert of a >6 month old change...
248249def 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 ,
250255) -> List [Revert ]:
251256 """Finds reverts across `across_ref` in `git_dir`, starting from `root`.
252257
@@ -260,6 +265,9 @@ def find_reverts(
260265 SHAs. These heuristics require that commit history from `root` to
261266 `some_parent_of_root` is loaded in memory. `max_pr_lookback` is how
262267 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.
263271 """
264272 across_sha = _rev_parse (git_dir , across_ref )
265273 root_sha = _rev_parse (git_dir , root )
@@ -281,10 +289,16 @@ def find_reverts(
281289 root_sha ,
282290 )
283291
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+
284298 all_reverts = []
285299 # Lazily load PR <-> commit mappings, since it can be expensive.
286300 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 :
288302 reverts , pr_reverts = _try_parse_reverts_from_commit_message (
289303 commit_message ,
290304 )
0 commit comments