]> git.0d.be Git - git-acab.git/blob - git-acab
rate limit progress messages
[git-acab.git] / git-acab
1 #! /usr/bin/python3
2 # amend HEAD commit to contain acab in its hash, it does so by repeatedly
3 # amending the commit with a new date.
4
5 import argparse
6 import hashlib
7 import os
8 import subprocess
9 import sys
10 import time
11
12 parser = argparse.ArgumentParser()
13 parser.add_argument('--start', type=str, default='commit', help='now or commit')
14 parser.add_argument('--prefix', action='store_true')
15 parser.add_argument('--suffix', action='store_true')
16 parser.add_argument('-q', '--quiet', action='store_true')
17 args = parser.parse_args()
18
19
20 def amend_commit(start_timestamp):
21     t0 = time.time()
22     counter = 0
23     cat_file = subprocess.run(['git', 'cat-file', 'commit', 'HEAD'], capture_output=True).stdout
24     cat_file_lines = cat_file.splitlines()
25     cat_file_lines[2] = cat_file_lines[2].replace(cat_file_lines[2].rsplit(b' ', 2)[1], b'$AUTHOR__$')
26     cat_file_lines[3] = cat_file_lines[3].replace(cat_file_lines[3].rsplit(b' ', 2)[1], b'$COMMITER$')
27     hashed_bytes_template = b'commit %s\0%s\n' % (
28         str(len(b'\n'.join(cat_file_lines)) + 1).encode(),
29         b'\n'.join(cat_file_lines),
30     )
31     authored_timestamp = start_timestamp
32     base_env = os.environ
33     last_print = 0
34     while True:
35         authored_timestamp -= 1
36         for committed_timestamp in range(start_timestamp, authored_timestamp, -1):
37             counter += 1
38             if not args.quiet and time.time() - last_print > 0.05:
39                 last_print = time.time()
40                 print(
41                     '%5d - %s - %s - [%s:%02d]'
42                     % (
43                         counter,
44                         time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(authored_timestamp)),
45                         time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(committed_timestamp)),
46                         int((time.time() - t0) // 60),
47                         int((time.time() - t0) % 60),
48                     ),
49                     end='\r',
50                 )
51
52             hashed_bytes = hashed_bytes_template.replace(
53                 b'$AUTHOR__$', str(authored_timestamp).encode()
54             ).replace(b'$COMMITER$', str(committed_timestamp).encode())
55             new_hash = hashlib.sha1(hashed_bytes).hexdigest()
56             if args.prefix and not new_hash.startswith('acab'):
57                 continue
58             if args.suffix and not new_hash.endswith('acab'):
59                 continue
60             if 'acab' not in new_hash:
61                 continue
62             base_env['GIT_COMMITTER_DATE'] = time.strftime(
63                 '%Y-%m-%d %H:%M:%S', time.localtime(committed_timestamp)
64             )
65             subprocess.run(
66                 [
67                     'git',
68                     'commit',
69                     '--no-verify',
70                     '--amend',
71                     '--no-edit',
72                     '--date=%s' % time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(authored_timestamp)),
73                 ],
74                 capture_output=True,
75                 env=base_env,
76             )
77             return
78
79
80 if args.start == 'commit':
81     p = subprocess.run(['git', 'show', '--format=format:%at'], capture_output=True)
82     start_timestamp = int(p.stdout[: p.stdout.index(b'\n')])
83 elif args.start == 'now':
84     start_timestamp = int(time.time())
85 else:
86     sys.stderr('unknown value for --start')
87     sys.exit(1)
88
89 amend_commit(start_timestamp)
90
91 if not args.quiet:
92     p = subprocess.run(['git', 'rev-parse', 'HEAD'], capture_output=True)
93     print('\ngot %s ðŸ”¥ðŸš“' % p.stdout.decode().strip())