Created
August 18, 2023 17:46
-
-
Save AdarshGrewal/27cc913dfb90bc1ceca4032add5aa347 to your computer and use it in GitHub Desktop.
a script to find closest matching commit to HEAD,mostly inspired from best-caf-kernel.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| from __future__ import print_function | |
| import sys | |
| import time | |
| from multiprocessing import Event, Pool, Process, Queue | |
| from subprocess import PIPE, Popen | |
| try: | |
| from Queue import Empty as Queue_Empty | |
| except ImportError: | |
| from queue import Empty as Queue_Empty | |
| def run_subprocess(cmd): | |
| sp = Popen(cmd, stdout=PIPE, stderr=PIPE, | |
| shell=True, universal_newlines=True) | |
| comm = sp.communicate() | |
| exit_code = sp.returncode | |
| if exit_code != 0: | |
| print("There was an error running the subprocess.\n" | |
| "cmd: %s\n" | |
| "exit code: %d\n" | |
| "stdout: %s\n" | |
| "stderr: %s" % (cmd, exit_code, comm[0], comm[1])) | |
| return comm | |
| def get_commit_hashes(limit): | |
| cmd = "git rev-list -n %d HEAD" % (limit + 1) # Include 1 more commit than needed | |
| comm = run_subprocess(cmd) | |
| commit_hashes = comm[0].strip("\n").split("\n") | |
| # Exclude the first commit hash which is the HEAD itself | |
| return commit_hashes[1:] | |
| def get_total_changes(commit_hash): | |
| cmd = "git diff %s --shortstat" % commit_hash | |
| comm = run_subprocess(cmd) | |
| try: | |
| a, d = comm[0].split(",")[1:] | |
| a = int(a.strip().split()[0]) | |
| d = int(d.strip().split()[0]) | |
| except ValueError: | |
| total = None | |
| else: | |
| total = a + d | |
| return total | |
| def worker(commit_hash): | |
| tc = get_total_changes(commit_hash) | |
| worker.q.put((commit_hash, tc)) | |
| def worker_init(q): | |
| worker.q = q | |
| def background(q, e, s): | |
| closest_matches = [] | |
| while True: | |
| try: | |
| ch, tc = q.get(False) | |
| except Queue_Empty: | |
| if e.is_set(): | |
| break | |
| else: | |
| if tc is None: | |
| tc = 0; | |
| if not s: | |
| print("%s has %d lines changed" % (ch, tc)) | |
| if len(closest_matches) < 10: | |
| closest_matches.append((ch, tc)) | |
| closest_matches.sort(key=lambda x: x[1]) | |
| else: | |
| if tc < closest_matches[-1][1]: | |
| closest_matches.pop() | |
| closest_matches.append((ch, tc)) | |
| closest_matches.sort(key=lambda x: x[1]) | |
| print("Closest matches:") | |
| for match in closest_matches: | |
| print("Commit Hash: %s, Lines changed: %d" % match) | |
| def main(): | |
| import argparse | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("-j", action="store", dest="jobs", default=1, type=int, | |
| metavar="N", help="number of jobs to run at once") | |
| parser.add_argument("-s", action="store_true", dest="silent", default=False, | |
| help="reduce the verbosity of the output") | |
| parser.add_argument("-n", action="store", dest="num_commits", default=10, type=int, | |
| metavar="N", help="number of commits to compare from HEAD") | |
| args = parser.parse_args() | |
| commit_hashes = get_commit_hashes(args.num_commits) | |
| if not commit_hashes: | |
| print("No commits to check. Bailing.") | |
| sys.exit(1) | |
| if not args.silent: | |
| print("number of commits to check: %d" % len(commit_hashes)) | |
| queue = Queue() | |
| event = Event() | |
| b = Process(target=background, args=(queue, event, args.silent)) | |
| b.start() | |
| pool = Pool(args.jobs, worker_init, [queue]) | |
| pool.map(worker, commit_hashes) | |
| pool.close() | |
| pool.join() | |
| event.set() | |
| b.join() | |
| if __name__ == '__main__': | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment