"""compare commits of logs in different branches selecting the time range is based on file 'sync_branches' which should be in the branch where logdif.py is running """ import sys from subprocess import check_output branches = sys.argv[1:3] commits = {} log_no = {} cursor = {} short_set = set() if len(sys.argv) < 3: print('Usage: python3 logdif.py []') sys.exit(0) if len(sys.argv) > 3: since = sys.argv[3] else: since_info = [] with open("sync_branches") as f: # a file containing # YYYY-mm-dd # for each date the branches are synced for line in f: if line.strip(): info = line.split() if set(branches) & set(info[1:3]) == set(branches): since_info.append(info[0]) since = sorted(since_info)[-1] if since_info else None gitlog = ['git', 'log', '--oneline'] if since: gitlog.append(f'--since-as-filter={since}') else: print(f'no info for {branches} found in file sync_branches') for br in branches: cursor[br] = 0 # collect hashes of commis newer than since short_output = check_output(gitlog + [br]) for line in short_output.decode('utf-8').split('\n'): if line: short_set.add(line.split(' ', 1)[0]) output = check_output(gitlog[:3] + [br]) log_no[br] = byno = [] no = 0 for line in output.decode('utf-8').split('\n'): if line: commit, title = line.split(' ', 1) byno.append([commit, title]) no += 1 # find matches for br, byno in log_no.items(): for no, line in enumerate(byno): commits.setdefault(line[1], {}).setdefault(br, []).append((no, line)) ordered = {} for title, info in commits.items(): # sort the info dict by value ordered[title] = {b: v for v, b in sorted((v, b) for b, v in info.items())} commits = ordered cnt = [0] def print_commit(line): if not line[1]: return # title cleared: this line is already printed # print and mark line as already printed info = commits[line[1]] output = [] title = line[1] visible = False for br in log_no: infolist = info.get(br) if infolist: no, iline = infolist.pop(0) if not infolist: info.pop(br) if iline[0] in short_set: visible = True output.append(f'{no:3}:{iline[0]}') iline[1] = '' # clear title else: output.append(' ' * 11) if visible: print(' '.join(output), title) cnt[0] += 1 if cnt[0] % 50 == 0: input(f' {br0:11s} {br1:11s}') (br0, log0), (br1, log1) = list(log_no.items()) no1 = 0 for no0, line0 in enumerate(log0): if line0[1]: # line not yet printed infodict = commits[line0[1]] if len(infodict) > 1: # found a match info0 = infodict[br1] # loop over commits in br1 until matched no no1end = info0[0][0] if no1end > no0: for n in range(no0, no1end): line1 = log1[n] print_commit(line1) no1 = no1end print_commit(line0)