Implement staging and unstaging hunks (#24606)
- [x] Staging hunks - [x] Unstaging hunks - [x] Write a randomized test - [x] Get test passing - [x] Fix existing bug in diff_base_byte_range computation - [x] Remote project support - [ ] ~~Improve performance of buffer_range_to_unchanged_diff_base_range~~ - [ ] ~~Bug: project diff editor scrolls to top when staging/unstaging hunk~~ existing issue - [ ] ~~UI~~ deferred - [x] Tricky cases - [x] Correctly handle acting on multiple hunks for a single file - [x] Remove path from index when unstaging the last staged hunk, if it's absent from HEAD, or staging the only hunk, if it's deleted in the working copy Release Notes: - Add `ToggleStagedSelectedDiffHunks` action for staging and unstaging individual diff hunks
This commit is contained in:
parent
ea8da43c6b
commit
eea6b526dc
18 changed files with 768 additions and 70 deletions
|
@ -23,11 +23,11 @@ use util::{maybe, ResultExt};
|
|||
use worktree::{ProjectEntryId, RepositoryEntry, StatusEntry};
|
||||
|
||||
pub struct GitState {
|
||||
project_id: Option<ProjectId>,
|
||||
client: Option<AnyProtoClient>,
|
||||
pub(super) project_id: Option<ProjectId>,
|
||||
pub(super) client: Option<AnyProtoClient>,
|
||||
pub update_sender: mpsc::UnboundedSender<(Message, oneshot::Sender<anyhow::Result<()>>)>,
|
||||
repositories: Vec<Entity<Repository>>,
|
||||
active_index: Option<usize>,
|
||||
update_sender: mpsc::UnboundedSender<(Message, oneshot::Sender<anyhow::Result<()>>)>,
|
||||
_subscription: Subscription,
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ pub enum GitRepo {
|
|||
},
|
||||
}
|
||||
|
||||
enum Message {
|
||||
pub enum Message {
|
||||
Commit {
|
||||
git_repo: GitRepo,
|
||||
message: SharedString,
|
||||
|
@ -59,6 +59,7 @@ enum Message {
|
|||
},
|
||||
Stage(GitRepo, Vec<RepoPath>),
|
||||
Unstage(GitRepo, Vec<RepoPath>),
|
||||
SetIndexText(GitRepo, RepoPath, Option<String>),
|
||||
}
|
||||
|
||||
pub enum GitEvent {
|
||||
|
@ -291,11 +292,32 @@ impl GitState {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
Message::SetIndexText(git_repo, path, text) => match git_repo {
|
||||
GitRepo::Local(repo) => repo.set_index_text(&path, text),
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
client,
|
||||
worktree_id,
|
||||
work_directory_id,
|
||||
} => client.send(proto::SetIndexText {
|
||||
project_id: project_id.0,
|
||||
worktree_id: worktree_id.to_proto(),
|
||||
work_directory_id: work_directory_id.to_proto(),
|
||||
path: path.as_ref().to_proto(),
|
||||
text,
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GitRepo {}
|
||||
|
||||
impl Repository {
|
||||
pub fn git_state(&self) -> Option<Entity<GitState>> {
|
||||
self.git_state.upgrade()
|
||||
}
|
||||
|
||||
fn id(&self) -> (WorktreeId, ProjectEntryId) {
|
||||
(self.worktree_id, self.repository_entry.work_directory_id())
|
||||
}
|
||||
|
@ -522,4 +544,19 @@ impl Repository {
|
|||
.ok();
|
||||
result_rx
|
||||
}
|
||||
|
||||
pub fn set_index_text(
|
||||
&self,
|
||||
path: &RepoPath,
|
||||
content: Option<String>,
|
||||
) -> oneshot::Receiver<anyhow::Result<()>> {
|
||||
let (result_tx, result_rx) = futures::channel::oneshot::channel();
|
||||
self.update_sender
|
||||
.unbounded_send((
|
||||
Message::SetIndexText(self.git_repo.clone(), path.clone(), content),
|
||||
result_tx,
|
||||
))
|
||||
.ok();
|
||||
result_rx
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue