コード例 #1
0
def get_temp_project(origin=None, repo_path=BARE_REPO_PATH):
    if origin:
        prefix_path = get_repo_root()
        temp_repo_path = tempfile.mkdtemp(suffix=".git",
                                          prefix="test_",
                                          dir=prefix_path)
        project_name = temp_repo_path[len(prefix_path) + 1:][:-4]
        project = CodeDoubanProject.add(project_name,
                                        TEMP_PROJECT_OWNER,
                                        TEMP_PROJECT_DESCRIPTION,
                                        fork_from=origin.id,
                                        create_trac=False)
        return project

    prefix_path = get_repo_root()
    temp_repo_path = tempfile.mkdtemp(suffix=".git",
                                      prefix="test_",
                                      dir=prefix_path)
    project_name = temp_repo_path[len(prefix_path) + 1:][:-4]
    project = CodeDoubanProject.add(project_name, TEMP_PROJECT_OWNER,
                                    TEMP_PROJECT_DESCRIPTION)

    shutil.rmtree(temp_repo_path)
    repo = Jagare(repo_path)
    repo.clone(temp_repo_path, bare=True)

    return project
コード例 #2
0
ファイル: utils.py プロジェクト: 000fan000/code
def get_temp_project(origin=None, repo_path=BARE_REPO_PATH):
    if origin:
        prefix_path = get_repo_root()
        temp_repo_path = tempfile.mkdtemp(suffix=".git",
                                          prefix="test_",
                                          dir=prefix_path)
        project_name = temp_repo_path[len(prefix_path) + 1:][:-4]
        project = CodeDoubanProject.add(project_name,
                                        TEMP_PROJECT_OWNER,
                                        TEMP_PROJECT_DESCRIPTION,
                                        fork_from=origin.id,
                                        create_trac=False)
        return project

    prefix_path = get_repo_root()
    temp_repo_path = tempfile.mkdtemp(suffix=".git",
                                      prefix="test_",
                                      dir=prefix_path)
    project_name = temp_repo_path[len(prefix_path) + 1:][:-4]
    project = CodeDoubanProject.add(project_name, TEMP_PROJECT_OWNER,
                                    TEMP_PROJECT_DESCRIPTION)

    shutil.rmtree(temp_repo_path)
    repo = Jagare(repo_path)
    repo.clone(temp_repo_path, bare=True)

    return project
コード例 #3
0
    def test_merge_commits(self):
        repo = Jagare(self.path)
        BR = 'br_test_merge'
        path = self.get_temp_path()

        # repo has work-tree
        repo.clone(path, branch=BARE_REPO_OTHER_BRANCH)
        repo = Jagare(os.path.join(path, '.git'))

        ret = repo.create_branch(BR, BARE_REPO_OTHER_BRANCH)
        assert ret

        commit_something(path, branch=BR)
        repo.update_head(BARE_REPO_OTHER_BRANCH)
        merge_index = repo.merge_commits(repo.head.target.hex, BR)
        assert merge_index['has_conflicts'] is False
コード例 #4
0
ファイル: test_merge.py プロジェクト: CMGS/ellen
    def test_merge_head(self):
        repo = Jagare(self.path)
        BR = 'br_test_merge'
        path = self.get_temp_path()

        # repo has work-tree
        repo.clone(path, branch=BARE_REPO_OTHER_BRANCH)
        repo = Jagare(os.path.join(path, '.git'))

        ret = repo.create_branch(BR, BARE_REPO_OTHER_BRANCH)
        assert ret

        commit_something(path, branch=BR)
        repo.update_head(BARE_REPO_OTHER_BRANCH)
        merge_result = repo.merge_head(BR)
        assert merge_result['is_fastforward']
