예제 #1
0
def test_commit_in_master_branch():
    gr = GitRepository('test-repos/git-2/')
    assert gr.get_head().hash == '29e929fbc5dc6a2e9c620069b24e2a143af4285f'

    gr.checkout('8986af2a679759e5a15794f6d56e6d46c3f302f1')

    git_to_change_head = GitRepository('test-repos/git-2/')
    commit = git_to_change_head.get_commit(
        '8169f76a3d7add54b4fc7bca7160d1f1eede6eda')
    assert commit.in_main_branch is False

    commit = git_to_change_head.get_commit(
        '168b3aab057ed61a769acf336a4ef5e64f76c9fd')
    assert commit.in_main_branch is True

    gr.reset()
    assert gr.get_head().hash == '29e929fbc5dc6a2e9c620069b24e2a143af4285f'
예제 #2
0
def test_get_head():
    gr = GitRepository('test-repos/test1/')
    assert gr is not None
    cs = gr.get_head()
    assert cs is not None

    assert cs.hash == 'da39b1326dbc2edfe518b90672734a08f3c13458'
    assert cs.author_date.timestamp() == 1522164679
예제 #3
0
def test_checkout_consecutive_commits():
    gr = GitRepository('test-repos/git-1/')
    gr.checkout('a7053a4dcd627f5f4f213dc9aa002eb1caf926f8')
    gr.checkout('f0dd1308bd904a9b108a6a40865166ee962af3d4')
    gr.checkout('9e71dd5726d775fb4a5f08506a539216e878adbb')
    files3 = gr.files()
    assert len(files3) == 3
    gr.reset()
예제 #4
0
def test_get_commit_from_tag():
    gr = GitRepository('test-repos/test1/')

    commit = gr.get_commit_from_tag('v1.4')

    assert commit.hash == '09f6182cef737db02a085e1d018963c7a29bde5a'
    with pytest.raises(IndexError):
        gr.get_commit_from_tag('v1.5')
예제 #5
0
def test_get_commits_last_modified_lines_rename_simple():
    gr = GitRepository('test-repos/test5/')

    buggy_commits = gr.get_commits_last_modified_lines(
        gr.get_commit('45ba0a61ccc448625bce0fea0301cf0c1ab32696'))

    assert len(buggy_commits) == 1
    assert 'e358878a00e78aca8366264d61a7319d00dd8186' in buggy_commits
예제 #6
0
def test_get_commits_last_modified_lines_simple():
    gr = GitRepository('test-repos/test5/')

    buggy_commits = gr.get_commits_last_modified_lines(
        gr.get_commit('e6d3b38a9ef683e8184eac10a0471075c2808bbd'))

    assert len(buggy_commits) == 1
    assert '540c7f31c18664a38190fafb6721b5174ff4a166' in buggy_commits
예제 #7
0
def test_number_of_modifications():
    gr = GitRepository('test-repos/git-1/')
    commit = gr.get_commit('866e997a9e44cb4ddd9e00efe49361420aff2559')
    assert commit.modifications[0].added == 62
    assert commit.modifications[0].removed == 0

    commit = gr.get_commit('d11dd6734ff4e60cac3a7b58d9267f138c9e05c7')
    assert commit.modifications[0].added == 1
    assert commit.modifications[0].removed == 1
예제 #8
0
def test_detail_rename():
    gr = GitRepository('test-repos/git-1/')
    commit = gr.get_commit('f0dd1308bd904a9b108a6a40865166ee962af3d4')

    assert commit.author.name == "Maurício Aniche"
    assert commit.author.email == "*****@*****.**"

    assert commit.modifications[0].new_path == "Matricula.javax"
    assert commit.modifications[0].old_path == "Matricula.java"
예제 #9
0
def test_get_commits_modified_file():
    gr = GitRepository('test-repos/test1/')

    commits = gr.get_commits_modified_file('file2.java')

    assert len(commits) == 3
    assert '09f6182cef737db02a085e1d018963c7a29bde5a' in commits
    assert '6411e3096dd2070438a17b225f44475136e54e3a' in commits
    assert 'a88c84ddf42066611e76e6cb690144e5357d132c' in commits
