Start on a Git-based review flow (#27103)
Release Notes: - N/A --------- Co-authored-by: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
68262fe7e4
commit
33faa66e35
10 changed files with 396 additions and 131 deletions
|
@ -11,10 +11,10 @@ use collections::HashMap;
|
|||
use fs::Fs;
|
||||
use futures::{
|
||||
channel::{mpsc, oneshot},
|
||||
future::{OptionFuture, Shared},
|
||||
future::{self, OptionFuture, Shared},
|
||||
FutureExt as _, StreamExt as _,
|
||||
};
|
||||
use git::repository::DiffType;
|
||||
use git::{repository::DiffType, Oid};
|
||||
use git::{
|
||||
repository::{
|
||||
Branch, CommitDetails, GitRepository, PushOptions, Remote, RemoteCommandOutput, RepoPath,
|
||||
|
@ -117,6 +117,16 @@ enum GitStoreState {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GitStoreCheckpoint {
|
||||
checkpoints_by_dot_git_abs_path: HashMap<PathBuf, RepositoryCheckpoint>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct RepositoryCheckpoint {
|
||||
sha: Oid,
|
||||
}
|
||||
|
||||
pub struct Repository {
|
||||
commit_message_buffer: Option<Entity<Buffer>>,
|
||||
git_store: WeakEntity<GitStore>,
|
||||
|
@ -506,6 +516,45 @@ impl GitStore {
|
|||
diff_state.read(cx).uncommitted_diff.as_ref()?.upgrade()
|
||||
}
|
||||
|
||||
pub fn checkpoint(&self, cx: &App) -> Task<Result<GitStoreCheckpoint>> {
|
||||
let mut dot_git_abs_paths = Vec::new();
|
||||
let mut checkpoints = Vec::new();
|
||||
for repository in self.repositories.values() {
|
||||
let repository = repository.read(cx);
|
||||
dot_git_abs_paths.push(repository.dot_git_abs_path.clone());
|
||||
checkpoints.push(repository.checkpoint().map(|checkpoint| checkpoint?));
|
||||
}
|
||||
|
||||
cx.background_executor().spawn(async move {
|
||||
let checkpoints: Vec<RepositoryCheckpoint> = future::try_join_all(checkpoints).await?;
|
||||
Ok(GitStoreCheckpoint {
|
||||
checkpoints_by_dot_git_abs_path: dot_git_abs_paths
|
||||
.into_iter()
|
||||
.zip(checkpoints)
|
||||
.collect(),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn restore_checkpoint(&self, checkpoint: GitStoreCheckpoint, cx: &App) -> Task<Result<()>> {
|
||||
let repositories_by_dot_git_abs_path = self
|
||||
.repositories
|
||||
.values()
|
||||
.map(|repo| (repo.read(cx).dot_git_abs_path.clone(), repo))
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
let mut tasks = Vec::new();
|
||||
for (dot_git_abs_path, checkpoint) in checkpoint.checkpoints_by_dot_git_abs_path {
|
||||
if let Some(repository) = repositories_by_dot_git_abs_path.get(&dot_git_abs_path) {
|
||||
tasks.push(repository.read(cx).restore_checkpoint(checkpoint));
|
||||
}
|
||||
}
|
||||
cx.background_spawn(async move {
|
||||
future::try_join_all(tasks).await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn downstream_client(&self) -> Option<(AnyProtoClient, ProjectId)> {
|
||||
match &self.state {
|
||||
GitStoreState::Local {
|
||||
|
@ -2922,4 +2971,30 @@ impl Repository {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn checkpoint(&self) -> oneshot::Receiver<Result<RepositoryCheckpoint>> {
|
||||
self.send_job(|repo, cx| async move {
|
||||
match repo {
|
||||
GitRepo::Local(git_repository) => {
|
||||
let sha = git_repository.checkpoint(cx).await?;
|
||||
Ok(RepositoryCheckpoint { sha })
|
||||
}
|
||||
GitRepo::Remote { .. } => Err(anyhow!("not implemented yet")),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn restore_checkpoint(
|
||||
&self,
|
||||
checkpoint: RepositoryCheckpoint,
|
||||
) -> oneshot::Receiver<Result<()>> {
|
||||
self.send_job(move |repo, cx| async move {
|
||||
match repo {
|
||||
GitRepo::Local(git_repository) => {
|
||||
git_repository.restore_checkpoint(checkpoint.sha, cx).await
|
||||
}
|
||||
GitRepo::Remote { .. } => Err(anyhow!("not implemented yet")),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue