예제 #1
0
    def test_commit_serialization(self):
        assert_commit_serialization(self.gitrwrepo, self.gitrwrepo.head, True)

        rwrepo = self.gitrwrepo
        make_object = rwrepo.odb.store
        # direct serialization - deserialization can be tested afterwards
        # serialization is probably limited on IO
        hc = rwrepo.commit(rwrepo.head)

        nc = 5000
        st = time()
        for i in xrange(nc):
            cm = Commit(rwrepo, Commit.NULL_BIN_SHA, hc.tree,
                        hc.author, hc.authored_date, hc.author_tz_offset,
                        hc.committer, hc.committed_date, hc.committer_tz_offset,
                        str(i), parents=hc.parents, encoding=hc.encoding)

            stream = BytesIO()
            cm._serialize(stream)
            slen = stream.tell()
            stream.seek(0)

            cm.binsha = make_object(IStream(Commit.type, slen, stream)).binsha
        # END commit creation
        elapsed = time() - st

        print("Serialized %i commits to loose objects in %f s ( %f commits / s )"
              % (nc, elapsed, nc / elapsed), file=sys.stderr)
예제 #2
0
    def create_commit(self, repo: Repository, commit: git.Commit):
        c = Commit(repo=repo)
        c.author = commit.author
        c.authored_datetime = commit.authored_datetime
        c.message = commit.message
        c.hex_sha = commit.hexsha
        c.bin_sha = commit.binsha
        c.committed_datetime = commit.committed_datetime
        c.count = commit.count()

        try:
            diffs = commit.diff(
                commit.hexsha,
                create_patch=True,
                ignore_blank_lines=True,
                ignore_space_at_eol=True,
                diff_filter="adm",
            )

            diff_text = "\n".join([str(x) for x in diffs])
            c.line_additions = len(re.findall(r"^\+ ", diff_text,
                                              re.MULTILINE))
            c.line_subtractions = len(
                re.findall(r"^- ", diff_text, re.MULTILINE))
        except git.GitCommandError:
            pass

        return c
예제 #3
0
    def test_serialization_unicode_support(self):
        assert Commit.default_encoding.lower() == 'utf-8'

        # create a commit with unicode in the message, and the author's name
        # Verify its serialization and deserialization
        cmt = self.rorepo.commit('0.1.6')
        assert isinstance(cmt.message, text_type)     # it automatically decodes it as such
        assert isinstance(cmt.author.name, text_type)  # same here

        cmt.message = u"üäêèß"
        assert len(cmt.message) == 5

        cmt.author.name = u"äüß"
        assert len(cmt.author.name) == 3

        cstream = BytesIO()
        cmt._serialize(cstream)
        cstream.seek(0)
        assert len(cstream.getvalue())

        ncmt = Commit(self.rorepo, cmt.binsha)
        ncmt._deserialize(cstream)

        assert cmt.author.name == ncmt.author.name
        assert cmt.message == ncmt.message
        # actually, it can't be printed in a shell as repr wants to have ascii only
        # it appears
        cmt.author.__repr__()
예제 #4
0
    def git_repo(self):
        with mock.patch("publish.Repo", spec=Repo, spec_set=True) as mock_repo:
            commits = [
                Commit(mock_repo, _h2b("111111"), message="First commit", parents=tuple()),
                Commit(mock_repo, _h2b("222222"), message="Second commit", parents=("111111",)),
                Commit(mock_repo, _h2b("333333"), message="Third commit", parents=("222222",))
            ]
            mock_repo.iter_commits.return_value = commits
            rev_parse_returns = {
                "heads/master": commits[-1],
                PREVIOUS_TAG: TagObject(mock_repo, _h2b("aaaaaa"), object=commits[-2], tag=PREVIOUS_TAG),
                CURRENT_TAG: TagObject(mock_repo, _h2b("bbbbbb"), object=commits[-1], tag=CURRENT_TAG)
            }
            mock_repo.rev_parse.side_effect = lambda x: rev_parse_returns[x]
            mock_repo.git.rev_parse.side_effect = lambda x, **kwargs: x

            def describe(rev=None, **kwargs):
                print("call to describe(%r, %r)" % (rev, kwargs))
                if rev is None:
                    return CURRENT_TAG
                if rev.endswith("^"):
                    if rev.startswith(CURRENT_TAG):
                        return PREVIOUS_TAG
                    raise GitCommandError("describe", "failed")
                raise AssertionError("Test wants to describe something unexpected: rev=%r, kwargs=%r" % (rev, kwargs))

            mock_repo.git.describe.side_effect = describe
            yield mock_repo
