Use git config --global user.email
for email address in automatic Co-authored-by
(#32624)
Release Notes: - Automatic population of `Co-authored-by` now uses `git config --global user.email` --------- Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com> Co-authored-by: Conrad <conrad@zed.dev>
This commit is contained in:
parent
e56a027bea
commit
7d708c14e4
24 changed files with 188 additions and 69 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -6162,6 +6162,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"askpass",
|
||||
"buffer_diff",
|
||||
"call",
|
||||
"chrono",
|
||||
"collections",
|
||||
"command_palette_hooks",
|
||||
|
|
|
@ -269,7 +269,6 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
|
|||
github_login: "nathansobo".into(),
|
||||
avatar_url: "http://avatar.com/nathansobo".into(),
|
||||
name: None,
|
||||
email: None,
|
||||
}],
|
||||
},
|
||||
);
|
||||
|
@ -323,7 +322,6 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
|
|||
github_login: "maxbrunsfeld".into(),
|
||||
avatar_url: "http://avatar.com/maxbrunsfeld".into(),
|
||||
name: None,
|
||||
email: None,
|
||||
}],
|
||||
},
|
||||
);
|
||||
|
@ -368,7 +366,6 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
|
|||
github_login: "as-cii".into(),
|
||||
avatar_url: "http://avatar.com/as-cii".into(),
|
||||
name: None,
|
||||
email: None,
|
||||
}],
|
||||
},
|
||||
);
|
||||
|
|
|
@ -1887,8 +1887,16 @@ mod tests {
|
|||
.set_entity(&entity3, &mut cx.to_async());
|
||||
drop(subscription3);
|
||||
|
||||
server.send(proto::JoinProject { project_id: 1 });
|
||||
server.send(proto::JoinProject { project_id: 2 });
|
||||
server.send(proto::JoinProject {
|
||||
project_id: 1,
|
||||
committer_name: None,
|
||||
committer_email: None,
|
||||
});
|
||||
server.send(proto::JoinProject {
|
||||
project_id: 2,
|
||||
committer_name: None,
|
||||
committer_email: None,
|
||||
});
|
||||
done_rx1.recv().await.unwrap();
|
||||
done_rx2.recv().await.unwrap();
|
||||
}
|
||||
|
|
|
@ -49,7 +49,6 @@ pub struct User {
|
|||
pub github_login: String,
|
||||
pub avatar_uri: SharedUri,
|
||||
pub name: Option<String>,
|
||||
pub email: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -58,6 +57,8 @@ pub struct Collaborator {
|
|||
pub replica_id: ReplicaId,
|
||||
pub user_id: UserId,
|
||||
pub is_host: bool,
|
||||
pub committer_name: Option<String>,
|
||||
pub committer_email: Option<String>,
|
||||
}
|
||||
|
||||
impl PartialOrd for User {
|
||||
|
@ -881,7 +882,6 @@ impl User {
|
|||
github_login: message.github_login,
|
||||
avatar_uri: message.avatar_url.into(),
|
||||
name: message.name,
|
||||
email: message.email,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -912,6 +912,8 @@ impl Collaborator {
|
|||
replica_id: message.replica_id as ReplicaId,
|
||||
user_id: message.user_id as UserId,
|
||||
is_host: message.is_host,
|
||||
committer_name: message.committer_name,
|
||||
committer_email: message.committer_email,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -185,7 +185,9 @@ CREATE TABLE "project_collaborators" (
|
|||
"connection_server_id" INTEGER NOT NULL REFERENCES servers (id) ON DELETE CASCADE,
|
||||
"user_id" INTEGER NOT NULL,
|
||||
"replica_id" INTEGER NOT NULL,
|
||||
"is_host" BOOLEAN NOT NULL
|
||||
"is_host" BOOLEAN NOT NULL,
|
||||
"committer_name" VARCHAR,
|
||||
"committer_email" VARCHAR
|
||||
);
|
||||
|
||||
CREATE INDEX "index_project_collaborators_on_project_id" ON "project_collaborators" ("project_id");
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
alter table project_collaborators
|
||||
add column committer_name varchar;
|
||||
alter table project_collaborators
|
||||
add column committer_email varchar;
|
|
@ -751,6 +751,8 @@ pub struct ProjectCollaborator {
|
|||
pub user_id: UserId,
|
||||
pub replica_id: ReplicaId,
|
||||
pub is_host: bool,
|
||||
pub committer_name: Option<String>,
|
||||
pub committer_email: Option<String>,
|
||||
}
|
||||
|
||||
impl ProjectCollaborator {
|
||||
|
@ -760,6 +762,8 @@ impl ProjectCollaborator {
|
|||
replica_id: self.replica_id.0 as u32,
|
||||
user_id: self.user_id.to_proto(),
|
||||
is_host: self.is_host,
|
||||
committer_name: self.committer_name.clone(),
|
||||
committer_email: self.committer_email.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,6 +118,8 @@ impl Database {
|
|||
user_id: collaborator.user_id.to_proto(),
|
||||
replica_id: collaborator.replica_id.0 as u32,
|
||||
is_host: false,
|
||||
committer_name: None,
|
||||
committer_email: None,
|
||||
})
|
||||
.collect(),
|
||||
})
|
||||
|
@ -225,6 +227,8 @@ impl Database {
|
|||
user_id: collaborator.user_id.to_proto(),
|
||||
replica_id: collaborator.replica_id.0 as u32,
|
||||
is_host: false,
|
||||
committer_name: None,
|
||||
committer_email: None,
|
||||
})
|
||||
.collect(),
|
||||
},
|
||||
|
@ -261,6 +265,8 @@ impl Database {
|
|||
replica_id: db_collaborator.replica_id.0 as u32,
|
||||
user_id: db_collaborator.user_id.to_proto(),
|
||||
is_host: false,
|
||||
committer_name: None,
|
||||
committer_email: None,
|
||||
})
|
||||
} else {
|
||||
collaborator_ids_to_remove.push(db_collaborator.id);
|
||||
|
@ -390,6 +396,8 @@ impl Database {
|
|||
replica_id: row.replica_id.0 as u32,
|
||||
user_id: row.user_id.to_proto(),
|
||||
is_host: false,
|
||||
committer_name: None,
|
||||
committer_email: None,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -739,7 +739,6 @@ impl Database {
|
|||
),
|
||||
github_login: user.github_login,
|
||||
name: user.name,
|
||||
email: user.email_address,
|
||||
})
|
||||
}
|
||||
proto::ChannelMember {
|
||||
|
|
|
@ -98,7 +98,9 @@ impl Database {
|
|||
user_id: ActiveValue::set(participant.user_id),
|
||||
replica_id: ActiveValue::set(ReplicaId(replica_id)),
|
||||
is_host: ActiveValue::set(true),
|
||||
..Default::default()
|
||||
id: ActiveValue::NotSet,
|
||||
committer_name: ActiveValue::Set(None),
|
||||
committer_email: ActiveValue::Set(None),
|
||||
}
|
||||
.insert(&*tx)
|
||||
.await?;
|
||||
|
@ -784,13 +786,27 @@ impl Database {
|
|||
project_id: ProjectId,
|
||||
connection: ConnectionId,
|
||||
user_id: UserId,
|
||||
committer_name: Option<String>,
|
||||
committer_email: Option<String>,
|
||||
) -> Result<TransactionGuard<(Project, ReplicaId)>> {
|
||||
self.project_transaction(project_id, |tx| async move {
|
||||
let (project, role) = self
|
||||
.access_project(project_id, connection, Capability::ReadOnly, &tx)
|
||||
.await?;
|
||||
self.join_project_internal(project, user_id, connection, role, &tx)
|
||||
self.project_transaction(project_id, move |tx| {
|
||||
let committer_name = committer_name.clone();
|
||||
let committer_email = committer_email.clone();
|
||||
async move {
|
||||
let (project, role) = self
|
||||
.access_project(project_id, connection, Capability::ReadOnly, &tx)
|
||||
.await?;
|
||||
self.join_project_internal(
|
||||
project,
|
||||
user_id,
|
||||
committer_name,
|
||||
committer_email,
|
||||
connection,
|
||||
role,
|
||||
&tx,
|
||||
)
|
||||
.await
|
||||
}
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
@ -799,6 +815,8 @@ impl Database {
|
|||
&self,
|
||||
project: project::Model,
|
||||
user_id: UserId,
|
||||
committer_name: Option<String>,
|
||||
committer_email: Option<String>,
|
||||
connection: ConnectionId,
|
||||
role: ChannelRole,
|
||||
tx: &DatabaseTransaction,
|
||||
|
@ -822,7 +840,9 @@ impl Database {
|
|||
user_id: ActiveValue::set(user_id),
|
||||
replica_id: ActiveValue::set(replica_id),
|
||||
is_host: ActiveValue::set(false),
|
||||
..Default::default()
|
||||
id: ActiveValue::NotSet,
|
||||
committer_name: ActiveValue::set(committer_name),
|
||||
committer_email: ActiveValue::set(committer_email),
|
||||
}
|
||||
.insert(tx)
|
||||
.await?;
|
||||
|
@ -1026,6 +1046,8 @@ impl Database {
|
|||
user_id: collaborator.user_id,
|
||||
replica_id: collaborator.replica_id,
|
||||
is_host: collaborator.is_host,
|
||||
committer_name: collaborator.committer_name,
|
||||
committer_email: collaborator.committer_email,
|
||||
})
|
||||
.collect(),
|
||||
worktrees,
|
||||
|
|
|
@ -553,6 +553,8 @@ impl Database {
|
|||
user_id: collaborator.user_id,
|
||||
replica_id: collaborator.replica_id,
|
||||
is_host: collaborator.is_host,
|
||||
committer_name: collaborator.committer_name.clone(),
|
||||
committer_email: collaborator.committer_email.clone(),
|
||||
})
|
||||
.collect(),
|
||||
worktrees: reshared_project.worktrees.clone(),
|
||||
|
@ -857,6 +859,8 @@ impl Database {
|
|||
user_id: collaborator.user_id,
|
||||
replica_id: collaborator.replica_id,
|
||||
is_host: collaborator.is_host,
|
||||
committer_name: collaborator.committer_name,
|
||||
committer_email: collaborator.committer_email,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ pub struct Model {
|
|||
pub user_id: UserId,
|
||||
pub replica_id: ReplicaId,
|
||||
pub is_host: bool,
|
||||
pub committer_name: Option<String>,
|
||||
pub committer_email: Option<String>,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
|
|
|
@ -126,12 +126,16 @@ async fn test_channel_buffers(db: &Arc<Database>) {
|
|||
peer_id: Some(rpc::proto::PeerId { id: 1, owner_id }),
|
||||
replica_id: 0,
|
||||
is_host: false,
|
||||
committer_name: None,
|
||||
committer_email: None,
|
||||
},
|
||||
rpc::proto::Collaborator {
|
||||
user_id: b_id.to_proto(),
|
||||
peer_id: Some(rpc::proto::PeerId { id: 2, owner_id }),
|
||||
replica_id: 1,
|
||||
is_host: false,
|
||||
committer_name: None,
|
||||
committer_email: None,
|
||||
}
|
||||
]
|
||||
);
|
||||
|
|
|
@ -14,7 +14,7 @@ use crate::{
|
|||
db::{
|
||||
self, BufferId, Capability, Channel, ChannelId, ChannelRole, ChannelsForUser,
|
||||
CreatedChannelMessage, Database, InviteMemberResult, MembershipUpdated, MessageId,
|
||||
NotificationId, Project, ProjectId, RejoinedProject, RemoveChannelMemberResult, ReplicaId,
|
||||
NotificationId, ProjectId, RejoinedProject, RemoveChannelMemberResult,
|
||||
RespondToChannelInvite, RoomId, ServerId, UpdatedChannelMessage, User, UserId,
|
||||
},
|
||||
executor::Executor,
|
||||
|
@ -1890,28 +1890,16 @@ async fn join_project(
|
|||
|
||||
let db = session.db().await;
|
||||
let (project, replica_id) = &mut *db
|
||||
.join_project(project_id, session.connection_id, session.user_id())
|
||||
.join_project(
|
||||
project_id,
|
||||
session.connection_id,
|
||||
session.user_id(),
|
||||
request.committer_name.clone(),
|
||||
request.committer_email.clone(),
|
||||
)
|
||||
.await?;
|
||||
drop(db);
|
||||
tracing::info!(%project_id, "join remote project");
|
||||
join_project_internal(response, session, project, replica_id)
|
||||
}
|
||||
|
||||
trait JoinProjectInternalResponse {
|
||||
fn send(self, result: proto::JoinProjectResponse) -> Result<()>;
|
||||
}
|
||||
impl JoinProjectInternalResponse for Response<proto::JoinProject> {
|
||||
fn send(self, result: proto::JoinProjectResponse) -> Result<()> {
|
||||
Response::<proto::JoinProject>::send(self, result)
|
||||
}
|
||||
}
|
||||
|
||||
fn join_project_internal(
|
||||
response: impl JoinProjectInternalResponse,
|
||||
session: Session,
|
||||
project: &mut Project,
|
||||
replica_id: &ReplicaId,
|
||||
) -> Result<()> {
|
||||
let collaborators = project
|
||||
.collaborators
|
||||
.iter()
|
||||
|
@ -1939,6 +1927,8 @@ fn join_project_internal(
|
|||
replica_id: replica_id.0 as u32,
|
||||
user_id: guest_user_id.to_proto(),
|
||||
is_host: false,
|
||||
committer_name: request.committer_name.clone(),
|
||||
committer_email: request.committer_email.clone(),
|
||||
}),
|
||||
};
|
||||
|
||||
|
@ -2567,7 +2557,6 @@ async fn get_users(
|
|||
id: user.id.to_proto(),
|
||||
avatar_url: format!("https://github.com/{}.png?size=128", user.github_login),
|
||||
github_login: user.github_login,
|
||||
email: user.email_address,
|
||||
name: user.name,
|
||||
})
|
||||
.collect();
|
||||
|
@ -2601,7 +2590,6 @@ async fn fuzzy_search_users(
|
|||
avatar_url: format!("https://github.com/{}.png?size=128", user.github_login),
|
||||
github_login: user.github_login,
|
||||
name: user.name,
|
||||
email: user.email_address,
|
||||
})
|
||||
.collect();
|
||||
response.send(proto::UsersResponse { users })?;
|
||||
|
|
|
@ -1610,6 +1610,8 @@ async fn test_following_across_workspaces(cx_a: &mut TestAppContext, cx_b: &mut
|
|||
.root(cx_a)
|
||||
.unwrap();
|
||||
|
||||
executor.run_until_parked();
|
||||
|
||||
workspace_a_project_b.update(cx_a2, |workspace, cx| {
|
||||
assert_eq!(workspace.project().read(cx).remote_id(), Some(project_b_id));
|
||||
assert!(workspace.is_being_followed(client_b.peer_id().unwrap()));
|
||||
|
|
|
@ -1876,7 +1876,6 @@ async fn test_active_call_events(
|
|||
github_login: "user_a".to_string(),
|
||||
avatar_uri: "avatar_a".into(),
|
||||
name: None,
|
||||
email: None,
|
||||
}),
|
||||
project_id: project_a_id,
|
||||
worktree_root_names: vec!["a".to_string()],
|
||||
|
@ -1896,7 +1895,6 @@ async fn test_active_call_events(
|
|||
github_login: "user_b".to_string(),
|
||||
avatar_uri: "avatar_b".into(),
|
||||
name: None,
|
||||
email: None,
|
||||
}),
|
||||
project_id: project_b_id,
|
||||
worktree_root_names: vec!["b".to_string()]
|
||||
|
|
|
@ -1218,7 +1218,6 @@ mod tests {
|
|||
avatar_uri: "avatar_fgh".into(),
|
||||
id: 103,
|
||||
name: None,
|
||||
email: None,
|
||||
}),
|
||||
nonce: 5,
|
||||
mentions: vec![(ranges[0].clone(), 101), (ranges[1].clone(), 102)],
|
||||
|
@ -1274,7 +1273,6 @@ mod tests {
|
|||
avatar_uri: "avatar_fgh".into(),
|
||||
id: 103,
|
||||
name: None,
|
||||
email: None,
|
||||
}),
|
||||
nonce: 5,
|
||||
mentions: Vec::new(),
|
||||
|
@ -1323,7 +1321,6 @@ mod tests {
|
|||
avatar_uri: "avatar_fgh".into(),
|
||||
id: 103,
|
||||
name: None,
|
||||
email: None,
|
||||
}),
|
||||
nonce: 5,
|
||||
mentions: Vec::new(),
|
||||
|
|
|
@ -26,8 +26,8 @@ use std::{
|
|||
};
|
||||
use sum_tree::MapSeekTarget;
|
||||
use thiserror::Error;
|
||||
use util::ResultExt;
|
||||
use util::command::{new_smol_command, new_std_command};
|
||||
use util::{ResultExt, paths};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub use askpass::{AskPassDelegate, AskPassResult, AskPassSession};
|
||||
|
@ -508,6 +508,50 @@ pub struct GitRepositoryCheckpoint {
|
|||
pub commit_sha: Oid,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GitCommitter {
|
||||
pub name: Option<String>,
|
||||
pub email: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn get_git_committer(cx: &AsyncApp) -> GitCommitter {
|
||||
if cfg!(any(feature = "test-support", test)) {
|
||||
return GitCommitter {
|
||||
name: None,
|
||||
email: None,
|
||||
};
|
||||
}
|
||||
|
||||
let git_binary_path =
|
||||
if cfg!(target_os = "macos") && option_env!("ZED_BUNDLE").as_deref() == Some("true") {
|
||||
cx.update(|cx| {
|
||||
cx.path_for_auxiliary_executable("git")
|
||||
.context("could not find git binary path")
|
||||
.log_err()
|
||||
})
|
||||
.ok()
|
||||
.flatten()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let git = GitBinary::new(
|
||||
git_binary_path.unwrap_or(PathBuf::from("git")),
|
||||
paths::home_dir().clone(),
|
||||
cx.background_executor().clone(),
|
||||
);
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let name = git.run(["config", "--global", "user.name"]).await.log_err();
|
||||
let email = git
|
||||
.run(["config", "--global", "user.email"])
|
||||
.await
|
||||
.log_err();
|
||||
GitCommitter { name, email }
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
impl GitRepository for RealGitRepository {
|
||||
fn reload_index(&self) {
|
||||
if let Ok(mut index) = self.repository.lock().index() {
|
||||
|
|
|
@ -21,6 +21,7 @@ agent_settings.workspace = true
|
|||
anyhow.workspace = true
|
||||
askpass.workspace = true
|
||||
buffer_diff.workspace = true
|
||||
call.workspace = true
|
||||
chrono.workspace = true
|
||||
collections.workspace = true
|
||||
command_palette_hooks.workspace = true
|
||||
|
|
|
@ -148,6 +148,7 @@ impl CommitModal {
|
|||
}
|
||||
}
|
||||
git_panel.set_modal_open(true, cx);
|
||||
git_panel.load_local_committer(cx);
|
||||
});
|
||||
|
||||
let dock = workspace.dock_at_position(git_panel.position(window, cx));
|
||||
|
|
|
@ -20,8 +20,9 @@ use editor::{
|
|||
use futures::StreamExt as _;
|
||||
use git::blame::ParsedCommitMessage;
|
||||
use git::repository::{
|
||||
Branch, CommitDetails, CommitOptions, CommitSummary, DiffType, FetchOptions, PushOptions,
|
||||
Remote, RemoteCommandOutput, ResetMode, Upstream, UpstreamTracking, UpstreamTrackingStatus,
|
||||
Branch, CommitDetails, CommitOptions, CommitSummary, DiffType, FetchOptions, GitCommitter,
|
||||
PushOptions, Remote, RemoteCommandOutput, ResetMode, Upstream, UpstreamTracking,
|
||||
UpstreamTrackingStatus, get_git_committer,
|
||||
};
|
||||
use git::status::StageStatus;
|
||||
use git::{Amend, ToggleStaged, repository::RepoPath, status::FileStatus};
|
||||
|
@ -358,6 +359,8 @@ pub struct GitPanel {
|
|||
context_menu: Option<(Entity<ContextMenu>, Point<Pixels>, Subscription)>,
|
||||
modal_open: bool,
|
||||
show_placeholders: bool,
|
||||
local_committer: Option<GitCommitter>,
|
||||
local_committer_task: Option<Task<()>>,
|
||||
_settings_subscription: Subscription,
|
||||
}
|
||||
|
||||
|
@ -520,6 +523,8 @@ impl GitPanel {
|
|||
update_visible_entries_task: Task::ready(()),
|
||||
width: None,
|
||||
show_placeholders: false,
|
||||
local_committer: None,
|
||||
local_committer_task: None,
|
||||
context_menu: None,
|
||||
workspace: workspace.weak_handle(),
|
||||
modal_open: false,
|
||||
|
@ -2250,6 +2255,19 @@ impl GitPanel {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn load_local_committer(&mut self, cx: &Context<Self>) {
|
||||
if self.local_committer_task.is_none() {
|
||||
self.local_committer_task = Some(cx.spawn(async move |this, cx| {
|
||||
let committer = get_git_committer(cx).await;
|
||||
this.update(cx, |this, cx| {
|
||||
this.local_committer = Some(committer);
|
||||
cx.notify()
|
||||
})
|
||||
.ok();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
fn potential_co_authors(&self, cx: &App) -> Vec<(String, String)> {
|
||||
let mut new_co_authors = Vec::new();
|
||||
let project = self.project.read(cx);
|
||||
|
@ -2272,34 +2290,38 @@ impl GitPanel {
|
|||
let Some(participant) = room.remote_participant_for_peer_id(*peer_id) else {
|
||||
continue;
|
||||
};
|
||||
if participant.can_write() && participant.user.email.is_some() {
|
||||
let email = participant.user.email.clone().unwrap();
|
||||
|
||||
new_co_authors.push((
|
||||
participant
|
||||
.user
|
||||
.name
|
||||
.clone()
|
||||
.unwrap_or_else(|| participant.user.github_login.clone()),
|
||||
email,
|
||||
))
|
||||
if !participant.can_write() {
|
||||
continue;
|
||||
}
|
||||
if let Some(email) = &collaborator.committer_email {
|
||||
let name = collaborator
|
||||
.committer_name
|
||||
.clone()
|
||||
.or_else(|| participant.user.name.clone())
|
||||
.unwrap_or_else(|| participant.user.github_login.clone());
|
||||
new_co_authors.push((name.clone(), email.clone()))
|
||||
}
|
||||
}
|
||||
if !project.is_local() && !project.is_read_only(cx) {
|
||||
if let Some(user) = room.local_participant_user(cx) {
|
||||
if let Some(email) = user.email.clone() {
|
||||
new_co_authors.push((
|
||||
user.name
|
||||
.clone()
|
||||
.unwrap_or_else(|| user.github_login.clone()),
|
||||
email.clone(),
|
||||
))
|
||||
}
|
||||
if let Some(local_committer) = self.local_committer(room, cx) {
|
||||
new_co_authors.push(local_committer);
|
||||
}
|
||||
}
|
||||
new_co_authors
|
||||
}
|
||||
|
||||
fn local_committer(&self, room: &call::Room, cx: &App) -> Option<(String, String)> {
|
||||
let user = room.local_participant_user(cx)?;
|
||||
let committer = self.local_committer.as_ref()?;
|
||||
let email = committer.email.clone()?;
|
||||
let name = committer
|
||||
.name
|
||||
.clone()
|
||||
.or_else(|| user.name.clone())
|
||||
.unwrap_or_else(|| user.github_login.clone());
|
||||
Some((name, email))
|
||||
}
|
||||
|
||||
fn toggle_fill_co_authors(
|
||||
&mut self,
|
||||
_: &ToggleFillCoAuthors,
|
||||
|
@ -4244,8 +4266,9 @@ impl Render for GitPanel {
|
|||
let has_write_access = self.has_write_access(cx);
|
||||
|
||||
let has_co_authors = room.map_or(false, |room| {
|
||||
room.read(cx)
|
||||
.remote_participants()
|
||||
self.load_local_committer(cx);
|
||||
let room = room.read(cx);
|
||||
room.remote_participants()
|
||||
.values()
|
||||
.any(|remote_participant| remote_participant.can_write())
|
||||
});
|
||||
|
|
|
@ -26,6 +26,7 @@ mod environment;
|
|||
use buffer_diff::BufferDiff;
|
||||
use context_server_store::ContextServerStore;
|
||||
pub use environment::{EnvironmentErrorMessage, ProjectEnvironmentEvent};
|
||||
use git::repository::get_git_committer;
|
||||
use git_store::{Repository, RepositoryId};
|
||||
pub mod search_history;
|
||||
mod yarn;
|
||||
|
@ -1323,9 +1324,12 @@ impl Project {
|
|||
),
|
||||
EntitySubscription::DapStore(client.subscribe_to_entity::<DapStore>(remote_id)?),
|
||||
];
|
||||
let committer = get_git_committer(&cx).await;
|
||||
let response = client
|
||||
.request_envelope(proto::JoinProject {
|
||||
project_id: remote_id,
|
||||
committer_email: committer.email,
|
||||
committer_name: committer.name,
|
||||
})
|
||||
.await?;
|
||||
Self::from_join_project_response(
|
||||
|
|
|
@ -189,6 +189,8 @@ message UpdateProject {
|
|||
|
||||
message JoinProject {
|
||||
uint64 project_id = 1;
|
||||
optional string committer_email = 2;
|
||||
optional string committer_name = 3;
|
||||
}
|
||||
|
||||
message JoinProjectResponse {
|
||||
|
|
|
@ -7,10 +7,10 @@ message PeerId {
|
|||
}
|
||||
|
||||
message User {
|
||||
reserved 4;
|
||||
uint64 id = 1;
|
||||
string github_login = 2;
|
||||
string avatar_url = 3;
|
||||
optional string email = 4;
|
||||
optional string name = 5;
|
||||
}
|
||||
|
||||
|
@ -24,4 +24,6 @@ message Collaborator {
|
|||
uint32 replica_id = 2;
|
||||
uint64 user_id = 3;
|
||||
bool is_host = 4;
|
||||
optional string committer_name = 5;
|
||||
optional string committer_email = 6;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue