Skip to content

[Feature] --changed-since オプション(Git 履歴ベースの変更検索) #91

@Kewton

Description

@Kewton

概要

指定期間内に変更されたファイルを Git 履歴から取得し、それらの関連情報を返す --changed-since オプションを追加する。

背景・動機

  • シナリオ5(朝のブリーフィング): 「昨夜の変更」に関連するドキュメント・コードを一括検索

提案する解決策

CLI インターフェース

# 12時間以内の変更ファイルの関連情報
commandindex search --changed-since "12 hours ago" --format json

# 昨日以降
commandindex search --changed-since "yesterday" --format json

# 特定コミット以降
commandindex search --changed-since "abc1234" --format json

CLI 設計方針

search サブコマンドのオプションとして --changed-since を追加する。既存の排他的検索モード(query/symbol/related/related_stdin/semantic)と同様に conflicts_with_all で排他制御を行う。

排他制御: --changed-since 側の conflicts_with_allquery, symbol, related, related_stdin, semantic, workspace, tag, path, file_type, heading, no_semantic, rerank を指定(clap v4 は片方定義で双方向に機能)

実装方針

  1. 入力判定ロジック: validate_commit_hash()(git_info.rs 既存)を利用し、入力がコミットハッシュか期間文字列かを判定
    • validate_commit_hash() が true → git log <hash>..HEAD --name-only --format=''(指定コミット以降の変更)
    • false → git log --since=<期間> --name-only --format=''
  2. 変更ファイル一覧を取得
  3. 共用ロジック: impact サブコマンド [Feature] impact サブコマンド(git diff ベースの影響分析) #90aggregate_impact()pub(crate) 化して共用。RelatedSearchEngine::find_related() で各ファイルの関連情報を取得
  4. 結果を ImpactResult 形式(changed_files/impact/overlap/summary)でマージして出力
  5. format_impact_results() を再利用して human/json/path 形式で出力
  6. main.rs 分岐: related_stdin と同様に、パターンマッチの前に if letchanged_since を先に分岐処理
  7. エラー型変換: From<ImpactError> for SearchError を実装
    • マッピング: Stdin→Stdin, IndexNotFound→IndexNotFound, SymbolDbNotFound→SymbolDbNotFound, Reader→Reader, SymbolStore→SymbolStore, RelatedSearch→RelatedSearch, Output→Output, NoValidPaths→InvalidArgument, InvalidArgument→InvalidArgument

期間の指定形式

  • Git の --since と同じ形式をサポート: "12 hours ago", "yesterday", "2026-03-22", "1 week ago"
  • コミットハッシュも指定可能: --changed-since "abc1234"git log abc1234..HEAD(指定コミット以降のすべての変更ファイルを取得)

入力バリデーション

  • 入力値の最大長制限(256文字)
  • 制御文字の拒否
  • 先頭 - の拒否(git 引数インジェクション防御)
  • Command::new("git").args() を使用しシェル経由実行を回避(コマンドインジェクション対策)
  • --since=<value> のように = 付き単一引数として渡す
  • git log 実行後の exit code チェック

パフォーマンス考慮

  • MAX_INPUT_FILES(500)を共用し、大量変更ファイル時に上限制限
  • INTERNAL_FETCH_LIMIT(1000)を共用

受け入れ基準

  • --changed-since で指定期間内の変更ファイルの関連情報が返る
  • Git の --since 形式とコミットハッシュ形式の両方に対応
  • コミットハッシュ指定時は hash..HEAD の範囲で変更ファイルを取得
  • human / json / path 出力形式に対応(ImpactResult 形式で出力)
  • 変更ファイルがない場合に「指定期間内の変更が見つかりません」のメッセージ表示
  • Git リポジトリ外や Git 未インストール環境で実行した場合に適切なエラーメッセージ
  • 不正な期間文字列指定時のエラーハンドリング(git log の exit code チェック)
  • 先頭 - の入力を拒否(引数インジェクション防御)
  • 既存の search オプション(query/symbol/related/semantic)との排他制御が正しく動作
  • cargo test / clippy / fmt 全パス

依存 Issue

実装規模

関連シナリオ

  • scenario.md シナリオ5

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions