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 <newren@gmail.com>
pull/13/head
Elijah Newren 16 years ago
parent 2c769de150
commit 3d10238a47

@ -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

Loading…
Cancel
Save