コード例 #5
0
    def test_merge_head(self):
        repo = Jagare(self.path)
        BR = 'br_test_merge'
        path = self.get_temp_path()

        # repo has work-tree
        repo.clone(path, branch=BARE_REPO_OTHER_BRANCH)
        repo = Jagare(os.path.join(path, '.git'))

        ret = repo.create_branch(BR, BARE_REPO_OTHER_BRANCH)
        assert ret

        commit_something(path, branch=BR)
        repo.update_head(BARE_REPO_OTHER_BRANCH)
        merge_result = repo.merge_head(BR)
        assert merge_result['is_fastforward']
コード例 #6
0
ファイル: test_merge.py プロジェクト: CMGS/ellen
    def test_merge_commits(self):
        repo = Jagare(self.path)
        BR = 'br_test_merge'
        path = self.get_temp_path()

        # repo has work-tree
        repo.clone(path, branch=BARE_REPO_OTHER_BRANCH)
        repo = Jagare(os.path.join(path, '.git'))

        ret = repo.create_branch(BR, BARE_REPO_OTHER_BRANCH)
        assert ret

        commit_something(path, branch=BR)
        repo.update_head(BARE_REPO_OTHER_BRANCH)
        merge_index = repo.merge_commits(repo.head.target.hex, BR)
        assert merge_index['has_conflicts'] == False
コード例 #7
0
ファイル: test_branch.py プロジェクト: CMGS/ellen
 def test_delete(self):
     repo = Jagare(self.path)
     path = self.get_temp_path()
     clone_repo = repo.clone(path, bare=True)
     clone_repo.delete_branch('chinese')
     branches = clone_repo.branches
     assert 'chinese' in repo.branches
     assert 'chinese' not in branches
     assert 'master' in branches
コード例 #8
0
 def test_delete(self):
     repo = Jagare(self.path)
     path = self.get_temp_path()
     clone_repo = repo.clone(path, bare=True)
     clone_repo.delete_branch('chinese')
     branches = clone_repo.branches
     assert 'chinese' in repo.branches
     assert 'chinese' not in branches
     assert 'master' in branches
コード例 #9
0
ファイル: test_clone.py プロジェクト: CMGS/ellen
 def test_mirror(self):
     repo = Jagare(self.path)
     path = self.get_temp_path()
     clone_repo = repo.clone(path, mirror=True)
     pygit2_repo = Repository(path)
     assert is_repository(path) is True
     assert pygit2_repo.is_empty is False
     assert pygit2_repo.is_bare is True
     assert clone_repo.empty is False
     assert clone_repo.bare is True
コード例 #10
0
ファイル: test_clone.py プロジェクト: tclh123/ellen
 def test_simple(self):
     repo = Jagare(self.path)
     path = self.get_temp_path()
     clone_repo = repo.clone(path)
     pygit2_repo = Repository(path)
     assert is_repository(path) is True
     assert pygit2_repo.is_empty is False
     assert pygit2_repo.is_bare is False
     assert clone_repo.empty is False
     assert clone_repo.bare is False
コード例 #11
0
ファイル: test_merge.py プロジェクト: CMGS/ellen
    def _merge(self, no_ff):
        repo = Jagare(self.path)
        BR = 'br_test_merge'
        path = self.get_temp_path()

        # repo has work-tree
        repo.clone(path, branch=BARE_REPO_OTHER_BRANCH)
        repo = Jagare(os.path.join(path, '.git'))

        ret = repo.create_branch(BR, BARE_REPO_OTHER_BRANCH)
        assert ret
        sha1 = repo.sha(BARE_REPO_OTHER_BRANCH)

        commit_something(path, branch=BR)
        repo.update_head(BARE_REPO_OTHER_BRANCH)
        ret = repo.merge(BR, no_ff=no_ff)
        sha2 = repo.sha(BARE_REPO_OTHER_BRANCH)

        assert sha1 != sha2
        assert repo.sha(sha1) == sha1
