Detailed changes
@@ -7065,7 +7065,7 @@ async fn test_remote_git_branches(
// Also try creating a new branch
cx_b.update(|cx| {
repo_b.update(cx, |repository, _cx| {
- repository.create_branch("totally-new-branch".to_string())
+ repository.create_branch("totally-new-branch".to_string(), None)
})
})
.await
@@ -326,7 +326,7 @@ async fn test_ssh_collaboration_git_branches(
// Also try creating a new branch
cx_b.update(|cx| {
repo_b.update(cx, |repo_b, _cx| {
- repo_b.create_branch("totally-new-branch".to_string())
+ repo_b.create_branch("totally-new-branch".to_string(), None)
})
})
.await
@@ -407,7 +407,11 @@ impl GitRepository for FakeGitRepository {
})
}
- fn create_branch(&self, name: String) -> BoxFuture<'_, Result<()>> {
+ fn create_branch(
+ &self,
+ name: String,
+ _base_branch: Option<String>,
+ ) -> BoxFuture<'_, Result<()>> {
self.with_state_async(true, move |state| {
state.branches.insert(name);
Ok(())
@@ -431,7 +431,8 @@ pub trait GitRepository: Send + Sync {
fn branches(&self) -> BoxFuture<'_, Result<Vec<Branch>>>;
fn change_branch(&self, name: String) -> BoxFuture<'_, Result<()>>;
- fn create_branch(&self, name: String) -> BoxFuture<'_, Result<()>>;
+ fn create_branch(&self, name: String, base_branch: Option<String>)
+ -> BoxFuture<'_, Result<()>>;
fn rename_branch(&self, branch: String, new_name: String) -> BoxFuture<'_, Result<()>>;
fn worktrees(&self) -> BoxFuture<'_, Result<Vec<Worktree>>>;
@@ -1358,14 +1359,28 @@ impl GitRepository for RealGitRepository {
.boxed()
}
- fn create_branch(&self, name: String) -> BoxFuture<'_, Result<()>> {
- let repo = self.repository.clone();
+ fn create_branch(
+ &self,
+ name: String,
+ base_branch: Option<String>,
+ ) -> BoxFuture<'_, Result<()>> {
+ let git_binary_path = self.any_git_binary_path.clone();
+ let working_directory = self.working_directory();
+ let executor = self.executor.clone();
+
self.executor
.spawn(async move {
- let repo = repo.lock();
- let current_commit = repo.head()?.peel_to_commit()?;
- repo.branch(&name, ¤t_commit, false)?;
- Ok(())
+ let mut args = vec!["switch", "-c", &name];
+ let base_branch_str;
+ if let Some(ref base) = base_branch {
+ base_branch_str = base.clone();
+ args.push(&base_branch_str);
+ }
+
+ GitBinary::new(git_binary_path, working_directory?, executor)
+ .run(&args)
+ .await?;
+ anyhow::Ok(())
})
.boxed()
}
@@ -241,18 +241,10 @@ impl BranchListDelegate {
return;
};
let new_branch_name = new_branch_name.to_string().replace(' ', "-");
+ let base_branch = from_branch.map(|b| b.to_string());
cx.spawn(async move |_, cx| {
- if let Some(based_branch) = from_branch {
- repo.update(cx, |repo, _| repo.change_branch(based_branch.to_string()))?
- .await??;
- }
-
- repo.update(cx, |repo, _| {
- repo.create_branch(new_branch_name.to_string())
- })?
- .await??;
repo.update(cx, |repo, _| {
- repo.change_branch(new_branch_name.to_string())
+ repo.create_branch(new_branch_name, base_branch)
})?
.await??;
@@ -2094,7 +2094,7 @@ impl GitStore {
repository_handle
.update(&mut cx, |repository_handle, _| {
- repository_handle.create_branch(branch_name)
+ repository_handle.create_branch(branch_name, None)
})?
.await??;
@@ -4747,29 +4747,35 @@ impl Repository {
})
}
- pub fn create_branch(&mut self, branch_name: String) -> oneshot::Receiver<Result<()>> {
+ pub fn create_branch(
+ &mut self,
+ branch_name: String,
+ base_branch: Option<String>,
+ ) -> oneshot::Receiver<Result<()>> {
let id = self.id;
- self.send_job(
- Some(format!("git switch -c {branch_name}").into()),
- move |repo, _cx| async move {
- match repo {
- RepositoryState::Local { backend, .. } => {
- backend.create_branch(branch_name).await
- }
- RepositoryState::Remote { project_id, client } => {
- client
- .request(proto::GitCreateBranch {
- project_id: project_id.0,
- repository_id: id.to_proto(),
- branch_name,
- })
- .await?;
+ let status_msg = if let Some(ref base) = base_branch {
+ format!("git switch -c {branch_name} {base}").into()
+ } else {
+ format!("git switch -c {branch_name}").into()
+ };
+ self.send_job(Some(status_msg), move |repo, _cx| async move {
+ match repo {
+ RepositoryState::Local { backend, .. } => {
+ backend.create_branch(branch_name, base_branch).await
+ }
+ RepositoryState::Remote { project_id, client } => {
+ client
+ .request(proto::GitCreateBranch {
+ project_id: project_id.0,
+ repository_id: id.to_proto(),
+ branch_name,
+ })
+ .await?;
- Ok(())
- }
+ Ok(())
}
- },
- )
+ }
+ })
}
pub fn change_branch(&mut self, branch_name: String) -> oneshot::Receiver<Result<()>> {
@@ -1662,7 +1662,7 @@ async fn test_remote_git_branches(cx: &mut TestAppContext, server_cx: &mut TestA
// Also try creating a new branch
cx.update(|cx| {
repository.update(cx, |repo, _cx| {
- repo.create_branch("totally-new-branch".to_string())
+ repo.create_branch("totally-new-branch".to_string(), None)
})
})
.await