def stage(self, paths): """Stage a set of paths. :param paths: List of paths, relative to the repository path """ from dulwich.index import cleanup_mode index = self.open_index() for path in paths: full_path = os.path.join(self.path, path) blob = Blob() try: st = os.stat(full_path) except OSError: # File no longer exists try: del index[path] except KeyError: pass # Doesn't exist in the index either else: f = open(full_path, 'rb') try: blob.data = f.read() finally: f.close() self.object_store.add_object(blob) # XXX: Cleanup some of the other file properties as well? index[path] = (st.st_ctime, st.st_mtime, st.st_dev, st.st_ino, cleanup_mode(st.st_mode), st.st_uid, st.st_gid, st.st_size, blob.id, 0) index.write()
def commit_handler(self, cmd): """Process a CommitCommand.""" commit = Commit() if cmd.author is not None: author = cmd.author else: author = cmd.committer (author_name, author_email, author_timestamp, author_timezone) = author (committer_name, committer_email, commit_timestamp, commit_timezone) = cmd.committer commit.author = "%s <%s>" % (author_name, author_email) commit.author_timezone = author_timezone commit.author_time = int(author_timestamp) commit.committer = "%s <%s>" % (committer_name, committer_email) commit.commit_timezone = commit_timezone commit.commit_time = int(commit_timestamp) commit.message = cmd.message commit.parents = [] if cmd.from_: self._reset_base(cmd.from_) for filecmd in cmd.iter_files(): if filecmd.name == "filemodify": if filecmd.data is not None: blob = Blob.from_string(filecmd.data) self.repo.object_store.add(blob) blob_id = blob.id else: assert filecmd.dataref[ 0] == ":", "non-marker refs not supported yet" blob_id = self.markers[filecmd.dataref[1:]] self._contents[filecmd.path] = (filecmd.mode, blob_id) elif filecmd.name == "filedelete": del self._contents[filecmd.path] elif filecmd.name == "filecopy": self._contents[filecmd.dest_path] = self._contents[ filecmd.src_path] elif filecmd.name == "filerename": self._contents[filecmd.new_path] = self._contents[ filecmd.old_path] del self._contents[filecmd.old_path] elif filecmd.name == "filedeleteall": self._contents = {} else: raise Exception("Command %s not supported" % filecmd.name) commit.tree = commit_tree( self.repo.object_store, ((path, hexsha, mode) for (path, (mode, hexsha)) in self._contents.iteritems())) if self.last_commit is not None: commit.parents.append(self.last_commit) commit.parents += cmd.merges self.repo.object_store.add_object(commit) self.repo[cmd.ref] = commit.id self.last_commit = commit.id if cmd.mark: self.markers[cmd.mark] = commit.id
def write_tree_diff(f, store, old_tree, new_tree): """Write tree diff. :param f: File-like object to write to. :param old_tree: Old tree id :param new_tree: New tree id """ changes = store.tree_changes(old_tree, new_tree) for (oldpath, newpath), (oldmode, newmode), (oldsha, newsha) in changes: if oldsha is None: old_blob = Blob.from_string("") else: old_blob = store[oldsha] if newsha is None: new_blob = Blob.from_string("") else: new_blob = store[newsha] write_blob_diff(f, (oldpath, oldmode, old_blob), (newpath, newmode, new_blob))
def commit_handler(self, cmd): """Process a CommitCommand.""" commit = Commit() if cmd.author is not None: author = cmd.author else: author = cmd.committer (author_name, author_email, author_timestamp, author_timezone) = author (committer_name, committer_email, commit_timestamp, commit_timezone) = cmd.committer commit.author = "%s <%s>" % (author_name, author_email) commit.author_timezone = author_timezone commit.author_time = int(author_timestamp) commit.committer = "%s <%s>" % (committer_name, committer_email) commit.commit_timezone = commit_timezone commit.commit_time = int(commit_timestamp) commit.message = cmd.message commit.parents = [] if cmd.from_: self._reset_base(cmd.from_) for filecmd in cmd.iter_files(): if filecmd.name == "filemodify": if filecmd.data is not None: blob = Blob.from_string(filecmd.data) self.repo.object_store.add(blob) blob_id = blob.id else: assert filecmd.dataref[0] == ":", "non-marker refs not supported yet" blob_id = self.markers[filecmd.dataref[1:]] self._contents[filecmd.path] = (filecmd.mode, blob_id) elif filecmd.name == "filedelete": del self._contents[filecmd.path] elif filecmd.name == "filecopy": self._contents[filecmd.dest_path] = self._contents[filecmd.src_path] elif filecmd.name == "filerename": self._contents[filecmd.new_path] = self._contents[filecmd.old_path] del self._contents[filecmd.old_path] elif filecmd.name == "filedeleteall": self._contents = {} else: raise Exception("Command %s not supported" % filecmd.name) commit.tree = commit_tree(self.repo.object_store, ((path, hexsha, mode) for (path, (mode, hexsha)) in self._contents.iteritems())) if self.last_commit is not None: commit.parents.append(self.last_commit) commit.parents += cmd.merges self.repo.object_store.add_object(commit) self.repo[cmd.ref] = commit.id self.last_commit = commit.id if cmd.mark: self.markers[cmd.mark] = commit.id
def blob_handler(self, cmd): """Process a BlobCommand.""" blob = Blob.from_string(cmd.data) self.repo.object_store.add_object(blob) if cmd.mark: self.markers[cmd.mark] = blob.id