From 76a804b8b049e3ca52d1c84392a2dff79588c1a5 Mon Sep 17 00:00:00 2001 From: ninemine <1371605831@qq.com> Date: Thu, 23 Oct 2025 23:49:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=88=86=E6=94=AF=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E4=B8=8E=E6=9F=A5=E7=9C=8B=E5=88=86=E6=94=AF=E6=8F=90?= =?UTF-8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.py | 98 +++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 18 deletions(-) diff --git a/app.py b/app.py index 8f45fef..d6668bd 100644 --- a/app.py +++ b/app.py @@ -105,8 +105,6 @@ class Cli: else: layer = 0 for line_index, line in enumerate(sp): - layer -= 1 - forward = sp[min(line_index+self.group_size, len(sp)-1)] if ConsoleFrontColor.GREEN in forward and ConsoleFrontColor.RED in forward: layer = self.group_size @@ -126,8 +124,9 @@ class Cli: layer = self.group_size else: perfix = "=" + layer -= 1 - if layer <= 0: + if layer < 0: continue print(f"{perfix}{FillString(line_index+1, max_length=status_len, side = "left")}{ConsoleFrontColor.RESET} | {line}") print(ConsoleFrontColor.RESET) @@ -138,13 +137,15 @@ class Cli: def __init__(self, asset:str, input:str, branch:str, *, history_file:Optional[str]=None, - verbose:bool=False + verbose:bool=False, + base_branch:str="main" ) -> None: self.config = GlobalConfig(asset,True) self.file = ToolFile(input) self.branch = branch self.verbose = verbose or self.config.FindItem("verbose", False) self.group_size = self.config.FindItem("group_size", 3) + self.base_branch = base_branch self.historys_file = self.config.GetFile(history_file if history_file is not None else break_down_path(self.file.GetAbsPath())|"history", False) if self.historys_file.Exists(): @@ -189,38 +190,38 @@ class Cli: self.print_out() - def compare(self) -> None: + def compare(self) -> bool: + ''' + 返回值: 是否比较成功且存在差异 + ''' if self.branch not in self.historys.branches: self.config.Log("Error", f"Branch {self.branch} not found") - return + return False head_commit = str(self.historys.ReadBranchHeadCommit(self.branch, self.historys_file.GetDirToolFile())) current_content = self.file.LoadAsText() operations = GetDiffOperations(head_commit, current_content) if len(operations) == 0: PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, "No changes") - return + return False self.show_compare_result(head_commit, operations) if self.verbose: PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, "\noperations:") print(f"{'\n'.join([f"{ConsoleFrontColor.GREEN if item[0] == "add" else ConsoleFrontColor.RED}{item[0]}{ConsoleFrontColor.RESET} \"{ConsoleFrontColor.YELLOW}{item[3]}{ConsoleFrontColor.RESET}\" on [{item[1]},{item[2]}]" for item in operations])}") + + return True def save(self) -> None: content = self.file.LoadAsText() root = HistoryObject(hashcode=hashlib.md5(content.encode()).hexdigest()) commit_name = f"{len(self.historys.obj_paths)}" - if self.branch not in self.historys.branches: - # 创建分支并为其创建新的树 - self.historys.obj_paths[commit_name] = None - self.historys.branches[self.branch] = commit_name - self.historys_file.MustExistsPath() - root.blocks=[HistoryBlock(mode="add",begin=0,end=len(content),content=content)] - PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, "\nAll content is new") - else: - head_commit = str(self.historys.ReadBranchHeadCommit(self.branch, self.historys_file.GetDirToolFile())) + + def create_change_operations(head_commit:str) -> bool: operations = GetDiffOperations(head_commit, content) + if len(operations) == 0: + return False for operation in operations: if operation[0] == "add": root.blocks.append(HistoryBlock(mode="add",begin=operation[1],end=operation[2],content=operation[3])) @@ -232,11 +233,37 @@ class Cli: if self.verbose: PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, "\noperations:") print(f"{'\n'.join([f"{ConsoleFrontColor.GREEN if item[0] == "add" else ConsoleFrontColor.RED}{item[0]}{ConsoleFrontColor.RESET} \"{ConsoleFrontColor.YELLOW}{item[3]}{ConsoleFrontColor.RESET}\" on [{item[1]},{item[2]}]" for item in operations])}") + + return True + + if self.branch not in self.historys.branches: + # 创建分支并为其创建新的树 + if self.base_branch == self.branch: + self.historys.obj_paths[commit_name] = None + self.historys.branches[self.branch] = commit_name + self.historys_file.MustExistsPath() + root.blocks=[HistoryBlock(mode="add",begin=0,end=len(content),content=content)] + PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, "All content is new") + PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, f"Branch {self.branch} created") + else: + head_commit = str(self.historys.ReadBranchHeadCommit(self.base_branch, self. historys_file.GetDirToolFile())) + if not create_change_operations(head_commit): + PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, "No changes") + return + # 创建树节点, 并链接 + self.historys.obj_paths[commit_name] = self.historys.branches[self.base_branch] + self.historys.branches[self.branch] = commit_name + else: + head_commit = str(self.historys.ReadBranchHeadCommit(self.branch, self.historys_file.GetDirToolFile())) + if not create_change_operations(head_commit): + PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, "No changes") + return # 创建树节点, 并链接 self.historys.obj_paths[commit_name] = self.historys.branches[self.branch] self.historys.branches[self.branch] = commit_name (self.historys_file.GetDirToolFile()|commit_name).SaveAsBinary(pickle.dumps(root)) (self.historys_file).SaveAsBinary(pickle.dumps(self.historys)) + PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, f"Branch {self.branch} saved commit {commit_name}") def view(self, commit_name:Optional[str]=None) -> None: if commit_name is None or commit_name == "": @@ -259,6 +286,29 @@ class Cli: self.file.SaveAsText(head_commit) PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, f"\nTaken {self.file} to commit {"head" if commit_name is None or commit_name == "" else commit_name}") + def list_branches(self) -> None: + if len(self.historys.branches) == 0: + PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, "No branches") + return + for branch in self.historys.branches: + PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, f"{branch} -> commit \"{self.historys.branches[branch]}\"") + + def list_commits(self) -> None: + if len(self.historys.branches) == 0: + PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, "No branches") + return + if self.branch not in self.historys.branches: + PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, f"Branch {self.branch} not found") + return + commit = self.historys.branches[self.branch] + PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, f"Branch {self.branch} commits:") + while commit in self.historys.obj_paths: + commit_file = self.historys_file.GetDirToolFile()|commit + commit_object = pickle.loads(commit_file.LoadAsBinary()) + PrintColorful(ConsoleFrontColor.LIGHTMAGENTA_EX, f"{commit}: {ConsoleFrontColor.YELLOW}{commit_object.hashcode}{ConsoleFrontColor.GREEN}{len(commit_object.blocks)}{ConsoleFrontColor.RESET}") + commit = self.historys.obj_paths[commit] + + def run() -> int: parser = argparse.ArgumentParser() # 目标文件 @@ -267,7 +317,8 @@ def run() -> int: # 可选的项目源 parser.add_argument("-a", "--asset", type=str, default=ProjectConfig.ProjectConfigFileFocus, help="配置文件目录") # 分支 - parser.add_argument("-b", "--branch", type=str, default="main", help="分支") + parser.add_argument("--base-branch", type=str, default="main", help="指定基分支") + parser.add_argument("--branch", type=str, default="main", help="指定分支, 当指定的分支不存在时会新建分支, 并以指定的基分支当前的commit为父节点创建分支节点, 如果没有指定基分支则默认使用main分支") # 是否详细信息 parser.add_argument("--verbose", action="store_true", help="是否详细信息") # 模式互斥组 @@ -277,6 +328,8 @@ def run() -> int: mode_group.add_argument("-v", "--view", type=str,default=None, help="查看记录内容") mode_group.add_argument("-r", "--restore", action="store_true", help="恢复当前文件") mode_group.add_argument("-t", "--take", type=str,default=None, help="获取指定提交的文件") + mode_group.add_argument("-lb", "--list-branches", action="store_true", help="列出所有分支") + mode_group.add_argument("-lc", "--list-commits", action="store_true", help="列出指定分支的提交列表") args = parser.parse_args() @@ -286,7 +339,8 @@ def run() -> int: cli = Cli(args.asset, args.input, args.branch, history_file=args.history, - verbose=args.verbose) + verbose=args.verbose, + base_branch=args.base_branch) # 比较 if args.compare: @@ -308,6 +362,14 @@ def run() -> int: elif args.take is not None: cli.take(args.take) return 0 + # 列出所有分支 + elif args.list_branches: + cli.list_branches() + return 0 + # 列出指定分支的提交列表 + elif args.list_commits: + cli.list_commits() + return 0 raise NotImplementedError("Not implemented mode")