You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
git-filter-repo/contrib/filter-repo-demos/clean-ignore

80 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""
This is a simple program that will delete files from history which match
current gitignore rules, while also:
1) pruning commits which become empty
2) pruning merge commits which become degenerate and have no changes
relative to its remaining relevant parent
3) rewriting commit hashes in commit messages to reference new commit IDs.
"""
"""
Please see the
***** API BACKWARD COMPATIBILITY CAVEAT *****
near the top of git-filter-repo.
"""
import argparse
import os
import subprocess
import sys
try:
import git_filter_repo as fr
except ImportError:
raise SystemExit("Error: Couldn't find git_filter_repo.py. Did you forget to make a symlink to git-filter-repo named git_filter_repo.py or did you forget to put the latter in your PYTHONPATH?")
class CheckIgnores:
def __init__(self):
self.ignored = set()
self.okay = set()
cmd = 'git check-ignore --stdin --verbose --non-matching --no-index'
self.check_ignore_process = subprocess.Popen(cmd.split(),
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
def __del__(self):
if self.check_ignore_process:
self.check_ignore_process.stdin.close()
def get_ignored(self, filenames):
ignored = set()
for name in filenames:
if name in self.ignored:
ignored.add(name)
elif name in self.okay:
continue
else:
self.check_ignore_process.stdin.write(name+b'\n')
self.check_ignore_process.stdin.flush()
result = self.check_ignore_process.stdout.readline().rstrip(b'\n')
(rest, pathname) = result.split(b"\t")
if name != pathname:
raise SystemExit("Error: Passed {} but got {}".format(name, pathname))
if rest == b'::':
self.okay.add(name)
else:
self.ignored.add(name)
ignored.add(name)
return ignored
def skip_ignores(self, commit, metadata):
filenames = [x.filename for x in commit.file_changes]
bad = self.get_ignored(filenames)
commit.file_changes = [x for x in commit.file_changes
if x.filename not in bad]
def main():
checker = CheckIgnores()
args = fr.FilteringOptions.parse_args(sys.argv[1:])
filter = fr.RepoFilter(args, commit_callback=checker.skip_ignores)
filter.run()
if __name__ == '__main__':
main()