From 46fb5213331e3d5b931bab705f5a326f8553a547 Mon Sep 17 00:00:00 2001 From: Lev Zakharov Date: Tue, 9 Sep 2025 21:44:46 +0300 Subject: [PATCH] git_ui: Show author name on commits in branch picker (#36812) See related discussion https://github.com/zed-industries/zed/discussions/36511. zed Release Notes: - Added option to show the author name in a branch picker commit information --------- Co-authored-by: Conrad Irwin --- assets/settings/default.json | 4 ++++ crates/git/src/repository.rs | 7 +++++- crates/git_ui/src/blame_ui.rs | 7 ++++++ crates/git_ui/src/branch_picker.rs | 23 ++++++++++++++---- crates/git_ui/src/commit_tooltip.rs | 1 + crates/git_ui/src/git_panel.rs | 2 ++ crates/git_ui/src/project_diff.rs | 1 + crates/project/src/git_store.rs | 2 ++ crates/project/src/project_settings.rs | 22 +++++++++++++++++ crates/proto/proto/git.proto | 1 + docs/src/configuring-zed.md | 33 ++++++++++++++++++++++++++ 11 files changed, 98 insertions(+), 5 deletions(-) diff --git a/assets/settings/default.json b/assets/settings/default.json index 6919578dc79be94171b66950b39d5296316f3ee1..1902aa5e87c79f1894e485fa79d1435f2a3aee8f 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -1199,6 +1199,10 @@ // The minimum column number to show the inline blame information at "min_column": 0 }, + // Control which information is shown in the branch picker. + "branch_picker": { + "show_author_name": true + }, // How git hunks are displayed visually in the editor. // This setting can take two values: // diff --git a/crates/git/src/repository.rs b/crates/git/src/repository.rs index 6d053e1855d34d3bc0c173f760e7f71cd816d288..1beaadbefd1bb4b9df5093428844b326a093b338 100644 --- a/crates/git/src/repository.rs +++ b/crates/git/src/repository.rs @@ -150,6 +150,7 @@ pub struct CommitSummary { pub subject: SharedString, /// This is a unix timestamp pub commit_timestamp: i64, + pub author_name: SharedString, pub has_parent: bool, } @@ -987,6 +988,7 @@ impl GitRepository for RealGitRepository { "%(upstream)", "%(upstream:track)", "%(committerdate:unix)", + "%(authorname)", "%(contents:subject)", ] .join("%00"); @@ -2022,6 +2024,7 @@ fn parse_branch_input(input: &str) -> Result> { let upstream_name = fields.next().context("no upstream")?.to_string(); let upstream_tracking = parse_upstream_track(fields.next().context("no upstream:track")?)?; let commiterdate = fields.next().context("no committerdate")?.parse::()?; + let author_name = fields.next().context("no authorname")?.to_string().into(); let subject: SharedString = fields .next() .context("no contents:subject")? @@ -2035,6 +2038,7 @@ fn parse_branch_input(input: &str) -> Result> { sha: head_sha, subject, commit_timestamp: commiterdate, + author_name: author_name, has_parent: !parent_sha.is_empty(), }), upstream: if upstream_name.is_empty() { @@ -2345,7 +2349,7 @@ mod tests { fn test_branches_parsing() { // suppress "help: octal escapes are not supported, `\0` is always null" #[allow(clippy::octal_escapes)] - let input = "*\0060964da10574cd9bf06463a53bf6e0769c5c45e\0\0refs/heads/zed-patches\0refs/remotes/origin/zed-patches\0\01733187470\0generated protobuf\n"; + let input = "*\0060964da10574cd9bf06463a53bf6e0769c5c45e\0\0refs/heads/zed-patches\0refs/remotes/origin/zed-patches\0\01733187470\0John Doe\0generated protobuf\n"; assert_eq!( parse_branch_input(input).unwrap(), vec![Branch { @@ -2362,6 +2366,7 @@ mod tests { sha: "060964da10574cd9bf06463a53bf6e0769c5c45e".into(), subject: "generated protobuf".into(), commit_timestamp: 1733187470, + author_name: SharedString::new("John Doe"), has_parent: false, }) }] diff --git a/crates/git_ui/src/blame_ui.rs b/crates/git_ui/src/blame_ui.rs index 2768e3dc6863b008693d1db853f24a2bf87e1b29..ad5823c1674353f2e0531e5f71e1420fe464bfe6 100644 --- a/crates/git_ui/src/blame_ui.rs +++ b/crates/git_ui/src/blame_ui.rs @@ -90,6 +90,11 @@ impl BlameRenderer for GitBlameRenderer { sha: blame_entry.sha.to_string().into(), subject: blame_entry.summary.clone().unwrap_or_default().into(), commit_timestamp: blame_entry.committer_time.unwrap_or_default(), + author_name: blame_entry + .committer_name + .clone() + .unwrap_or_default() + .into(), has_parent: true, }, repository.downgrade(), @@ -229,6 +234,7 @@ impl BlameRenderer for GitBlameRenderer { .into() }), commit_timestamp: commit_details.commit_time.unix_timestamp(), + author_name: commit_details.author_name.clone(), has_parent: false, }; @@ -374,6 +380,7 @@ impl BlameRenderer for GitBlameRenderer { sha: blame_entry.sha.to_string().into(), subject: blame_entry.summary.clone().unwrap_or_default().into(), commit_timestamp: blame_entry.committer_time.unwrap_or_default(), + author_name: blame_entry.committer_name.unwrap_or_default().into(), has_parent: true, }, repository.downgrade(), diff --git a/crates/git_ui/src/branch_picker.rs b/crates/git_ui/src/branch_picker.rs index d90f2c0408a58564ac6c191fae6395d7d853ea79..e5bdce7722fcc87a935a4a7f11d8159fbb49e6af 100644 --- a/crates/git_ui/src/branch_picker.rs +++ b/crates/git_ui/src/branch_picker.rs @@ -10,6 +10,8 @@ use gpui::{ }; use picker::{Picker, PickerDelegate, PickerEditorPosition}; use project::git_store::Repository; +use project::project_settings::ProjectSettings; +use settings::Settings; use std::sync::Arc; use time::OffsetDateTime; use time_format::format_local_timestamp; @@ -454,7 +456,7 @@ impl PickerDelegate for BranchListDelegate { ) -> Option { let entry = &self.matches[ix]; - let (commit_time, subject) = entry + let (commit_time, author_name, subject) = entry .branch .most_recent_commit .as_ref() @@ -467,9 +469,10 @@ impl PickerDelegate for BranchListDelegate { OffsetDateTime::now_utc(), time_format::TimestampFormat::Relative, ); - (Some(formatted_time), Some(subject)) + let author = commit.author_name.clone(); + (Some(formatted_time), Some(author), Some(subject)) }) - .unwrap_or_else(|| (None, None)); + .unwrap_or_else(|| (None, None, None)); let icon = if let Some(default_branch) = self.default_branch.clone() && entry.is_new @@ -550,7 +553,19 @@ impl PickerDelegate for BranchListDelegate { "based off the current branch".to_string() } } else { - subject.unwrap_or("no commits found".into()).to_string() + let show_author_name = ProjectSettings::get_global(cx) + .git + .branch_picker + .unwrap_or_default() + .show_author_name; + + subject.map_or("no commits found".into(), |subject| { + if show_author_name && author_name.is_some() { + format!("{} • {}", author_name.unwrap(), subject) + } else { + subject.to_string() + } + }) }; Label::new(message) .size(LabelSize::Small) diff --git a/crates/git_ui/src/commit_tooltip.rs b/crates/git_ui/src/commit_tooltip.rs index a470bc69256068e687542334544bd9d2fc19c0cb..809274beae369736ddeb4bb6e3ddc2cca2b15262 100644 --- a/crates/git_ui/src/commit_tooltip.rs +++ b/crates/git_ui/src/commit_tooltip.rs @@ -229,6 +229,7 @@ impl Render for CommitTooltip { .into() }), commit_timestamp: self.commit.commit_time.unix_timestamp(), + author_name: self.commit.author_name.clone(), has_parent: false, }; diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index d558d21d2e8287338b4171d8057d3fdfdee69232..07a59de02a16390ebb97550ecefe075514dda2aa 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -5017,6 +5017,7 @@ impl Component for PanelRepoFooter { sha: "abc123".into(), subject: "Modify stuff".into(), commit_timestamp: 1710932954, + author_name: "John Doe".into(), has_parent: true, }), } @@ -5034,6 +5035,7 @@ impl Component for PanelRepoFooter { sha: "abc123".into(), subject: "Modify stuff".into(), commit_timestamp: 1710932954, + author_name: "John Doe".into(), has_parent: true, }), } diff --git a/crates/git_ui/src/project_diff.rs b/crates/git_ui/src/project_diff.rs index 69ebd83ea8c1a78f13f2218c020bd8654f2b4374..9d0a575247427ec5fe674b342d0f2660e40e2299 100644 --- a/crates/git_ui/src/project_diff.rs +++ b/crates/git_ui/src/project_diff.rs @@ -1220,6 +1220,7 @@ mod preview { sha: "abc123".into(), subject: "Modify stuff".into(), commit_timestamp: 1710932954, + author_name: "John Doe".into(), has_parent: true, }), } diff --git a/crates/project/src/git_store.rs b/crates/project/src/git_store.rs index 92c68f6646654eee773fbdfad71f2df63b8f8dbd..4e54cd0798fa521709da7eb619366abbea2f4d25 100644 --- a/crates/project/src/git_store.rs +++ b/crates/project/src/git_store.rs @@ -4752,6 +4752,7 @@ fn branch_to_proto(branch: &git::repository::Branch) -> proto::Branch { sha: commit.sha.to_string(), subject: commit.subject.to_string(), commit_timestamp: commit.commit_timestamp, + author_name: commit.author_name.to_string(), }), } } @@ -4781,6 +4782,7 @@ fn proto_to_branch(proto: &proto::Branch) -> git::repository::Branch { sha: commit.sha.to_string().into(), subject: commit.subject.to_string().into(), commit_timestamp: commit.commit_timestamp, + author_name: commit.author_name.to_string().into(), has_parent: true, } }), diff --git a/crates/project/src/project_settings.rs b/crates/project/src/project_settings.rs index 694e244e63e2b2861d640ec32ce0a1f5c50be52f..0d3cda3b8fd5beb89ac8aa8ffc119c6e5a5400da 100644 --- a/crates/project/src/project_settings.rs +++ b/crates/project/src/project_settings.rs @@ -405,6 +405,10 @@ pub struct GitSettings { /// /// Default: on pub inline_blame: Option, + /// Which information to show in the branch picker. + /// + /// Default: on + pub branch_picker: Option, /// How hunks are displayed visually in the editor. /// /// Default: staged_hollow @@ -509,6 +513,24 @@ impl Default for InlineBlameSettings { } } +#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct BranchPickerSettings { + /// Whether to show author name as part of the commit information. + /// + /// Default: false + #[serde(default)] + pub show_author_name: bool, +} + +impl Default for BranchPickerSettings { + fn default() -> Self { + Self { + show_author_name: true, + } + } +} + #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, Hash)] pub struct BinarySettings { pub path: Option, diff --git a/crates/proto/proto/git.proto b/crates/proto/proto/git.proto index cfb036987519b50f591d3fb0ca3c11f157a72f08..ef4d7aea63f620b31d20c8599bc38195776255a8 100644 --- a/crates/proto/proto/git.proto +++ b/crates/proto/proto/git.proto @@ -95,6 +95,7 @@ message CommitSummary { string sha = 1; string subject = 2; int64 commit_timestamp = 3; + string author_name = 4; } message GitBranches { diff --git a/docs/src/configuring-zed.md b/docs/src/configuring-zed.md index c83dd84b881b4dd25c94bd795f49a937a7480d7c..552dc97e45137ea4a4b9d9371ffd3c0e8b432c4d 100644 --- a/docs/src/configuring-zed.md +++ b/docs/src/configuring-zed.md @@ -2023,6 +2023,9 @@ To interpret all `.c` files as C++, files called `MyLockFile` as TOML and files "inline_blame": { "enabled": true }, + "branch_picker": { + "show_author_name": true + }, "hunk_style": "staged_hollow" } } @@ -2154,6 +2157,36 @@ Example: } ``` +### Branch Picker + +- Description: Configuration related to the branch picker. +- Setting: `branch_picker` +- Default: + +```json +{ + "git": { + "branch_picker": { + "show_author_name": false + } + } +} +``` + +**Options** + +1. Show the author name in the branch picker: + +```json +{ + "git": { + "branch_picker": { + "show_author_name": true + } + } +} +``` + ### Hunk Style - Description: What styling we should use for the diff hunks.