# amending the commit with a new date.
import argparse
+import hashlib
import os
+import subprocess
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')
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):
+def amend_commit(start_timestamp):
t0 = time.time()
counter = 0
+ cat_file = subprocess.run(['git', 'cat-file', 'commit', 'HEAD'], capture_output=True).stdout
+ cat_file_lines = cat_file.splitlines()
+ cat_file_lines[2] = cat_file_lines[2].replace(cat_file_lines[2].rsplit(b' ', 2)[1], b'$AUTHOR__$')
+ cat_file_lines[3] = cat_file_lines[3].replace(cat_file_lines[3].rsplit(b' ', 2)[1], b'$COMMITER$')
+ hashed_bytes_template = b'commit %s\0%s\n' % (
+ str(len(b'\n'.join(cat_file_lines)) + 1).encode(),
+ b'\n'.join(cat_file_lines),
+ )
authored_timestamp = start_timestamp
+ base_env = os.environ
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]'
end='\r',
)
- commit = initial_commit.replace(
- authored_date=authored_timestamp, committed_date=committed_timestamp
- )
- if args.prefix and not commit.hexsha.startswith('acab'):
+ hashed_bytes = hashed_bytes_template.replace(
+ b'$AUTHOR__$', str(authored_timestamp).encode()
+ ).replace(b'$COMMITER$', str(committed_timestamp).encode())
+ new_hash = hashlib.sha1(hashed_bytes).hexdigest()
+ if args.prefix and not new_hash.startswith('acab'):
continue
- if args.suffix and not commit.hexsha.endswith('acab'):
+ if args.suffix and not new_hash.endswith('acab'):
continue
- if 'acab' not in commit.hexsha:
+ if 'acab' not in new_hash:
continue
- repo.active_branch.set_commit(commit)
- repo.git.prune()
- return commit
-
+ base_env['GIT_COMMITTER_DATE'] = time.strftime(
+ '%Y-%m-%d %H:%M:%S', time.localtime(committed_timestamp)
+ )
+ subprocess.run(
+ [
+ 'git',
+ 'commit',
+ '--no-verify',
+ '--amend',
+ '--no-edit',
+ '--date=%s' % time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(authored_timestamp)),
+ ],
+ capture_output=True,
+ env=base_env,
+ )
+ return
-repo = git.Repo()
-commit = repo.commit('HEAD')
if args.start == 'commit':
- start_timestamp = commit.authored_date
+ p = subprocess.run(['git', 'show', '--format=format:%at'], capture_output=True)
+ start_timestamp = int(p.stdout[: p.stdout.index(b'\n')])
elif args.start == 'now':
start_timestamp = int(time.time())
else:
sys.stderr('unknown value for --start')
sys.exit(1)
-new_head = amend_commit(repo, commit, start_timestamp)
+amend_commit(start_timestamp)
if not args.quiet:
- print('\ngot %s 🔥🚓' % new_head.hexsha)
+ p = subprocess.run(['git', 'rev-parse', 'HEAD'], capture_output=True)
+ print('\ngot %s 🔥🚓' % p.stdout.decode().strip())