Restructure git diff state management to allow viewing buffers with different diff bases (#21258)
This is a pure refactor of our Git diff state management. Buffers are no longer are associated with one single diff (the unstaged changes). Instead, there is an explicit project API for retrieving a buffer's unstaged changes, and the `Editor` view layer is responsible for choosing what diff to associate with a buffer. The reason for this change is that we'll soon want to add multiple "git diff views" to Zed, one of which will show the *uncommitted* changes for a buffer. But that view will need to co-exist with other views of the same buffer, which may want to show the unstaged changes. ### Todo * [x] Get git gutter and git hunks working with new structure * [x] Update editor tests to use new APIs * [x] Update buffer tests * [x] Restructure remoting/collab protocol * [x] Update assertions about staged text in `random_project_collaboration_tests` * [x] Move buffer tests for git diff management to a new spot, using the new APIs Release Notes: - N/A --------- Co-authored-by: Richard <richard@zed.dev> Co-authored-by: Cole <cole@zed.dev> Co-authored-by: Conrad <conrad@zed.dev>
This commit is contained in:
parent
31796171de
commit
a2115e7242
29 changed files with 1832 additions and 1651 deletions
|
@ -104,7 +104,6 @@ pub enum CreatedEntry {
|
|||
pub struct LoadedFile {
|
||||
pub file: Arc<File>,
|
||||
pub text: String,
|
||||
pub diff_base: Option<String>,
|
||||
}
|
||||
|
||||
pub struct LoadedBinaryFile {
|
||||
|
@ -707,6 +706,30 @@ impl Worktree {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn load_staged_file(&self, path: &Path, cx: &AppContext) -> Task<Result<Option<String>>> {
|
||||
match self {
|
||||
Worktree::Local(this) => {
|
||||
let path = Arc::from(path);
|
||||
let snapshot = this.snapshot();
|
||||
cx.background_executor().spawn(async move {
|
||||
if let Some(repo) = snapshot.repository_for_path(&path) {
|
||||
if let Some(repo_path) = repo.relativize(&snapshot, &path).log_err() {
|
||||
if let Some(git_repo) =
|
||||
snapshot.git_repositories.get(&*repo.work_directory)
|
||||
{
|
||||
return Ok(git_repo.repo_ptr.load_index_text(&repo_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
})
|
||||
}
|
||||
Worktree::Remote(_) => {
|
||||
Task::ready(Err(anyhow!("remote worktrees can't yet load staged files")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_binary_file(
|
||||
&self,
|
||||
path: &Path,
|
||||
|
@ -1362,28 +1385,9 @@ impl LocalWorktree {
|
|||
let entry = self.refresh_entry(path.clone(), None, cx);
|
||||
let is_private = self.is_path_private(path.as_ref());
|
||||
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
cx.spawn(|this, _cx| async move {
|
||||
let abs_path = abs_path?;
|
||||
let text = fs.load(&abs_path).await?;
|
||||
let mut index_task = None;
|
||||
let snapshot = this.update(&mut cx, |this, _| this.as_local().unwrap().snapshot())?;
|
||||
if let Some(repo) = snapshot.repository_for_path(&path) {
|
||||
if let Some(repo_path) = repo.relativize(&snapshot, &path).log_err() {
|
||||
if let Some(git_repo) = snapshot.git_repositories.get(&*repo.work_directory) {
|
||||
let git_repo = git_repo.repo_ptr.clone();
|
||||
index_task = Some(
|
||||
cx.background_executor()
|
||||
.spawn(async move { git_repo.load_index_text(&repo_path) }),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let diff_base = if let Some(index_task) = index_task {
|
||||
index_task.await
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let worktree = this
|
||||
.upgrade()
|
||||
|
@ -1413,11 +1417,7 @@ impl LocalWorktree {
|
|||
}
|
||||
};
|
||||
|
||||
Ok(LoadedFile {
|
||||
file,
|
||||
text,
|
||||
diff_base,
|
||||
})
|
||||
Ok(LoadedFile { file, text })
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue