fs: a rename of the open file itself no longer drops the staged write
The pending commit moved to `to.join("")`, which has a trailing slash, so
the commit rename failed and the staged file was deleted.
This commit is contained in:
+5
-1
@@ -339,8 +339,12 @@ impl HostDescriptor for ActorFs<'_> {
|
|||||||
HostDescriptor::rename_at(&mut self.inner, fd, old_path, new_fd, new_path).await?;
|
HostDescriptor::rename_at(&mut self.inner, fd, old_path, new_fd, new_path).await?;
|
||||||
// Open writes and directories below a renamed folder move with it.
|
// Open writes and directories below a renamed folder move with it.
|
||||||
if let Some((from, to)) = moved {
|
if let Some((from, to)) = moved {
|
||||||
|
// `join("")` would add a trailing slash, so a renamed file itself
|
||||||
|
// needs its own case.
|
||||||
let rebase = |p: &mut PathBuf| {
|
let rebase = |p: &mut PathBuf| {
|
||||||
if let Ok(rest) = p.strip_prefix(&from) {
|
if *p == from {
|
||||||
|
*p = to.clone();
|
||||||
|
} else if let Ok(rest) = p.strip_prefix(&from) {
|
||||||
*p = to.join(rest);
|
*p = to.join(rest);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -776,6 +776,21 @@ async fn close_commits_open_file_after_parent_directory_rename() {
|
|||||||
host.stop().await;
|
host.stop().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn close_commits_a_staged_write_after_the_file_itself_is_renamed() {
|
||||||
|
let (_, host, mut mailbox) = filesystem_world("rename-staged-file").await;
|
||||||
|
let write = json!({"type": "write", "path": "/data/x", "text": "old"});
|
||||||
|
ask_type(&host, &mut mailbox, "writer", write, "ok").await;
|
||||||
|
let open = json!({"type": "open-truncate", "path": "/data/x", "text": "new"});
|
||||||
|
ask_type(&host, &mut mailbox, "writer", open, "opened").await;
|
||||||
|
let rename = json!({"type": "rename", "path": "/data/x", "to": "/data/x.renamed"});
|
||||||
|
ask_type(&host, &mut mailbox, "writer", rename, "ok").await;
|
||||||
|
ask_type(&host, &mut mailbox, "writer", json!({"type": "close", "path": "/data/x"}), "closed").await;
|
||||||
|
let read = json!({"type": "read", "path": "/data/x.renamed"});
|
||||||
|
assert_eq!(ask_type(&host, &mut mailbox, "writer", read, "content").await.body["text"], "new");
|
||||||
|
host.stop().await;
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn truncate_without_create_commits_existing_file_on_close() {
|
async fn truncate_without_create_commits_existing_file_on_close() {
|
||||||
let (_, host, mut mailbox) = filesystem_world("truncate-without-create").await;
|
let (_, host, mut mailbox) = filesystem_world("truncate-without-create").await;
|
||||||
|
|||||||
Reference in New Issue
Block a user