예제 #5
0
    def test_iteration(self):
        # we can iterate commits
        all_commits = Commit.list_items(self.rorepo, self.rorepo.head)
        assert all_commits
        self.assertEqual(all_commits, list(self.rorepo.iter_commits()))

        # this includes merge commits
        mcomit = self.rorepo.commit('d884adc80c80300b4cc05321494713904ef1df2d')
        assert mcomit in all_commits

        # we can limit the result to paths
        ltd_commits = list(self.rorepo.iter_commits(paths='CHANGES'))
        assert ltd_commits and len(ltd_commits) < len(all_commits)

        # show commits of multiple paths, resulting in a union of commits
        less_ltd_commits = list(
            Commit.iter_items(self.rorepo,
                              'master',
                              paths=('CHANGES', 'AUTHORS')))
        assert len(ltd_commits) < len(less_ltd_commits)

        class Child(Commit):
            def __init__(self, *args, **kwargs):
                super(Child, self).__init__(*args, **kwargs)

        child_commits = list(
            Child.iter_items(self.rorepo,
                             'master',
                             paths=('CHANGES', 'AUTHORS')))
        assert type(child_commits[0]) == Child
예제 #6
0
def git_commit():
    time = "Sat, 13 Dec 2019 12:40:00 +0000"
    repo = Repo(path)
    os.environ["GIT_AUTHOR_DATE"] = time
    os.environ["GIT_COMMITTER_DATE"] = time
    repo.git.add('--all')
    comm = Commit(repo, Commit.NULL_BIN_SHA, None, None, time, 0, None, time,
                  0, COMMIT_MESSAGE, None, None)
    #for x in range(0, 100000):
    #try:
    comm.message = 'noonce' + COMMIT_MESSAGE
    print(comm.hexsha)
예제 #7
0
    def assert_commit_serialization(self,
                                    rwrepo,
                                    commit_id,
                                    print_performance_info=False):
        """traverse all commits in the history of commit identified by commit_id and check
        if the serialization works.
        :param print_performance_info: if True, we will show how fast we are"""
        ns = 0  # num serializations
        nds = 0  # num deserializations

        st = time.time()
        for cm in rwrepo.commit(commit_id).traverse():
            nds += 1

            # assert that we deserialize commits correctly, hence we get the same
            # sha on serialization
            stream = BytesIO()
            cm._serialize(stream)
            ns += 1
            streamlen = stream.tell()
            stream.seek(0)

            istream = rwrepo.odb.store(IStream(Commit.type, streamlen, stream))
            self.assertEqual(istream.hexsha, cm.hexsha.encode('ascii'))

            nc = Commit(rwrepo, Commit.NULL_BIN_SHA, cm.tree, cm.author,
                        cm.authored_date, cm.author_tz_offset, cm.committer,
                        cm.committed_date, cm.committer_tz_offset, cm.message,
                        cm.parents, cm.encoding)

            self.assertEqual(nc.parents, cm.parents)
            stream = BytesIO()
            nc._serialize(stream)
            ns += 1
            streamlen = stream.tell()
            stream.seek(0)

            # reuse istream
            istream.size = streamlen
            istream.stream = stream
            istream.binsha = None
            nc.binsha = rwrepo.odb.store(istream).binsha

            # if it worked, we have exactly the same contents !
            self.assertEqual(nc.hexsha, cm.hexsha)
        # END check commits
        elapsed = time.time() - st

        if print_performance_info:
            print(
                "Serialized %i and deserialized %i commits in %f s ( (%f, %f) commits / s"
                % (ns, nds, elapsed, ns / elapsed, nds / elapsed),
                file=sys.stderr)