コード例 #12
0
    def _merge(self, no_ff):
        repo = Jagare(self.path)
        BR = 'br_test_merge'
        path = self.get_temp_path()

        # repo has work-tree
        repo.clone(path, branch=BARE_REPO_OTHER_BRANCH)
        repo = Jagare(os.path.join(path, '.git'))

        ret = repo.create_branch(BR, BARE_REPO_OTHER_BRANCH)
        assert ret
        sha1 = repo.sha(BARE_REPO_OTHER_BRANCH)

        commit_something(path, branch=BR)
        repo.update_head(BARE_REPO_OTHER_BRANCH)
        ret = repo.merge(BR, no_ff=no_ff)
        sha2 = repo.sha(BARE_REPO_OTHER_BRANCH)

        assert sha1 != sha2
        assert repo.sha(sha1) == sha1
コード例 #13
0
ファイル: mixes.py プロジェクト: CMGS/jagare
def clone(name, clone_from):
    target_path = os.path.join(config.REPOS_PATH, name)
    target_path = endwith_git(target_path)

    clone_path = os.path.join(config.REPOS_PATH, clone_from)
    clone_path = endwith_git(clone_path)

    repository_exist = is_repository(target_path)

    if repository_exist:
        raise JagareError("repository already exists", 409)

    clone_repository_exist = is_repository(clone_path)

    if not clone_repository_exist:
        raise JagareError("clone repository does not exist", 400)

    jagare = Jagare(clone_path)
    jagare.clone(target_path, bare=True)

    return make_message_response("clone success")
コード例 #14
0
ファイル: jagare_handler.py プロジェクト: tclh123/jagare-rpc
 def clone_to(self, path, to_path, is_bare, branch, is_mirror, env):
     try:
         repo = Jagare(path)
         to_repo = repo.clone(path=to_path, bare=is_bare, branch=branch,
                              mirror=is_mirror, env=env)
         return Repository(path=to_repo.path,
                           is_empty=to_repo.empty,
                           is_bare=to_repo.bare,
                           workdir=to_repo.repository.workdir,
                           head=to_repo.head and to_repo.head.name)
     except Exception as e:
         raise ServiceUnavailable(repr(e))
コード例 #15
0
    def test_merge_flow(self):
        repo = Jagare(self.path)
        BR = 'br_test_merge'
        sha1 = repo.sha(BARE_REPO_OTHER_BRANCH)

        from_repo_path = self.get_temp_path()
        from_repo = repo.clone(from_repo_path,
                               branch=BARE_REPO_OTHER_BRANCH,
                               bare=True)
        ret = from_repo.create_branch(BR, BARE_REPO_OTHER_BRANCH)
        assert ret
        commit_something(from_repo_path, branch=BR)

        tmpdir = self.get_temp_path()

        # different repo
        sha = repo.merge_flow('lh',
                              '*****@*****.**',
                              'test_header',
                              'test_body',
                              tmpdir,
                              from_repo_path,
                              BR,
                              BARE_REPO_OTHER_BRANCH,
                              remote_name='hub/xxxproject',
                              no_ff=True)
        assert sha

        sha2 = repo.sha(BARE_REPO_OTHER_BRANCH)

        assert sha1 != sha2
        assert repo.sha(sha1) == sha1

        # same repo
        tmpdir2 = self.get_temp_path()
        from_sha1 = from_repo.sha(BARE_REPO_OTHER_BRANCH)
        assert from_sha1 == sha1
        sha = from_repo.merge_flow('lh',
                                   '*****@*****.**',
                                   'test_header',
                                   'test_body',
                                   tmpdir2,
                                   from_repo_path,
                                   BR,
                                   BARE_REPO_OTHER_BRANCH,
                                   no_ff=True)
        assert sha
        from_sha2 = from_repo.sha(BARE_REPO_OTHER_BRANCH)
        assert from_sha1 != from_sha2
        assert from_repo.sha(from_sha1) == from_sha1
