Skip to content

feat: /auto-commit — auto git commit after code changes#22

Merged
kienbui1995 merged 1 commit intomainfrom
feat/git-auto-commit
Apr 11, 2026
Merged

feat: /auto-commit — auto git commit after code changes#22
kienbui1995 merged 1 commit intomainfrom
feat/git-auto-commit

Conversation

@kienbui1995
Copy link
Copy Markdown
Owner

@kienbui1995 kienbui1995 commented Apr 11, 2026

Toggle with /auto-commit. After write tools execute, auto-stages and commits with LLM-generated message.

Works with /auto-test: test first, commit only if tests pass.

162 tests pass.

Summary by CodeRabbit

Release Notes

  • New Features
    • Added /auto-commit command to toggle automatic Git commits.
    • When enabled, file modifications are automatically committed with auto-generated messages after write operations.
    • Real-time status messages display whether auto-commit is currently ON or OFF.

Toggle with /auto-commit. After write tools, auto stages all changes
and commits with LLM-generated message. Runs after auto-test if both enabled.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2026

📝 Walkthrough

Walkthrough

This PR introduces an auto-commit feature to the application. It adds a new AutoCommitToggle command that allows users to toggle automatic Git commits after write operations. The feature includes a runtime flag, CLI/TUI command handlers, and logic in the core runtime to automatically commit when write-style tools are executed.

Changes

Cohort / File(s) Summary
TUI Command & App State
mc/crates/mc-tui/src/app.rs, mc/crates/mc-tui/src/commands.rs
Added AutoCommitToggle enum variant to PendingCommand and implemented /auto-commit slash command handler to toggle the feature, mirroring existing auto-test command pattern.
CLI Handler
mc/crates/mc-cli/src/main.rs
Implemented PendingCommand::AutoCommitToggle handler that acquires non-blocking lock on runtime, toggles auto_commit flag, and appends status message to output indicating ON/OFF state.
Runtime Auto-Commit Logic
mc/crates/mc-core/src/runtime.rs
Added public auto_commit: bool field to ConversationRuntime and extended run_turn to automatically execute git add -A, compute staged diff stat, generate commit message, and perform git commit when enabled and write-style tools are executed.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant TUI as TUI/Commands
    participant CLI as CLI Handler
    participant Runtime
    participant Git

    User->>TUI: Enter /auto-commit
    TUI->>TUI: Set PendingCommand::AutoCommitToggle
    CLI->>Runtime: Toggle auto_commit flag
    Runtime->>CLI: Return ON/OFF status
    CLI->>User: Display status message

    User->>Runtime: Execute write tool (e.g., write_file)
    Runtime->>Runtime: Check auto_commit enabled
    Runtime->>Git: git add -A
    Runtime->>Git: git diff --cached --stat
    Runtime->>Runtime: Generate commit message
    Runtime->>Git: git commit -m <message>
    Git-->>Runtime: Commit result
    Runtime->>User: Display commit output/error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 A toggle command hops into play,