예제 #8
0
def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False):
    """traverse all commits in the history of commit identified by commit_id and check
    if the serialization works.
    :param print_performance_info: if True, we will show how fast we are"""
    ns = 0      # num serializations
    nds = 0     # num deserializations

    st = time.time()
    for cm in rwrepo.commit(commit_id).traverse():
        nds += 1

        # assert that we deserialize commits correctly, hence we get the same
        # sha on serialization
        stream = BytesIO()
        cm._serialize(stream)
        ns += 1
        streamlen = stream.tell()
        stream.seek(0)

        istream = rwrepo.odb.store(IStream(Commit.type, streamlen, stream))
        assert istream.hexsha == cm.hexsha.encode('ascii')

        nc = Commit(rwrepo, Commit.NULL_BIN_SHA, cm.tree,
                    cm.author, cm.authored_date, cm.author_tz_offset,
                    cm.committer, cm.committed_date, cm.committer_tz_offset,
                    cm.message, cm.parents, cm.encoding)

        assert nc.parents == cm.parents
        stream = BytesIO()
        nc._serialize(stream)
        ns += 1
        streamlen = stream.tell()
        stream.seek(0)

        # reuse istream
        istream.size = streamlen
        istream.stream = stream
        istream.binsha = None
        nc.binsha = rwrepo.odb.store(istream).binsha

        # if it worked, we have exactly the same contents !
        assert nc.hexsha == cm.hexsha
    # END check commits
    elapsed = time.time() - st

    if print_performance_info:
        print("Serialized %i and deserialized %i commits in %f s ( (%f, %f) commits / s"
              % (ns, nds, elapsed, ns / elapsed, nds / elapsed), file=sys.stderr)
예제 #9
0
파일: gitutils.py 프로젝트: jydennis/thexp
def archive(test_viewer: TestViewer) -> Experiment:
    """
    将某次 test 对应 commit 的文件打包,相关命令为
        git archive -o <filename> <commit-id>
    :param test_viewer:
    :return:
    """
    repo = test_viewer.repo
    commit = Commit(repo, hex_to_bin(test_viewer.json_info['commit_hash']))

    old_path = os.getcwd()
    os.chdir(commit.tree.abspath)
    exp = Experiment('Archive')

    revert_path = exp.makedir('archive')
    revert_fn = os.path.join(revert_path, "file.zip")
    exp.regist_plugin('archive', {
        'file': revert_fn,
        'test_name': test_viewer.test_name
    })
    with open(revert_fn, 'wb') as w:
        commit.repo.archive(w, commit)

    exp.end()
    os.chdir(old_path)
    return exp
예제 #10
0
    def assert_gpgsig_deserialization(self, cstream):
        assert 'gpgsig' in 'precondition: need gpgsig'

        class RepoMock:
            def __init__(self, bytestr):
                self.bytestr = bytestr

            @property
            def odb(self):
                class ODBMock:
                    def __init__(self, bytestr):
                        self.bytestr = bytestr

                    def stream(self, *args):
                        stream = Mock(spec_set=['read'],
                                      return_value=self.bytestr)
                        stream.read.return_value = self.bytestr
                        return ('binsha', 'typename', 'size', stream)

                return ODBMock(self.bytestr)

        repo_mock = RepoMock(cstream.getvalue())
        for field in Commit.__slots__:
            c = Commit(repo_mock, b'x' * 20)
            assert getattr(c, field) is not None
예제 #11
0
 def test_list(self):
     # This doesn't work anymore, as we will either attempt getattr with bytes, or compare 20 byte string
     # with actual 20 byte bytes. This usage makes no sense anyway
     assert isinstance(
         Commit.list_items(
             self.rorepo, '0.1.5',
             max_count=5)['5117c9c8a4d3af19a9958677e45cda9269de1541'],
         Commit)
예제 #12
0
    def test_iteration(self):
        # we can iterate commits
        all_commits = Commit.list_items(self.rorepo, self.rorepo.head)
        assert all_commits
        assert all_commits == list(self.rorepo.iter_commits())

        # this includes merge commits
        mcomit = self.rorepo.commit('d884adc80c80300b4cc05321494713904ef1df2d')
        assert mcomit in all_commits

        # we can limit the result to paths
        ltd_commits = list(self.rorepo.iter_commits(paths='CHANGES'))
        assert ltd_commits and len(ltd_commits) < len(all_commits)

        # show commits of multiple paths, resulting in a union of commits
        less_ltd_commits = list(Commit.iter_items(self.rorepo, 'master', paths=('CHANGES', 'AUTHORS')))
        assert len(ltd_commits) < len(less_ltd_commits)
