示例#1
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
示例#2
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__()
示例#3
0
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
示例#4
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
示例#5
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)
示例#6
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)
示例#7
0
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
示例#8
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})
示例#9
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)
示例#10
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
示例#11
0
 def GetCommitsBetweenIds(newer: str, older: str) -> list:
     """
     Get a list of commits between two Git commits.
     
     Args:
         newer (str): The newer Git commit id for the comparison.
         older (str): The older Git commit id for the comparison.
     
     Returns:
         A list of commits.
     """
     commits = list()
     output = subprocess.check_output([
         'git', 'log', '{newer}...{older}'.format(newer=newer, older=older)
     ]).decode('utf-8')
     if (len(output) < 1):
         return commits
     commitLog = str(output).split('\n')
     lineIndex = 0
     while (lineIndex < len(commitLog)):
         commitLogLine = str(commitLog[lineIndex])
         if (commitLogLine.startswith('commit')):
             # Commit log item startsexpression
             commit = Commit()
             # Get commit hash from the commit
             commit.hash = str(commitLog[lineIndex]).split(' ')[1]
             lineIndex = lineIndex + 1
             # Get "Author:", "{author's name} <{author's email}>"
             logLine = str(commitLog[lineIndex]).split(':', 1)[1].lstrip()
             user = User()
             user.name = logLine.split('<', 1)[0].rstrip(' ')
             user.email = logLine.split('<', 1)[1].lstrip().replace(
                 '\r', '').replace('\n', '')
             commit.author = user
             lineIndex = lineIndex + 1
             # Split "Date:   ", "{actual date}"
             logLine = str(commitLog[lineIndex]).split('Date:')[1]
             dateString = logLine = logLine.lstrip().replace('\r',
                                                             '').replace(
                                                                 '\n', '')
             commit.date = Date.ConvertGitStringToDate(dateString)
             # Skip extra line between date and commit title
             lineIndex = lineIndex + 2
             # Add the title to the commit but remove leading whitespace and trailing linefeed
             commit.title = str(commitLog[lineIndex]).lstrip().replace(
                 '\r', '').replace('\n', '')
             lineIndex = lineIndex + 1
             # Skip extra line between title and commit message
             lineIndex = lineIndex + 1
             # Commit message lasts until another commit message starts or the log ends
             commit.message = ""
             while (lineIndex < len(commitLog)):
                 if (str(commitLog[lineIndex]).startswith('commit')):
                     break
                 commit.message = commit.message + commitLog[
                     lineIndex].lstrip()
                 lineIndex = lineIndex + 1
             commits.append(commit)
             break
         else:
             lineIndex = lineIndex + 1
     return commits
示例#12
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)
示例#13
0
 def test_repr(self):
     commit = Commit(self.rorepo, Commit.NULL_BIN_SHA)
     assert_equal('<git.Commit "%s">' % Commit.NULL_HEX_SHA, repr(commit))
示例#14
0
 def test_str(self):
     commit = Commit(self.rorepo, Commit.NULL_BIN_SHA)
     assert_equal(Commit.NULL_HEX_SHA, str(commit))
示例#15
0
 def get_commit(self, head: bytes) -> Commit:
     return Commit(self._get_repo(), head)
示例#16
0
def get_commit_files(git_repo, commit_sha):
    return Commit(git_repo, commit_sha).stats.files
示例#17
0
 def create_commits(cls, ids: List[str],
                    messages: List[str]) -> List[Commit]:
     return [
         Commit(repo=Mock(), binsha=commit, message=message)
         for commit, message in zip(ids, messages)
     ]
示例#18
0
 def build_commits(cls, commits: List[str],
                   messages: List[str]) -> List[Commit]:
     return [
         Commit(repo=Mock(), binsha=commit, message=message)
         for commit, message in zip(commits, messages)
     ]
示例#19
0
 def commit(self):
     if self._commit is None:
         from gitdb.util import hex_to_bin
         from git import Commit
         self._commit = Commit(self.repo, hex_to_bin(self.commit_hash))
     return self._commit