Skip to content

feat(cli-pr-monitor): takt NoChange cleanup 後に @ を PR tip へ re-parent (task 6) - #67

Merged
aloekun merged 1 commit into
masterfrom
feat-cli-pr-monitor-reparent-task6
Apr 22, 2026
Merged

feat(cli-pr-monitor): takt NoChange cleanup 後に @ を PR tip へ re-parent (task 6)#67
aloekun merged 1 commit into
masterfrom
feat-cli-pr-monitor-reparent-task6

Conversation

@aloekun

@aloekun aloekun commented Apr 22, 2026

Copy link
Copy Markdown
Owner

概要

takt fix が NoChange で空 fix commit を abandon した後、@ が stale な空 commit の上に残り、次の jj new がそこに積まれる問題を解消する (task 6)。

背景

PR #64 / PR #66 で連続発生。毎回 jj abandon <current>jj abandon <stale>jj new -r <PR-tip> の 3 ステップ手修正が必要だった。

変更内容

  • fix_commit.rs::try_abandon_empty_fix_commit: abandon 成功後に reparent_at_to_pr_tip を呼び出すフローを追加
  • push_jj_bookmark.rs::resolve_pr_tip_commit_id: 単一の非 trunk local bookmark を PR tip として解決
  • 既に @- が PR tip と一致する場合は redundant な空 commit を作らずスキップ
  • 複数 bookmark (stacked PR 想定) は fail-safe でスキップ
  • stages/mod.rs: push_jj_bookmarkpub(crate) 化 (fix_commit.rs から参照するため)

テスト

  • ユニットテスト 90 件、pass
  • 統合テスト 7 件、pass (新規 2 件):
    • integration_try_abandon_reparents_at_to_pr_tip_after_cleanup: メインシナリオで @- が PR tip に戻ることを実 jj で確認
    • integration_try_abandon_skips_reparent_with_multiple_bookmarks: 複数 bookmark 時の fail-safe skip 挙動を確認

残タスク

  • 実 PR での E2E 検証: 次回 CodeRabbit NoChange ループで reparent を目視 (本 PR マージ後のリリース)

参照

Summary by CodeRabbit

リリースノート

  • 新機能
    • PR チップコミットへの自動リパレント機能を追加しました。空のコミット削除後、変更内容が正しい PR チップの下に配置されるようになります。
    • ブックマークベースの PR チップ解決機能を実装しました。プルリクエストの検出がより確実になります。
    • 冗長な空コミット生成を防ぐロジックを追加しました。

… (task 6)

takt fix が NoChange で空 fix commit を abandon した後、@ が stale な空
commit の上に残り、次の jj new がそこに積まれる問題を解消する。abandon
成功後に単一の非 trunk local bookmark を PR tip として解決し、jj new -r
<tip> で @ を PR tip 直下に戻す。

以下は fail-safe で skip する:
- bookmark 0 件 / 複数件 (stacked PR 想定)
- @- が既に PR tip と一致 (redundant な空 commit を作らない)
- jj new -r <tip> 自体の失敗 (ログのみで処理継続)

同じフローは takt 未完了経路 (monitor.rs:80) の abandon にも適用される。

関連: PR #64 / PR #66 で連続発生した事例
参照: ADR-022 原則 5 (PR 包含 changeset の不変性)
@coderabbitai

coderabbitai Bot commented Apr 22, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

このPRは、cli-pr-monitorの空の修正コミットクリーンアップ(タスク6)の実装を完了しています。jj abandon成功後に@をPRチップに再配置するロジックを追加し、ローカルブックマークに基づくPRチップ解決機構を実装し、検証テストを追加しています。push_jj_bookmarkモジュールはキャレット公開になります。

Changes

Cohort / File(s) Summary
ドキュメント更新
docs/todo.md
タスク6の完了ステータスを更新。背景と未実装項目を削除し、実装済みの@再配置ロジック、PR チップ解決、条件付きスキップ、及び統合テスト結果で置き換え。
コア実装:空コミット再配置
src/cli-pr-monitor/src/fix_commit.rs
try_abandon_empty_fix_commit関数後にreparent_at_to_pr_tipを呼び出すよう拡張。resolve_pr_tip_commit_idでPRチップを解決、@-が既にマッチする場合はスキップ、jj newで再配置。新しいヘルパー関数parent_commit_id_isと2つの無視された統合テストを追加。
モジュール可視性変更
src/cli-pr-monitor/src/stages/mod.rs
push_jj_bookmarkモジュールの可視性をmodからpub(crate) modに変更。
PR チップ解決ロジック
src/cli-pr-monitor/src/stages/push_jj_bookmark.rs
新しいpub(crate) fn resolve_pr_tip_commit_id()を追加。ローカルの非トランクブックマークをフェッチし、正確に1つの場合のみそのコミットIDを返す。複数またはゼロの場合はNoneを返す。