コード例 #16
0
ファイル: Project.py プロジェクト: webangeld/py-deploy
    def cloneRepo(payload):
        """ clone to local """
        project_id = payload.get('project_id', None)
        pro = ProjectModel()
        project_info = pro.getInfoByProjectId(project_id)
        error = None
        if project_info:
            try:
                Jagare.clone(project_info['gitaddress'],
                             project_info['localaddress'],
                             callbacks=Jagare.auth(project_info['gituser'],
                                                   conf.auth.pubkey,
                                                   conf.auth.privkey, ''))
                res_string = 'ready'
            except Exception as e:
                res_string = 'clone_error'
                error = str(e)
        else:
            res_string = 'no_project'
            error = 'not found this project'

        pro.updateProjectState(project_id, res_string, error)

        return 'success'
コード例 #17
0
ファイル: jagare_handler.py プロジェクト: tclh123/jagare-rpc
 def clone_to(self, path, to_path, is_bare, branch, is_mirror, env):
     try:
         repo = Jagare(path)
         to_repo = repo.clone(path=to_path,
                              bare=is_bare,
                              branch=branch,
                              mirror=is_mirror,
                              env=env)
         return Repository(path=to_repo.path,
                           is_empty=to_repo.empty,
                           is_bare=to_repo.bare,
                           workdir=to_repo.repository.workdir,
                           head=to_repo.head and to_repo.head.name)
     except Exception as e:
         raise ServiceUnavailable(repr(e))
コード例 #18
0
ファイル: test_merge.py プロジェクト: tclh123/ellen
    def test_can_merge(self):
        repo = Jagare(self.path)
        BR = 'br_test_merge'

        from_repo_path = self.get_temp_path()
        from_repo = repo.clone(from_repo_path, branch=BARE_REPO_OTHER_BRANCH,
                               bare=True)
        ret = from_repo.create_branch(BR, BARE_REPO_OTHER_BRANCH)
        assert ret
        commit_something(from_repo_path, branch=BR)

        tmpdir = self.get_temp_path()

        ret = repo.can_merge(tmpdir,
                             from_repo_path, BR, BARE_REPO_OTHER_BRANCH,
                             remote_name='hub/xxxproject')
        assert ret is True
コード例 #19
0
    def test_can_merge(self):
        repo = Jagare(self.path)
        BR = 'br_test_merge'

        from_repo_path = self.get_temp_path()
        from_repo = repo.clone(from_repo_path,
                               branch=BARE_REPO_OTHER_BRANCH,
                               bare=True)
        ret = from_repo.create_branch(BR, BARE_REPO_OTHER_BRANCH)
        assert ret
        commit_something(from_repo_path, branch=BR)

        tmpdir = self.get_temp_path()

        ret = repo.can_merge(tmpdir,
                             from_repo_path,
                             BR,
                             BARE_REPO_OTHER_BRANCH,
                             remote_name='hub/xxxproject')
        assert ret is True
コード例 #20
0
ファイル: test_merge.py プロジェクト: tclh123/ellen
    def test_merge_flow(self):
        repo = Jagare(self.path)
        BR = 'br_test_merge'
        sha1 = repo.sha(BARE_REPO_OTHER_BRANCH)

        from_repo_path = self.get_temp_path()
        from_repo = repo.clone(from_repo_path, branch=BARE_REPO_OTHER_BRANCH,
                               bare=True)
        ret = from_repo.create_branch(BR, BARE_REPO_OTHER_BRANCH)
        assert ret
        commit_something(from_repo_path, branch=BR)

        tmpdir = self.get_temp_path()

        # different repo
        sha = repo.merge_flow('lh', '*****@*****.**',
                              'test_header', 'test_body', tmpdir,
                              from_repo_path, BR, BARE_REPO_OTHER_BRANCH,
                              remote_name='hub/xxxproject', no_ff=True)
        assert sha

        sha2 = repo.sha(BARE_REPO_OTHER_BRANCH)

        assert sha1 != sha2
        assert repo.sha(sha1) == sha1

        # same repo
        tmpdir2 = self.get_temp_path()
        from_sha1 = from_repo.sha(BARE_REPO_OTHER_BRANCH)
        assert from_sha1 == sha1
        sha = from_repo.merge_flow('lh', '*****@*****.**',
                                   'test_header', 'test_body', tmpdir2,
                                   from_repo_path, BR, BARE_REPO_OTHER_BRANCH,
                                   no_ff=True)
        assert sha
        from_sha2 = from_repo.sha(BARE_REPO_OTHER_BRANCH)
        assert from_sha1 != from_sha2
        assert from_repo.sha(from_sha1) == from_sha1