예제 #10
0
def test_get_commits_last_modified_lines_multiple():
    gr = GitRepository('test-repos/test5/')

    buggy_commits = gr.get_commits_last_modified_lines(gr.get_commit('9942ee9dcdd1103e5808d544a84e6bc8cade0e54'))

    assert len(buggy_commits) == 3
    assert '2eb905e5e7be414fd184d6b4f1571b142621f4de' in buggy_commits
    assert '20a40688521c1802569e60f9d55342c3bfdd772c' in buggy_commits
    assert '22505e97dca6f843549b3a484b3609be4e3acf17' in buggy_commits
예제 #11
0
def test_get_tagged_commits():
    gr = GitRepository('test-repos/git-8/')

    tagged_commits = gr.get_tagged_commits()

    assert len(tagged_commits) == 3
    assert '6bb9e2c6a8080e6b5b34e6e316c894b2ddbf7fcd' == tagged_commits[0]
    assert '4638730126d40716e230c2040751a13153fb1556' == tagged_commits[1]
    assert '627e1ad917a188a861c9fedf6e5858b79edbe439' == tagged_commits[2]
예제 #12
0
def test_filepahs():
    gr = GitRepository('test-repos/test7')
    c = gr.get_commit('f0f8aea2db50ed9f16332d86af3629ff7780583e')

    mod0 = c.modifications[0]

    assert mod0.filename == 'a.java'
    assert mod0.new_path == str(Path('dir2/a.java'))
    assert mod0.old_path == str(Path('dir2/a.java'))
예제 #13
0
    def traverse_commits(self) -> Generator[Commit, None, None]:
        """
        Analyze all the specified commits (all of them by default), returning
        a generator of commits.
        """
        for path_repo in self._conf.get('path_to_repos'):
            # if it is a remote repo, clone it first in a temporary folder!
            if self._is_remote(path_repo):
                if self._conf.get('clone_repo_to'):
                    clone_folder = str(Path(self._conf.get('clone_repo_to')))
                    if not os.path.isdir(clone_folder):
                        raise Exception(
                            "Not a directory: {0}".format(clone_folder))
                    path_repo = self._clone_remote_repos(
                        clone_folder, path_repo)
                else:
                    tmp_folder = tempfile.TemporaryDirectory()
                    path_repo = self._clone_remote_repos(
                        tmp_folder.name, path_repo)

            git_repo = GitRepository(path_repo, self._conf)
            self._conf.set_value("git_repo", git_repo)
            self._conf.sanity_check_filters()

            logger.info('Analyzing git repository in %s', git_repo.path)

            # Get the commits that modified the filepath. In this case, we can not use
            # git rev-list since it doesn't have the option --follow, necessary to follow
            # the renames. Hence, we manually call git log instead
            if self._conf.get('filepath') is not None:
                self._conf.set_value(
                    'filepath_commits',
                    git_repo.get_commits_modified_file(
                        self._conf.get('filepath')))

            # Gets only the commits that are tagged
            if self._conf.get('only_releases'):
                self._conf.set_value('tagged_commits',
                                     git_repo.get_tagged_commits())

            # Build the arguments to pass to git rev-list.
            rev, kwargs = self._conf.build_args()

            # Iterate over all the commits returned by git rev-list
            for commit in git_repo.get_list_commits(rev, **kwargs):
                logger.info('Commit #%s in %s from %s', commit.hash,
                            commit.committer_date, commit.author.name)

                if self._conf.is_commit_filtered(commit):
                    logger.info('Commit #%s filtered', commit.hash)
                    continue

                yield commit

            # cleaning, this is necessary since GitPython issues on memory leaks
            self._conf.set_value("git_repo", None)
            git_repo.clear()
예제 #14
0
def test_modification_status():
    gr = GitRepository('test-repos/git-1/')
    commit = gr.get_commit('866e997a9e44cb4ddd9e00efe49361420aff2559')
    assert ModificationType.ADD == commit.modifications[0].change_type

    commit = gr.get_commit('57dbd017d1a744b949e7ca0b1c1a3b3dd4c1cbc1')
    assert ModificationType.MODIFY == commit.modifications[0].change_type

    commit = gr.get_commit('ffccf1e7497eb8136fd66ed5e42bef29677c4b71')
    assert ModificationType.DELETE == commit.modifications[0].change_type
