def history(self, path=None, revision=None, branch='master', since_revision=None, since=None, sort=True): if revision == self.null_revision: return [] if path is not None: path = clean_path(path) if since_revision: ctime = self.revision(since_revision).commit_time if since: since = max(ctime, since) else: since = ctime if revision or branch: pending = set([self._get_commit(revision, branch).id]) else: pending = set(self._repo.get_refs().values()) visited = set() result = [] repo = self.repo while pending: commit_id = pending.pop() commit = self.revision(commit_id) if commit_id in visited: continue visited.add(commit_id) if since and since > commit.commit_time: continue if commit_id != since_revision: pending.update(commit._commit.parents) if path: tree = repo[commit._commit.tree] found = False parents = commit._commit.parents for parent in parents: parent_tree = repo[repo[parent].tree] if not is_same_object(repo, tree, parent_tree, path): found = True break if not parents and get_by_path(repo, tree, path): found = True if not found: continue result.append(commit) if sort: result.sort(key=attrgetter('commit_time'), reverse=True) return result
def do_read(self, path, revision=None, branch='master'): path = clean_path(path) repo = self.repo if revision == self.null_revision: raise FileDoesNotExist(self, "'%s' does not exist at revision null" % path) c = self._get_commit(revision, branch) obj = get_by_path(repo, repo[c.tree], path) if not obj: raise FileDoesNotExist(self, "'%s' does not exist" % path) if not isinstance(obj, Blob): raise FileDoesNotExist(self, "'%s' is not a regular file" % path) data = obj.as_pretty_string() return data
def do_read(self, path, revision=None, branch='master'): path = clean_path(path) repo = self.repo if revision == self.null_revision: raise FileDoesNotExist( self, "'%s' does not exist at revision null" % path) c = self._get_commit(revision, branch) obj = get_by_path(repo, repo[c.tree], path) if not obj: raise FileDoesNotExist(self, "'%s' does not exist" % path) if not isinstance(obj, Blob): raise FileDoesNotExist(self, "'%s' is not a regular file" % path) data = obj.as_pretty_string() return data
def do_commit(self, message='', author=None, committer=None, branch='master', parent=None): if isinstance(message, unicode): message = message.encode('utf-8') repo = self.repo try: parent = self._get_commit(parent, branch) root = repo[parent.tree] except BranchDoesNotExist: if branch == 'master': # initial commit root = Tree() else: raise cache = {} paths = set() objects = set() for path, (action, data) in self.changes.iteritems(): path = clean_path(path) paths.add(path) dirname, filename = os.path.split(path) trees = self._collect(root, dirname, cache) if action == WRITE: blob = Blob.from_string(data) trees[-1][2][filename] = (self.file_mode, blob.id) cache[blob.id] = blob elif action == DELETE: del trees[-1][2][filename] elif action == RENAME: old = self._collect(root, data, cache) mode, name, obj = old[-1] del old[-2][2][name] trees[-1][2][filename] = (mode, obj.id) cache.update(self._link(old[:-1])) paths.add(data) cache.update(self._link(trees)) else: objects.add(root) # collect all objects that have to be committed for path in paths: objects.update([obj for mode, name, obj in self._collect(root, path, cache)]) # create the commit c = Commit() if parent: c.parents = [parent.id] c.tree = root.id c.committer = committer or self.committer c.author = author or c.committer t = time.localtime() c.commit_time = c.author_time = int(time.mktime(t)) c.commit_timezone = c.author_timezone = t.tm_isdst * 3600 - time.timezone c.encoding = "UTF-8" c.message = message objects.add(c) # write everything to disk for obj in objects: repo.object_store.add_object(obj) repo.refs['refs/heads/%s' % branch] = c.id return DulwichCommit(self, c)
def do_commit(self, message='', author=None, committer=None, branch='master', parent=None): if isinstance(message, unicode): message = message.encode('utf-8') repo = self.repo try: parent = self._get_commit(parent, branch) root = repo[parent.tree] except BranchDoesNotExist: if branch == 'master': # initial commit root = Tree() else: raise cache = {} paths = set() objects = set() for path, (action, data) in self.changes.iteritems(): path = clean_path(path) paths.add(path) dirname, filename = os.path.split(path) trees = self._collect(root, dirname, cache) if action == WRITE: blob = Blob.from_string(data) trees[-1][2][filename] = (self.file_mode, blob.id) cache[blob.id] = blob elif action == DELETE: del trees[-1][2][filename] elif action == RENAME: old = self._collect(root, data, cache) mode, name, obj = old[-1] del old[-2][2][name] trees[-1][2][filename] = (mode, obj.id) cache.update(self._link(old[:-1])) paths.add(data) cache.update(self._link(trees)) else: objects.add(root) # collect all objects that have to be committed for path in paths: objects.update( [obj for mode, name, obj in self._collect(root, path, cache)]) # create the commit c = Commit() if parent: c.parents = [parent.id] c.tree = root.id c.committer = committer or self.committer c.author = author or c.committer t = time.localtime() c.commit_time = c.author_time = int(time.mktime(t)) c.commit_timezone = c.author_timezone = t.tm_isdst * 3600 - time.timezone c.encoding = "UTF-8" c.message = message objects.add(c) # write everything to disk for obj in objects: repo.object_store.add_object(obj) repo.refs['refs/heads/%s' % branch] = c.id return DulwichCommit(self, c)