Add git repository analyzer module
This commit is contained in:
@@ -5,6 +5,8 @@ from src.models import Commit
|
||||
|
||||
|
||||
class GitRepository:
|
||||
"""Wrapper for git repository operations."""
|
||||
|
||||
def __init__(self, path: str):
|
||||
self.path = path
|
||||
self._repo: Optional[Repo] = None
|
||||
@@ -19,18 +21,10 @@ class GitRepository:
|
||||
commits = []
|
||||
|
||||
try:
|
||||
commit_iter = repo.iter_commits(
|
||||
rev=None,
|
||||
since=since.isoformat() if since else None,
|
||||
until=until.isoformat() if until else None,
|
||||
max_count=None,
|
||||
)
|
||||
|
||||
for git_commit in commit_iter:
|
||||
for git_commit in repo.iter_commits():
|
||||
commit = self._convert_git_commit(git_commit)
|
||||
if commit:
|
||||
commits.append(commit)
|
||||
|
||||
except GitCommandError as e:
|
||||
raise ValueError(f"Error reading git repository: {e}")
|
||||
|
||||
@@ -38,12 +32,8 @@ class GitRepository:
|
||||
|
||||
def _convert_git_commit(self, git_commit) -> Optional[Commit]:
|
||||
try:
|
||||
parents = [p.hexsha for p in git_commit.parents]
|
||||
is_merge = len(parents) > 1
|
||||
|
||||
is_revert = False
|
||||
if git_commit.message.lower().startswith(("revert", "reverted")):
|
||||
is_revert = True
|
||||
is_merge = len(git_commit.parents) > 1
|
||||
is_revert = git_commit.message.lower().startswith(("revert", "reverted"))
|
||||
|
||||
file_changes = []
|
||||
additions = 0
|
||||
@@ -52,8 +42,7 @@ class GitRepository:
|
||||
try:
|
||||
if git_commit.stats and git_commit.stats.files:
|
||||
for filepath, stats in git_commit.stats.files.items():
|
||||
file_change = self._create_file_change(filepath, stats)
|
||||
file_changes.append(file_change)
|
||||
file_changes.append(filepath)
|
||||
additions += stats.get('insertions', 0)
|
||||
deletions += stats.get('deletions', 0)
|
||||
except Exception:
|
||||
@@ -62,56 +51,28 @@ class GitRepository:
|
||||
return Commit(
|
||||
sha=git_commit.hexsha,
|
||||
message=git_commit.message.strip(),
|
||||
author_name=git_commit.author.name or "Unknown",
|
||||
author=git_commit.author.name or "Unknown",
|
||||
author_email=git_commit.author.email or "",
|
||||
committed_datetime=datetime.fromtimestamp(git_commit.committed_date),
|
||||
author_datetime=datetime.fromtimestamp(git_commit.authored_date),
|
||||
parents=parents,
|
||||
additions=additions,
|
||||
deletions=deletions,
|
||||
files_changed=len(file_changes),
|
||||
file_changes=file_changes,
|
||||
timestamp=datetime.fromtimestamp(git_commit.committed_date),
|
||||
lines_added=additions,
|
||||
lines_deleted=deletions,
|
||||
files_changed=file_changes,
|
||||
is_merge=is_merge,
|
||||
is_revert=is_revert,
|
||||
)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def _create_file_change(self, filepath: str, stats: dict) -> "FileChange":
|
||||
from src.models import FileChange
|
||||
return FileChange(
|
||||
filepath=filepath,
|
||||
additions=stats.get('insertions', 0),
|
||||
deletions=stats.get('deletions', 0),
|
||||
changes=stats.get('insertions', 0) + stats.get('deletions', 0),
|
||||
)
|
||||
|
||||
def get_commit_count(self) -> int:
|
||||
return sum(1 for _ in self.get_repo().iter_commits())
|
||||
|
||||
def get_unique_authors(self) -> set:
|
||||
authors = set()
|
||||
for commit in self.get_repo().iter_commits():
|
||||
if commit.author.name:
|
||||
authors.add(commit.author.name)
|
||||
return authors
|
||||
|
||||
def get_authors(self):
|
||||
from src.models import Author
|
||||
authors = {}
|
||||
for commit in self.get_repo().iter_commits():
|
||||
if commit.author.name and commit.author.email:
|
||||
email = commit.author.email
|
||||
if email not in authors:
|
||||
authors[email] = Author(
|
||||
name=commit.author.name,
|
||||
email=email,
|
||||
commit_count=0,
|
||||
lines_added=0,
|
||||
lines_deleted=0,
|
||||
)
|
||||
authors[email].commit_count += 1
|
||||
return list(authors.values())
|
||||
def get_authors(self) -> List[Author]:
|
||||
"""Get list of authors from commits."""
|
||||
authors_dict = {}
|
||||
for commit in self.get_commits():
|
||||
if commit.author_email not in authors_dict:
|
||||
authors_dict[commit.author_email] = Author(
|
||||
name=commit.author,
|
||||
email=commit.author_email,
|
||||
)
|
||||
return list(authors_dict.values())
|
||||
|
||||
def close(self):
|
||||
if self._repo:
|
||||
|
||||
Reference in New Issue
Block a user