Merge current main while preserving governance repairs
Why: main advanced with merged-task-name and legacy evidence guards during this task. Evidence: SELF 44 lifecycle regressions pass after resolving both hunks; independent review repairs are recorded in the task card. Impact: retains both task-start protections and the stronger JSON/legacy receipt reader, without rewriting either branch history. Refs: Dev PR #211 and #212; .task/feature-governance-reliability.md
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
# feature/task-start-merged-guard 任务卡
|
||||
|
||||
任务主记录:PR #211 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/211(merge 04e07dea89);状态:已完成(回填);owner:weichen
|
||||
|
||||
## 基线与授权
|
||||
|
||||
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 43d33aa4921078bc202393b99cba017d7f731b98
|
||||
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard(worktree);分支:feature/task-start-merged-guard
|
||||
- 授权与交付终点:owner 2026-10-05 授权立项(决策清单 #7);改 scripts/task.sh 加守护 + 测试 + PR 合入为本卡终点;不改 task.sh 其他行为。
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
- **目标**:`cmd_start` 在分支名校验后新增守护——本地或远端存在同名分支且已包含于 `origin/main` 时拒绝启动(exit 非零),提示「沿用原分支或换新 slug」。
|
||||
- **背景**:2026-10-05 EXT-1 复核轮实测,合入后再 `task-start` 同名分支会从新 main 长出第二段历史、空卡覆盖已合入任务卡(两轮证据差点丢失,靠 git show 恢复);旧逻辑只校验本地分支能否创建,不查是否刚合入。
|
||||
- **非目标**:不改 precheck/task-sync/finish 等其他子命令;不做「恢复原卡」的自动修复(拒绝即可,恢复留给人工);不引入新依赖。
|
||||
- **范围变更(2026-10-05 12:33)**:本卡功能负例的证据命令含 `||`,暴露 `cmd_sync` 证据扫描按裸 `|` 切行、把转义碎片当 HEAD 传给 `git diff` 致 fatal 128 杀死 sync 的潜在缺陷(task-sync 门禁被卡死,卡内 12:30–12:32 五次中毒复现)——**同 PR 一并修复**(非十六进制单元格跳过,WARN 语义不变)。
|
||||
|
||||
## 同步记录
|
||||
|
||||
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|
||||
|---|---|---|---|
|
||||
| 启动 | 43d33aa4921078bc202393b99cba017d7f731b98 | 43d33aa4921078bc202393b99cba017d7f731b98 | 2026-10-05T12:28:26Z |
|
||||
|
||||
## 证据(Evidence)
|
||||
|
||||
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
|
||||
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|
||||
|---|---|---|---|---|---|
|
||||
|
||||
## 结果与验证
|
||||
|
||||
- 结果:cmd_start 守护 + cmd_sync 证据扫描加固均落地(见范围变更)。守护:已合入同名分支拒绝启动、提示沿用原分支或换新 slug,负例实测无 worktree 副作用;扫描:含 `\|\|` 转义行的卡片上 sync 正常完成、WARN 语义不变。
|
||||
- 验证:bash -n PASS;功能负例 PASS(exit≠0 断言,无副作用);sync 修复验证 PASS(exit 0);make test 全链 PASS(修复前 94f8d47 与最终 HEAD 两轮,exit 0);权威源为 CI 在 PR HEAD 的 make test+make build(GATE)。
|
||||
- 影响与剩余项:仅 scripts/task.sh 两处;下游建仓(Agent-System-RDM)将复制修复后的版本。
|
||||
| 2026-10-05T12:28:53Z | `bash -n scripts/task.sh` | 94f8d4760b | 0 | SELF | e3b0c44298fc1c14 |
|
||||
|
||||
<!-- evidence:run 2026-10-05T12:28:53Z -->
|
||||
```
|
||||
$ bash -n scripts/task.sh
|
||||
[exit 0 | HEAD 94f8d4760b | sha256:e3b0c44298fc1c14] 输出尾部 15 行:
|
||||
|
||||
```
|
||||
| 2026-10-05T12:28:53Z | `bash scripts/task.sh start feature/ext-1-inproc-handler && exit 1 \|\| echo 'guard refused merged branch as expected'` | 94f8d4760b | 0 | SELF | 937f2c0a1987b4f7 |
|
||||
|
||||
<!-- evidence:run 2026-10-05T12:28:53Z -->
|
||||
```
|
||||
$ bash scripts/task.sh start feature/ext-1-inproc-handler && exit 1 || echo 'guard refused merged branch as expected'
|
||||
[exit 0 | HEAD 94f8d4760b | sha256:937f2c0a1987b4f7] 输出尾部 15 行:
|
||||
ERROR: branch feature/ext-1-inproc-handler already merged into origin/main — reuse the original branch or pick a new slug (task-start must not recreate merged cards)
|
||||
guard refused merged branch as expected
|
||||
```
|
||||
| 2026-10-05T12:29:05Z | `make test` | 94f8d4760b | 0 | SELF | 84092b2ad053ee79 |
|
||||
|
||||
<!-- evidence:run 2026-10-05T12:29:05Z -->
|
||||
```
|
||||
$ make test
|
||||
[exit 0 | HEAD 94f8d4760b | sha256:84092b2ad053ee79] 输出尾部 20 行:
|
||||
|
||||
✓ test/ui.test.tsx (6 tests) 66ms
|
||||
✓ test/toolblock.test.tsx (4 tests) 76ms
|
||||
✓ test/overlay-host.test.tsx (6 tests) 68ms
|
||||
✓ test/file-preview.test.tsx (9 tests) 89ms
|
||||
✓ test/inbox.test.tsx (13 tests) 93ms
|
||||
✓ test/card-anchor.test.tsx (4 tests) 96ms
|
||||
✓ test/inline-confirm.test.tsx (7 tests) 107ms
|
||||
✓ test/capability.test.tsx (14 tests) 153ms
|
||||
|
||||
Test Files 14 passed (14)
|
||||
Tests 103 passed (103)
|
||||
Start at 12:29:37
|
||||
Duration 619ms (transform 415ms, setup 0ms, import 1.36s, tests 955ms, environment 3.25s)
|
||||
|
||||
knip unused exports 55 <= 55
|
||||
cd deps/agent-command && go vet ./... && go test -count=1 ./...
|
||||
ok agent-command 0.002s
|
||||
ok agent-command/conformance 0.002s
|
||||
make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard'
|
||||
```
|
||||
| 2026-10-05T12:30:24Z | `make task-sync` | 94f8d4760b | 2 | SELF | c59e97420676c4fa |
|
||||
|
||||
<!-- evidence:run 2026-10-05T12:30:24Z -->
|
||||
```
|
||||
$ make task-sync
|
||||
[exit 2 | HEAD 94f8d4760b | sha256:c59e97420676c4fa] 输出尾部 15 行:
|
||||
make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard'
|
||||
ERROR: dirty tree — 先显式提交;不隐式 stash(collaboration.md:11)
|
||||
make[1]: *** [Makefile:36: task-sync] Error 1
|
||||
make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard'
|
||||
```
|
||||
| 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | e58035a8e4b60dc291d9245d669c5a3a561fd699 | 2026-10-05T12:30:36Z |
|
||||
| 2026-10-05T12:30:36Z | `make task-sync` | e58035a8e4 | 2 | SELF | 12717b8736ff03bf |
|
||||
|
||||
<!-- evidence:run 2026-10-05T12:30:36Z -->
|
||||
```
|
||||
$ make task-sync
|
||||
[exit 2 | HEAD e58035a8e4 | sha256:12717b8736ff03bf] 输出尾部 15 行:
|
||||
make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard'
|
||||
Already up to date.
|
||||
make[1]: *** [Makefile:36: task-sync] Error 128
|
||||
make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard'
|
||||
```
|
||||
| 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | 879bf64b94a6f1c3b126ec52a778b1f8c7630266 | 2026-10-05T12:30:49Z |
|
||||
| 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | 09aa6e59b08ff74ca3e5c78ab1bffc55e386993c | 2026-10-05T12:31:08Z |
|
||||
| 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | 9e30c5f656ccaf3186c966c7452df2da3d75292f | 2026-10-05T12:31:17Z |
|
||||
| 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | b3a5a31d10d03dabe13e03ddbf29c736f892dea2 | 2026-10-05T12:31:59Z |
|
||||
| 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | 2fec8b4e829bdb27006c924d51d56016331bde44 | 2026-10-05T12:32:00Z |
|
||||
| 2026-10-05T12:32:55Z | `bash -n scripts/task.sh && bash scripts/task.sh sync && echo 'sync survives escaped-pipe evidence row'` | 278bff9a31 | 1 | SELF | afc745546e4eb5ba |
|
||||
|
||||
<!-- evidence:run 2026-10-05T12:32:55Z -->
|
||||
```
|
||||
$ bash -n scripts/task.sh && bash scripts/task.sh sync && echo 'sync survives escaped-pipe evidence row'
|
||||
[exit 1 | HEAD 278bff9a31 | sha256:afc745546e4eb5ba] 输出尾部 15 行:
|
||||
ERROR: dirty tree — 先显式提交;不隐式 stash(collaboration.md:11)
|
||||
```
|
||||
| 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | 1e0508e8a7071bcd92e78089c6c30c41caf1b594 | 2026-10-05T12:33:06Z |
|
||||
| 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | 9a3ebe6539d97445a7b5705a0a48bd9a1124aa90 | 2026-10-05T12:33:16Z |
|
||||
| 2026-10-05T12:33:16Z | `bash -n scripts/task.sh && bash scripts/task.sh sync >/dev/null 2>&1 && echo 'sync survives escaped-pipe evidence row'` | 9a3ebe6539 | 0 | SELF | 2a3457acb8b31495 |
|
||||
|
||||
<!-- evidence:run 2026-10-05T12:33:16Z -->
|
||||
```
|
||||
$ bash -n scripts/task.sh && bash scripts/task.sh sync >/dev/null 2>&1 && echo 'sync survives escaped-pipe evidence row'
|
||||
[exit 0 | HEAD 9a3ebe6539 | sha256:2a3457acb8b31495] 输出尾部 15 行:
|
||||
sync survives escaped-pipe evidence row
|
||||
```
|
||||
| 2026-10-05T12:33:22Z | `make test` | de75f1ede9 | 0 | SELF | 9a4f394d8e0f5c60 |
|
||||
|
||||
<!-- evidence:run 2026-10-05T12:33:22Z -->
|
||||
```
|
||||
$ make test
|
||||
[exit 0 | HEAD de75f1ede9 | sha256:9a4f394d8e0f5c60] 输出尾部 20 行:
|
||||
✓ test/collapsible.test.tsx (5 tests) 79ms
|
||||
✓ test/ui.test.tsx (6 tests) 70ms
|
||||
✓ test/tabstrip.test.tsx (3 tests) 79ms
|
||||
✓ test/file-preview.test.tsx (9 tests) 84ms
|
||||
✓ test/overlay-host.test.tsx (6 tests) 79ms
|
||||
✓ test/inbox.test.tsx (13 tests) 90ms
|
||||
✓ test/inline-confirm.test.tsx (7 tests) 106ms
|
||||
✓ test/card-anchor.test.tsx (4 tests) 107ms
|
||||
✓ test/capability.test.tsx (14 tests) 157ms
|
||||
|
||||
Test Files 14 passed (14)
|
||||
Tests 103 passed (103)
|
||||
Start at 12:33:50
|
||||
Duration 651ms (transform 432ms, setup 0ms, import 1.42s, tests 993ms, environment 3.42s)
|
||||
|
||||
knip unused exports 55 <= 55
|
||||
cd deps/agent-command && go vet ./... && go test -count=1 ./...
|
||||
ok agent-command 0.002s
|
||||
ok agent-command/conformance 0.002s
|
||||
make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard'
|
||||
```
|
||||
|
||||
## 闭合记录(card-autoclose 回填)
|
||||
|
||||
- 依据:merge 04e07dea89ed6471349600901a23f7de770359c2(PR #211)已包含于 origin/main,分支成果已落盘;本段为合入后回填。
|
||||
- 合并主题:Merge pull request 'Guard task-start against merged branch names; harden sync evidence scan' (#211) from feature/task-start-merged-guard into main
|
||||
- 归档:随闭合移入 .task/archive/;任务执行期的过程证据见原任务记录与 PR。
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"status": "complete",
|
||||
"verdict": "All four specified repair findings resolved at fixed source SHA",
|
||||
"evidence_source": "REPLAY",
|
||||
"reviewer": "/root/verify_review_repairs",
|
||||
"scope": "Bounded verification of original findings 1-4; not a whole-repository review or release gate",
|
||||
"source_sha": "b84667a697ab88e7eb09b78ba6b00175729937b2",
|
||||
"diff_base_sha": "976d2e84434f6a089cb8ccd1da33e151a6cc375d",
|
||||
"original_review_source_sha": "c0abfb0250980af7f1b18c785eb4b55240a8d855",
|
||||
"original_review_artifact_commit": "b84667a697ab88e7eb09b78ba6b00175729937b2",
|
||||
"original_review_artifact_path": ".task/reviews/governance-reliability.json",
|
||||
"snapshot": "/tmp/governance-repair-replay-urtmaen7",
|
||||
"snapshot_file_count_verified_against_commit": 22,
|
||||
"commands": [
|
||||
{
|
||||
"command": "PYTHONDONTWRITEBYTECODE=1 GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_GLOBAL=/dev/null GIT_ALLOW_PROTOCOL=file GIT_TERMINAL_PROMPT=0 python3 -m unittest discover -s tests -p test_task.py -v",
|
||||
"cwd": "/tmp/governance-repair-replay-urtmaen7",
|
||||
"exit_code": 0,
|
||||
"tests_run": 42,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"result": "OK",
|
||||
"elapsed_seconds": 9.509,
|
||||
"output_path": "/tmp/governance-review-repair-task.log",
|
||||
"output_sha256": "eeb1bba7e4eae6369c5931a4c4756c8cdef78da49f97b7d4af2aa0c80de642fb"
|
||||
},
|
||||
{
|
||||
"command": "PYTHONDONTWRITEBYTECODE=1 GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_GLOBAL=/dev/null GIT_ALLOW_PROTOCOL=file GIT_TERMINAL_PROMPT=0 python3 -m unittest discover -s tests -p test_evidence.py -v",
|
||||
"cwd": "/tmp/governance-repair-replay-urtmaen7",
|
||||
"exit_code": 0,
|
||||
"tests_run": 31,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"result": "OK",
|
||||
"elapsed_seconds": 3.981,
|
||||
"output_path": "/tmp/governance-review-repair-evidence.log",
|
||||
"output_sha256": "3824093772141bb2fbe7e2f72bfa8ba8113dadc5dbe20ecb2d242e3a8088bd44"
|
||||
}
|
||||
],
|
||||
"total_tests": 73,
|
||||
"findings": [
|
||||
{
|
||||
"id": 1,
|
||||
"severity": "P1",
|
||||
"resolution": "RESOLVED",
|
||||
"evidence_source": "REPLAY",
|
||||
"summary": "Finish refuses parent removal when recursively inspected component common metadata belongs to the removal roots and serves another registered worktree. Clean, staged, unstaged, and nested linked component cases preserve Git usability and content; normal clean component cleanup passes.",
|
||||
"tests": [
|
||||
"test_finish_preserves_linked_component_worktrees_at_the_pinned_head",
|
||||
"test_finish_preserves_linked_nested_component_worktree",
|
||||
"test_finish_recycles_clean_submodule_without_shared_config_changes"
|
||||
],
|
||||
"historical_provenance_used_to_dismiss": false
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"severity": "P2",
|
||||
"resolution": "RESOLVED",
|
||||
"evidence_source": "REPLAY",
|
||||
"summary": "Sync detects stale JSON and legacy receipts, warns for malformed or missing fields and unresolved recorded commits, and treats non-card before/after dirt as unverified. Card-only changes remain fresh. Recorded command is not executed.",
|
||||
"tests": [
|
||||
"test_sync_warns_when_json_evidence_predates_noncard_changes",
|
||||
"test_sync_still_warns_for_stale_legacy_table_evidence",
|
||||
"test_sync_warns_for_malformed_json_evidence",
|
||||
"test_sync_warns_for_missing_json_receipt_fields_even_with_valid_checksum",
|
||||
"test_sync_warns_for_unresolved_json_evidence_head",
|
||||
"test_sync_warns_for_unresolved_legacy_evidence_head",
|
||||
"test_sync_warns_when_json_before_state_contains_uncommitted_code",
|
||||
"test_sync_warns_when_json_after_state_contains_uncommitted_code",
|
||||
"test_sync_keeps_json_evidence_fresh_after_metadata_only_changes",
|
||||
"test_sync_does_not_execute_json_receipt_command"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"severity": "P2",
|
||||
"resolution": "RESOLVED",
|
||||
"evidence_source": "REPLAY",
|
||||
"summary": "Thirty Authorization syntax/scheme combinations cover JSON, dictionary, plain, assignment, case, and whitespace forms. Capture command/output/receipt/card/console and import contain no synthetic credential. Imported unredacted receipts are rejected even with valid checksums.",
|
||||
"tests": [
|
||||
"test_authorization_forms_are_redacted_in_capture_console_and_import",
|
||||
"test_authorization_forms_are_redacted_on_direct_card_capture",
|
||||
"test_import_rejects_unredacted_authorization_with_valid_checksums"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"severity": "P2",
|
||||
"resolution": "RESOLVED",
|
||||
"evidence_source": "REPLAY",
|
||||
"summary": "Explicit abandon removes the clean worktree while keeping local and file-remote branch tips and the abandonment reason note; missing reason refuses removal and preserves checkout and refs without writing a note.",
|
||||
"tests": [
|
||||
"test_finish_abandon_retains_local_remote_tips_and_reason",
|
||||
"test_finish_abandon_without_reason_preserves_checkout_and_refs"
|
||||
]
|
||||
}
|
||||
],
|
||||
"remaining_scope_blockers": [],
|
||||
"limitations": [
|
||||
"Canonical working directory had scripts/task.sh merge conflict at initial inspection; the tested exported snapshot is byte-equal to b84667a. This verdict does not validate subsequent source changes or merge resolutions.",
|
||||
"No real remote or service used; Git allowed protocol file only. No canonical source or task-state mutations performed.",
|
||||
"No full make test/build, CI, broad review, or cross-model pipeline executed."
|
||||
]
|
||||
}
|
||||
+10
-1
@@ -118,13 +118,22 @@ cmd_precheck() {
|
||||
|
||||
cmd_start() {
|
||||
need_repo
|
||||
local name="${1:-}"; [ -n "$name" ] || die "usage: task.sh start <feature|fix|hotfix>/<slug>"
|
||||
local name="${1:-}"; [ -n "$name" ] || die "usage: task.sh start <feature|fix|hotfix|release>/<slug>"
|
||||
echo "$name" | grep -qE '^(feature|fix|hotfix|release)/[A-Za-z0-9._-]+$' || die "branch name must match (feature|fix|hotfix|release)/<slug>"
|
||||
fetch_target
|
||||
[ -n "${PRECHECK_RECEIPT:-}" ] || die "PRECHECK_RECEIPT required: capture RECEIPT=/tmp/task-precheck.json CMD='make precheck' make evidence first"
|
||||
PRECHECK_RECEIPT=$(realpath -- "$PRECHECK_RECEIPT")
|
||||
VALIDATE_RECEIPT="$PRECHECK_RECEIPT" bash "${SCRIPT_DIR}/evidence.sh"
|
||||
check_worktree before-sync
|
||||
# 已合入的同名分支不得重建(2026-10-05 实测:合入后再 task-start 同名会从新 main 长出
|
||||
# 第二段历史,空卡覆盖已合入任务卡,两轮证据差点丢失)。复核/追加沿用原分支或换新 slug。
|
||||
local guard_ref
|
||||
for guard_ref in "refs/heads/${name}" "refs/remotes/origin/${name}"; do
|
||||
if git rev-parse -q --verify "${guard_ref}" >/dev/null \
|
||||
&& git merge-base --is-ancestor "${guard_ref}" "origin/${TARGET_BRANCH}"; then
|
||||
die "branch ${name} already merged into origin/${TARGET_BRANCH} — reuse the original branch or pick a new slug (task-start must not recreate merged cards)"
|
||||
fi
|
||||
done
|
||||
[ "$(git status --porcelain | { grep -v '^.. \.zcode/' || true; } | wc -l)" -eq 0 ] || die "dirty tree — resolve first (precheck verdict BUSY)"
|
||||
[ "$(git submodule status --recursive 2>/dev/null | { grep -cE '^\+|^U' || true; })" -eq 0 ] || die "submodule drift/conflict — resolve first (precheck verdict BUSY)"
|
||||
git merge-base --is-ancestor "origin/${TARGET_BRANCH}" HEAD || die "local ${TARGET_BRANCH} behind origin — pull --ff-only first"
|
||||
|
||||
@@ -512,6 +512,19 @@ class TaskLifecycleTests(unittest.TestCase):
|
||||
result = self.task(wt, "sync")
|
||||
self.assertIn("[evidence] WARN", result.stdout)
|
||||
|
||||
def test_sync_reads_legacy_commands_with_escaped_pipes(self):
|
||||
wt = self.worktree()
|
||||
card = self.task_card(wt)
|
||||
head = self.git(wt, "rev-parse", "--short=10", "HEAD").stdout.strip()
|
||||
card.write_text(card.read_text() +
|
||||
f"\n| 2026-10-05T00:00:00Z | `false \\|\\| true` | `{head}` | 0 | SELF | abc |\n")
|
||||
self.commit_evidence(wt)
|
||||
self.advance_remote()
|
||||
result = self.task(wt, "sync")
|
||||
self.assertIn("[synced]", result.stdout)
|
||||
self.assertIn("[evidence] WARN", result.stdout)
|
||||
self.assertNotIn("unverified", result.stdout)
|
||||
|
||||
def test_finish_preserves_main_and_active_index_lock(self):
|
||||
result = self.task(self.repo, "finish", check=False)
|
||||
self.assertNotEqual(result.returncode, 0, result.stdout)
|
||||
@@ -548,6 +561,26 @@ class TaskLifecycleTests(unittest.TestCase):
|
||||
self.assertNotEqual(result.returncode, 0, result.stdout)
|
||||
self.assertFalse((self.root / "repo-wt-feature-new").exists(), result.stdout)
|
||||
|
||||
def test_start_preserves_merged_local_and_remote_branch_names(self):
|
||||
receipt = self.capture_precheck()
|
||||
head = self.git(self.repo, "rev-parse", "HEAD").stdout.strip()
|
||||
for kind in ("local", "remote"):
|
||||
with self.subTest(kind=kind):
|
||||
name = "feature/merged-" + kind
|
||||
if kind == "local":
|
||||
self.git(self.repo, "branch", name, head)
|
||||
ref = "refs/heads/" + name
|
||||
else:
|
||||
self.git(self.repo, "push", "origin", head + ":refs/heads/" + name)
|
||||
ref = "refs/remotes/origin/" + name
|
||||
self.git(self.repo, "fetch", "origin", "refs/heads/" + name + ":" + ref)
|
||||
result = self.task(self.repo, "start", name, check=False,
|
||||
env=self.env | {"PRECHECK_RECEIPT": str(receipt)})
|
||||
self.assertNotEqual(result.returncode, 0, result.stdout)
|
||||
self.assertIn("already merged", result.stdout)
|
||||
self.assertFalse((self.root / ("repo-wt-" + name.replace("/", "-"))).exists())
|
||||
self.assertEqual(self.git(self.repo, "rev-parse", ref).stdout.strip(), head)
|
||||
|
||||
def test_start_imports_precheck_and_creates_four_part_commit(self):
|
||||
receipt = self.capture_precheck()
|
||||
self.task(self.repo, "start", "feature/new", env=self.env | {"PRECHECK_RECEIPT": str(receipt)})
|
||||
|
||||
Reference in New Issue
Block a user