Only count remote-unreachable commits as local work in finish guard
ci / test (pull_request) Successful in 2m19s
ci / test (pull_request) Successful in 2m19s
Why: 本地 main 停在 origin/main 顶端(克隆默认态)在 pin 为 feature 顶端时不在 pin 历史内,--branches 直判仍会误阻(本 worktree 自身收尾实测踩到)。 Evidence: 第五例回归(本地默认分支+克隆 reflog 不阻)全绿;五例套件+全套治理回归 GOVERNANCE-SUITE-OK;worktree 实际 finish 通过即端到端自证。 Impact: local_work_outside 候选提交先过 --not --remotes 过滤(远端可达即已保全); stash 仍恒算本地独有。
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -107,16 +107,19 @@ def local_work_outside(child, expected):
|
||||
"""2026-10-05 修复:pinned-history 检查此前用 --all --reflog,把 refs/remotes 也
|
||||
计入——pin 在 feature 顶端的子仓因 origin/main 不在 pin 历史内而永远无法 finish
|
||||
(实测被迫删远端引用+清 reflog 绕过,损害现场)。只认「本地独有」工作:
|
||||
本地分支、stash、以及 HEAD 的 reflog(最近检出轨迹里的独有提交);
|
||||
refs/remotes 一律不算——远端有副本即已保全。"""
|
||||
if git(child, "rev-list", "--branches", "--not", expected).strip():
|
||||
return True
|
||||
if git(child, "stash", "list").strip():
|
||||
return True
|
||||
不在任何远端跟踪引用历史内的提交才算。克隆默认分支停在 origin/main 顶端、
|
||||
reflog 里的检出轨迹等「远端有副本」的状态一律不算;stash 恒为本地独有。"""
|
||||
candidates = git(child, "rev-list", "--branches", "--not", expected).split()
|
||||
for line in git(child, "reflog", "show", "HEAD", "--format=%H").splitlines():
|
||||
tip = line.strip()
|
||||
if tip and git(child, "rev-list", "-1", tip, "--not", expected).strip():
|
||||
if tip:
|
||||
candidates.append(tip)
|
||||
for tip in dict.fromkeys(candidates): # 去重保序
|
||||
# 远端任一引用可达 ⇒ 已保全,不算本地独有
|
||||
if git(child, "rev-list", "-1", tip, "--not", "--remotes").strip():
|
||||
return True
|
||||
if git(child, "stash", "list").strip():
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
@@ -758,6 +758,23 @@ class FinishGuardFixTests(unittest.TestCase):
|
||||
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
|
||||
self.assertFalse(wt.exists())
|
||||
|
||||
|
||||
def test_local_default_branch_at_origin_main_does_not_block(self):
|
||||
"""克隆默认分支停在 origin/main 顶端(pin 为 feature 顶端时不在其历史内)
|
||||
且 HEAD reflog 含克隆/检出轨迹——均为远端有副本的状态,不得阻断 finish。"""
|
||||
self.add_submodule_pinned_off_main()
|
||||
wt = self.worktree()
|
||||
self.git(wt, "submodule", "update", "--init", "--recursive")
|
||||
(self.repo / "tracked").write_text("implementation done\n")
|
||||
self.git(self.repo, "add", "-A")
|
||||
self.git(self.repo, "commit", "-q", "-m", "done")
|
||||
self.git(self.repo, "push", "-q", "origin", "feature/guard")
|
||||
self.git(self.repo, "merge", "--no-ff", "-q", "-m", "Merge feature/guard", "feature/guard")
|
||||
self.git(self.repo, "push", "-q", "origin", "main")
|
||||
result = self.task(wt, "finish", check=False)
|
||||
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
|
||||
self.assertFalse(wt.exists())
|
||||
|
||||
def test_local_unique_commit_still_preserved(self):
|
||||
self.add_submodule_pinned_off_main()
|
||||
wt = self.worktree()
|
||||
|
||||
Reference in New Issue
Block a user