Detailed changes
@@ -1,5 +1,5 @@
use crate::{FakeFs, FakeFsEntry, Fs};
-use anyhow::{Context as _, Result};
+use anyhow::{Context as _, Result, bail};
use collections::{HashMap, HashSet};
use futures::future::{self, BoxFuture, join_all};
use git::{
@@ -350,11 +350,13 @@ impl GitRepository for FakeGitRepository {
})
}
- fn rename_branch(&self, new_name: String) -> BoxFuture<'_, Result<()>> {
+ fn rename_branch(&self, branch: String, new_name: String) -> BoxFuture<'_, Result<()>> {
self.with_state_async(true, move |state| {
- if let Some(current_branch) = &state.current_branch_name {
- state.branches.insert(new_name.clone());
- state.branches.remove(current_branch);
+ if !state.branches.remove(&branch) {
+ bail!("no such branch: {branch}");
+ }
+ state.branches.insert(new_name.clone());
+ if state.current_branch_name == Some(branch) {
state.current_branch_name = Some(new_name);
}
Ok(())
@@ -370,7 +370,7 @@ pub trait GitRepository: Send + Sync {
fn change_branch(&self, name: String) -> BoxFuture<'_, Result<()>>;
fn create_branch(&self, name: String) -> BoxFuture<'_, Result<()>>;
- fn rename_branch(&self, new_name: String) -> BoxFuture<'_, Result<()>>;
+ fn rename_branch(&self, branch: String, new_name: String) -> BoxFuture<'_, Result<()>>;
fn reset(
&self,
@@ -1131,7 +1131,7 @@ impl GitRepository for RealGitRepository {
.boxed()
}
- fn rename_branch(&self, new_name: String) -> BoxFuture<'_, Result<()>> {
+ fn rename_branch(&self, branch: String, new_name: String) -> BoxFuture<'_, Result<()>> {
let git_binary_path = self.git_binary_path.clone();
let working_directory = self.working_directory();
let executor = self.executor.clone();
@@ -1139,7 +1139,7 @@ impl GitRepository for RealGitRepository {
self.executor
.spawn(async move {
match GitBinary::new(git_binary_path, working_directory?, executor)
- .run_with_output(&["branch", "-m", &new_name])
+ .run_with_output(&["branch", "-m", &branch, &new_name])
.await
{
Ok(_) => Ok(()),
@@ -276,9 +276,12 @@ impl RenameBranchModal {
}
let repo = self.repo.clone();
+ let current_branch = self.current_branch.to_string();
cx.spawn(async move |_, cx| {
match repo
- .update(cx, |repo, _| repo.rename_branch(new_name.clone()))?
+ .update(cx, |repo, _| {
+ repo.rename_branch(current_branch, new_name.clone())
+ })?
.await
{
Ok(Ok(_)) => Ok(()),
@@ -417,6 +417,7 @@ impl GitStore {
client.add_entity_request_handler(Self::handle_get_default_branch);
client.add_entity_request_handler(Self::handle_change_branch);
client.add_entity_request_handler(Self::handle_create_branch);
+ client.add_entity_request_handler(Self::handle_rename_branch);
client.add_entity_request_handler(Self::handle_git_init);
client.add_entity_request_handler(Self::handle_push);
client.add_entity_request_handler(Self::handle_pull);
@@ -1948,6 +1949,25 @@ impl GitStore {
Ok(proto::Ack {})
}
+ async fn handle_rename_branch(
+ this: Entity<Self>,
+ envelope: TypedEnvelope<proto::GitRenameBranch>,
+ mut cx: AsyncApp,
+ ) -> Result<proto::Ack> {
+ let repository_id = RepositoryId::from_proto(envelope.payload.repository_id);
+ let repository_handle = Self::repository_for_request(&this, repository_id, &mut cx)?;
+ let branch = envelope.payload.branch;
+ let new_name = envelope.payload.new_name;
+
+ repository_handle
+ .update(&mut cx, |repository_handle, _| {
+ repository_handle.rename_branch(branch, new_name)
+ })?
+ .await??;
+
+ Ok(proto::Ack {})
+ }
+
async fn handle_show(
this: Entity<Self>,
envelope: TypedEnvelope<proto::GitShow>,
@@ -4199,18 +4219,30 @@ impl Repository {
)
}
- pub fn rename_branch(&mut self, new_name: String) -> oneshot::Receiver<Result<()>> {
- let _id = self.id;
+ pub fn rename_branch(
+ &mut self,
+ branch: String,
+ new_name: String,
+ ) -> oneshot::Receiver<Result<()>> {
+ let id = self.id;
self.send_job(
- Some(format!("git branch -m {new_name}").into()),
+ Some(format!("git branch -m {branch} {new_name}").into()),
move |repo, _cx| async move {
match repo {
- RepositoryState::Local { backend, .. } => backend.rename_branch(new_name).await,
- RepositoryState::Remote { .. } => {
- // Remote branch renaming not implemented yet
- Err(anyhow::anyhow!(
- "Branch renaming is not supported for remote repositories yet"
- ))
+ RepositoryState::Local { backend, .. } => {
+ backend.rename_branch(branch, new_name).await
+ }
+ RepositoryState::Remote { project_id, client } => {
+ client
+ .request(proto::GitRenameBranch {
+ project_id: project_id.0,
+ repository_id: id.to_proto(),
+ branch,
+ new_name,
+ })
+ .await?;
+
+ Ok(())
}
}
},
@@ -182,8 +182,8 @@ message GitChangeBranch {
message GitRenameBranch {
uint64 project_id = 1;
- reserved 2;
- uint64 repository_id = 3;
+ uint64 repository_id = 2;
+ string branch = 3;
string new_name = 4;
}
@@ -301,6 +301,7 @@ messages!(
(AskPassResponse, Background),
(GitCreateBranch, Background),
(GitChangeBranch, Background),
+ (GitRenameBranch, Background),
(CheckForPushedCommits, Background),
(CheckForPushedCommitsResponse, Background),
(GitDiff, Background),
@@ -477,6 +478,7 @@ request_messages!(
(AskPassRequest, AskPassResponse),
(GitCreateBranch, Ack),
(GitChangeBranch, Ack),
+ (GitRenameBranch, Ack),
(CheckForPushedCommits, CheckForPushedCommitsResponse),
(GitDiff, GitDiffResponse),
(GitInit, Ack),
@@ -607,6 +609,7 @@ entity_messages!(
Pull,
AskPassRequest,
GitChangeBranch,
+ GitRenameBranch,
GitCreateBranch,
CheckForPushedCommits,
GitDiff,