Keep private identities out of maintenance source

This commit is contained in:
ragnarok-clanker 2026-10-26 15:35:17 +01:00
commit a77a3645a1
2 changed files with 29 additions and 9 deletions

View file

@ -1,10 +1,26 @@
import argparse
import re
import subprocess
repo='/data/repo'
subprocess.run(['git','-C',repo,'filter-repo','--force',
'--blob-callback', "import re; blob.data = re.sub(rb'(?i)[a-z0-9.!#$%&*+/=?^_`{|}~-]*spl3en[a-z0-9.!#$%&*+/=?^_`{|}~-]*@[a-z0-9.-]+', b'ragnarok-clanker', blob.data); blob.data = re.sub(rb'(?i)spl3en', b'ragnarok-clanker', blob.data)",
'--message-callback', "import re; message = re.sub(rb'(?i)[a-z0-9.!#$%&*+/=?^_`{|}~-]*spl3en[a-z0-9.!#$%&*+/=?^_`{|}~-]*@[a-z0-9.-]+', b'ragnarok-clanker', message); return re.sub(rb'(?i)spl3en', b'ragnarok-clanker', message)",
'--name-callback', "import re; return re.sub(rb'(?i)spl3en', b'ragnarok-clanker', name)",
'--email-callback', "return b'ragnarok-clanker' if b'spl3en' in email.lower() else email",
'--filename-callback', "import re; return re.sub(rb'(?i)spl3en', b'ragnarok-clanker', filename)",
'--refname-callback', "import re; return re.sub(rb'(?i)spl3en', b'ragnarok-clanker', refname)"
],check=True)
parser = argparse.ArgumentParser(description='Replace a private identity with ragnarok-clanker in Git history.')
parser.add_argument('identity', help='Private identity to replace, case-insensitively')
parser.add_argument('--repo', default='/data/repo', help='Repository whose history will be rewritten')
args = parser.parse_args()
if not args.identity:
parser.error('identity must not be empty')
identity = re.escape(args.identity.encode())
pattern = b'(?i)' + identity
email_pattern = rb'(?i)[a-z0-9.!#$%&*+/=?^_`{|}~-]*' + identity + rb'[a-z0-9.!#$%&*+/=?^_`{|}~-]*@[a-z0-9.-]+'
replace = f"re.sub({pattern!r}, b'ragnarok-clanker', value)"
replace_email = f"re.sub({email_pattern!r}, b'ragnarok-clanker', value)"
subprocess.run([
'git', '-C', args.repo, 'filter-repo', '--force',
'--blob-callback', f'import re; value = blob.data; value = {replace_email}; blob.data = {replace}',
'--message-callback', f'import re; value = message; value = {replace_email}; return {replace}',
'--name-callback', f'import re; value = name; return {replace}',
'--email-callback', f"import re; return b'ragnarok-clanker' if re.search({pattern!r}, email) else email",
'--filename-callback', f'import re; value = filename; return {replace}',
'--refname-callback', f'import re; value = refname; return {replace}',
], check=True)