コード例 #21
0
ファイル: repo.py プロジェクト: banjin/code
class Repo(object):
    provided_features = []

    def __init__(self, path):
        self.type = "repo"
        self.path = path
        self.repo = Jagare(self.path)

    def provide(self, name):
        '''检查是否提供某功能,即是否提供某接口'''
        return name in self.provided_features

    @property
    def is_empty(self):
        return self.repo.empty

    @property
    def default_branch(self):
        branch = None
        head = self.repo.head
        if head:
            branch = head.name.rpartition('/')[-1]
        return branch

    def update_default_branch(self, name):
        branches = self.repo.branches
        if name not in branches:
            return None
        self.repo.update_head(name)

    def clone(self, path, bare=None, branch=None, mirror=None, env=None):
        self.repo.clone(path, bare=bare, branch=branch, mirror=mirror, env=env)

    def archive(self, name):
        content = self.repo.archive(name)
        outbuffer = StringIO()
        zipfile = gzip.GzipFile(mode='wb', compresslevel=6, fileobj=outbuffer)
        zipfile.writelines(content)
        zipfile.close()
        out = outbuffer.getvalue()
        return out

    def get_submodule(self, ref, path):
        path = path.strip()
        gitmodules = self.repo.show("%s:%s" % (ref, '.gitmodules'))
        if not gitmodules:
            return None
        submodules_lines = gitmodules["data"].split('\n')
        modules_str = '\n'.join([line.strip() for line in submodules_lines])
        config = ConfigParser.RawConfigParser()
        config.readfp(StringIO(modules_str))
        for section in config.sections():
            if config.has_option(section, 'path') and config.get(
                    section, 'path') == path:
                url = config.get(section, 'url')
                return Submodule(url, path)
        return None

    def get_file(self, ref, path):
        blob = self.repo.show("%s:%s" % (ref, path))
        if not blob:
            return None
        if blob['type'] != 'blob':
            return None
        # TODO: validate blob
        return Blob(self, blob)

    def get_file_by_lines(self, ref, path):
        blob = self.get_file(ref, path)
        # TODO: blob.size < xxx
        if not blob or blob.binary:
            return None
        if not blob.data:
            return []
        src = blob.data
        return src.splitlines()

    def get_file_n_lines(self, ref, path):
        lines = self.get_file_by_lines(ref, path)
        if lines:
            return len(lines)
        return 0

    def get_commits(self, *w, **kw):
        commits = self.repo.rev_list(*w, **kw)
        # TODO: validate commits
        return [Commit(self, commit) for commit in commits]

    def get_raw_diff(self, ref, from_ref=None, **kw):
        ''' get Jagare formated diff dict '''
        return self.repo.diff(ref, from_ref=from_ref, **kw)

    def get_diff(self,
                 ref=None,
                 from_ref=None,
                 linecomments=[],
                 raw_diff=None,
                 **kw):
        ''' get ngit wrapped diff object '''
        _raw_diff = None
        if raw_diff:
            _raw_diff = raw_diff
        elif ref:
            _raw_diff = self.get_raw_diff(ref, from_ref=from_ref, **kw)
        if _raw_diff:
            return Diff(self, _raw_diff, linecomments)
        else:
            return None

    def get_diff_length(self, ref, from_ref=None, **kw):
        _raw_diff = self.get_raw_diff(ref, from_ref=from_ref, **kw)
        return len(_raw_diff['patches']) if _raw_diff else 0

    def get_last_commit(self, ref, path=None):
        if not path:
            return self.get_commit(ref)
        commit = self.repo.rev_list(ref, path=path, max_count=1)
        if not commit:
            return None
        commit = commit[0]
        commit = Commit(self, commit)
        return commit

    def get_commit(self, ref):
        sha = self.repo.resolve_commit(ref)
        if not sha:
            return None
        commit = self.repo.show(sha)
        if not commit:
            return None
        # TODO: validate commit
        return Commit(self, commit)

    def delete_branch(self, name):
        self.repo.delete_branch(name)

    def get_path_by_ref(self, ref):
        ''' get blob or tree '''
        path = self.repo.show(ref)
        if not path:
            return None
        if path['type'] == 'tree':
            path = Tree(self, path['entries'])
        elif path['type'] == 'blob':
            path = Blob(self, path)
        else:
            path = None
        return path

    def get_path(self, ref, path):
        _item = self.repo.show("%s:%s" % (ref, path))
        if not _item:
            return None
        if _item['type'] == 'tree':
            item = Tree(self, _item['entries'])
        elif _item['type'] == 'blob':
            item = Blob(self, _item)
        else:
            item = None
        return item
