filter-repo: implement --debug

Signed-off-by: Elijah Newren <newren@gmail.com>
pull/13/head
Elijah Newren 6 years ago
parent 9499c78b94
commit f103735e01

@ -1104,6 +1104,11 @@ def get_args():
fast-export` and filter its output, and save
both the original and the filtered version for
comparison.''')
parser.add_argument('--debug', action='store_true',
help='''Print additional information about operations
being performed and commands being run. When
used together with --dry-run, also show extra
information about what would be run.''')
parser.add_argument('revisions', nargs='*',
help='''Branches/tags/refs to rewrite. Special rev-list
@ -1231,8 +1236,23 @@ class InputFileBackup:
self.output_file.write(line)
return line
class DualFileWriter:
def __init__(self, file1, file2):
self.file1 = file1
self.file2 = file2
def write(self, *args):
self.file1.write(*args)
self.file2.write(*args)
def close(self):
self.file1.close()
self.file2.close()
def run_fast_filter():
args = get_args()
if args.debug:
print("[DEBUG] Parsed arguments:\n{}".format(args))
# Determine basic repository information
orig_refs = get_refs()
@ -1244,30 +1264,39 @@ def run_fast_filter():
sanity_check(orig_refs, is_bare)
# Create a temporary directory for storing some results
if args.dry_run:
if args.dry_run or args.debug:
results_tmp_dir = os.path.join(git_dir, 'filter-repo')
if not os.path.isdir(results_tmp_dir):
os.mkdir(results_tmp_dir)
# Do actual filtering
fep = subprocess.Popen(['git', 'fast-export', '--no-data'] + args.revisions,
stdout=subprocess.PIPE)
fip = subprocess.Popen('git fast-import --force --quiet'.split(),
stdin=subprocess.PIPE)
fep_cmd = ['git', 'fast-export', '--no-data'] + args.revisions
fip_cmd = 'git fast-import --force --quiet'.split()
fep = subprocess.Popen(fep_cmd, stdout=subprocess.PIPE)
fip = subprocess.Popen(fip_cmd, stdin=subprocess.PIPE)
filter = FastExportFilter(
commit_callback = lambda c : tweak_commit(args, c),
)
# Determine whether to make a copy of input
input = fep.stdout
if args.dry_run:
output = open(os.path.join(results_tmp_dir, 'fast-export.original'), 'w')
if args.dry_run or args.debug:
fe_orig = os.path.join(results_tmp_dir, 'fast-export.original')
output = open(fe_orig, 'w')
input = InputFileBackup(input, output)
if args.debug:
print("[DEBUG] Running: {}".format(' '.join(fep_cmd)))
print(" (saving a copy of the output at {})".format(fe_orig))
# Determine where to send output
output = fip.stdin
if args.dry_run:
output = open(os.path.join(results_tmp_dir, 'fast-export.filtered'), 'w')
if args.dry_run or args.debug:
fe_filt = os.path.join(results_tmp_dir, 'fast-export.filtered')
output = open(fe_filt, 'w')
if args.debug:
output = DualFileWriter(fip.stdin, output)
print("[DEBUG] Running: {}".format(' '.join(fip_cmd)))
print(" (using the following file as input: {})".format(fe_filt))
# Run the filter
filter.run(input, output)
@ -1283,26 +1312,34 @@ def run_fast_filter():
if args.dry_run:
print("NOTE: Not running fast-import or cleaning up; --dry-run passed.")
print(" Requested filtering can be seen by comparing:")
print(" {}/fast-export.original".format(results_tmp_dir))
print(" {}/fast-export.filtered".format(results_tmp_dir))
print(" {}\n {}".format(fe_orig, fe_filt))
sys.exit(0)
# Remove unused refs
refs_to_nuke = set(orig_refs) - filter.get_seen_refs()
p = subprocess.Popen('git update-ref --stdin'.split(), stdin=subprocess.PIPE)
p.stdin.write(''.join(["option no-deref\ndelete {}\n".format(x)
for x in refs_to_nuke]))
p.stdin.close()
if p.wait():
raise SystemExit("git update-ref failed; see above")
if refs_to_nuke:
if args.debug:
print("[DEBUG] Deleting the following refs:\n "+
"\n ".join(refs_to_nuke))
p = subprocess.Popen('git update-ref --stdin'.split(),
stdin=subprocess.PIPE)
p.stdin.write(''.join(["option no-deref\ndelete {}\n".format(x)
for x in refs_to_nuke]))
p.stdin.close()
if p.wait():
raise SystemExit("git update-ref failed; see above")
# Nuke the reflogs and repack
subprocess.call('git reflog expire --expire=now --all'.split())
subprocess.call('git gc --prune=now'.split())
if not args.debug:
print("Repacking your repo and cleaning out old unneeded objects")
cleanup_cmds = ['git reflog expire --expire=now --all'.split(),
'git gc --prune=now'.split()]
if not is_bare:
# Reset to the new HEAD
subprocess.call('git reset --hard'.split())
cleanup_cmds.append('git reset --hard'.split())
for cmd in cleanup_cmds:
if args.debug:
print("[DEBUG] Running: {}".format(' '.join(cmd)))
subprocess.call(cmd)
if __name__ == '__main__':
run_fast_filter()

Loading…
Cancel
Save