Fix crash in git checkout (#33499)
Closes #33438 Release Notes: - git: Use git cli to perform checkouts (to avoid a crash seen in libgit2)
This commit is contained in:
parent
9e2023bffc
commit
d74f3f4ea6
1 changed files with 30 additions and 23 deletions
|
@ -1032,32 +1032,39 @@ impl GitRepository for RealGitRepository {
|
||||||
|
|
||||||
fn change_branch(&self, name: String) -> BoxFuture<'_, Result<()>> {
|
fn change_branch(&self, name: String) -> BoxFuture<'_, Result<()>> {
|
||||||
let repo = self.repository.clone();
|
let repo = self.repository.clone();
|
||||||
|
let working_directory = self.working_directory();
|
||||||
|
let git_binary_path = self.git_binary_path.clone();
|
||||||
|
let executor = self.executor.clone();
|
||||||
|
let branch = self.executor.spawn(async move {
|
||||||
|
let repo = repo.lock();
|
||||||
|
let branch = if let Ok(branch) = repo.find_branch(&name, BranchType::Local) {
|
||||||
|
branch
|
||||||
|
} else if let Ok(revision) = repo.find_branch(&name, BranchType::Remote) {
|
||||||
|
let (_, branch_name) = name.split_once("/").context("Unexpected branch format")?;
|
||||||
|
let revision = revision.get();
|
||||||
|
let branch_commit = revision.peel_to_commit()?;
|
||||||
|
let mut branch = repo.branch(&branch_name, &branch_commit, false)?;
|
||||||
|
branch.set_upstream(Some(&name))?;
|
||||||
|
branch
|
||||||
|
} else {
|
||||||
|
anyhow::bail!("Branch not found");
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(branch
|
||||||
|
.name()?
|
||||||
|
.context("cannot checkout anonymous branch")?
|
||||||
|
.to_string())
|
||||||
|
});
|
||||||
|
|
||||||
self.executor
|
self.executor
|
||||||
.spawn(async move {
|
.spawn(async move {
|
||||||
let repo = repo.lock();
|
let branch = branch.await?;
|
||||||
let branch = if let Ok(branch) = repo.find_branch(&name, BranchType::Local) {
|
|
||||||
branch
|
|
||||||
} else if let Ok(revision) = repo.find_branch(&name, BranchType::Remote) {
|
|
||||||
let (_, branch_name) =
|
|
||||||
name.split_once("/").context("Unexpected branch format")?;
|
|
||||||
let revision = revision.get();
|
|
||||||
let branch_commit = revision.peel_to_commit()?;
|
|
||||||
let mut branch = repo.branch(&branch_name, &branch_commit, false)?;
|
|
||||||
branch.set_upstream(Some(&name))?;
|
|
||||||
branch
|
|
||||||
} else {
|
|
||||||
anyhow::bail!("Branch not found");
|
|
||||||
};
|
|
||||||
|
|
||||||
let revision = branch.get();
|
GitBinary::new(git_binary_path, working_directory?, executor)
|
||||||
let as_tree = revision.peel_to_tree()?;
|
.run(&["checkout", &branch])
|
||||||
repo.checkout_tree(as_tree.as_object(), None)?;
|
.await?;
|
||||||
repo.set_head(
|
|
||||||
revision
|
anyhow::Ok(())
|
||||||
.name()
|
|
||||||
.context("Branch name could not be retrieved")?,
|
|
||||||
)?;
|
|
||||||
Ok(())
|
|
||||||
})
|
})
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue