From 3d10238a47f3e9b4e3830ed9d31d725491f6b033 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 12 Feb 2009 17:40:51 -0700 Subject: [PATCH] filter-repo: make it easier to skip blobs & commits Automatically do renaming of references to commits that were skipped, and automatically remove skipped blobs from the output of commits that reference them. Signed-off-by: Elijah Newren --- git-filter-repo | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/git-filter-repo b/git-filter-repo index 6811ae0..dce6f7b 100755 --- a/git-filter-repo +++ b/git-filter-repo @@ -36,10 +36,14 @@ class GitElement(object): def __init__(self): self.type = None self.dumped = 0 + self.old_id = None def dump(self, file): raise SystemExit("Unimplemented function: %s.dump()", type(self)) + def set_old_id(self, value): + self.old_id = value + class Blob(GitElement): def __init__(self, data): GitElement.__init__(self) @@ -56,6 +60,10 @@ class Blob(GitElement): file.write('data %d\n%s' % (len(self.data), self.data)) file.write('\n') + def skip(self): + self.dumped = 2 + ids.record_rename(self.old_id or self.id, None) + class Reset(GitElement): def __init__(self, ref, from_ref = None): GitElement.__init__(self) @@ -72,19 +80,25 @@ class Reset(GitElement): file.write('from :%d\n' % self.from_ref) file.write('\n') + def skip(self): + self.dumped = 2 + class FileChanges(GitElement): - def __init__(self, type, filename, mode = None, id = None): + def __init__(self, type, filename, id = None, mode = None): GitElement.__init__(self) self.type = type self.filename = filename + self.mode = None + self.id = None if type == 'M': - if not mode or not id: + if mode is None: raise SystemExit("file mode and idnum needed for %s" % filename) self.mode = mode self.id = id def dump(self, file): - if self.dumped: return + skipped = (self.type == 'M' and self.id is None) + if self.dumped or skipped: return self.dumped = 1 if self.type == 'M': @@ -94,6 +108,9 @@ class FileChanges(GitElement): else: raise SystemExit("Unhandled filechange type: %s" % self.type) + def skip(self): + self.dumped = 2 + class Commit(GitElement): def __init__(self, branch, author_name, author_email, author_date, @@ -137,6 +154,10 @@ class Commit(GitElement): change.dump(file) file.write('\n') + def skip(self, new_id): + self.dumped = 2 + ids.record_rename(self.old_id or self.id, new_id) + class FastExportFilter(object): def __init__(self, tag_callback = None, commit_callback = None, @@ -179,10 +200,10 @@ class FastExportFilter(object): if self.nextline.startswith('M '): (mode, idnum, path) = \ re.match('M (\d+) :(\d+) (.*)\n$', self.nextline).groups() - idnum = int(idnum) + idnum = ids.translate( int(idnum) ) if path.startswith('"'): path = unquote(path) - filechange = FileChanges('M', path, mode, idnum) + filechange = FileChanges('M', path, idnum, mode) self._advance_nextline() elif self.nextline.startswith('D '): path = self.nextline[2:-1] @@ -223,6 +244,7 @@ class FastExportFilter(object): # Create the blob blob = Blob(data) if id: + blob.set_old_id(id) ids.record_rename(id, blob.id) # Call any user callback to allow them to modify the blob @@ -295,6 +317,7 @@ class FastExportFilter(object): from_commit, merge_commits) if id: + commit.set_old_id(id) ids.record_rename(id, commit.id) # Call any user callback to allow them to modify the commit