mirror of
https://github.com/Dictionarry-Hub/profilarr.git
synced 2026-01-22 10:51:02 +01:00
- pulls now correctly identify merge conflicts and enter a merge state - user resolves each file individually - commit resolve merge state - allows users to keep custom changes and pull in updates - improve commit message component - seperated commit / add functionality
111 lines
3.9 KiB
Python
111 lines
3.9 KiB
Python
# git/status/status.py
|
|
import git
|
|
from git.exc import GitCommandError, InvalidGitRepositoryError
|
|
import logging
|
|
from .incoming_changes import get_incoming_changes
|
|
from .outgoing_changes import get_outgoing_changes
|
|
from .merge_conflicts import get_merge_conflicts
|
|
from .utils import determine_type
|
|
import os
|
|
import yaml
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def get_commits_ahead(repo, branch):
|
|
return list(repo.iter_commits(f'origin/{branch}..{branch}'))
|
|
|
|
|
|
def get_commits_behind(repo, branch):
|
|
return list(repo.iter_commits(f'{branch}..origin/{branch}'))
|
|
|
|
|
|
def get_unpushed_changes(repo, branch):
|
|
"""Get detailed info about files modified in unpushed commits"""
|
|
try:
|
|
# Get the file paths
|
|
unpushed_files = repo.git.diff(f'origin/{branch}..{branch}',
|
|
'--name-only').split('\n')
|
|
unpushed_files = [f for f in unpushed_files if f]
|
|
|
|
detailed_changes = []
|
|
for file_path in unpushed_files:
|
|
try:
|
|
# Get the current content of the file to extract name
|
|
with open(os.path.join(repo.working_dir, file_path), 'r') as f:
|
|
content = yaml.safe_load(f.read())
|
|
|
|
detailed_changes.append({
|
|
'type':
|
|
determine_type(file_path),
|
|
'name':
|
|
content.get('name', os.path.basename(file_path)),
|
|
'file_path':
|
|
file_path
|
|
})
|
|
except Exception as e:
|
|
logger.warning(
|
|
f"Could not get details for {file_path}: {str(e)}")
|
|
# Fallback to basic info if we can't read the file
|
|
detailed_changes.append({
|
|
'type': determine_type(file_path),
|
|
'name': os.path.basename(file_path),
|
|
'file_path': file_path
|
|
})
|
|
|
|
return detailed_changes
|
|
except Exception as e:
|
|
logger.error(f"Error getting unpushed changes: {str(e)}")
|
|
return []
|
|
|
|
|
|
def get_git_status(repo_path):
|
|
try:
|
|
logger.debug(f"Attempting to get status for repo at {repo_path}")
|
|
repo = git.Repo(repo_path)
|
|
branch = repo.active_branch.name
|
|
remote_branch_exists = f"origin/{branch}" in [
|
|
ref.name for ref in repo.remotes.origin.refs
|
|
]
|
|
|
|
# Check for merge state
|
|
is_merging = os.path.exists(os.path.join(repo.git_dir, 'MERGE_HEAD'))
|
|
|
|
# Get merge conflicts if we're in a merge state
|
|
merge_conflicts = get_merge_conflicts(repo) if is_merging else []
|
|
|
|
# Get all changes first
|
|
outgoing_changes = get_outgoing_changes(repo)
|
|
logger.debug(f"Outgoing changes detected: {outgoing_changes}")
|
|
|
|
if remote_branch_exists:
|
|
repo.remotes.origin.fetch()
|
|
commits_behind = get_commits_behind(repo, branch)
|
|
commits_ahead = get_commits_ahead(repo, branch)
|
|
incoming_changes = get_incoming_changes(repo, branch)
|
|
unpushed_files = get_unpushed_changes(
|
|
repo, branch) if commits_ahead else []
|
|
else:
|
|
commits_behind = []
|
|
commits_ahead = []
|
|
incoming_changes = []
|
|
unpushed_files = []
|
|
|
|
status = {
|
|
"branch": branch,
|
|
"remote_branch_exists": remote_branch_exists,
|
|
"outgoing_changes": outgoing_changes,
|
|
"commits_behind": len(commits_behind),
|
|
"commits_ahead": len(commits_ahead),
|
|
"incoming_changes": incoming_changes,
|
|
"has_unpushed_commits": len(commits_ahead) > 0,
|
|
"unpushed_files": unpushed_files,
|
|
"is_merging": is_merging,
|
|
"merge_conflicts": merge_conflicts,
|
|
"has_conflicts": bool(merge_conflicts)
|
|
}
|
|
return True, status
|
|
except Exception as e:
|
|
logger.error(f"Error in get_git_status: {str(e)}", exc_info=True)
|
|
return False, str(e)
|