Sequence Diagram(s)

sequenceDiagram
    participant Client as fix_commit.rs
    participant Resolve as push_jj_bookmark.rs
    participant JJ as jj CLI
    participant Log as jj log

    Client->>JJ: jj abandon (empty commit)
    JJ-->>Client: success/failure
    
    alt abandon successful
        Client->>Resolve: resolve_pr_tip_commit_id()
        Resolve->>JJ: jj bookmark list (non-trunk)
        JJ-->>Resolve: bookmarks
        
        alt exactly 1 bookmark found
            Resolve->>Log: jj log -r <bookmark> commit_id
            Log-->>Resolve: commit_id
            Resolve-->>Client: Some(commit_id)
            
            Client->>Log: check parent_commit_id_is(pr_tip)
            Log-->>Client: false (needs reparent)
            
            Client->>JJ: jj new -r <pr_tip>
            JJ-->>Client: reparent complete
        else multiple or zero bookmarks
            Resolve-->>Client: None
            Client->>Client: skip reparent
        end
    else abandon failed
        Client->>Client: return early
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed プルリクエストのタイトルは、PR の主な変更内容である「NoChange cleanup 後に @ を PR tip へ re-parent する機能追加」を正確に反映しており、変更セットの中核をよく要約している。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/cli-pr-monitor/src/fix_commit.rs (2)

437-444: nit: CwdRestore 構造体が各統合テストで重複定義されています。

integration_try_abandon_reparents_at_to_pr_tip_after_cleanupintegration_try_abandon_skips_reparent_with_multiple_bookmarks (および既存 integration_try_abandon_empty_fix_commit_without_id_drops_orphan_child) で同一の CwdRestore struct + Drop impl が繰り返されています。#[cfg(test)] mod tests の先頭に 1 つ抽出すると DRY になります。本 PR のスコープ外でもよく、優先度は低です。

