示例#1
0
文件: backend.py 项目: jcteng/vacuous
    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
示例#2
0
文件: backend.py 项目: jcteng/vacuous
 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
示例#3
0
文件: backend.py 项目: jcteng/vacuous
    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)