# PR #2142: add branch name w/ sync function for git info
- URL: https://github.com/openai/codex/pull/2142
- Author: pap-openai
- Created: 2025-08-10 19:38:56 UTC
- Updated: 2025-08-12 16:37:40 UTC
- Changes: +38/-6, Files changed: 7, Commits: 3
## Description
## Full Diff
```diff
diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs
index 2dd48bf366..024fec1fae 100644
--- a/codex-rs/core/src/codex.rs
+++ b/codex-rs/core/src/codex.rs
@@ -902,9 +902,11 @@ async fn submission_loop(
}
}
- // Gather history metadata for SessionConfiguredEvent.
- let (history_log_id, history_entry_count) =
- crate::message_history::history_metadata(&config).await;
+ // Gather history metadata for SessionConfiguredEvent and await git info.
+ let git_info_fut = crate::git_info::collect_git_info(&sess.as_ref().unwrap().cwd);
+ let history_fut = crate::message_history::history_metadata(&config);
+ let (git_info, (history_log_id, history_entry_count)) =
+ tokio::join!(git_info_fut, history_fut);
// ack
let events = std::iter::once(Event {
@@ -914,6 +916,7 @@ async fn submission_loop(
model,
history_log_id,
history_entry_count,
+ git_info,
}),
})
.chain(mcp_connection_errors.into_iter());
diff --git a/codex-rs/core/src/git_info.rs b/codex-rs/core/src/git_info.rs
index 52d029f669..506b02b76c 100644
--- a/codex-rs/core/src/git_info.rs
+++ b/codex-rs/core/src/git_info.rs
@@ -6,8 +6,12 @@ use tokio::process::Command;
use tokio::time::Duration as TokioDuration;
use tokio::time::timeout;
-/// Timeout for git commands to prevent freezing on large repositories
-const GIT_COMMAND_TIMEOUT: TokioDuration = TokioDuration::from_secs(5);
+/// Timeout for git commands to prevent freezing on large repositories.
+///
+/// Tests that wait for the initial `SessionConfigured` event use a short
+/// timeout (~1s). Collecting Git info is best-effort and must not block the
+/// session handshake, so we cap individual Git calls to a small value.
+const GIT_COMMAND_TIMEOUT: TokioDuration = TokioDuration::from_millis(400);
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct GitInfo {
diff --git a/codex-rs/core/src/protocol.rs b/codex-rs/core/src/protocol.rs
index 4972f10d98..5db3cd7c48 100644
--- a/codex-rs/core/src/protocol.rs
+++ b/codex-rs/core/src/protocol.rs
@@ -19,6 +19,7 @@ use uuid::Uuid;
use crate::config_types::ReasoningEffort as ReasoningEffortConfig;
use crate::config_types::ReasoningSummary as ReasoningSummaryConfig;
+use crate::git_info::GitInfo;
use crate::message_history::HistoryEntry;
use crate::model_provider_info::ModelProviderInfo;
use crate::parse_command::ParsedCommand;
@@ -695,6 +696,10 @@ pub struct SessionConfiguredEvent {
/// Current number of entries in the history log.
pub history_entry_count: usize,
+
+ /// Optional Git metadata for the configured cwd.
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub git_info: Option,
}
/// User's decision in response to an ExecApprovalRequest.
@@ -757,6 +762,7 @@ mod tests {
model: "codex-mini-latest".to_string(),
history_log_id: 0,
history_entry_count: 0,
+ git_info: None,
}),
};
let serialized = serde_json::to_string(&event).unwrap();
diff --git a/codex-rs/exec/src/event_processor_with_human_output.rs b/codex-rs/exec/src/event_processor_with_human_output.rs
index 1d35dcb73f..aca6a75592 100644
--- a/codex-rs/exec/src/event_processor_with_human_output.rs
+++ b/codex-rs/exec/src/event_processor_with_human_output.rs
@@ -494,6 +494,7 @@ impl EventProcessor for EventProcessorWithHumanOutput {
model,
history_log_id: _,
history_entry_count: _,
+ git_info: _,
} = session_configured_event;
ts_println!(
diff --git a/codex-rs/mcp-server/src/mcp_protocol.rs b/codex-rs/mcp-server/src/mcp_protocol.rs
index 0528e18a39..426352e647 100644
--- a/codex-rs/mcp-server/src/mcp_protocol.rs
+++ b/codex-rs/mcp-server/src/mcp_protocol.rs
@@ -908,6 +908,7 @@ mod tests {
model: "codex-mini-latest".into(),
history_log_id: 42,
history_entry_count: 3,
+ git_info: None,
}),
};
diff --git a/codex-rs/mcp-server/src/outgoing_message.rs b/codex-rs/mcp-server/src/outgoing_message.rs
index e7b0b9b63c..9528e35fbf 100644
--- a/codex-rs/mcp-server/src/outgoing_message.rs
+++ b/codex-rs/mcp-server/src/outgoing_message.rs
@@ -244,6 +244,7 @@ mod tests {
model: "gpt-4o".to_string(),
history_log_id: 1,
history_entry_count: 1000,
+ git_info: None,
}),
};
@@ -284,6 +285,7 @@ mod tests {
model: "gpt-4o".to_string(),
history_log_id: 1,
history_entry_count: 1000,
+ git_info: None,
};
let event = Event {
id: "1".to_string(),
diff --git a/codex-rs/tui/src/history_cell.rs b/codex-rs/tui/src/history_cell.rs
index b49e59972c..97a1dd865a 100644
--- a/codex-rs/tui/src/history_cell.rs
+++ b/codex-rs/tui/src/history_cell.rs
@@ -233,6 +233,7 @@ impl HistoryCell {
session_id: _,
history_log_id: _,
history_entry_count: _,
+ git_info,
} = event;
if is_first_event {
let cwd_str = match relativize_to_home(&config.cwd) {
@@ -241,6 +242,18 @@ impl HistoryCell {
None => config.cwd.display().to_string(),
};
+ // Use async-collected Git info from the event if available.
+ let branch_suffix = git_info
+ .and_then(|g| g.branch)
+ .map(|b| format!(" ({b})"))
+ .unwrap_or_default();
+
+ let path_and_branch = if branch_suffix.is_empty() {
+ format!(" {cwd_str}")
+ } else {
+ format!(" {cwd_str}{branch_suffix}")
+ };
+
let lines: Vec> = vec![
Line::from(vec![
Span::raw(">_ ").dim(),
@@ -248,7 +261,7 @@ impl HistoryCell {
"You are using OpenAI Codex in",
Style::default().add_modifier(Modifier::BOLD),
),
- Span::raw(format!(" {cwd_str}")).dim(),
+ Span::raw(path_and_branch).dim(),
]),
Line::from("".dim()),
Line::from(" To get started, describe a task or try one of these commands:".dim()),
@@ -883,6 +896,8 @@ impl HistoryCell {
}
}
+//
+
impl WidgetRef for &HistoryCell {
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
Paragraph::new(Text::from(self.plain_lines()))
```
## Review Comments
### codex-rs/core/src/codex.rs
- Created: 2025-08-12 16:36:46 UTC | Link: https://github.com/openai/codex/pull/2142#discussion_r2270521623
```diff
@@ -902,9 +902,11 @@ async fn submission_loop(
}
}
- // Gather history metadata for SessionConfiguredEvent.
- let (history_log_id, history_entry_count) =
- crate::message_history::history_metadata(&config).await;
+ // Gather history metadata for SessionConfiguredEvent and await git info.
```
> I feel like we should be specifying the timeout somehow at this callsite (either updating `collect_git_info()` to take a timeout, or wrapping these calls with `tokio::time::timeout`) to ensure that this runs in a bounded amount of time.
>
> One challenge is that here, we are latency-sensitive and I agre with the short timeout.
>
> Though the other callsite in `rollout.rs` is less latency-sensitive, and arguably should be able to specify a more generous timeout.
>
> That said, from the callsite, one would expect to specify the timeout of the overall operation, whereas internally inside `collect_git_info()`, `run_git_command_with_timeout()` is run twice in series, so if `collect_git_info()` took its own `timeout` argument, arguably we should divide it by two and use the halved version for each internal call to `run_git_command_with_timeout()`?
>
> I admit there's already the existing issue here that `crate::message_history::history_metadata()` should also be bound by a timeout, though I don't know what value to use (`0?`) if the timeout expires before it completes.
### codex-rs/tui/src/history_cell.rs
- Created: 2025-08-12 00:18:38 UTC | Link: https://github.com/openai/codex/pull/2142#discussion_r2268276198
```diff
@@ -212,14 +212,27 @@ impl HistoryCell {
None => config.cwd.display().to_string(),
};
+ // Determine the current Git branch (if any) for display using
+ // the shared Git info collector in a way that is safe in sync contexts.
+ let branch_suffix = codex_core::git_info::collect_git_info_blocking(&config.cwd)
```
> Can we make this part of the `SessionConfiguredEvent` so we can do all this work async?
- Created: 2025-08-12 16:37:21 UTC | Link: https://github.com/openai/codex/pull/2142#discussion_r2270522896
```diff
@@ -883,6 +896,8 @@ impl HistoryCell {
}
}
+//
```
> remove?