git: Pick which remote to fetch (#26897)

I don't want to fetch `--all` branch, we should can picker which remote
to fetch.

Release Notes:

- Added the `git::FetchFrom` action to fetch from a single remote.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
This commit is contained in:
CharlesChen0823 2025-06-06 23:28:07 +08:00 committed by GitHub
parent a40ee74a1f
commit edd40566b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 155 additions and 42 deletions

View file

@ -49,6 +49,7 @@ actions!(
ForcePush,
Pull,
Fetch,
FetchFrom,
Commit,
Amend,
Cancel,

View file

@ -193,6 +193,44 @@ pub enum ResetMode {
Mixed,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum FetchOptions {
All,
Remote(Remote),
}
impl FetchOptions {
pub fn to_proto(&self) -> Option<String> {
match self {
FetchOptions::All => None,
FetchOptions::Remote(remote) => Some(remote.clone().name.into()),
}
}
pub fn from_proto(remote_name: Option<String>) -> Self {
match remote_name {
Some(name) => FetchOptions::Remote(Remote { name: name.into() }),
None => FetchOptions::All,
}
}
pub fn name(&self) -> SharedString {
match self {
Self::All => "Fetch all remotes".into(),
Self::Remote(remote) => remote.name.clone(),
}
}
}
impl std::fmt::Display for FetchOptions {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
FetchOptions::All => write!(f, "--all"),
FetchOptions::Remote(remote) => write!(f, "{}", remote.name),
}
}
}
/// Modifies .git/info/exclude temporarily
pub struct GitExcludeOverride {
git_exclude_path: PathBuf,
@ -381,6 +419,7 @@ pub trait GitRepository: Send + Sync {
fn fetch(
&self,
fetch_options: FetchOptions,
askpass: AskPassDelegate,
env: Arc<HashMap<String, String>>,
// This method takes an AsyncApp to ensure it's invoked on the main thread,
@ -1196,18 +1235,20 @@ impl GitRepository for RealGitRepository {
fn fetch(
&self,
fetch_options: FetchOptions,
ask_pass: AskPassDelegate,
env: Arc<HashMap<String, String>>,
cx: AsyncApp,
) -> BoxFuture<Result<RemoteCommandOutput>> {
let working_directory = self.working_directory();
let remote_name = format!("{}", fetch_options);
let executor = cx.background_executor().clone();
async move {
let mut command = new_smol_command("git");
command
.envs(env.iter())
.current_dir(&working_directory?)
.args(["fetch", "--all"])
.args(["fetch", &remote_name])
.stdout(smol::process::Stdio::piped())
.stderr(smol::process::Stdio::piped());