From 77f1cf646a8f50470ca52455624c5a75358a88ba Mon Sep 17 00:00:00 2001 From: Amit Singh Date: Tue, 21 Apr 2026 20:33:56 +0530 Subject: [PATCH 1/2] fix(git): add use_forge_committer config option to control committer identity --- crates/forge_app/src/git_app.rs | 22 +++++++++++++--------- crates/forge_config/.forge.toml | 1 + crates/forge_config/src/config.rs | 5 +++++ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/crates/forge_app/src/git_app.rs b/crates/forge_app/src/git_app.rs index 5c13c7a40e..7fc77e6543 100644 --- a/crates/forge_app/src/git_app.rs +++ b/crates/forge_app/src/git_app.rs @@ -126,11 +126,12 @@ impl> GitApp< }) } - /// Commits changes with the provided commit message + /// Commits changes with the provided commit message. /// - /// Sets the user as the author (from git config) and ForgeCode as the - /// committer. This properly attributes the commit to both the user and - /// ForgeCode using Git's author/committer distinction. + /// When `use_forge_committer` is enabled, Forge uses the Git + /// author/committer distinction to keep the user as the author while + /// setting ForgeCode as the committer. When disabled, Git uses the local + /// configured committer identity. /// /// # Arguments /// @@ -143,14 +144,17 @@ impl> GitApp< pub async fn commit(&self, message: String, has_staged_files: bool) -> Result { let cwd = self.services.get_environment().cwd; let flags = if has_staged_files { "" } else { " -a" }; + let use_forge_committer = self.services.get_config()?.use_forge_committer; - // Set ForgeCode as the committer while keeping the user as the author - // by prefixing the command with environment variables // Escape single quotes in the message by replacing ' with '\'' let escaped_message = message.replace('\'', r"'\''"); - let commit_command = format!( - "GIT_COMMITTER_NAME='ForgeCode' GIT_COMMITTER_EMAIL='noreply@forgecode.dev' git commit {flags} -m '{escaped_message}'" - ); + let commit_command = if use_forge_committer { + format!( + "GIT_COMMITTER_NAME='ForgeCode' GIT_COMMITTER_EMAIL='noreply@forgecode.dev' git commit {flags} -m '{escaped_message}'" + ) + } else { + format!("git commit {flags} -m '{escaped_message}'") + }; let commit_result = self .services diff --git a/crates/forge_config/.forge.toml b/crates/forge_config/.forge.toml index 4459a9ef2d..7df89c2839 100644 --- a/crates/forge_config/.forge.toml +++ b/crates/forge_config/.forge.toml @@ -32,6 +32,7 @@ research_subagent = false currency_symbol = "$" currency_conversion_rate = 1.0 subagents = true +use_forge_committer = true [retry] backoff_factor = 2 diff --git a/crates/forge_config/src/config.rs b/crates/forge_config/src/config.rs index d08fdb3a9b..7373d2807d 100644 --- a/crates/forge_config/src/config.rs +++ b/crates/forge_config/src/config.rs @@ -195,6 +195,11 @@ pub struct ForgeConfig { /// Model and provider configuration used for commit message generation. #[serde(default, skip_serializing_if = "Option::is_none")] pub commit: Option, + /// Whether `forge commit` should override `GIT_COMMITTER_NAME` and + /// `GIT_COMMITTER_EMAIL` with the Forge identity. Defaults to `true` via + /// the embedded `.forge.toml` defaults. + #[serde(default)] + pub use_forge_committer: bool, /// Maximum number of recent commits included as context for commit message /// generation. #[serde(default)] From b609a8a0030a480ac61cc3c8cda542821456426b Mon Sep 17 00:00:00 2001 From: Amit Singh Date: Tue, 21 Apr 2026 21:05:31 +0530 Subject: [PATCH 2/2] fix(git): add use_forge_committer config option to control committer identity --- forge.schema.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/forge.schema.json b/forge.schema.json index e6b2d2e953..9eb73842f5 100644 --- a/forge.schema.json +++ b/forge.schema.json @@ -355,6 +355,11 @@ } ] }, + "use_forge_committer": { + "description": "Whether `forge commit` should override `GIT_COMMITTER_NAME` and\n`GIT_COMMITTER_EMAIL` with the Forge identity. Defaults to `true` via\nthe embedded `.forge.toml` defaults.", + "type": "boolean", + "default": false + }, "verify_todos": { "description": "Enables the pending todos hook that checks for incomplete todo items\nwhen a task ends and reminds the LLM about them.", "type": "boolean",