Skip to content

fix(git): ブランチ切替の dirty 確認が失敗したとき切替を止める - #3439

Merged
Kewton merged 1 commit into
developfrom
feature/3436-checkout-dirty-fail-closed
Oct 8, 2026
Merged

Kewton merged 1 commit into
developfrom
feature/3436-checkout-dirty-fail-closed

Conversation

@Kewton

@Kewton Kewton commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Summary

force でないブランチの checkout は、前に git status --porcelain で dirty を確かめるが、execGitCommand が null(失敗。負荷時の 1 秒 timeout を含む)を返すとガードを素通りしていた(src/lib/git/git-branches.ts:322)。

  • checkout: status が null のときは checkout を実行せず GitTimeoutError('Could not verify working tree state') を投げる(fail-closed)。handleGitApiError は HTTP 504 { error: 'Git command timed out' } に写す。dirty(409)とは区別される。force は従来どおりこのガードを通らない
  • 同じ型のガード(探索で発見): src/lib/git/git-reset.ts の isDefaultBranchForReset は rev-parse HEAD が null だと false(=既定ブランチの保護が外れる)になり、reset --hard が進みえた。同じく GitTimeoutError で拒否する
  • git-status.ts(getGitStatus)は fix(git): git status が読めないとき worktree を clean と表示する #3435 で別に直すため触っていない

Refs #3436(develop 向けのため Closes は使わない)

Test plan

  • commandmatedev verify --task(契約 gates: lint / typecheck / unit-related + work-evidence / scope / env-clean、requireCommit: true)すべて PASS(exit 0)
  • tests/unit/lib/git/git-branches.test.ts に status 失敗で checkout しない・reset の保護が外れないケースを追加。既存の dirty / clean / force のテストは無変更で通過。既存の it/describe の削除 0 件
  • tests/unit/guards 合格、changelog-fragments.mjs check exit 0
  • CI の Unit Tests(unit-related で裁定したので、マージは Unit Tests の pass 後)

🤖 Generated with Claude Code

force でない checkout は `status --porcelain` が null(失敗・timeout)を返すと
ガードを素通りしていた。null のときは checkout を実行せず
GitTimeoutError('Could not verify working tree state') を投げる。

エラー型: git-errors.ts に「状態を確かめられない」型は GitTimeoutError のみ
(timeout/失敗を示す既存型)なのでそれを使い、メッセージで dirty
(GitDirtyError, 409 dirty) と区別した。handleGitApiError は GitTimeoutError を
HTTP 504 `{ error: 'Git command timed out' }` に写す(メッセージは応答に出ない)。
force の checkout は従来どおりガードを通らない。

同型ガード探索 (grep "execGitCommand(['status'" src/lib/git):
- git-status.ts:36 getGitStatus: #3435 で別に直すので触らない
- git-stash/git-commit/git-route-helpers: null を clean とみなすガードなし
- git-reset.ts isDefaultBranchForReset: rev-parse HEAD が null だと false
  (=デフォルトブランチ保護を外す)で reset --hard が進みうる fail-open。
  同じく GitTimeoutError で拒否するよう修正。
対の場所探索: docs の ja/en・同処理の写し・古い動きを固定したテストを探したが
該当なし(既存テストは null を返すケースを固定していない)。

本文に無い指摘: なし

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Kewton Kewton added the bug Something isn't working label Oct 8, 2026
@Kewton
Kewton merged commit f195cf6 into develop Oct 8, 2026
16 checks passed
@Kewton
Kewton deleted the feature/3436-checkout-dirty-fail-closed branch October 8, 2026 11:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant