feat(git): tag management with restore for deleted tags and branches - #354
feat(git): tag management with restore for deleted tags and branches#354Wz58luck wants to merge 6 commits into
Conversation
- Add git.createTag / git.deleteTag to lithe-core with pre-flight validation (duplicate name, unresolvable target, missing tag) and a structured tagDeletion record carrying the peeled target and original annotation for session-scoped restore - Document both operations in rust-core-api.md and extend write.json fixtures for the second platform - macOS: New Tag dialog on commit rows with inline validation, Delete Tag confirmation on tag references, and a deleted-tag banner with restore and dismiss
- deleteBranch resolves refs/heads/<name> before deleting and returns a structured branchDeletion record with the previous commit, so hosts can recreate the branch without re-querying - Document the record in rust-core-api.md and extend write.json fixtures - macOS: deleted-branch banner in the Git log with restore and dismiss, sharing the deleted-tag notice UI
…agement # Conflicts: # macos/Tests/LitheGitModuleTests/GitModuleTests.swift # shared/contracts/rust-core-api.md # shared/fixtures/git/write.json
1lck
left a comment
There was a problem hiding this comment.
整体实现方向是对的,CI 也已通过。下面几项建议在合并前修正;另外附了后续可维护性改进建议。
|
补充的维护性建议:
|
限制标签目标为提交对象,并保留注释标签的原始换行。\n统一恢复状态策略、标签类型约束与跨端名称校验。\n\nRefs 1lck#354
| ) | ||
| .with_details(peeled.output)); | ||
| } | ||
| let mut result = execute_git(root, &["tag".into(), "-d".into(), name.clone()], None)?; |
There was a problem hiding this comment.
[P1] 这里的 peeled 是前面 probe 得到的目标 OID,但实际删除仍只按 tag 名称执行 git tag -d。如果另一个 Git 进程在两步之间 force-update 同名 tag,实际删除的是新目标,返回的 tagDeletion.deletedTarget 却仍是旧目标;Restore 会静默指回错误提交。下面的 ref_exists 只确认 ref 最终不存在,不能确认删除的是预期 OID。
建议获取未 peel 的 ref object OID,并使用带 expected-old-OID 的原子删除(例如 git update-ref --delete <ref> <expectedOid>);如果 OID 已变化,应返回明确失败且不生成恢复记录。delete_branch 的 probe-then-mutate 路径也需要同样的一致性保护。
| if reference.kind == .tag { | ||
| Divider() | ||
|
|
||
| Button("Delete Tag…", role: .destructive) { |
There was a problem hiding this comment.
[P2] 这里对所有 tag 引用都展示删除入口,但 Core 的 deleteTag 要求 refs/tags/<name>^{commit} 能够解析。合法的 tree/blob tag(例如 git tag tree-tag HEAD^{tree})会正常出现在 Tags 列表中,却在确认后必然失败。
如果 commit-only 是有意的恢复契约,建议在引用模型中带出是否可 peel 到 commit,并禁用或隐藏该操作、说明原因;否则需要扩展 deletion record 以支持非 commit target 的恢复。建议同时补一个 tree/blob tag 的回归测试,确保 UI 可用性和 Core 能力保持一致。
|
@Wz58luck 我基于最新 head 整体实现方向是合理的:#342 的提交行新建 tag、Tags 列表删除、确认界面和会话内恢复流程都已经接通;命令构造与结构化恢复记录放在 目前仍有阻塞合并的问题:删除前 probe 到的 ref OID 与实际 mutation 没有原子一致性保护,并发更新同名 tag/branch 时可能删除新目标、却按旧目标生成恢复记录,最终 Restore 会静默恢复到错误提交。另外,合法的 tree/blob tag 当前会显示一个必然失败的删除操作,建议按行级评论统一 UI 能力与 Core contract。 验证方面,Rust Core、Swift bridge、Windows 边界检查以及 macOS Git 模块重点测试均通过。PR 的完整 Swift 稳定性任务仍失败在已有的 15 秒超时测试 |
Closes #342
实现内容
共享命令(rust/lithe-core)
git.write新增createTag/deleteTag:createTag:name+revision+ 可选message;非空 message 创建附注标签(git tag -a),否则轻量标签。创建前探测重名(A tag named '<name>' already exists)与目标可解析性(Could not resolve tag target '<rev>'),返回稳定invalid_request错误而非解析本地化 stderr。deleteTag:删除前用git cat-file采集标签类型与原始 annotation(换行保真,剔除签名块),rev-parse <ref>{}取剥离后的目标提交;成功响应携带结构化tagDeletion(name/deletedTarget/kind/message)。deleteBranch删除前解析分支指向的提交,成功后返回结构化branchDeletion(name/deletedTarget),供宿主提供"还原"入口;分支不存在时返回稳定错误The branch '<name>' does not exist。rust-core-api.md与shared/fixtures/git/write.json已同步更新,供第二个平台后续消费。macOS
git branch -d(安全删除),不会出现未合并提交被舍弃的场景。验证