예제 #13
0
def get_files_list(args, head_commit: Commit,
                   latest_commit: Commit) -> List[RemoteFile]:
    diff_list = head_commit.diff(latest_commit.hexsha)
    return [
        RemoteFile(args.file_url_pattern,
                   path=name,
                   revision=head_commit.hexsha)
        for name in _get_files_in_diff_list(diff_list)
    ]
예제 #14
0
 def __init__(self, url_pattern: str, source: Commit):
     self.revision: str = source.hexsha
     self.message: str = source.message
     author: Actor = source.author
     self.author = RemoteUser(author.name, author.email)
     self.date: datetime = source.committed_datetime
     self.files: Set[str] = set()
     self.parents: Set[str] = set(p.hexsha for p in source.iter_parents())
     self.url = url_pattern.replace("REVISION", self.revision)
예제 #15
0
 def get_commit_diff(commit: git.Commit) -> List[git.Diff]:
     """Get modified files of the given commit."""
     if len(commit.parents) == 1:
         return commit.parents[0].diff(commit, create_patch=True)
     elif len(commit.parents) == 0:
         # First commit in the repo
         return commit.diff(git.NULL_TREE, create_patch=True)
     else:
         # Probably a merge commit, we can't do much about it
         return []
예제 #16
0
def get_news_between_commits(commit1: Commit, commit2: Commit,
                             news_fragment_dir: Path) -> List[News]:
    diffs = commit1.diff(commit2)
    paths = [
        diff.a_path for diff in diffs if diff.change_type in
        ("A", "C", "R", "M") and news_fragment_dir == Path(diff.a_path).parent
    ]
    return [
        News(file_name=path, content=file_content_from_commit(commit2, path))
        for path in paths
    ]
예제 #17
0
def get_commits_not_in_prs(start_ref, end_ref):
    """
    Return a tuple of commits that exist between start_ref and end_ref,
    but were not merged to the end_ref. If everyone is following the
    pull request process correctly, this should return an empty tuple.
    """
    return tuple(Commit.iter_items(
        repo,
        "{start}..{end}".format(start=start_ref, end=end_ref),
        first_parent=True, no_merges=True,
    ))
예제 #18
0
 def test_commit_iteration(self):
     # bound to stream parsing performance
     nc = 0
     st = time()
     for c in Commit.iter_items(self.gitrorepo, self.gitrorepo.head):
         nc += 1
         self._query_commit_info(c)
     # END for each traversed commit
     elapsed_time = time() - st
     print("Iterated %i Commits in %s [s] ( %f commits/s )"
           % (nc, elapsed_time, nc / elapsed_time), file=sys.stderr)
예제 #19
0
 def test_commit_iteration(self):
     # bound to stream parsing performance
     nc = 0
     st = time()
     for c in Commit.iter_items(self.gitrorepo, self.gitrorepo.head):
         nc += 1
         self._query_commit_info(c)
     # END for each traversed commit
     elapsed_time = time() - st
     print("Iterated %i Commits in %s [s] ( %f commits/s )" %
           (nc, elapsed_time, nc / elapsed_time),
           file=sys.stderr)
예제 #20
0
    def test_commit_serialization(self):
        self.assert_commit_serialization(self.gitrwrepo, '58c78e6', True)

        rwrepo = self.gitrwrepo
        make_object = rwrepo.odb.store
        # direct serialization - deserialization can be tested afterwards
        # serialization is probably limited on IO
        hc = rwrepo.commit(rwrepo.head)

        nc = 5000
        st = time()
        for i in range(nc):
            cm = Commit(rwrepo,
                        Commit.NULL_BIN_SHA,
                        hc.tree,
                        hc.author,
                        hc.authored_date,
                        hc.author_tz_offset,
                        hc.committer,
                        hc.committed_date,
                        hc.committer_tz_offset,
                        str(i),
                        parents=hc.parents,
                        encoding=hc.encoding)

            stream = BytesIO()
            cm._serialize(stream)
            slen = stream.tell()
            stream.seek(0)

            cm.binsha = make_object(IStream(Commit.type, slen, stream)).binsha
        # END commit creation
        elapsed = time() - st

        print(
            "Serialized %i commits to loose objects in %f s ( %f commits / s )"
            % (nc, elapsed, nc / elapsed),
            file=sys.stderr)
