Skip to content

Commit 0b70b72

Browse files
committed
filter-repo: provide extra metadata to some callbacks
For other programs importing git-filter-repo as a library and passing a blob, commit, tag, or reset callback to RepoFilter, pass a second parameter to these functions with extra metadata they might find useful. For simplicity of implementation, this technically changes the calling signature of the --*-callback functions passed on the command line, but we hide that behind a _do_not_use_this_variable parameter for now, leave it undocumented, and encourage folks who want to use it to write an actual python program that imports git-filter-repo. In the future, we may modify the --*-callback functions to not pass this extra parameter, or if it is deemed sufficiently useful, then we'll rename the second parameter and document it. As already noted in our API compatibilty caveat near the top of git-filter-repo, I am not guaranteeing API backwards compatibility. That especially applies to this metadata argument, other than the fact that it'll be a dict mapping strings to some kind of value. I might add more keys, rename them, change the corresponding value, or even remove keys that used to be part of metadata. Signed-off-by: Elijah Newren <[email protected]>
1 parent c58e83e commit 0b70b72

8 files changed

+26
-20
lines changed

git-filter-repo

+12-6
Original file line numberDiff line numberDiff line change
@@ -2454,7 +2454,7 @@ class RepoFilter(object):
24542454

24552455
def _handle_arg_callbacks(self):
24562456
def make_callback(argname, str):
2457-
exec('def callback({}):\n'.format(argname)+
2457+
exec('def callback({}, _do_not_use_this_var = None):\n'.format(argname)+
24582458
' '+'\n '.join(str.splitlines()), globals())
24592459
return callback #namespace['callback']
24602460
def handle(type):
@@ -2828,6 +2828,12 @@ class RepoFilter(object):
28282828
if len(orig_parents) >= 2 and len(commit.parents) < 2:
28292829
self._commits_no_longer_merges.append((commit.original_id, new_id))
28302830

2831+
def callback_metadata(self, extra_items = dict()):
2832+
return {'commit_rename_func': self._get_rename,
2833+
'ancestry_graph': self._graph,
2834+
'original_ancestry_graph': self._orig_graph,
2835+
**extra_items}
2836+
28312837
def _tweak_blob(self, blob):
28322838
if self._args.replace_text:
28332839
for literal, replacement in self._args.replace_text['literals']:
@@ -2836,7 +2842,7 @@ class RepoFilter(object):
28362842
blob.data = regex.sub(replacement, blob.data)
28372843

28382844
if self._blob_callback:
2839-
self._blob_callback(blob)
2845+
self._blob_callback(blob, self.callback_metadata())
28402846

28412847
def _tweak_commit(self, commit, aux_info):
28422848
def filename_matches(path_expression, pathname):
@@ -2982,7 +2988,7 @@ class RepoFilter(object):
29822988

29832989
# Call the user-defined callback, if any
29842990
if self._commit_callback:
2985-
self._commit_callback(commit)
2991+
self._commit_callback(commit, self.callback_metadata(aux_info))
29862992

29872993
# Now print the resulting commit, or if prunable skip it
29882994
if not commit.dumped:
@@ -3047,15 +3053,15 @@ class RepoFilter(object):
30473053

30483054
# Call general purpose tag callback
30493055
if self._tag_callback:
3050-
self._tag_callback(tag)
3056+
self._tag_callback(tag, self.callback_metadata())
30513057

30523058
def _tweak_reset(self, reset):
30533059
if self._args.tag_rename:
30543060
reset.ref = RepoFilter._do_tag_rename(self._args.tag_rename, reset.ref)
30553061
if self._refname_callback:
30563062
reset.ref = self._refname_callback(reset.ref)
30573063
if self._reset_callback:
3058-
self._reset_callback(reset)
3064+
self._reset_callback(reset, self.callback_metadata())
30593065

30603066
# Record we've seen this ref and don't need to force a manual update
30613067
# for it.
@@ -3187,7 +3193,7 @@ class RepoFilter(object):
31873193

31883194
# Call any user callback to allow them to modify the reset
31893195
if self._reset_callback:
3190-
self._reset_callback(reset)
3196+
self._reset_callback(reset, self.callback_metadata())
31913197

31923198
# Now print the resulting reset
31933199
reset.dump(self._output)

t/t9391/commit_info.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import git_filter_repo as fr
1313

14-
def change_up_them_commits(commit):
14+
def change_up_them_commits(commit, metadata):
1515
# Change the commit author
1616
if commit.author_name == b"Copy N. Paste":
1717
commit.author_name = b"Ima L. Oser"

t/t9391/file_filter.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
import sys
1515
import git_filter_repo as fr
1616

17-
def drop_file_by_contents(blob):
17+
def drop_file_by_contents(blob, metadata):
1818
bad_file_contents = b'The launch code is 1-2-3-4.'
1919
if blob.data == bad_file_contents:
2020
blob.skip()
2121

22-
def drop_files_by_name(commit):
22+
def drop_files_by_name(commit, metadata):
2323
new_file_changes = []
2424
for change in commit.file_changes:
2525
if not change.filename.endswith(b'.doc'):

t/t9391/print_progress.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ def print_progress():
2424
print("\rRewriting commits... %d/%d (%d objects)"
2525
% (commit_count, total_commits, object_count), end='')
2626

27-
def my_blob_callback(blob):
27+
def my_blob_callback(blob, metadata):
2828
global object_count
2929
object_count += 1
3030
print_progress()
3131

32-
def my_commit_callback(commit):
32+
def my_commit_callback(commit, metadata):
3333
global commit_count
3434
commit_count += 1
3535
print_progress()

t/t9391/rename-master-to-develop.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import git_filter_repo as fr
1515

16-
def my_commit_callback(commit):
16+
def my_commit_callback(commit, metadata):
1717
if commit.branch == b"refs/heads/master":
1818
commit.branch = b"refs/heads/develop"
1919

t/t9391/splice_repos.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ def __init__(self, repo1, repo2, output_dir):
2424
self.commit_map = {}
2525
self.last_commit = None
2626

27-
def skip_reset(self, reset):
27+
def skip_reset(self, reset, metadata):
2828
reset.skip()
2929

30-
def hold_commit(self, commit):
30+
def hold_commit(self, commit, metadata):
3131
commit.skip(new_id = commit.id)
3232
letter = re.match(b'Commit (.)', commit.message).group(1)
3333
self.commit_map[letter] = commit
3434

35-
def weave_commit(self, commit):
35+
def weave_commit(self, commit, metadata):
3636
letter = re.match(b'Commit (.)', commit.message).group(1)
3737
prev_letter = bytes([ord(letter)-1])
3838

@@ -65,14 +65,14 @@ def run(self):
6565

6666
i1args = fr.FilteringOptions.parse_args(['--source', self.repo1])
6767
i1 = fr.RepoFilter(i1args,
68-
reset_callback = lambda r: self.skip_reset(r),
69-
commit_callback = lambda c: self.hold_commit(c))
68+
reset_callback = self.skip_reset,
69+
commit_callback = self.hold_commit)
7070
i1.set_output(out)
7171
i1.run()
7272

7373
i2args = fr.FilteringOptions.parse_args(['--source', self.repo2])
7474
i2 = fr.RepoFilter(i2args,
75-
commit_callback = lambda c: self.weave_commit(c))
75+
commit_callback = self.weave_commit)
7676
i2.set_output(out)
7777
i2.run()
7878

t/t9391/strip-cvs-keywords.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import re
1515
import git_filter_repo as fr
1616

17-
def strip_cvs_keywords(blob):
17+
def strip_cvs_keywords(blob, metadata):
1818
# FIXME: Should first check if blob is a text file to avoid ruining
1919
# binaries. Could use python.magic here, or just output blob.data to
2020
# the unix 'file' command

t/t9391/unusual.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def handle_checkpoint(checkpoint_object):
106106
'''[1:]).encode())
107107

108108
counts = collections.Counter()
109-
def look_for_reset(obj):
109+
def look_for_reset(obj, metadata):
110110
print("Processing {}".format(obj))
111111
counts[type(obj)] += 1
112112
if type(obj) == fr.Reset:

0 commit comments

Comments
 (0)