예제 #15
0
def test_tags():
    gr = GitRepository('test-repos/git-8/')
    commit = gr.get_commit_from_tag('tag1')
    assert commit.hash == '6bb9e2c6a8080e6b5b34e6e316c894b2ddbf7fcd'

    commit = gr.get_commit_from_tag('tag2')
    assert commit.hash == '4638730126d40716e230c2040751a13153fb1556'

    with pytest.raises(IndexError):
        gr.get_commit_from_tag('tag4')
예제 #16
0
def test_merge_commits():
    gr = GitRepository('test-repos/git-2/')
    commit = gr.get_commit("168b3aab057ed61a769acf336a4ef5e64f76c9fd")
    assert commit.merge is False

    commit = gr.get_commit("8169f76a3d7add54b4fc7bca7160d1f1eede6eda")
    assert commit.merge is False

    commit = gr.get_commit("29e929fbc5dc6a2e9c620069b24e2a143af4285f")
    assert commit.merge is True
예제 #17
0
def test_parent_commits():
    gr = GitRepository('test-repos/git-5/')
    merge_commit = gr.get_commit('5d9d79607d7e82b6f236aa29be4ba89a28fb4f15')
    assert len(merge_commit.parents) == 2
    assert 'fa8217c324e7fb46c80e1ddf907f4e141449637e' in merge_commit.parents
    assert 'ff663cf1931a67d5e47b75fc77dcea432c728052' in merge_commit.parents

    normal_commit = gr.get_commit('ff663cf1931a67d5e47b75fc77dcea432c728052')
    assert len(normal_commit.parents) == 1
    assert '4a17f31c0d1285477a3a467d0bc3cb38e775097d' in normal_commit.parents
예제 #18
0
def test_eq_commit():
    gr = GitRepository('test-repos/git-11')
    c1 = gr.get_commit('1734d6da01378bad3aade12b52bb4aa8954835dc')
    c2 = gr.get_commit('2c1327f957ba3b2a5e86eaed097b0a425236719e')
    c3 = gr.get_commit('1734d6da01378bad3aade12b52bb4aa8954835dc')
    m1 = gr.get_commit('1734d6da01378bad3aade12b52bb4aa8954835dc'
                       '').modifications[0]
    assert c1 == c3
    assert c1 == c1
    assert c1 != m1
    assert c1 != c2
예제 #19
0
    def traverse_commits(self) -> Generator[Commit, None, None]:
        """
        Analyze all the specified commits (all of them by default), returning
        a generator of commits.
        """
        for path_repo in self._conf.get('path_to_repos'):
            if self._is_remote(path_repo):
                path_repo = self._clone_remote_repos(self._clone_folder(),
                                                     path_repo)

            git_repo = GitRepository(path_repo, self._conf)
            # saving the GitRepository object for further use
            self._conf.set_value("git_repo", git_repo)

            # when multiple repos are given in input, this variable will serve as a reminder
            # of which one we are currently analyzing
            self._conf.set_value('path_to_repo', path_repo)

            # checking that the filters are set correctly
            self._conf.sanity_check_filters()

            logger.info('Analyzing git repository in %s', git_repo.path)

            # Get the commits that modified the filepath. In this case, we can not use
            # git rev-list since it doesn't have the option --follow, necessary to follow
            # the renames. Hence, we manually call git log instead
            if self._conf.get('filepath') is not None:
                self._conf.set_value(
                    'filepath_commits',
                    git_repo.get_commits_modified_file(
                        self._conf.get('filepath')))

            # Gets only the commits that are tagged
            if self._conf.get('only_releases'):
                self._conf.set_value('tagged_commits',
                                     git_repo.get_tagged_commits())

            # Build the arguments to pass to git rev-list.
            rev, kwargs = self._conf.build_args()

            # Iterate over all the commits returned by git rev-list
            for commit in git_repo.get_list_commits(rev, **kwargs):
                logger.info('Commit #%s in %s from %s', commit.hash,
                            commit.committer_date, commit.author.name)

                if self._conf.is_commit_filtered(commit):
                    logger.info('Commit #%s filtered', commit.hash)
                    continue

                yield commit

            # cleaning, this is necessary since GitPython issues on memory leaks
            self._conf.set_value("git_repo", None)
            git_repo.clear()
