Skip to content

Instantly share code, notes, and snippets.

@AdarshGrewal
Created August 18, 2023 17:46
Show Gist options
  • Select an option

  • Save AdarshGrewal/27cc913dfb90bc1ceca4032add5aa347 to your computer and use it in GitHub Desktop.

Select an option

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
#!/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