예제 #21
0
def modified_files_for_commit(commit: Commit, log: Any) -> Set:
    """
    Return modified, added, renamed, and removed files for a given commit and its parent.

    :param commit: The commit to query.
    :param log: A logger.
    :return: The set of changed files.
    """
    if not commit.parents:
        return set()

    parent = commit.parents[0]
    diff = commit.diff(parent)
    return get_changed_files(diff, log)
예제 #22
0
    def _find_parents(self, child: Commit, file_path):
        history = list(child.iter_parents(paths=file_path))
        from_id = self._map[child.hexsha]

        if len(history) >= 1:
            parent_1 = history[0]
            to_id = self._map[parent_1.hexsha]
            self.edges.append((from_id, to_id))

            if len(history) >= 2:
                parent_2 = history[1]

                hist_p_1 = list(parent_1.iter_parents(paths=file_path))
                if parent_2 not in hist_p_1:
                    to_id = self._map[parent_2.hexsha]
                    self.edges.append((from_id, to_id))
예제 #23
0
def get_modifications(commit: Commit) -> List[Modification]:
    """Extracts all the modifications from a given commit.

    Arguments:
        commit {Commit} -- A git commit.

    Returns:
        List[Modification] -- All modifications contained within the git commit.
    """

    if commit.parents:
        diffs = commit.parents[0].diff(commit)
    else:
        # initial commit
        diffs = commit.diff(NULL_TREE)

    return [Modification.from_diff(d, tree=commit.tree) for d in diffs]
예제 #24
0
 def _do_commit (self, repo, head, tree_binsha, msg, parent=None):
     """ if parent parameter is None, we make it default to be [head.commit]
         
         return new commit's hexsha, on error return None and output error
         """
     assert (repo)
     assert head is None or isinstance (head, HEAD) or isinstance (head, Head)
     assert msg != None
     if parent is None:
         try:
             parent = [head.commit]
         except ValueError:
             pass
     new_commit = Commit.create_from_tree (repo, Tree (repo, tree_binsha), msg, \
                         parent_commits=parent, head=False) # because the first commit has no parent, parameter head==True likely fails
     head.commit = new_commit #modify head's ref to commit
     return new_commit
예제 #25
0
파일: git.py 프로젝트: tonybaloney/wily
def whatchanged(commit_a: Commit,
                commit_b: Commit) -> Tuple[List[str], List[str], List[str]]:
    """Get files added, modified and deleted between commits."""
    diffs = commit_b.diff(commit_a)
    added_files = []
    modified_files = []
    deleted_files = []
    for diff in diffs:
        if diff.new_file:
            added_files.append(diff.b_path)
        elif diff.deleted_file:
            deleted_files.append(diff.a_path)
        elif diff.renamed_file:
            added_files.append(diff.b_path)
            deleted_files.append(diff.a_path)
        elif diff.change_type == "M":
            modified_files.append(diff.a_path)
    return added_files, modified_files, deleted_files
예제 #26
0
    def test_rev_list_bisect_all(self):
        """
        'git rev-list --bisect-all' returns additional information
        in the commit header.  This test ensures that we properly parse it.
        """
        revs = self.rorepo.git.rev_list('933d23bf95a5bd1624fbcdf328d904e1fa173474',
                                        first_parent=True,
                                        bisect_all=True)

        commits = Commit._iter_from_process_or_stream(self.rorepo, StringProcessAdapter(revs.encode('ascii')))
        expected_ids = (
            '7156cece3c49544abb6bf7a0c218eb36646fad6d',
            '1f66cfbbce58b4b552b041707a12d437cc5f400a',
            '33ebe7acec14b25c5f84f35a664803fcab2f7781',
            '933d23bf95a5bd1624fbcdf328d904e1fa173474'
        )
        for sha1, commit in zip(expected_ids, commits):
            assert_equal(sha1, commit.hexsha)