예제 #20
0
def test_commit_in_master_branch(repo: GitRepository):
    assert repo.get_head().hash == '29e929fbc5dc6a2e9c620069b24e2a143af4285f'

    repo.checkout('8986af2a679759e5a15794f6d56e6d46c3f302f1')

    git_to_change_head = GitRepository('test-repos/branches_merged')
    commit = git_to_change_head.get_commit('8169f76a3d7add54b4fc7bca7160d1f1eede6eda')
    assert commit.in_main_branch is False

    repo.reset()
    assert repo.get_head().hash == '29e929fbc5dc6a2e9c620069b24e2a143af4285f'
예제 #21
0
def test_get_commits_last_modified_lines_for_single_file():
    gr = GitRepository('test-repos/test5/')

    commit = gr.get_commit('0f726924f96621e4965039123098ba83e39ffba6')
    buggy_commits = None
    for mod in commit.modifications:
        if mod.filename == 'A.java':
            buggy_commits = gr.get_commits_last_modified_lines(commit, mod)

    assert len(buggy_commits) == 1
    assert 'e2ed043eb96c05ebde653a44ae733ded9ef90750' in buggy_commits
예제 #22
0
def test_get_commits_last_modified_lines_rename_simple_more_commits():
    gr = GitRepository('test-repos/test5/')

    buggy_commits = gr.get_commits_last_modified_lines(
        gr.get_commit('04fadd3e68c58281db6cf15119f9769880ac1cbc'))

    assert len(buggy_commits) == 2
    assert '9b373199c270f9b24c37fee70f9e2b3ee9b816e3' in buggy_commits[
        'A.java']
    assert '9b373199c270f9b24c37fee70f9e2b3ee9b816e3' in buggy_commits[
        'B.java']
예제 #23
0
def test_branches_from_commit():
    gr = GitRepository('test-repos/git-1/')
    commit = gr.get_commit('a997e9d400f742003dea601bb05a9315d14d1124')

    assert len(commit.branches) == 1
    assert 'b2' in commit.branches

    commit = gr.get_commit('866e997a9e44cb4ddd9e00efe49361420aff2559')
    assert len(commit.branches) == 2
    assert 'master' in commit.branches
    assert 'b2' in commit.branches
예제 #24
0
def test_get_commits_last_modified_lines_hyper_blame_unblamable(tmp_path):
    p = tmp_path / "ignore.txt"
    p.write_text("540c7f31c18664a38190fafb6721b5174ff4a166")

    gr = GitRepository('test-repos/test5/')

    buggy_commits = gr.get_commits_last_modified_lines(
        gr.get_commit('e6d3b38a9ef683e8184eac10a0471075c2808bbd'),
        hashes_to_ignore_path=str(p))

    assert len(buggy_commits) == 0
예제 #25
0
def test_get_commits_last_modified_lines_hyper_blame_with_renaming():
    gr = GitRepository('test-repos/test5/')

    buggy_commits = gr.get_commits_last_modified_lines(
        gr.get_commit('be0772cbaa2eba32bf97aae885199d1a357ddc93'))

    assert len(buggy_commits) == 2
    assert '9568d20856728304ab0b4d2d02fb9e81d0e5156d' in buggy_commits[
        'A.java']
    assert '9568d20856728304ab0b4d2d02fb9e81d0e5156d' in buggy_commits[
        'H.java']
예제 #26
0
def test_get_commit():
    gr = GitRepository('test-repos/test1/')
    c = gr.get_commit('09f6182cef737db02a085e1d018963c7a29bde5a')
    to_zone = timezone(timedelta(hours=1))

    assert '09f6182cef737db02a085e1d018963c7a29bde5a' == c.hash
    assert 'ishepard' == c.author.name
    assert 'ishepard' == c.committer.name
    assert datetime(2018, 3, 22, 10, 42, 3, tzinfo=to_zone).timestamp() == c.author_date.timestamp()
    assert 1 == len(c.modifications)
    assert 'Ooops file2' == c.msg
    assert c.in_main_branch is True
