filter-repo: support deleteall directive

Signed-off-by: Elijah Newren <newren@gmail.com>
This commit is contained in:
Elijah Newren 2019-06-22 08:04:52 -06:00
parent a78831c984
commit e9678a367f
2 changed files with 22 additions and 11 deletions

View File

@ -548,7 +548,7 @@ class FileChange(_GitElement):
elements are components within a Commit element. elements are components within a Commit element.
""" """
def __init__(self, type_, filename, id_ = None, mode = None): def __init__(self, type_, filename = None, id_ = None, mode = None):
_GitElement.__init__(self) _GitElement.__init__(self)
# Denote the type of file-change (b'M' for modify, b'D' for delete, etc) # Denote the type of file-change (b'M' for modify, b'D' for delete, etc)
@ -562,23 +562,27 @@ class FileChange(_GitElement):
# Record the mode (mode describes type of file entry (non-executable, # Record the mode (mode describes type of file entry (non-executable,
# executable, or symlink)). # executable, or symlink)).
self.mode = None self.mode = mode
# blob_id is the id (mark) of the affected blob # blob_id is the id (mark) of the affected blob
self.blob_id = None self.blob_id = id_
if type_ == b'DELETEALL':
assert filename is None and id_ is None and mode is None
self.filename = b'' # Just so PathQuoting.enquote doesn't die
else:
assert filename is not None
# For b'M' file changes (modify), expect to have id and mode
if type_ == b'M': if type_ == b'M':
if mode is None: assert id_ is not None and mode is not None
raise SystemExit(_("file mode and idnum needed for %s") % filename) # pragma: no cover elif type_ == b'D':
self.mode = mode assert id_ is None and mode is None
self.blob_id = id_
# For b'R' file changes (rename), expect to have newname as third arg
elif type_ == b'R': # pragma: no cover (now avoid fast-export renames) elif type_ == b'R': # pragma: no cover (now avoid fast-export renames)
assert mode is None
if id_ is None: if id_ is None:
raise SystemExit(_("new name needed for rename of %s") % filename) raise SystemExit(_("new name needed for rename of %s") % filename)
self.filename = (self.filename, id_) self.filename = (self.filename, id_)
self.blob_id = None
def dump(self, file_): def dump(self, file_):
""" """
@ -595,6 +599,8 @@ class FileChange(_GitElement):
file_.write(b'M %s %s %s\n' % (self.mode, self.blob_id, quoted_filename)) file_.write(b'M %s %s %s\n' % (self.mode, self.blob_id, quoted_filename))
elif self.type == b'D': elif self.type == b'D':
file_.write(b'D %s\n' % quoted_filename) file_.write(b'D %s\n' % quoted_filename)
elif self.type == b'DELETEALL':
file_.write(b'deleteall\n')
else: else:
raise SystemExit(_("Unhandled filechange type: %s") % self.type) # pragma: no cover raise SystemExit(_("Unhandled filechange type: %s") % self.type) # pragma: no cover
@ -3028,6 +3034,9 @@ class RepoFilter(object):
# issues a deleteall directive which has no filename, and thus this # issues a deleteall directive which has no filename, and thus this
# block would normally strip it. Of course, FileChange() and # block would normally strip it. Of course, FileChange() and
# _parse_optional_filechange() would need updates too. # _parse_optional_filechange() would need updates too.
if change.type == b'DELETEALL':
new_file_changes[b''] = change
continue
if change.filename in self._newnames: if change.filename in self._newnames:
change.filename = self._newnames[change.filename] change.filename = self._newnames[change.filename]
else: else:

View File

@ -80,7 +80,9 @@ out.insert(devel)
world = Blob(b"Hello\nGoodbye") world = Blob(b"Hello\nGoodbye")
out.insert(world) out.insert(world)
changes = [FileChange(b'M', b'world', world.id, mode=b"100644")] changes = [FileChange(b'DELETEALL'),
FileChange(b'M', b'world', world.id, mode=b"100644"),
FileChange(b'M', b'bar', bar.id, mode=b"100644")]
when = datetime(2006, 8, 17, tzinfo=FixedTimeZone(b"+0200")) when = datetime(2006, 8, 17, tzinfo=FixedTimeZone(b"+0200"))
when_string = fr.date_to_string(when) when_string = fr.date_to_string(when)
commit4 = Commit(b"refs/heads/devel", commit4 = Commit(b"refs/heads/devel",