switch to using GitPython
authorFrédéric Péters <fpeters@0d.be>
Fri, 3 Sep 2021 17:01:43 +0000 (19:01 +0200)
committerFrédéric Péters <fpeters@0d.be>
Fri, 3 Sep 2021 17:02:04 +0000 (19:02 +0200)
git-acab

index 0a65146..b2f0af4 100755 (executable)
--- a/git-acab
+++ b/git-acab
@@ -3,10 +3,12 @@
 # amending the commit with a new date.
 
 import argparse
-import subprocess
+import os
 import sys
 import time
 
+import git
+
 parser = argparse.ArgumentParser()
 parser.add_argument('--start', type=str, default='commit', help='now or commit')
 parser.add_argument('--prefix', action='store_true')
@@ -14,55 +16,62 @@ parser.add_argument('--suffix', action='store_true')
 parser.add_argument('-q', '--quiet', action='store_true')
 args = parser.parse_args()
 
+while not os.path.exists('.git'):
+    os.chdir('..')
+    if os.getcwd() == '/':
+        sys.stderr('failed to find a git repository')
+        sys.exit(1)
+
+
+def amend_commit(repo, initial_commit, start_timestamp):
+    t0 = time.time()
+    counter = 0
+    authored_timestamp = start_timestamp
+    while True:
+        authored_timestamp -= 1
+        for committed_timestamp in range(start_timestamp, authored_timestamp, -1):
+            counter += 1
+            if counter % 10000 == 0:
+                repo.git.prune()
+            if not args.quiet:
+                print(
+                    '%5d - %s - %s - [%s:%02d]'
+                    % (
+                        counter,
+                        time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(authored_timestamp)),
+                        time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(committed_timestamp)),
+                        int((time.time() - t0) // 60),
+                        int((time.time() - t0) % 60),
+                    ),
+                    end='\r',
+                )
+
+            commit = initial_commit.replace(
+                authored_date=authored_timestamp, committed_date=committed_timestamp
+            )
+            if args.prefix and not commit.hexsha.startswith('acab'):
+                continue
+            if args.suffix and not commit.hexsha.endswith('acab'):
+                continue
+            if 'acab' not in commit.hexsha:
+                continue
+            repo.active_branch.set_commit(commit)
+            repo.git.prune()
+            return commit
+
+
+repo = git.Repo()
+commit = repo.commit('HEAD')
+
 if args.start == 'commit':
-    p = subprocess.run(['git', 'show', '--format=format:%at'], capture_output=True)
-    timestamp = int(p.stdout[: p.stdout.index(b'\n')])
+    start_timestamp = commit.authored_date
 elif args.start == 'now':
-    timestamp = int(time.time())
+    start_timestamp = int(time.time())
 else:
     sys.stderr('unknown value for --start')
     sys.exit(1)
 
-t0 = time.time()
-counter = 0
-direction = -1
-while True:
-    counter += 1
-    timestamp += direction
-    if counter % 3600 == 0:
-        # don't move more than one hour in the past, going back to initial time
-        # will give new commit hashes as the commit date (not author date) will
-        # be different.
-        direction = - direction
-    if not args.quiet:
-        print(
-            '%5d - %s - [%s:%02d]'
-            % (
-                counter,
-                time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp)),
-                int((time.time() - t0) // 60),
-                int((time.time() - t0) % 60),
-            ),
-            end='\r',
-        )
-    p = subprocess.run(
-        [
-            'git',
-            'commit',
-            '--no-verify',
-            '--amend',
-            '--no-edit',
-            '--date=%s' % time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp)),
-        ],
-        capture_output=True,
-    )
-    p = subprocess.run(['git', 'rev-parse', 'HEAD'], capture_output=True)
-    if args.prefix and not p.stdout.startswith(b'acab'):
-        continue
-    if args.suffix and not p.stdout.strip().endswith(b'acab'):
-        continue
-    if b'acab' in p.stdout:
-        break
+new_head = amend_commit(repo, commit, start_timestamp)
 
 if not args.quiet:
-    print('\ngot %s 🔥🚓' % p.stdout.decode().strip())
+    print('\ngot %s 🔥🚓' % new_head.hexsha)