def iter_file_commands(self): """Iterator returning FileCommand objects. If an invalid file command is found, the line is silently pushed back and iteration ends. """ while True: line = self.next_line() if line is None: break elif len(line) == 0 or line.startswith(b'#'): continue # Search for file commands in order of likelihood elif line.startswith(b'M '): yield self._parse_file_modify(line[2:]) elif line.startswith(b'D '): path = self._path(line[2:]) yield commands.FileDeleteCommand(path) elif line.startswith(b'R '): old, new = self._path_pair(line[2:]) yield commands.FileRenameCommand(old, new) elif line.startswith(b'C '): src, dest = self._path_pair(line[2:]) yield commands.FileCopyCommand(src, dest) elif line.startswith(b'deleteall'): yield commands.FileDeleteAllCommand() else: self.push_line(line) break
def _convert_rename(self, fc): """Convert a FileRenameCommand into a new FileCommand. :return: None if the rename is being ignored, otherwise a new FileCommand based on the whether the old and new paths are inside or outside of the interesting locations. """ old = fc.old_path new = fc.new_path keep_old = self._path_to_be_kept(old) keep_new = self._path_to_be_kept(new) if keep_old and keep_new: fc.old_path = self._adjust_for_new_root(old) fc.new_path = self._adjust_for_new_root(new) return fc elif keep_old: # The file has been renamed to a non-interesting location. # Delete it! old = self._adjust_for_new_root(old) return commands.FileDeleteCommand(old) elif keep_new: # The file has been renamed into an interesting location # We really ought to add it but we don't currently buffer # the contents of all previous files and probably never want # to. Maybe fast-import-info needs to be extended to # remember all renames and a config file can be passed # into here ala fast-import? self.warning("cannot turn rename of %s into an add of %s yet" % (old, new)) return None
def setUp(self): super(TestCommitCopy, self).setUp() file_cmds = iter([ commands.FileDeleteCommand(b'readme.txt'), commands.FileModifyCommand(b'NEWS', 0o100644, None, b'blah blah blah'), ]) committer = (b'Joe Wong', b'*****@*****.**', 1234567890, -6 * 3600) self.c = commands.CommitCommand(b'refs/heads/master', b'bbb', None, committer, b'release v1.0', b':aaa', None, file_cmds)
def _iter_files(self, base_tree, new_tree): for (old_path, new_path), (old_mode, new_mode), (old_hexsha, new_hexsha) in \ self.store.tree_changes(base_tree, new_tree): if new_path is None: yield commands.FileDeleteCommand(old_path) continue if not stat.S_ISDIR(new_mode): blob = self.store[new_hexsha] marker = self.emit_blob(blob) if old_path != new_path and old_path is not None: yield commands.FileRenameCommand(old_path, new_path) if old_mode != new_mode or old_hexsha != new_hexsha: yield commands.FileModifyCommand(new_path, new_mode, marker, None)
def test_commit_with_filecommands(self): file_cmds = iter([ commands.FileDeleteCommand(b'readme.txt'), commands.FileModifyCommand(b'NEWS', 0o100644, None, b'blah blah blah'), ]) # user tuple is (name, email, secs-since-epoch, secs-offset-from-utc) committer = (b'Joe Wong', b'*****@*****.**', 1234567890, -6 * 3600) c = commands.CommitCommand(b'refs/heads/master', b'bbb', None, committer, b'release v1.0', b':aaa', None, file_cmds) self.assertEqual( b"commit refs/heads/master\n" b"mark :bbb\n" b"committer Joe Wong <*****@*****.**> 1234567890 -0600\n" b"data 12\n" b"release v1.0\n" b"from :aaa\n" b"D readme.txt\n" b"M 644 inline NEWS\n" b"data 14\n" b"blah blah blah", bytes(c))
def test_file_delete(self): from fastimport import commands self.simple_commit() commit = self.make_file_commit([commands.FileDeleteCommand("path")]) self.assertEqual([], self.repo[commit.tree].items())
def test_filedelete(self): c = commands.FileDeleteCommand(b'foo/bar') self.assertEqual(b'D foo/bar', bytes(c))