Skip to content

fix: validate git state before worktree clone creation#440

Open
takeru wants to merge 1 commit intonrslib:mainfrom
takeru:takt/20260301T1158-fix-worktree-no-git-repo
Open

fix: validate git state before worktree clone creation#440
takeru wants to merge 1 commit intonrslib:mainfrom
takeru:takt/20260301T1158-fix-worktree-no-git-repo

Conversation

@takeru
Copy link

@takeru takeru commented Mar 1, 2026

Summary

  • worktree作成前にgitリポジトリの状態を検証する checkGitCloneReadiness() を追加
  • gitリポジトリ未初期化 (not_git_repo) またはコミットなし (no_commits) の場合、git clone --shared が失敗する問題を事前に検出
  • インタラクティブモードではフォールバック確認、パイプラインモードでは自動フォールバック

Changes

  • src/infra/task/git.ts: checkGitCloneReadiness() 関数を追加
  • src/features/tasks/execute/selectAndExecute.ts: confirmAndCreateWorktree() にgit状態検証を追加、null返却時のタスク保存処理を追加
  • src/features/pipeline/steps.ts: resolveExecutionContext() でnull結果のハンドリングを追加
  • テスト3ファイル追加・2ファイル更新

Test plan

  • npm run test で既存テストがパスすることを確認
  • 新規テスト cli-worktree-git-validation.test.ts, git-clone-readiness.test.ts がパスすることを確認
  • gitリポジトリ未初期化のディレクトリでworktree作成を試みた場合のフォールバック動作を確認

Closes #439

🤖 Generated with Claude Code

---

# タスク指示書

## タスク

gitリポジトリが未初期化またはコミットがない状態でworktree(shared clone)作成が失敗する問題を修正する。

## 背景

git未設定のプロジェクトで `takt` を実行すると、worktree作成時に `git clone --branch main` が失敗する。

**再現パターン:**
1. `git init` していないディレクトリ → gitリポジトリではない
2. `git init` のみ(コミットなし)→ ブランチが存在しない(`detectDefaultBranch()` が `'main'` をフォールバック返却するが、実際のブランチは存在しない)

**現在のエラー:**
```
fatal: Remote branch main not found in upstream origin
```

**原因の流れ:**
1. `confirmAndCreateWorktree()` (`src/features/tasks/execute/selectAndExecute.ts`) が `createSharedClone()` を呼ぶ
2. `createSharedClone()` (`src/infra/task/clone.ts`) が `resolveBaseBranch()` → `detectDefaultBranch()` を呼ぶ
3. `detectDefaultBranch()` (`src/infra/task/branchList.ts`) はブランチが存在しなくてもフォールバックで `'main'` を返す
4. `cloneAndIsolate()` が `git clone --branch main` を実行 → ブランチが存在しないため失敗

## 参照資料

- `src/infra/task/clone.ts` — CloneManager, `createSharedClone()`, `resolveBaseBranch()`
- `src/features/tasks/execute/selectAndExecute.ts` — `confirmAndCreateWorktree()`
- `src/infra/task/branchList.ts` — `detectDefaultBranch()`
- `src/features/pipeline/steps.ts` — `resolveExecutionContext()` (pipelineモードのworktree作成)

## 要件

### 優先度:高

#### 1. worktree作成前のgit状態バリデーション
- worktree(shared clone)を作成する前に、gitリポジトリの状態を検証する関数を追加する
- チェック対象:
  - gitリポジトリとして初期化されているか(`.git` ディレクトリの存在、または `git rev-parse --is-inside-work-tree` で確認)
  - コミットが1つ以上存在するか(`git rev-parse HEAD` が成功するか)
- 配置場所はplanner判断

#### 2. インタラクティブモード:作成不可時のフォールバック動作
- `confirmAndCreateWorktree()` でworktreeが作れない場合、ユーザーに原因を説明してフォールバックを提案する
  - git未初期化:「gitリポジトリが初期化されていません」等のメッセージ
  - コミットなし:「コミットが存在しないためブランチがありません」等のメッセージ
- 「カレントディレクトリで直接実行しますか?」とユーザーに確認(`confirm()`)
  - Yes → `{ execCwd: cwd, isWorktree: false }` を返す(worktreeなしでカレントディレクトリ実行)
  - No → タスクを `.takt/tasks/` に保存して終了する(既存の `saveTaskFile()` または `TaskRunner.addTask()` を利用)

#### 3. pipelineモード:同様のチェック
- `resolveExecutionContext()` (`src/features/pipeline/steps.ts`) の `options.createWorktree` パスでも同様のバリデーションを行う
- pipelineモードはインタラクティブではないため、エラーメッセージを出力して `--skip-git` の使用を案内するか、自動的にin-place実行にフォールバックする(planner判断)

### 優先度:中

#### 4. 既存の正常系を壊さない
- gitリポジトリが正常に初期化され、コミットがある場合は従来通りworktreeが作成されること
- テストで正常系・異常系の両方をカバーすること

## 再現手順

```bash
# パターン1: git initなし
mkdir /tmp/test-no-git && cd /tmp/test-no-git
takt "hello"
# → "Create worktree?" → Y → エラー

# パターン2: git initのみ(コミットなし)
mkdir /tmp/test-no-commit && cd /tmp/test-no-commit
git init
takt "hello"
# → "Create worktree?" → Y → エラー
```

## 確認方法

- パターン1, 2 でエラーではなくフォールバックプロンプトが表示されること
- 正常なgitリポジトリ(コミットあり)では従来通りworktreeが作成されること
- pipelineモードでも適切にハンドリングされること
@masanobu-naruse
Copy link
Contributor

PR のご対応ありがとうございます!

マージ前にコンフリクトが発生してしまいました。申し訳ないのですが、ブランチのリベースをお願いできますでしょうか。

コンフリクト箇所:

  • src/features/tasks/execute/selectAndExecute.ts
  • src/features/pipeline/steps.ts

PR のブランチ作成後、main 側で selectAndExecute.ts に対して2件の変更が入ってしまったことが原因です(--create-worktree オプションの削除・--auto-pr のパイプラインモード専用化)。

confirmAndCreateWorktree の戻り値を nullable にする変更と checkGitCloneReadiness の追加ロジック自体は有効な修正なので、現在の main ベースで組み込み直す形でリベースをお願いできると助かります。

@nrslib nrslib closed this Mar 2, 2026
@nrslib nrslib reopened this Mar 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

git未初期化/コミットなしでworktree作成が失敗する問題を修正

3 participants