diff --git a/git.py b/git.py new file mode 100644 index 0000000..13aa633 --- /dev/null +++ b/git.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""git_helper —— 交互式 Git 工作流助手(沙盒验证副本)""" +import subprocess +import sys + +MAIN_BRANCH = "master" + + +def run(cmd, check=True, capture=True): + print(f"\n$ {cmd}") + try: + result = subprocess.run(cmd, shell=True, capture_output=capture, text=True) + except Exception as e: + print(f"[!] 命令执行异常: {e}") + return None + if result.stdout: + print(result.stdout.strip()) + if result.returncode != 0: + if result.stderr: + print(result.stderr.strip()) + if check: + print("[!] 命令执行失败,已中止。") + return None + return result + + +def confirm(prompt="确定要执行吗?"): + ans = input(f"\n{prompt} [y/N]: ").strip().lower() + return ans in ("y", "yes") + + +def current_branch(): + result = subprocess.run( + "git branch --show-current", shell=True, capture_output=True, text=True + ) + return result.stdout.strip() or "(unknown)" + + +def show_status(): + print("\n===== 当前仓库状态 =====") + run("git status", check=False) + print("\n===== 远程配置 =====") + run("git remote -v", check=False) + print("=========================\n") + + +def sync_from_upstream(): + print("\n>>> [1] 拉取原作者代码") + status = run("git status --porcelain", check=False, capture=True) + if status and status.stdout.strip(): + print("[!] 当前工作区有未提交的改动") + if confirm("是否先执行 'git stash' 暂存这些改动?"): + run("git stash push -m \"auto-stash before sync\"") + else: + print("已取消同步。") + return + steps = [ + f"git checkout {MAIN_BRANCH}", + "git fetch upstream", + f"git merge upstream/{MAIN_BRANCH}", + f"git push origin {MAIN_BRANCH}", + ] + print("\n即将依次执行:") + for i, s in enumerate(steps, 1): + print(f" {i}) {s}") + if not confirm("确认执行以上同步步骤?"): + print("已取消。") + return + for step in steps: + if run(step) is None: + print("[!] 同步中断,请检查上方错误信息。") + return + print("\n✅ 原作者代码已同步并推送。") + + +def push_feature(): + print("\n>>> [2] 推送自己的功能到仓库") + if confirm("是否先基于最新的 master 创建/更新功能分支?(推荐:是)"): + run(f"git checkout {MAIN_BRANCH}") + run("git fetch upstream") + run(f"git merge upstream/{MAIN_BRANCH}") + branch = input("\n请输入功能分支名(留空则使用当前分支): ").strip() + if branch: + existing = run(f"git branch --list {branch}", check=False, capture=True) + if existing and existing.stdout.strip(): + run(f"git checkout {branch}") + run(f"git rebase {MAIN_BRANCH}") + else: + run(f"git checkout -b {branch}") + else: + print(f"(将使用当前分支:{current_branch()})") + run("git status", check=False) + if not confirm("确认将以上改动加入提交?"): + print("已取消。") + return + add_mode = input("添加方式:[A] 全部 / [F] 指定文件 ? ").strip().lower() + if add_mode == "f": + files = input("请输入要添加的文件(空格分隔): ").strip() + if not files: + print("[!] 未指定文件,已取消。") + return + run(f"git add {files}") + else: + run("git add .") + msg = input("请输入 commit 信息(留空使用默认): ").strip() + if not msg: + msg = "chore: update via git_helper" + if run(f"git commit -m \"{msg}\"") is None: + print("[!] 提交失败。") + return + target_branch = branch if branch else current_branch() + print(f"\n准备推送分支 '{target_branch}' 到 origin ...") + if not confirm(f"执行: git push -u origin {target_branch} ?"): + print("已取消推送。") + return + run(f"git push -u origin {target_branch}") + print("\n✅ 功能已推送。如需回馈原作者,可到 GitHub 创建 PR。") + + +def main(): + while True: + print("\n========== Git 工作流助手 ==========") + print(f" 当前分支: {current_branch()}") + print(" 1) 拉取原作者代码") + print(" 2) 推送自己的功能到仓库") + print(" 3) 查看仓库状态") + print(" 4) 退出") + print("===================================") + choice = input("请选择操作 [1-4]: ").strip() + if choice == "1": + sync_from_upstream() + elif choice == "2": + push_feature() + elif choice == "3": + show_status() + elif choice == "4": + print("再见!") + sys.exit(0) + else: + print("[!] 无效输入,请输入 1-4。") + + +if __name__ == "__main__": + main() \ No newline at end of file