mirror of
https://github.com/openai/codex.git
synced 2026-04-28 16:45:54 +00:00
241 lines
9.6 KiB
Markdown
241 lines
9.6 KiB
Markdown
# 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
|
|
|
|
<img width="738" height="311" alt="image" src="https://github.com/user-attachments/assets/2a9ab58d-ba3f-428c-8139-0bea2838ee03" />
|
|
|
|
## 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<GitInfo>,
|
|
}
|
|
|
|
/// 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<Line<'static>> = 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? |