Auto-commits the changes of the day,
Write tools trigger Git's embrace,
With generated messages keeping pace! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely describes the main feature: adding a toggleable /auto-commit command that automatically commits git changes after code modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/git-auto-commit

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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mc/crates/mc-core/src/runtime.rs`:
- Around line 495-515: The auto-commit path currently ignores test results and
can commit even if the test command failed to launch or exited non-zero; add and
check a tests_passed flag (e.g. a bool variable scoped with the other
auto_test_cmd logic) so that before the auto-commit block (inside the if
self.auto_commit { ... }) you skip committing unless tests_passed is true;
ensure the test-running code (where auto_test_cmd is executed) sets tests_passed
= false on spawn/launch errors and when the child process exits with non-zero
status, and only sets tests_passed = true on a successful zero exit, then update
the commit condition (with tool_calls and had_writes) to also require
tests_passed before running git add/commit and calling
generate_commit_message/on_event (ProviderEvent::ToolOutputDelta).
- Around line 499-510: Replace the blocking std::process::Command calls in the
auto-commit block with tokio::process::Command and await their outputs (similar
to the earlier auto-test block); for each command used (git add, git diff
--cached --stat, git commit -m) use tokio::process::Command, await the Output,
check output.status.success(), and read both stdout and stderr to decide which
ProviderEvent::ToolOutputDelta to emit; update references around
generate_commit_message, on_event, and ProviderEvent::ToolOutputDelta so that
failures (non-success status or spawn errors) emit a clear error message
including stderr, while success emits the trimmed stdout as before.

In `@mc/crates/mc-tui/src/commands.rs`:
- Around line 111-113: The new handler registers
PendingCommand::AutoCommitToggle but you must also add the command to the
discoverability structures: add the "/auto-commit" entry (with its brief
description) into the App::SLASH_COMMANDS collection and update the slash-help
rendering (the function/constant that builds the `/help` text for slash
commands) so the command appears in help output and Tab completion; ensure the
string and description match the handler name PendingCommand::AutoCommitToggle
so completion and help stay in sync.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 93b92b0b-5089-4d08-aacf-cf5cd2313b72

📥 Commits

Reviewing files that changed from the base of the PR and between 5dfe70c and 08738a1.

📒 Files selected for processing (4)
  • mc/crates/mc-cli/src/main.rs
  • mc/crates/mc-core/src/runtime.rs
  • mc/crates/mc-tui/src/app.rs
  • mc/crates/mc-tui/src/commands.rs

Comment on lines +495 to +515
// Auto-commit: stage and commit with LLM-generated message
if self.auto_commit {
let had_writes = tool_calls.iter().any(|t| matches!(t.as_str(), "write_file" | "edit_file" | "batch_edit" | "apply_patch"));
if had_writes {
let _ = std::process::Command::new("git").args(["add", "-A"]).output();
if let Ok(diff) = std::process::Command::new("git").args(["diff", "--cached", "--stat"]).output() {
let stat = String::from_utf8_lossy(&diff.stdout);
if !stat.trim().is_empty() {
on_event(&ProviderEvent::ToolOutputDelta("📦 Auto-committing...\n".into()));
let msg = self.generate_commit_message(provider, &stat).await;
match std::process::Command::new("git").args(["commit", "-m", &msg]).output() {
Ok(o) => {
let out = String::from_utf8_lossy(&o.stdout);
on_event(&ProviderEvent::ToolOutputDelta(format!("✓ {}\n", out.trim())));
}
Err(e) => on_event(&ProviderEvent::ToolOutputDelta(format!("commit error: {e}\n"))),
}
}
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Require an explicit test success before auto-commit.

When auto_test_cmd is enabled, a failure to launch the test command in the preceding block falls through to this commit path, so the repo can still be committed without any passing test result. Track a tests_passed flag and skip auto-commit on both execution errors and non-zero exits to match the PR contract.

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

In `@mc/crates/mc-core/src/runtime.rs` around lines 495 - 515, The auto-commit
path currently ignores test results and can commit even if the test command
failed to launch or exited non-zero; add and check a tests_passed flag (e.g. a
bool variable scoped with the other auto_test_cmd logic) so that before the
auto-commit block (inside the if self.auto_commit { ... }) you skip committing
unless tests_passed is true; ensure the test-running code (where auto_test_cmd
is executed) sets tests_passed = false on spawn/launch errors and when the child
process exits with non-zero status, and only sets tests_passed = true on a
successful zero exit, then update the commit condition (with tool_calls and
had_writes) to also require tests_passed before running git add/commit and
calling generate_commit_message/on_event (ProviderEvent::ToolOutputDelta).

Comment on lines +499 to +500
let _ = std::process::Command::new("git").args(["add", "-A"]).output();
if let Ok(diff) = std::process::Command::new("git").args(["diff", "--cached", "--stat"]).output() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don't stage the whole repository here.

git add -A will commit unrelated local edits and any test artifacts produced just before this block, not only files written by this turn. Because tool_calls only records tool names, even a failed write attempt plus pre-existing changes can become an unexpected commit. Stage only the paths that were successfully modified in this turn.

Comment on lines +499 to +510
let _ = std::process::Command::new("git").args(["add", "-A"]).output();
if let Ok(diff) = std::process::Command::new("git").args(["diff", "--cached", "--stat"]).output() {
let stat = String::from_utf8_lossy(&diff.stdout);
if !stat.trim().is_empty() {
on_event(&ProviderEvent::ToolOutputDelta("📦 Auto-committing...\n".into()));
let msg = self.generate_commit_message(provider, &stat).await;
match std::process::Command::new("git").args(["commit", "-m", &msg]).output() {
Ok(o) => {
let out = String::from_utf8_lossy(&o.stdout);
on_event(&ProviderEvent::ToolOutputDelta(format!("✓ {}\n", out.trim())));
}
Err(e) => on_event(&ProviderEvent::ToolOutputDelta(format!("commit error: {e}\n"))),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cd mc && find . -name "runtime.rs" -type f | head -5

Repository: kienbui1995/mc-code

Length of output: 94


🏁 Script executed:

cd mc && git ls-files | grep -E "runtime\.rs|src/" | head -20

Repository: kienbui1995/mc-code

Length of output: 668


🏁 Script executed:

cd mc && ls -la crates/mc-core/src/ | head -20

Repository: kienbui1995/mc-code

Length of output: 1227


🏁 Script executed:

cd mc && head -20 crates/mc-core/src/runtime.rs && wc -l crates/mc-core/src/runtime.rs

Repository: kienbui1995/mc-code

Length of output: 720


🏁 Script executed:

cd mc && sed -n '490,520p' crates/mc-core/src/runtime.rs

Repository: kienbui1995/mc-code

Length of output: 1746


🏁 Script executed:

cd mc && sed -n '450,530p' crates/mc-core/src/runtime.rs

Repository: kienbui1995/mc-code

Length of output: 4419


🏁 Script executed:

cd mc && sed -n '300,350p' crates/mc-core/src/runtime.rs | grep -A 20 "fn run_turn"

Repository: kienbui1995/mc-code

Length of output: 45


🏁 Script executed:

cd mc && sed -n '200,300p' crates/mc-core/src/runtime.rs | grep -B 5 "async fn run_turn"

Repository: kienbui1995/mc-code

Length of output: 222


🏁 Script executed:

cd mc && grep -n "async fn run_turn" crates/mc-core/src/runtime.rs

Repository: kienbui1995/mc-code

Length of output: 93


🏁 Script executed:

cd mc && sed -n '247,270p' crates/mc-core/src/runtime.rs

Repository: kienbui1995/mc-code

Length of output: 1191


🏁 Script executed:

cd mc && sed -n '450,475p' crates/mc-core/src/runtime.rs

Repository: kienbui1995/mc-code

Length of output: 1380


🏁 Script executed:

cd mc && grep -n "tokio::process::Command" crates/mc-core/src/runtime.rs | head -10

Repository: kienbui1995/mc-code

Length of output: 413


🏁 Script executed:

cd mc && sed -n '495,515p' crates/mc-core/src/runtime.rs

Repository: kienbui1995/mc-code

Length of output: 1480


🏁 Script executed:

cd mc && sed -n '470,495p' crates/mc-core/src/runtime.rs | tail -20

Repository: kienbui1995/mc-code

Length of output: 1254


🏁 Script executed:

cd mc && sed -n '540,600p' crates/mc-core/src/runtime.rs | grep -A 30 "generate_commit_message"

Repository: kienbui1995/mc-code

Length of output: 45


🏁 Script executed:

cd mc && grep -n "fn generate_commit_message" crates/mc-core/src/runtime.rs

Repository: kienbui1995/mc-code

Length of output: 166


🏁 Script executed:

cd mc && sed -n '199,220p' crates/mc-core/src/runtime.rs

Repository: kienbui1995/mc-code

Length of output: 934


🏁 Script executed:

cd mc && sed -n '471,490p' crates/mc-core/src/runtime.rs

Repository: kienbui1995/mc-code

Length of output: 1341


Replace std::process::Command with tokio::process::Command and check exit status.

These synchronous git calls block the Tokio executor inside an async function. Additionally, Ok(output) only confirms the process started—git commit can still fail (hooks, missing config, conflicts) but the code prints anyway while ignoring stderr. Notice the auto-test block above (lines 471–490) correctly uses tokio::process::Command with .await and checks output.status.success().

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

In `@mc/crates/mc-core/src/runtime.rs` around lines 499 - 510, Replace the
blocking std::process::Command calls in the auto-commit block with
tokio::process::Command and await their outputs (similar to the earlier
auto-test block); for each command used (git add, git diff --cached --stat, git
commit -m) use tokio::process::Command, await the Output, check
output.status.success(), and read both stdout and stderr to decide which
ProviderEvent::ToolOutputDelta to emit; update references around
generate_commit_message, on_event, and ProviderEvent::ToolOutputDelta so that
failures (non-success status or spawn errors) emit a clear error message
including stderr, while success emits the trimmed stdout as before.

Comment on lines +111 to +113
"/auto-commit" => {
app.pending_command = Some(PendingCommand::AutoCommitToggle);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Complete the discoverability wiring for /auto-commit.

This adds the handler, but the command is still missing from the /help text and App::SLASH_COMMANDS, so help output and Tab completion stay stale.

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

In `@mc/crates/mc-tui/src/commands.rs` around lines 111 - 113, The new handler
registers PendingCommand::AutoCommitToggle but you must also add the command to
the discoverability structures: add the "/auto-commit" entry (with its brief
description) into the App::SLASH_COMMANDS collection and update the slash-help
rendering (the function/constant that builds the `/help` text for slash
commands) so the command appears in help output and Tab completion; ensure the
string and description match the handler name PendingCommand::AutoCommitToggle
so completion and help stay in sync.

@kienbui1995 kienbui1995 merged commit 1789a95 into main Apr 11, 2026
6 of 7 checks passed
@kienbui1995 kienbui1995 deleted the feat/git-auto-commit branch April 11, 2026 17:28
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