Use different commit author for collab project clients (#24058)

Follow-up of https://github.com/zed-industries/zed/pull/23869

* Retrieves user + email for collab project clients and use these when
such users commit

Same as in https://github.com/zed-industries/zed/pull/23329, "is it the
right user name and e-mail" and "how to override these" questions apply.

* If this data is unavailable, forbid committing to the remote client

* Forbid running related actions in git panel, if committing/writing is
not permitted


Release Notes:

- N/A
This commit is contained in:
Kirill Bulatov 2025-02-01 01:25:58 +02:00 committed by GitHub
parent 93c7b54caa
commit 9a6b9e3124
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 182 additions and 50 deletions

View file

@ -62,7 +62,7 @@ pub trait GitRepository: Send + Sync {
/// If any of the paths were previously staged but do not exist in HEAD, they will be removed from the index.
fn unstage_paths(&self, paths: &[RepoPath]) -> Result<()>;
fn commit(&self, message: &str) -> Result<()>;
fn commit(&self, message: &str, name_and_email: Option<(&str, &str)>) -> Result<()>;
}
impl std::fmt::Debug for dyn GitRepository {
@ -283,17 +283,23 @@ impl GitRepository for RealGitRepository {
Ok(())
}
fn commit(&self, message: &str) -> Result<()> {
fn commit(&self, message: &str, name_and_email: Option<(&str, &str)>) -> Result<()> {
let working_directory = self
.repository
.lock()
.workdir()
.context("failed to read git work directory")?
.to_path_buf();
let mut args = vec!["commit", "--quiet", "-m", message];
let author = name_and_email.map(|(name, email)| format!("{name} <{email}>"));
if let Some(author) = author.as_deref() {
args.push("--author");
args.push(author);
}
let cmd = new_std_command(&self.git_binary_path)
.current_dir(&working_directory)
.args(["commit", "--quiet", "-m", message])
.args(args)
.status()?;
if !cmd.success() {
return Err(anyhow!("Failed to commit: {cmd}"));
@ -444,7 +450,7 @@ impl GitRepository for FakeGitRepository {
unimplemented!()
}
fn commit(&self, _message: &str) -> Result<()> {
fn commit(&self, _message: &str, _name_and_email: Option<(&str, &str)>) -> Result<()> {
unimplemented!()
}
}