예제 #27
0
파일: crate.py 프로젝트: wangkirin/romt
def blobs_in_commit_range(
        start_commit: git.Commit, end_commit: git.Commit
) -> Generator[Tuple[str, bytes, bytes], None, None]:
    """Generate (blob_path, start_blob, end_blob)."""
    if start_commit:
        for diff in end_commit.diff(start_commit):
            # diff.a_xxx goes with end_commit.
            if diff.a_blob:
                a_blob = diff.a_blob.data_stream.read()
                if diff.b_blob:
                    b_blob = diff.b_blob.data_stream.read()
                else:
                    b_blob = b""
                yield diff.a_path, b_blob, a_blob
    else:
        for item in end_commit.tree.traverse():
            if item.type == "blob":
                yield item.path, b"", item.data_stream.read()
예제 #28
0
def get_commit_diff(commit: git.Commit) -> List[git.Diff]:
    """Get modified files of the given commit.

    Args:
        commit: Commit to get the diff of.

    Returns:
        List of git.Diff containing information about the modified files
        in the given commit.
    """
    if len(commit.parents) == 1:
        return commit.parents[0].diff(commit, create_patch=True)
    elif len(commit.parents) == 0:
        # First commit in the repo
        return commit.diff(git.NULL_TREE, create_patch=True)
    else:
        # Probably a merge commit, we can't do much about it
        return []
예제 #29
0
파일: gitutils.py 프로젝트: jydennis/thexp
def reset(test_viewer: TestViewer) -> Experiment:
    """
    将工作目录中的文件恢复到某个commit
        恢复快照的 git 流程:
            git branch experiment
            git add . & git commit -m ... // 保证文件最新,防止冲突报错,这一步由 Experiment() 代为完成
            git checkout <commit-id> // 恢复文件到 <commit-id>
            git checkout -b reset // 将当前状态附到新的临时分支 reset 上
            git branch experiment // 切换回 experiment 分支
            git add . & git commit -m ... // 将当前状态重新提交到最新
                // 此时experiment 中最新的commit 为恢复的<commit-id>
            git branch -D reset  // 删除临时分支
            git branch master // 最终回到原来分支,保证除文件变动外git状态完好
    :param test_viewer: TestViewer
    :return:
    """
    repo = test_viewer.repo
    commit = Commit(repo, hex_to_bin(test_viewer.json_info['commit_hash']))

    old_path = os.getcwd()
    os.chdir(commit.tree.abspath)
    exp = Experiment('Reset')

    repo = commit.repo  # type:Repo
    with branch(commit.repo, _GITKEY.thexp_branch) as new_branch:
        repo.git.checkout(commit.hexsha)
        repo.git.checkout('-b', 'reset')
        repo.head.reference = new_branch
        repo.git.add('.')
        ncommit = repo.index.commit("Reset from {}".format(commit.hexsha))
        repo.git.branch('-d', 'reset')
    exp.regist_plugin(
        'reset',
        {
            'test_name': test_viewer.test_name,  # 从哪个状态恢复
            'from': exp.commit.hexsha,  # reset 运行时的快照
            'where': commit.hexsha,  # 恢复到哪一次 commit,是恢复前的保存的状态
            'to': ncommit.hexsha,  # 对恢复后的状态再次进行提交,此时 from 和 to 两次提交状态应该完全相同
        })

    exp.end()
    os.chdir(old_path)
    return exp
예제 #30
0
def commit(request, commit_hexsha):
    binsha = binascii.unhexlify(commit_hexsha)
    commit = Commit(repo, binsha)
    details = {
        'hexsha':
        commit.hexsha,
        'author':
        commit.author.name,
        'message':
        commit.message,
        'authored_datetime':
        commit.authored_datetime,
        'files': [{
            'filename': key,
            'changes': value
        } for key, value in commit.stats.files.items()],
        'author_email':
        commit.author.email
    }
    return JsonResponse({'commit': details})