コード例 #22
0
ファイル: repo.py プロジェクト: 4T-Shirt/code
class Repo(object):
    provided_features = []

    def __init__(self, path):
        self.type = "repo"
        self.path = path
        self.repo = Jagare(self.path)

    def provide(self, name):
        '''检查是否提供某功能,即是否提供某接口'''
        return name in self.provided_features

    @property
    def is_empty(self):
        return self.repo.empty

    @property
    def default_branch(self):
        branch = None
        head = self.repo.head
        if head:
            branch = head.name.rpartition('/')[-1]
        return branch

    def update_default_branch(self, name):
        branches = self.repo.branches
        if name not in branches:
            return None
        self.repo.update_head(name)

    def clone(self, path, bare=None, branch=None, mirror=None, env=None):
        self.repo.clone(path,
                        bare=bare, branch=branch,
                        mirror=mirror, env=env)

    def archive(self, name):
        content = self.repo.archive(name)
        outbuffer = StringIO()
        zipfile = gzip.GzipFile(mode='wb', compresslevel=6, fileobj=outbuffer)
        zipfile.writelines(content)
        zipfile.close()
        out = outbuffer.getvalue()
        return out

    def get_submodule(self, ref, path):
        path = path.strip()
        gitmodules = self.repo.show("%s:%s" % (ref, '.gitmodules'))
        if not gitmodules:
            return None
        submodules_lines = gitmodules["data"].split('\n')
        modules_str = '\n'.join([line.strip() for line in submodules_lines])
        config = ConfigParser.RawConfigParser()
        config.readfp(StringIO(modules_str))
        for section in config.sections():
            if config.has_option(section, 'path') and config.get(section, 'path')==path:
                url = config.get(section, 'url')
                return Submodule(url, path)
        return None


    def get_file(self, ref, path):
        blob = self.repo.show("%s:%s" % (ref, path))
        if not blob:
            return None
        if blob['type'] != 'blob':
            return None
        # TODO: validate blob
        return Blob(self, blob)

    def get_file_by_lines(self, ref, path):
        blob = self.get_file(ref, path)
        # TODO: blob.size < xxx
        if not blob or blob.binary:
            return None
        if not blob.data:
            return []
        src = blob.data
        return src.splitlines()

    def get_file_n_lines(self, ref, path):
        lines = self.get_file_by_lines(ref, path)
        if lines:
            return len(lines)
        return 0

    def get_commits(self, *w, **kw):
        commits = self.repo.rev_list(*w, **kw)
        # TODO: validate commits
        return [Commit(self, commit) for commit in commits]

    def get_raw_diff(self, ref, from_ref=None, **kw):
        ''' get Jagare formated diff dict '''
        return self.repo.diff(ref, from_ref=from_ref, **kw)

    def get_diff(self, ref=None, from_ref=None,
                 linecomments=[], raw_diff=None, **kw):
        ''' get ngit wrapped diff object '''
        _raw_diff = None
        if raw_diff:
            _raw_diff = raw_diff
        elif ref:
            _raw_diff = self.get_raw_diff(ref, from_ref=from_ref, **kw)
        if _raw_diff:
            return Diff(self, _raw_diff, linecomments)
        else:
            return None

    def get_diff_length(self, ref, from_ref=None, **kw):
        _raw_diff = self.get_raw_diff(ref, from_ref=from_ref, **kw)
        return len(_raw_diff['patches']) if _raw_diff else 0

    def get_last_commit(self, ref, path=None):
        if not path:
            return self.get_commit(ref)
        commit = self.repo.rev_list(ref, path=path, max_count=1)
        if not commit:
            return None
        commit = commit[0]
        commit = Commit(self, commit)
        return commit

    def get_commit(self, ref):
        sha = self.repo.resolve_commit(ref)
        if not sha:
            return None
        commit = self.repo.show(sha)
        if not commit:
            return None
        # TODO: validate commit
        return Commit(self, commit)

    def delete_branch(self, name):
        self.repo.delete_branch(name)

    def get_path_by_ref(self, ref):
        ''' get blob or tree '''
        path = self.repo.show(ref)
        if not path:
            return None
        if path['type'] == 'tree':
            path = Tree(self, path['entries'])
        elif path['type'] == 'blob':
            path = Blob(self, path)
        else:
            path = None
        return path

    def get_path(self, ref, path):
        _item = self.repo.show("%s:%s" % (ref, path))
        if not _item:
            return None
        if _item['type'] == 'tree':
            item = Tree(self, _item['entries'])
        elif _item['type'] == 'blob':
            item = Blob(self, _item)
        else:
            item = None
        return item
