Files
QuickGit/quickgit/git_operations.py

215 lines
6.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Git操作模块 - 提供Git基本操作功能
"""
import os
from datetime import datetime
from .utils import CommandExecutor, OutputFormatter
from .config import Config
class GitOperations:
"""Git操作类"""
def __init__(self):
self.executor = CommandExecutor()
self.current_dir = os.getcwd()
def is_git_repo(self) -> bool:
"""检查当前目录是否是Git仓库"""
return os.path.isdir('.git')
def init_repo(self) -> bool:
"""
初始化Git仓库
Returns:
是否成功
"""
from .utils import Colors
if self.is_git_repo():
OutputFormatter.warning("当前目录已经是Git仓库")
return True
print(f"{Colors.CYAN}{'-' * 60}{Colors.ENDC}")
# 初始化Git仓库
OutputFormatter.step(1, "初始化Git仓库...")
success, _ = self.executor.run("git init", show_output=False)
if not success:
OutputFormatter.error("Git初始化失败")
return False
OutputFormatter.success("Git仓库初始化成功")
# 创建main分支
OutputFormatter.step(2, "创建main分支...")
success, _ = self.executor.run(f"git checkout -b {Config.DEFAULT_BRANCH}", show_output=False)
if success:
OutputFormatter.success("main分支创建成功")
else:
OutputFormatter.warning("main分支创建失败将使用默认分支")
# 创建.gitignore文件
OutputFormatter.step(3, "创建.gitignore文件...")
self._create_gitignore()
# 首次提交
OutputFormatter.step(4, "进行首次提交...")
self.executor.run("git add .", show_output=False)
success, _ = self.executor.run('git commit -m "first commit"', show_output=False)
if success:
OutputFormatter.success("首次提交完成")
else:
OutputFormatter.warning("首次提交失败(可能没有文件可提交)")
print(f"{Colors.CYAN}{'-' * 60}{Colors.ENDC}")
return True
def _create_gitignore(self):
"""创建.gitignore文件"""
try:
with open('.gitignore', 'w', encoding='utf-8') as f:
f.write(Config.GITIGNORE_TEMPLATE)
OutputFormatter.success(".gitignore文件创建成功")
except Exception as e:
OutputFormatter.error(f".gitignore文件创建失败: {str(e)}")
def get_status(self) -> tuple[bool, str]:
"""
获取Git状态
Returns:
(是否成功, 状态输出)
"""
return self.executor.run("git status --short", show_output=False)
def has_changes(self) -> bool:
"""
检查是否有更改
Returns:
是否有更改
"""
success, output = self.get_status()
return success and bool(output.strip())
def add_all(self) -> bool:
"""
添加所有更改
Returns:
是否成功
"""
OutputFormatter.info("正在添加文件...")
success, _ = self.executor.run("git add .", show_output=False)
if success:
OutputFormatter.success("文件添加成功")
else:
OutputFormatter.error("添加文件失败")
return success
def commit(self, message: str) -> bool:
"""
提交更改
Args:
message: 提交信息
Returns:
是否成功
"""
if not message:
message = f"update: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
OutputFormatter.status('running', f"提交更改: {message}")
success, _ = self.executor.run(f'git commit -m "{message}"', show_output=True)
if success:
OutputFormatter.success("提交成功")
else:
OutputFormatter.error("提交失败")
return success
def get_current_branch(self) -> str:
"""
获取当前分支
Returns:
分支名
"""
success, branch = self.executor.run("git branch --show-current", show_output=False)
if success and branch.strip():
return branch.strip()
return Config.DEFAULT_BRANCH
def push(self, remote: str, branch: str = "") -> bool:
"""
推送到远程仓库
Args:
remote: 远程仓库名
branch: 分支名(默认为当前分支)
Returns:
是否成功
"""
if not branch:
branch = self.get_current_branch()
OutputFormatter.status('running', f"推送到 {remote}/{branch}...")
# 先尝试直接推送
success, _ = self.executor.run(f"git push {remote} {branch}", show_output=True)
if not success:
# 如果失败,尝试设置上游分支
OutputFormatter.info("尝试设置上游分支...")
success, _ = self.executor.run(f"git push -u {remote} {branch}", show_output=True)
if success:
OutputFormatter.success(f"成功推送到 {remote}")
else:
OutputFormatter.error(f"推送到 {remote} 失败")
return success
def pull(self, remote: str, branch: str = "") -> bool:
"""
从远程仓库拉取
Args:
remote: 远程仓库名
branch: 分支名(默认为当前分支)
Returns:
是否成功
"""
if not branch:
branch = self.get_current_branch()
OutputFormatter.status('running', f"{remote}/{branch} 拉取更新...")
success, _ = self.executor.run(f"git pull {remote} {branch}", show_output=True)
if success:
OutputFormatter.success(f"成功从 {remote} 拉取更新")
else:
OutputFormatter.error(f"{remote} 拉取失败")
return success
def show_status(self):
"""显示仓库状态"""
from .utils import Colors
print(f"{Colors.CYAN}{'-' * 60}{Colors.ENDC}")
OutputFormatter.key_value(">> 当前目录", self.current_dir, Colors.BRIGHT_YELLOW)
print(f"{Colors.CYAN}{'-' * 60}{Colors.ENDC}")
# Git状态
print(f"{Colors.BRIGHT_BLUE}>> Git状态{Colors.ENDC}")
self.executor.run("git status", show_output=True)
# 最近提交
print(f"\n{Colors.BRIGHT_MAGENTA}>> 最近3次提交{Colors.ENDC}")
self.executor.run("git log --oneline -3", show_output=True)
print(f"{Colors.CYAN}{'-' * 60}{Colors.ENDC}")