예제 #31
0
    def get_git_info(self, path):
        unique_authors = []
        seen_authors = []
        last_commit_date = ""
        # print("get_git_info for " + path)
        for c in Commit.iter_items(self.localrepo, self.localrepo.head, path):
            if not last_commit_date:
                # Use the last commit and get the date
                last_commit_date = time.strftime("%Y-%m-%d",
                                                 time.gmtime(c.authored_date))
            c.author.email = c.author.email.lower()
            if not (c.author.email in self.authors):
                # Not in cache: let's ask GitHub
                self.authors[c.author.email] = {}
                # First, search by email
                print("Search by email: " + c.author.email)
                info = self.get_gituser_info( c.author.email, \
                    { 'query': '{ search(type: USER, query: "in:email ' + c.author.email + '", first: 1) { edges { node { ... on User { login name url } } } } }' })
                if info:
                    self.authors[c.author.email] = info
                else:
                    # If not found, search by name
                    print("   User not found by email, search by name: " +
                          c.author.name)
                    info = self.get_gituser_info( c.author.name, \
                        { 'query': '{ search(type: USER, query: "in:name ' + c.author.name + '", first: 1) { edges { node { ... on User { login name url } } } } }' })
                    if info:
                        self.authors[c.author.email] = info
                    else:
                        # If not found, use local git info only and gravatar avatar
                        self.authors[c.author.email] = { 'login':'', \
                            'name':c.author.name if c.author.name else '', \
                            'url':'', \
                            'avatar':'https://www.gravatar.com/avatar/' + hashlib.md5(c.author.email.encode('utf-8')).hexdigest() + '?d=identicon' }
            if c.author.email not in seen_authors:
                seen_authors.append(c.author.email)
                unique_authors.append(self.authors[c.author.email])
                #print("  Author: "+ self.authors[c.author.email]['name'] + " ("+ str(self.authors[c.author.email]['email'])+ ")")

        return unique_authors, last_commit_date
예제 #32
0
    def __setstate__(self, state: dict):
        from gitdb.util import hex_to_bin
        from git import Commit
        self._start_time = state['_start_time']
        self._time_fmt = state['_time_fmt']

        self._exp_name = state['_exp_name']
        self._exp_dir = state['_exp_dir']
        self._test_dir = state['_test_dir']
        self._project_dir = state['_project_dir']

        self._hold_dirs = state['_hold_dirs']
        self._plugins = state['_plugins']
        self._tags = state['_tags']

        self._exc_dict = state.get('_exc_dict', None)
        self._end_state = state['_end_state']

        self._in_main = state['_in_main']

        self._repo = None
        self._commit = Commit(self.repo, hex_to_bin(state['_commit']))
        self._config = globs
예제 #33
0
def create_rpmbuild_content(repo, target, config):
    rpm_prefix = config['rpm']['prefix']
    for branch in repo.branches:
        # We only want environment branches, not manifest branches.
        if not branch.name.startswith(manifest_branch_prefix):
            manifest_branch_name = manifest_branch_prefix + branch.name
            # If there is no equivalent manifest branch, we need to
            # skip this environment.
            if manifest_branch_name not in repo.branches:
                continue
            branch.checkout()
            labelled_tags = tags_by_label(os.path.join(repo.working_dir,
                                                       'labels'))

            # Get number of commits to determine the version of the env rpm.
            commit_num = len(list(Commit.iter_items(repo, branch.commit))) 

            # Keep track of the labels which have tags - its those we want.
            for label, tag in labelled_tags.items():
                create_rpmbuild_for_tag(repo, tag, target, config)
                fname = '{}-env-{}-label-{}.spec'.format(rpm_prefix, branch.name, label)
                with open(os.path.join(target, 'SPECS', fname), 'w') as fh:
                    fh.write(generate.render_env(branch.name, label,
                                                 repo, config, tag, commit_num))
예제 #34
0
    def get_files_changed_between_commits(commit_a: Commit, commit_b: Commit)-> (Set[str], Set[str]):
        """Determine what files have been added or modified between commits b and a
        Those files should be added to a_files and if they are present in commit b,
        added to b_files

        :param commit_a:
        :param commit_b:
        :return: a pair of sets, the first set is the files in commit a
        the second set is the files in commit b
        ":rtype (Set[str], Set[str]):
        """

        diffs = commit_b.diff(other=commit_a)

        a_files = set()  # type: Set[str]
        b_files = set()  # type: Set[str]

        for diff in diffs:
            if diff.new_file or (diff.a_blob and diff.b_blob and diff.a_blob != diff.b_blob):
                a_files.add(diff.a_path)
                if not diff.new_file:
                    b_files.add(diff.b_path)

        return a_files, b_files
