mirror of
https://github.com/newren/git-filter-repo.git
synced 2024-09-19 00:00:08 +02:00
805ce360fa
While the underlying fast-export and fast-import streams explicitly separate 'from' commit (first parent) and 'merge' commits (all other parents), foisting that separation into the Commit object for filter-repo forces additional places in the code to deal with that distinction. It results in less clear code, and especially does not make sense to push upon folks who may want to use filter-repo as a library. Signed-off-by: Elijah Newren <newren@gmail.com>
85 lines
2.6 KiB
Python
Executable File
85 lines
2.6 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
"""
|
|
Please see the
|
|
***** API BACKWARD COMPATIBILITY CAVEAT *****
|
|
near the top of git-filter-repo.
|
|
|
|
Also, note that splicing repos may need some special care as fast-export
|
|
only shows the files that changed relative to the first parent, so there
|
|
may be gotchas if you are to splice near merge commits; this example does
|
|
not try to handle any such special cases.
|
|
"""
|
|
|
|
import re
|
|
import sys
|
|
import git_filter_repo as fr
|
|
|
|
class InterleaveRepositories:
|
|
def __init__(self, repo1, repo2, output_dir):
|
|
self.repo1 = repo1
|
|
self.repo2 = repo2
|
|
self.output_dir = output_dir
|
|
|
|
self.commit_map = {}
|
|
self.last_commit = None
|
|
|
|
def skip_reset(self, reset):
|
|
reset.skip()
|
|
|
|
def hold_commit(self, commit):
|
|
commit.skip(new_id = commit.id)
|
|
letter = re.match('Commit (.)', commit.message).group(1)
|
|
self.commit_map[letter] = commit
|
|
|
|
def weave_commit(self, commit):
|
|
letter = re.match('Commit (.)', commit.message).group(1)
|
|
prev_letter = chr(ord(letter)-1)
|
|
|
|
# Splice in any extra commits needed
|
|
if prev_letter in self.commit_map:
|
|
new_commit = self.commit_map[prev_letter]
|
|
new_commit.parents = [self.last_commit] if self.last_commit else []
|
|
new_commit.dump(self.out._output)
|
|
commit.parents = [new_commit.id]
|
|
|
|
# Dump our commit now
|
|
commit.dump(self.out._output)
|
|
|
|
# Make sure that commits that depended on new_commit.id will now depend
|
|
# on commit.id
|
|
if prev_letter in self.commit_map:
|
|
self.last_commit = commit.id
|
|
fr.record_id_rename(new_commit.id, commit.id)
|
|
|
|
def run(self):
|
|
blob = fr.Blob('public gpg key contents')
|
|
tag = fr.Tag('gpg-pubkey', blob.id,
|
|
'Ima Tagger', 'ima@tagg.er', '1136199845 +0300',
|
|
'Very important explanation and stuff')
|
|
|
|
args = fr.FilteringOptions.parse_args(['--target', self.output_dir])
|
|
out = fr.RepoFilter(args)
|
|
out.importer_only()
|
|
self.out = out
|
|
|
|
i1args = fr.FilteringOptions.parse_args(['--source', self.repo1])
|
|
i1 = fr.RepoFilter(i1args,
|
|
reset_callback = lambda r: self.skip_reset(r),
|
|
commit_callback = lambda c: self.hold_commit(c))
|
|
i1.set_output(out)
|
|
i1.run()
|
|
|
|
i2args = fr.FilteringOptions.parse_args(['--source', self.repo2])
|
|
i2 = fr.RepoFilter(i2args,
|
|
commit_callback = lambda c: self.weave_commit(c))
|
|
i2.set_output(out)
|
|
i2.run()
|
|
|
|
blob.dump(out._output)
|
|
tag.dump(out._output)
|
|
out.finish()
|
|
|
|
splicer = InterleaveRepositories(sys.argv[1], sys.argv[2], sys.argv[3])
|
|
splicer.run()
|