fix: ensure that the entry is already available after remote restore

The `RestoreProjectEntryResponse` was simply returning the `entry_id`,
instead of the whole entry information. On the
`RemoteWorktree::restore_worktree` side, the `entry_id` was being used
to obtain the entry, so as to then insert the proto entry, using
`RemoteWorktree::insert_entry`.

Unfortunately, this could lead to panics, for example:

1. Create a new file
2. Undo, which will trash file
3. Redo, which will restore the file

As far as I can tell, this was happening because the `RemoteWorktree`
wasn't yet updated on our end, so there wasn't actually an entry being
returned for `RemoteWorktree::entry_for_id`. As such, this commit
updates the `entry_id` field, and type, in `RestoreProjectEntryResponse`
to the actual `Entry` data, just like in `ProjectEntryResponse`.
This commit is contained in:
dino
2026-04-17 16:22:36 +01:00
parent 06f1fa9af5
commit 34a7355b22
4 changed files with 12 additions and 18 deletions
+1 -1
View File
@@ -2856,7 +2856,7 @@ impl Fs for FakeFs {
.lock()
.trash
.lock()
.insert((trashed_entry.clone(), fake_entry));
.insert((trashed_entry, fake_entry));
Ok(trash_id)
}
+1 -1
View File
@@ -2620,7 +2620,7 @@ impl Project {
Ok(ProjectPath {
worktree_id: worktree_id,
path: entry.path.clone(),
path: entry.path,
})
})
}
+1 -1
View File
@@ -161,7 +161,7 @@ message TrashProjectEntryResponse {
}
message RestoreProjectEntryResponse {
uint64 entry_id = 1;
Entry entry = 1;
uint64 worktree_scan_id = 2;
}
+9 -15
View File
@@ -1062,7 +1062,7 @@ impl Worktree {
let entry = task.await?;
Ok(proto::RestoreProjectEntryResponse {
entry_id: entry.id.to_proto(),
entry: Some(proto::Entry::from(&entry)),
worktree_scan_id: scan_id as u64,
})
}
@@ -2261,21 +2261,15 @@ impl RemoteWorktree {
cx.spawn(async move |this, cx| {
let response = request.await?;
let scan_id = response.worktree_scan_id as usize;
let entry_id = ProjectEntryId(response.entry_id as usize);
let proto_entry = response.entry.context("Missing entry in in response")?;
let (task, entry) = this.update(cx, |worktree, cx| {
// TODO!(dino): Remove `entry_for_id(entry_id).unwrap()` call,
// avoid unwrapping.
let remote_worktree = worktree.as_remote_mut().unwrap();
let entry = remote_worktree.entry_for_id(entry_id).unwrap().clone();
let proto_entry = proto::Entry::from(&entry);
let task = remote_worktree.insert_entry(proto_entry, scan_id, cx);
(task, entry)
})?;
task.await?;
Ok(entry)
this.update(cx, move |worktree, cx| {
worktree
.as_remote_mut()
.unwrap()
.insert_entry(proto_entry, scan_id, cx)
})?
.await
})
}