git
This commit is contained in:
@@ -8,6 +8,7 @@ import os
|
||||
|
||||
from fastapi import HTTPException
|
||||
from git import Repo
|
||||
from git.exc import GitCommandError
|
||||
|
||||
from src.core.logger import belief_scope, logger
|
||||
|
||||
@@ -173,12 +174,60 @@ class GitServiceBranchMixin:
|
||||
# @PURPOSE: Switch to a specific branch (concurrent-safe).
|
||||
# @PRE Repository exists and the specified branch name exists.
|
||||
# @POST The repository working directory is updated to the specified branch.
|
||||
# @SIDE_EFFECT May raise HTTPException(409) if local changes conflict with checkout.
|
||||
# @SIDE_EFFECT May raise HTTPException(500) if Git operation fails for other reasons.
|
||||
def checkout_branch(self, dashboard_id: int, name: str):
|
||||
with self._locked(dashboard_id):
|
||||
with belief_scope("GitService.checkout_branch"):
|
||||
repo = self.get_repo(dashboard_id)
|
||||
logger.reason(f"Checking out branch {name}", extra={"src": "checkout_branch"})
|
||||
repo.git.checkout(name)
|
||||
try:
|
||||
repo.git.checkout(name)
|
||||
except GitCommandError as e:
|
||||
stderr = str(e.stderr or "")
|
||||
details = str(e)
|
||||
lowered = stderr.lower()
|
||||
if "local changes" in lowered or "would be overwritten" in lowered:
|
||||
# Parse the list of files from stderr
|
||||
files = []
|
||||
for line in stderr.split("\n"):
|
||||
stripped = line.strip()
|
||||
if stripped.startswith("\t") and (
|
||||
stripped.endswith(".yaml") or "/" in stripped
|
||||
):
|
||||
files.append(stripped.strip())
|
||||
raise HTTPException(
|
||||
status_code=409,
|
||||
detail={
|
||||
"error_code": "GIT_CHECKOUT_LOCAL_CHANGES",
|
||||
"message": (
|
||||
f"Невозможно переключиться на ветку '{name}' — "
|
||||
f"локальные изменения будут перезаписаны. "
|
||||
f"Зафиксируйте или отложите изменения."
|
||||
),
|
||||
"message_en": (
|
||||
f"Cannot checkout branch '{name}' — "
|
||||
f"local changes would be overwritten. "
|
||||
f"Commit or stash your changes first."
|
||||
),
|
||||
"files": files,
|
||||
"next_steps": [
|
||||
"Зафиксируйте изменения (Commit) в текущей ветке перед переключением",
|
||||
"Отложите изменения через Stash (вручную: git stash)",
|
||||
"Отмените локальные изменения, если они не нужны",
|
||||
],
|
||||
"next_steps_en": [
|
||||
"Commit your changes in the current branch before switching",
|
||||
"Stash your changes manually: git stash",
|
||||
"Discard local changes if not needed",
|
||||
],
|
||||
},
|
||||
)
|
||||
logger.error(f"[checkout_branch][Coherence:Failed] {e}")
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Git checkout failed: {details}",
|
||||
)
|
||||
# endregion checkout_branch
|
||||
|
||||
# region commit_changes [C:4] [TYPE Function] [SEMANTICS git,commit,stage,lock]
|
||||
|
||||
Reference in New Issue
Block a user