예제 #35
0
def newcommit(repo, message, date, name=None, email=None):
    """Creates a commit object with a custom date.
    :param repo: Repo object the commit should be part of
    :param tree: Tree object
    :param message: Commit message. It may be an empty string
                    if no message is provided.
    :param date: Date in seconds, as an Int
    :return: Commit object representing the new commit
    :note:
        Additional information about the committer and Author are taken from
        the git configuration
    """

    tree = repo.index.write_tree()
    try:
        parents = [repo.head.commit]
    except ValueError:
        parents = []

    # Committer and Author info
    cr = repo.config_reader()
    if name == None or email == None:
        actor = Actor.committer(cr)
    else:
        actor = Actor(name, email)

    committer = actor
    author = actor

    # Date
    # offset = altzone # 3600*offsethours
    offset = 0  # UTC

    author_time, author_offset = date, offset
    committer_time, committer_offset = date, offset

    # assume utf8 encoding
    enc_section, enc_option = Commit.conf_encoding.split('.')
    conf_encoding = cr.get_value(enc_section,
                                 enc_option,
                                 Commit.default_encoding)

    # Create New Commit
    new_commit = Commit(repo, Commit.NULL_BIN_SHA, tree,
                    author, author_time, author_offset,
                    committer, committer_time, committer_offset,
                    message, parents, conf_encoding)

    stream = StringIO()
    new_commit._serialize(stream)
    streamlen = stream.tell()
    stream.seek(0)

    istream = repo.odb.store(IStream(Commit.type, streamlen, stream))
    new_commit.binsha = istream.binsha

    # Advance HEAD to the new commit automatically.
    # need late import here, importing git at the very beginning throws.
    import git.refs
    try:
        repo.head.set_commit(new_commit, logmsg="commit: %s" % message)
    except ValueError:
        # head is not yet set to the ref our HEAD points to
        # Happens on first commit
        import git.refs
        master = git.refs.Head.create(repo, repo.head.ref,
                                      new_commit, logmsg="commit (initial): %s" % message)
        repo.head.set_reference(master, logmsg='commit: Switching to %s' % master)
    # END handle empty repositories
    return new_commit
예제 #36
0
 def test_equality(self):
     commit1 = Commit(self.rorepo, Commit.NULL_BIN_SHA)
     commit2 = Commit(self.rorepo, Commit.NULL_BIN_SHA)
     commit3 = Commit(self.rorepo, "\1" * 20)
     assert_equal(commit1, commit2)
     assert_not_equal(commit2, commit3)
예제 #37
0
    def commit(self, commit, message):
        """Commits files given a commit message and a given commit"""
        self.repo.git.commit()

class CommitFile(object):
    """Holds some information about a file in addition to its diff"""
    def __init__(self):
        self.isUntracked = None
        self.isRenamed = None
        self.diff = None
        self.lineNumbers = None
        #self.

    def setDiff(self, diff):
        """"""
        self.diff = diff

if __name__ == "__main__":
    x = GitManager('')
    print x.grabUntrackedFiles()
    print x.grabAllFilesToBeCommited()
    commit = Commit.new(x.repo, x.repo.head.ref)
    print commit
    print commit.author
    print commit.committer
    print dir(commit.stats)
    print commit.stats.files
    #print x.createCommitForPartialFiles()
    #print commit.diff(None, None)
    #print x.repo.commit().diff(None, None)[1].a_blob.path
예제 #38
0
 def test_list(self):
     # This doesn't work anymore, as we will either attempt getattr with bytes, or compare 20 byte string
     # with actual 20 byte bytes. This usage makes no sense anyway
     assert isinstance(Commit.list_items(self.rorepo, '0.1.5', max_count=5)[
                       '5117c9c8a4d3af19a9958677e45cda9269de1541'], Commit)