Also applies to: 549-556

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cli-pr-monitor/src/fix_commit.rs` around lines 437 - 444, Multiple
integration tests duplicate the CwdRestore struct and its Drop impl; extract a
single shared definition into the tests module to avoid repetition. Remove the
duplicated CwdRestore struct + impl from the individual tests (those in
integration_try_abandon_reparents_at_to_pr_tip_after_cleanup,
integration_try_abandon_skips_reparent_with_multiple_bookmarks, and
integration_try_abandon_empty_fix_commit_without_id_drops_orphan_child) and add
one definition of struct CwdRestore { original: std::path::PathBuf } with its
Drop impl (fn drop calling std::env::set_current_dir(&self.original)) at the top
of the #[cfg(test)] mod tests so all tests can reuse it.

156-211: reparent ロジックの fail-safe 設計は妥当。

3 段階の skip (PR tip 未解決 / @- 既一致 / jj new 失敗) がすべてログのみで非致命に倒されており、try_abandon_empty_fix_commit の呼び出し側への副作用がない点は良好です。parent_commit_id_is が失敗時 false を返して reparent を試行するフォールバック挙動も docstring で明示されています。

nit: resolve_pr_tip_commit_id が 0 件 / 複数件 / 取得失敗のいずれかで None になるため、ログ上その区別がつきません。将来 triage の必要が出たら resolve_pr_tip_commit_idResult<Option<String>, &'static str> 相当の返りに変えて理由付きログを残す余地がありますが、現状の運用では優先度低です。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cli-pr-monitor/src/fix_commit.rs` around lines 156 - 211, The PR nit
requests more informative logging when resolve_pr_tip_commit_id() fails: change
resolve_pr_tip_commit_id to return a Result<Option<String>, String> (or a small
enum) so it can signal concrete failure reasons (no bookmarks / ambiguous / exec
error), update reparent_at_to_pr_tip to match on Ok(Some(id)) / Ok(None) /
Err(reason) and log the specific reason when skipping re-parent, and adjust any
callers (e.g., try_abandon_empty_fix_commit) to handle the new signature; keep
parent_commit_id_is and the existing jj new error handling unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/cli-pr-monitor/src/fix_commit.rs`:
- Around line 437-444: Multiple integration tests duplicate the CwdRestore
struct and its Drop impl; extract a single shared definition into the tests
module to avoid repetition. Remove the duplicated CwdRestore struct + impl from
the individual tests (those in
integration_try_abandon_reparents_at_to_pr_tip_after_cleanup,
integration_try_abandon_skips_reparent_with_multiple_bookmarks, and
integration_try_abandon_empty_fix_commit_without_id_drops_orphan_child) and add
one definition of struct CwdRestore { original: std::path::PathBuf } with its
Drop impl (fn drop calling std::env::set_current_dir(&self.original)) at the top
of the #[cfg(test)] mod tests so all tests can reuse it.
- Around line 156-211: The PR nit requests more informative logging when
resolve_pr_tip_commit_id() fails: change resolve_pr_tip_commit_id to return a
Result<Option<String>, String> (or a small enum) so it can signal concrete
failure reasons (no bookmarks / ambiguous / exec error), update
reparent_at_to_pr_tip to match on Ok(Some(id)) / Ok(None) / Err(reason) and log
the specific reason when skipping re-parent, and adjust any callers (e.g.,
try_abandon_empty_fix_commit) to handle the new signature; keep
parent_commit_id_is and the existing jj new error handling unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e2199fcc-dece-415a-8132-82de017f8344

📥 Commits

Reviewing files that changed from the base of the PR and between 44b33ef and 0f1cc5a.

📒 Files selected for processing (4)
  • docs/todo.md
  • src/cli-pr-monitor/src/fix_commit.rs
  • src/cli-pr-monitor/src/stages/mod.rs
  • src/cli-pr-monitor/src/stages/push_jj_bookmark.rs

@aloekun
aloekun merged commit ee95695 into master Apr 22, 2026
1 check passed
@aloekun
aloekun deleted the feat-cli-pr-monitor-reparent-task6 branch April 22, 2026 08:38
aloekun added a commit that referenced this pull request Apr 22, 2026
…68)

* feat(cli-pr-monitor): observer mode で post-pr review を並行通知化 (task 2)

## 主要変更

- `cli-pr-monitor --observe` サブコマンドを新設 (read-only 観測パス)
  - `pr-monitor-state.json` を 5 秒間隔ポーリング
  - `action != continue_monitoring` 検出で state 全文を stdout に出して exit 0
  - `notified=true` はサイレント exit (Claude Code 再起動時の重複防止)
  - 10 分タイムアウトで exit 1 (orphan OK)
- `decide()` を pure function として切り出し、7 パターンの unit test を追加
- `poll.rs`: iteration を跨いで `notified` flag を preserve
  (`PrMonitorState::new` が毎回 false リセットする挙動を修正)
- `start_monitoring` 冒頭で state を明示初期化 (新セッション開始時の reset)
- `package.json` に `observe-pr` / `mark-notified` スクリプト復活
- ADR-018 に 2026-04-22 追記で仕組みを反映

## 付随: todo.md cleanup

- task 4 (post-pr-review workflow の push 反映確認) を削除
  理由: task 3 (PR #61) + task 6 (PR #67) の bookmark auto-advance で gap 解消済み
  ADR-022 の「主フロー vs 観測」責務分離原則とも整合
- task 2 を実装完了状態に縮退 (E2E 検証のみ残置)

## 参照

- ADR-018 追記 — observer モード仕様
- ADR-022 — 主フロー 100% 機械的 / observer は read-only side effect
- docs/todo.md task 2

## テスト

- `cargo test -p cli-pr-monitor`: 97 passed / 0 failed / 7 ignored
- `cargo clippy --release`: warning なし
- 手動検証: 終端状態検出 (exit 0) / notified=true サイレント exit の両分岐確認

* fix(review): apply CodeRabbit fixes for #68

Resolved findings:
- [Major] src/cli-pr-monitor/src/stages/monitor.rs:38 observer 起動前に stale state を読ませない初期化位置にしてください。

* refactor(cli-pr-monitor): started_at の fallback を現在時刻にする (CodeRabbit nitpick)

## 変更

- `start_monitoring` の init_state で `pr_info.push_time.clone().unwrap_or_default()` を
  `unwrap_or_else(utc_now_iso8601)` に置き換え
- `push_time=None` だと `started_at=""` になる観測性の問題を防御的に修正

## 背景

PR #68 CodeRabbit 2 回目レビュー (Nitpick) の提案:
現状の `run_monitor_only` 経路では直前で `Some(utc_now_iso8601())` が設定されるため
到達しないが、将来 `start_monitoring` が他経路から直接呼ばれた場合に started_at が
空文字列になり observability を損なう恐れあり。`run_create_pr` 冒頭の早期 reset と
同じフォールバック (utc_now_iso8601) に揃える。

## テスト

- `cargo test -p cli-pr-monitor`: 97 pass
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.

1 participant