Skip to content

fix(git): git status を読めなかった worktree を clean と報告しない - #3440

Merged
Kewton merged 3 commits into
developfrom
feature/3435-git-status-unknown
Oct 8, 2026
Merged

Kewton merged 3 commits into
developfrom
feature/3435-git-status-unknown

Conversation

@Kewton

@Kewton Kewton commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Summary

getGitStatus(src/lib/git/git-status.ts)は git status --porcelain が失敗(本番では負荷時の 1 秒 timeout)すると isDirty=false を返し、未コミットの変更がある worktree が「変更なし」と表示されていた。

表し方: isDirty は boolean のまま、任意の statusUnknown?: boolean を足す(不明のときだけ付く)。isDirty: boolean | null にすると、既存の読み手(=== false の比較・JSON の読み手・boolean 前提の型)を壊しうるため。成功時(clean / dirty)の応答は従来とまったく同じ。

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

範囲外(この PR では扱わない)

  • src/lib/skills/install-plan.ts / update-plan.ts / uninstall-plan.ts / src/cli/commands/skill-format.ts の workingTreeDirty は boolean のままで「不明」を区別して表示できない(今回は dirty 側に倒し、clean と言わないことだけを保証)。追跡 Issue にするかは run の完了報告で判断する

Test plan

  • commandmatedev verify --task: work-evidence / scope / env-clean / lint / typecheck / unit(テスト全体)すべて PASS(exit 0)
  • 新規 tests/unit/lib/git/git-status-unknown-3435.test.ts(timeout で statusUnknown、clean / dirty は従来どおりでキー無し、preview-diff の fail-safe)、tests/unit/components/git-status-unknown-3435.test.tsx(各表示面の描画)
  • develop 取り込み後(fix(git): ブランチ切替の dirty 確認が失敗したとき切替を止める #3439 を含む)に npx tsc --noEmit、tests/unit/lib/git・新規テスト・guards・docs が合格。既存の it/describe の削除 0 件
  • CI

🤖 Generated with Claude Code

Kewton and others added 3 commits October 8, 2026 18:24
getGitStatus は `git status --porcelain` が失敗(null、本番では負荷時の 1 秒
timeout)すると isDirty=false を返し、未コミットの変更がある worktree が
「変更なし」と表示されていた。

表し方: (b) isDirty は boolean のまま、任意の `statusUnknown?: boolean` を足す。
- (a) `isDirty: boolean | null` は既存の読み手(`=== false` 比較、CLI/外部の
  JSON 読み手、boolean 前提の型)を壊しうる。GitStatus の型注記も
  「新フィールドは optional で後方互換に」と定めている。
- statusUnknown は不明のときだけ付ける。成功時(clean/dirty)の応答は
  byte 単位で従来どおりで、既存テスト(toEqual を含む)は無変更で通る。
- GET /git/status は `...status` で展開するので自動で載る。checkout/reset の
  応答(CheckoutResponse/ResetResponse)にも同じ任意フィールドを足した。

UI: 不明のとき clean に見せない。
- GitCurrentStatusBar: 「変更の有無が不明」バッジ(git-status-unknown-badge)
- DesktopHeader / MobileHeader: branch 横に「?」(title に説明)
- SkillTargetSelector: 不明は dirty=null(既存の「不明」表示)へ写す
- 文言は locales/ja・en の worktree.json に追加(git.statusUnknown、
  git.currentStatus.statusUnknown / statusUnknownTooltip)

対になる場所の洗い出し(grep -rn isDirty src。未保存の意味の isDirty は対象外):
- 型の写し: src/types/models.ts(GitStatus)、src/types/git.ts
  (CheckoutResponse/ResetResponse)→ 直した。
- src/cli/types/: git の isDirty / GitStatus の写しは無い(grep で 0 件)→ 変更なし。
- src/hooks/useWorktreeDetailController.ts の isDirty はファイルタブの未保存
  (別の意味)→ 変更なし。
- DesktopHeader の headerFitKey(isDirty で幅の再計算キーを作る)→ 不明の
  「?」も幅に効くので statusUnknown をキーに足した。
- 同じ判定の写し src/lib/skills/preview-diff.ts readSkillGitTargetState
  (`status !== null && ...`)→ 直した。dirty は WORKING_TREE_DIRTY 警告と
  表示にしか使われない(ブロックには使われない)ので、不明は警告を出す側
  (dirty=true)に倒した。三値化は install-plan / update-plan /
  uninstall-plan / cli skill-format に波及し範囲外。
- src/lib/git/git-branches.ts:322(checkout の dirty ガード)は #3436 で
  別に直すため触っていない。
- 古い動きを固定したテスト: status 失敗を clean とみなすテストは無かった。

本文に無い指摘: src/lib/skills/install-plan.ts / update-plan.ts /
uninstall-plan.ts / src/cli/commands/skill-format.ts の workingTreeDirty は
boolean のままで、「不明」を区別して表示できない(今回は dirty 側に倒して
clean と言わないことだけを保証)。

テスト: tests/unit/lib/git/git-status-unknown-3435.test.ts(timeout で
statusUnknown、clean/dirty は従来どおりでキー無し、preview-diff の fail-safe)、
tests/unit/components/git-status-unknown-3435.test.tsx(各表示面の描画)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Kewton Kewton added the bug Something isn't working label Oct 8, 2026
@Kewton
Kewton merged commit 29283f6 into develop Oct 8, 2026
4 of 15 checks passed
@Kewton
Kewton deleted the feature/3435-git-status-unknown 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