def test_get_tagged_commits(repo: GitRepository): tagged_commits = repo.get_tagged_commits() assert len(tagged_commits) == 3 assert '6bb9e2c6a8080e6b5b34e6e316c894b2ddbf7fcd' == tagged_commits[0] assert '4638730126d40716e230c2040751a13153fb1556' == tagged_commits[1] assert '627e1ad917a188a861c9fedf6e5858b79edbe439' == tagged_commits[2]
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()
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()
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) if self._conf.get('filepath') is not None: self._conf.set_value( 'filepath_commits', git_repo.get_commits_modified_file( self._conf.get('filepath'))) if self._conf.get('only_releases'): self._conf.set_value('tagged_commits', git_repo.get_tagged_commits()) for commit in git_repo.get_list_commits( self._conf.get('only_in_branch'), not self._conf.get('reversed_order')): 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 self._conf.set_value("git_repo", None) git_repo.clear()
def traverse_commits(self) -> Generator[Commit, None, None]: """ Analyze all the specified commits (all of them by default), returning a generator of commits. """ if isinstance(self._path_to_repo, str): self._path_to_repo = [self._path_to_repo] for path_repo in self._path_to_repo: # if it is a remote repo, clone it first in a temporary folder! if self._isremote(path_repo): tmp_folder = tempfile.TemporaryDirectory() path_repo = self._clone_remote_repos(tmp_folder.name, path_repo) git_repo = GitRepository(path_repo) self._sanity_check_filters(git_repo) self._check_timezones() logger.info('Analyzing git repository in %s', git_repo.path) if self._filepath is not None: self._filepath_commits = git_repo.get_commits_modified_file( self._filepath) if self._only_releases: self._tagged_commits = git_repo.get_tagged_commits() for commit in git_repo.get_list_commits(self._only_in_branch, not self._reversed_order): logger.info('Commit #%s in %s from %s', commit.hash, commit.committer_date, commit.author.name) if self._is_commit_filtered(commit): logger.info('Commit #%s filtered', commit.hash) continue yield commit
def test_get_tagged_commits_wo_tags(): gr = GitRepository('test-repos/git-7/') tagged_commits = gr.get_tagged_commits() assert len(tagged_commits) == 0
def test_get_tagged_commits_wo_tags(repo: GitRepository): tagged_commits = repo.get_tagged_commits() assert len(tagged_commits) == 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'): local_path_repo = path_repo if self._is_remote(path_repo): local_path_repo = self._clone_remote_repo( self._clone_folder(), path_repo) # Get absolute path local_path_repo = str(Path(local_path_repo).expanduser().resolve()) # 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', local_path_repo) git_repo = GitRepository(local_path_repo, self._conf) # saving the GitRepository object for further use self._conf.set_value("git_repo", git_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() # delete the temporary directory if created if self._is_remote(path_repo) and self._cleanup is True: assert self._tmp_dir is not None try: self._tmp_dir.cleanup() except PermissionError: # on Windows, Python 3.5, 3.6, 3.7 are not able to delete # git directories because of read-only files. This is now fixed # in python 3.8. In this case, we need to use an # onerror callback to clear the read-only bit. # see https://docs.python.org/3/library/shutil.html?highlight=shutil#rmtree-example def remove_readonly(func, path, _): os.chmod(path, stat.S_IWRITE) func(path) shutil.rmtree(self._tmp_dir.name, onerror=remove_readonly)