2019-04-02 16:12:47 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import argparse
|
2019-04-04 14:34:04 +00:00
|
|
|
from os import path, getcwd, makedirs, listdir, remove, rename
|
|
|
|
from subprocess import run, DEVNULL
|
2019-04-02 16:12:47 +00:00
|
|
|
|
2019-06-29 14:56:27 +00:00
|
|
|
from folder import folder
|
2019-04-02 16:12:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(description='''
|
|
|
|
Shrink a git changelog into a patchset (based on git format-patch)
|
|
|
|
''')
|
|
|
|
|
2019-06-29 14:56:27 +00:00
|
|
|
parser.add_argument('worktree', metavar='WORKTREE', action='store', type=lambda x: folder('worktree', x), help='Worktree (assumed in ../worktree/)')
|
2019-04-02 16:12:47 +00:00
|
|
|
parser.add_argument('patchset', metavar='PATCHSET', action='store', type=lambda x: folder('patchset', x), help='Destination patchset (assumed in ../patchset/)')
|
2019-04-05 13:39:03 +00:00
|
|
|
parser.add_argument('--raw', action='store_true', help='Do not neaten up commits')
|
2019-04-02 16:12:47 +00:00
|
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
|
|
|
|
args.patchset = path.abspath(args.patchset)
|
|
|
|
|
|
|
|
|
|
|
|
assert not path.exists(path.join(args.patchset, '.git')) # protect against argument swap
|
|
|
|
assert path.exists(path.join(args.worktree, '.git'))
|
|
|
|
|
|
|
|
|
|
|
|
makedirs(args.patchset, exist_ok=True)
|
|
|
|
|
|
|
|
for do_delete in listdir(args.patchset):
|
|
|
|
do_delete = path.join(args.patchset, do_delete)
|
|
|
|
if path.splitext(do_delete)[1].lower() == '.patch':
|
|
|
|
remove(do_delete)
|
|
|
|
|
|
|
|
|
2019-06-29 14:13:18 +00:00
|
|
|
run(['git', 'format-patch', '-o', args.patchset, '--anchored=;', 'patchset-base'], stdout=DEVNULL, cwd=args.worktree, check=True)
|
2019-04-04 14:34:04 +00:00
|
|
|
|
2019-04-05 13:39:03 +00:00
|
|
|
if args.raw: exit()
|
2019-04-04 14:34:04 +00:00
|
|
|
|
|
|
|
# Edit the patches to look a bit better (and be more reproducible)
|
|
|
|
patchnames = [x for x in sorted(listdir(args.patchset)) if path.splitext(x)[1].lower() == '.patch']
|
|
|
|
strip_chars = min(len(x) - len(x.lstrip('0')) for x in patchnames)
|
|
|
|
|
|
|
|
for do_edit in patchnames:
|
|
|
|
real_file = path.join(args.patchset, do_edit)
|
|
|
|
fake_file = path.join(args.patchset, do_edit + '~')
|
|
|
|
new_file = path.join(args.patchset, do_edit[strip_chars:].lower())
|
|
|
|
|
|
|
|
print(path.basename(new_file))
|
|
|
|
|
|
|
|
rename(real_file, fake_file)
|
|
|
|
|
|
|
|
with open(new_file, 'w') as o, open(fake_file, 'r') as i:
|
|
|
|
for hdr_line in i:
|
|
|
|
if hdr_line == '\n':
|
|
|
|
o.write(hdr_line)
|
|
|
|
break
|
|
|
|
elif hdr_line.startswith('Subject:'):
|
|
|
|
if '[' in hdr_line:
|
|
|
|
o.write('Subject:' + hdr_line.rpartition(']')[2])
|
|
|
|
else:
|
|
|
|
o.write(hdr_line)
|
|
|
|
elif hdr_line.startswith('From:'):
|
|
|
|
o.write('From: Horst Beepmanh <>\n')
|
|
|
|
|
|
|
|
for msg_line in i:
|
|
|
|
o.write(msg_line)
|
|
|
|
if msg_line == '---\n': break
|
|
|
|
|
2019-04-05 13:39:03 +00:00
|
|
|
for junk_line in i:
|
|
|
|
if junk_line == junk_line.lstrip():
|
|
|
|
o.write(junk_line)
|
2019-04-04 14:34:04 +00:00
|
|
|
break
|
|
|
|
|
|
|
|
for diff_line in i:
|
2019-04-05 13:39:03 +00:00
|
|
|
if diff_line.startswith('index'): # strip this hash line if possible
|
|
|
|
next_line = next(i)
|
|
|
|
if next_line.startswith('GIT binary patch'):
|
|
|
|
o.write(diff_line)
|
|
|
|
o.write(next_line)
|
|
|
|
else:
|
|
|
|
o.write(next_line)
|
2019-04-04 14:34:04 +00:00
|
|
|
else:
|
|
|
|
o.write(diff_line)
|
|
|
|
|
|
|
|
remove(fake_file)
|