コード例 #23
0
ファイル: repo.py プロジェクト: 000fan000/code
class Repo(object):
    provided_features = []

    def __init__(self, path):
        self.type = "repo"
        self.path = path
        self.repo = Jagare(self.path)

    def provide(self, name):
        '''检查是否提供某功能,即是否提供某接口'''
        return name in self.provided_features

    @property
    def empty(self):
        return self.is_empty

    @property
    def is_empty(self):
        return self.repo.empty

    @property
    def default_branch(self):
        branch = ''
        head = self.repo.head
        if head:
            branch = head.name[REFS_HEADS_PREFIX_LENGTH:]
        return branch

    def update_default_branch(self, name):
        branches = self.repo.branches
        if name not in branches:
            return None
        self.repo.update_head(name)

    def clone(self, path, bare=None, branch=None,
              mirror=None, env=None, shared=None):
        self.repo.clone(path,
                        bare=bare, branch=branch,
                        mirror=mirror, env=env)
        # shared=shared) why?

    def archive(self, name, ref='master', ext='tar.gz'):
        content = self.repo.archive(name, ref=ref)
        if ext == 'tar':
            return content
        outbuffer = StringIO()
        zipfile = gzip.GzipFile(mode='wb', compresslevel=6, fileobj=outbuffer)
        zipfile.write(content)
        zipfile.close()
        out = outbuffer.getvalue()
        return out

    def get_submodule(self, ref, path):
        path = path.strip()
        gitmodules = self.repo.show("%s:%s" % (ref, '.gitmodules'))
        if not gitmodules:
            return None
        submodules_lines = gitmodules["data"].split('\n')
        modules_str = '\n'.join([line.strip() for line in submodules_lines])
        config = ConfigParser.RawConfigParser()
        config.readfp(StringIO(modules_str))
        for section in config.sections():
            if config.has_option(section, 'path') and config.get(
                    section, 'path') == path:
                url = config.get(section, 'url')
                return Submodule(url, path)
        return None

    def get_file(self, ref, path):
        blob = self.repo.show("%s:%s" % (ref, path))
        if not blob:
            return None
        if blob['type'] != 'blob':
            return None
        # TODO: validate blob
        return Blob(self, blob)

    def get_file_by_lines(self, ref, path):
        blob = self.get_file(ref, path)
        # TODO: blob.size < xxx
        if not blob or blob.binary:
            return None
        if not blob.data:
            return []
        src = blob.data
        return src.splitlines()

    def get_file_n_lines(self, ref, path):
        lines = self.get_file_by_lines(ref, path)
        if lines:
            return len(lines)
        return 0

    def get_commits(self, to_ref, from_ref=None, path=None, skip=0,
                    max_count=0, author=None, query=None, first_parent=None,
                    since=0, no_merges=None):
        commits = self.repo.rev_list(to_ref=to_ref, from_ref=from_ref,
                                     path=path, skip=skip,
                                     max_count=max_count, author=author,
                                     query=query, first_parent=first_parent,
                                     since=since, no_merges=no_merges)
        return [Commit(self, commit) for commit in commits]

    def get_raw_diff(self, ref, from_ref=None, paths=None, **kw):
        ''' get Jagare formated diff dict '''
        try:
            diff = self.repo.diff(ref, from_ref=from_ref, paths=paths, **kw)
        except KeyError:
            return None
        return diff

    def get_diff(self, ref=None, from_ref=None,
                 linecomments=[], raw_diff=None, paths=None, **kw):
        ''' get ngit wrapped diff object '''
        _raw_diff = None
        if raw_diff:
            _raw_diff = raw_diff
        elif ref:
            _raw_diff = self.get_raw_diff(ref, from_ref=from_ref,
                                          paths=paths, **kw)
        if _raw_diff:
            return Diff(self, _raw_diff, linecomments)
        else:
            return None

    def get_diff_length(self, ref, from_ref=None, **kw):
        _raw_diff = self.get_raw_diff(ref, from_ref=from_ref, **kw)
        return len(_raw_diff['patches']) if _raw_diff else 0

    def get_last_commit(self, ref, path=None, no_merges=False):
        if not path:
            return self.get_commit(ref)
        commit = self.repo.rev_list(ref, path=path, max_count=1,
                                    no_merges=no_merges)
        if not commit:
            return None
        commit = commit[0]
        commit = Commit(self, commit)
        return commit

    def get_previours_commit(self, ref, path):
        """previours commit that touch the specified path"""
        commits = self.repo.rev_list(ref, path=path, max_count=2,
                                     no_merges=True)
        for commit in commits:
            if commit['sha'] != self.repo.sha(ref):
                return Commit(self, commit)
        return None

    def get_commit(self, ref):
        sha = self.repo.resolve_commit(ref)
        if not sha:
            return None
        commit = self.repo.show(sha)
        if not commit:
            return None
        # TODO: validate commit
        return Commit(self, commit)

    def delete_branch(self, name):
        self.repo.delete_branch(name)

    def get_path_by_ref(self, ref):
        ''' get blob or tree '''
        path = self.repo.show(ref)
        if not path:
            return None
        if path['type'] == 'tree':
            path = Tree(self, path['entries'])
        elif path['type'] == 'blob':
            path = Blob(self, path)
        else:
            path = None
        return path

    def get_path(self, ref, path):
        _item = self.repo.show("%s:%s" % (ref, path))
        if not _item:
            return None
        if _item['type'] == 'tree':
            item = Tree(self, _item['entries'])
        elif _item['type'] == 'blob':
            item = Blob(self, _item)
        else:
            item = None
        return item

    def get_last_update_timestamp(self):
        commit = self.get_last_commit('HEAD')
        if not commit:
            return 0
        return int(commit.author_timestamp)