예제 #27
0
def test_get_first_commit():
    gr = GitRepository('test-repos/test1/')
    c = gr.get_commit('a88c84ddf42066611e76e6cb690144e5357d132c')
    to_zone = timezone(timedelta(hours=1))

    assert 'a88c84ddf42066611e76e6cb690144e5357d132c' == c.hash
    assert 'ishepard' == c.author.name
    assert 'ishepard' == c.committer.name
    assert datetime(2018,3,22,10,41,11,tzinfo=to_zone).timestamp() == c.author_date.timestamp()
    assert 2 == len(c.modifications)
    assert 'First commit adding 2 files' == c.msg
    assert c.in_main_branch is True
예제 #28
0
def test_changed_methods():

    gr = GitRepository("test-repos/diff")

    # add a new method
    mod = gr.get_commit(
        'ea95227e0fd128aa69c7ab6a8ac485f72251b3ed').modifications[0]
    assert len(mod.changed_methods) == 1
    assert mod.changed_methods[
        0].name == 'GitRepository::singleProjectThirdMethod'

    # add 2 new methods
    mod = gr.get_commit(
        'd8eb8e80b671246a43c98d97b05f6d1c5ada14fb').modifications[0]
    assert len(mod.changed_methods) == 2

    # remove one method
    mod = gr.get_commit(
        '0c8f9fdec926785198b399a2c49adb5884aa952c').modifications[0]
    assert len(mod.changed_methods) == 1

    # add and remove one one method at different locations
    mod = gr.get_commit(
        'd8bb142c5616041b71cbfaa11eeb768d9a1a296e').modifications[0]
    assert len(mod.changed_methods) == 2

    # add and remove one one method at the same location
    # this is equivalent to replacing a method - although we expect 2 methods
    mod = gr.get_commit(
        '9e9473d5ca310b7663e9df93c402302b6b7f24aa').modifications[0]
    assert len(mod.changed_methods) == 2

    # update a method
    mod = gr.get_commit(
        'b267a14e0503fdac36d280422f16360d1f661f12').modifications[0]
    assert len(mod.changed_methods) == 1

    # update and add a new method
    mod = gr.get_commit(
        '2489099dfd90edb99ddc2c82b62524b66c07c687').modifications[0]
    assert len(mod.changed_methods) == 2

    # update and delete methods
    mod = gr.get_commit(
        '5aebeb30e0238543a93e5bed806639481460cd9a').modifications[0]
    assert len(mod.changed_methods) == 2

    # delete 3 methods (test cleanup - revert the test file to its
    # initial set of methods)
    mod = gr.get_commit(
        '9f6ddc2aac740a257af59a76860590cb8a84c77b').modifications[0]
    assert len(mod.changed_methods) == 3
예제 #29
0
def test_checkout_with_commit_not_fully_merged_to_master():
    gr = GitRepository('test-repos/git-9/')
    gr.checkout('developing')
    files1 = gr.files()
    assert len(files1) == 2
    gr.reset()
    assert 4, "temp branch should be cleared." == len(gr.repo.branches)
    files2 = gr.files()
    assert len(files2) == 1
    gr.checkout('developing')
    files1 = gr.files()
    assert len(files1) == 2
    gr.reset()
예제 #30
0
def test_files():
    gr = GitRepository('test-repos/test2')
    all = gr.files()

    assert len(all) == 8
    assert str(Path('test-repos/test2/tmp1.py')) in all
    assert str(Path('test-repos/test2/tmp2.py')) in all
    assert str(Path('test-repos/test2/fold1/tmp3.py')) in all
    assert str(Path('test-repos/test2/fold1/tmp4.py')) in all
    assert str(Path('test-repos/test2/fold2/tmp5.py')) in all
    assert str(Path('test-repos/test2/fold2/tmp6.py')) in all
    assert str(Path('test-repos/test2/fold2/fold3/tmp7.py')) in all
    assert str(Path('test-repos/test2/fold2/fold3/tmp8.py')) in all