Fix replication of head text when head matches index (#24306)
Release Notes: - N/A --------- Co-authored-by: cole-miller <m@cole-miller.net>
This commit is contained in:
parent
59738f88c2
commit
b710945949
4 changed files with 126 additions and 5 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -10700,6 +10700,7 @@ dependencies = [
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
"telemetry_events",
|
"telemetry_events",
|
||||||
"toml 0.8.19",
|
"toml 0.8.19",
|
||||||
|
"unindent",
|
||||||
"util",
|
"util",
|
||||||
"worktree",
|
"worktree",
|
||||||
]
|
]
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl BufferChangeSetState {
|
||||||
let diff_bases_change = match mode {
|
let diff_bases_change = match mode {
|
||||||
Mode::HeadOnly => DiffBasesChange::SetHead(message.committed_text),
|
Mode::HeadOnly => DiffBasesChange::SetHead(message.committed_text),
|
||||||
Mode::IndexOnly => DiffBasesChange::SetIndex(message.staged_text),
|
Mode::IndexOnly => DiffBasesChange::SetIndex(message.staged_text),
|
||||||
Mode::IndexMatchesHead => DiffBasesChange::SetBoth(message.staged_text),
|
Mode::IndexMatchesHead => DiffBasesChange::SetBoth(message.committed_text),
|
||||||
Mode::IndexAndHead => DiffBasesChange::SetEach {
|
Mode::IndexAndHead => DiffBasesChange::SetEach {
|
||||||
index: message.staged_text,
|
index: message.staged_text,
|
||||||
head: message.committed_text,
|
head: message.committed_text,
|
||||||
|
@ -402,7 +402,7 @@ impl RemoteBufferStore {
|
||||||
.await?;
|
.await?;
|
||||||
let mode = Mode::from_i32(response.mode).ok_or_else(|| anyhow!("Invalid mode"))?;
|
let mode = Mode::from_i32(response.mode).ok_or_else(|| anyhow!("Invalid mode"))?;
|
||||||
let bases = match mode {
|
let bases = match mode {
|
||||||
Mode::IndexMatchesHead => DiffBasesChange::SetBoth(response.staged_text),
|
Mode::IndexMatchesHead => DiffBasesChange::SetBoth(response.committed_text),
|
||||||
Mode::IndexAndHead => DiffBasesChange::SetEach {
|
Mode::IndexAndHead => DiffBasesChange::SetEach {
|
||||||
head: response.committed_text,
|
head: response.committed_text,
|
||||||
index: response.staged_text,
|
index: response.staged_text,
|
||||||
|
@ -896,7 +896,7 @@ impl LocalBufferStore {
|
||||||
let diff_bases_change =
|
let diff_bases_change =
|
||||||
match (needs_staged_text, needs_committed_text) {
|
match (needs_staged_text, needs_committed_text) {
|
||||||
(true, true) => Some(if staged_text == committed_text {
|
(true, true) => Some(if staged_text == committed_text {
|
||||||
DiffBasesChange::SetBoth(staged_text)
|
DiffBasesChange::SetBoth(committed_text)
|
||||||
} else {
|
} else {
|
||||||
DiffBasesChange::SetEach {
|
DiffBasesChange::SetEach {
|
||||||
index: staged_text,
|
index: staged_text,
|
||||||
|
@ -944,7 +944,7 @@ impl LocalBufferStore {
|
||||||
(index, head, Mode::IndexAndHead)
|
(index, head, Mode::IndexAndHead)
|
||||||
}
|
}
|
||||||
DiffBasesChange::SetBoth(text) => {
|
DiffBasesChange::SetBoth(text) => {
|
||||||
(text, None, Mode::IndexMatchesHead)
|
(None, text, Mode::IndexMatchesHead)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let message = proto::UpdateDiffBases {
|
let message = proto::UpdateDiffBases {
|
||||||
|
|
|
@ -77,7 +77,7 @@ node_runtime = { workspace = true, features = ["test-support"] }
|
||||||
project = { workspace = true, features = ["test-support"] }
|
project = { workspace = true, features = ["test-support"] }
|
||||||
remote = { workspace = true, features = ["test-support"] }
|
remote = { workspace = true, features = ["test-support"] }
|
||||||
lsp = { workspace = true, features=["test-support"] }
|
lsp = { workspace = true, features=["test-support"] }
|
||||||
|
unindent.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -27,6 +27,7 @@ use std::{
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
use unindent::Unindent as _;
|
||||||
use util::{path, separator};
|
use util::{path, separator};
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
@ -1183,6 +1184,125 @@ async fn test_remote_rename_entry(cx: &mut TestAppContext, server_cx: &mut TestA
|
||||||
assert_eq!(worktree.entry_for_path("README.rst").unwrap().id, entry.id)
|
assert_eq!(worktree.entry_for_path("README.rst").unwrap().id, entry.id)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_remote_git_diffs(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
|
||||||
|
let text_2 = "
|
||||||
|
fn one() -> usize {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
"
|
||||||
|
.unindent();
|
||||||
|
let text_1 = "
|
||||||
|
fn one() -> usize {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
"
|
||||||
|
.unindent();
|
||||||
|
|
||||||
|
let fs = FakeFs::new(server_cx.executor());
|
||||||
|
fs.insert_tree(
|
||||||
|
"/code",
|
||||||
|
json!({
|
||||||
|
"project1": {
|
||||||
|
".git": {},
|
||||||
|
"src": {
|
||||||
|
"lib.rs": text_2
|
||||||
|
},
|
||||||
|
"README.md": "# project 1",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
fs.set_index_for_repo(
|
||||||
|
Path::new("/code/project1/.git"),
|
||||||
|
&[("src/lib.rs".into(), text_1.clone())],
|
||||||
|
);
|
||||||
|
fs.set_head_for_repo(
|
||||||
|
Path::new("/code/project1/.git"),
|
||||||
|
&[("src/lib.rs".into(), text_1.clone())],
|
||||||
|
);
|
||||||
|
|
||||||
|
let (project, _headless) = init_test(&fs, cx, server_cx).await;
|
||||||
|
let (worktree, _) = project
|
||||||
|
.update(cx, |project, cx| {
|
||||||
|
project.find_or_create_worktree("/code/project1", true, cx)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let worktree_id = cx.update(|cx| worktree.read(cx).id());
|
||||||
|
cx.executor().run_until_parked();
|
||||||
|
|
||||||
|
let buffer = project
|
||||||
|
.update(cx, |project, cx| {
|
||||||
|
project.open_buffer((worktree_id, Path::new("src/lib.rs")), cx)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let change_set = project
|
||||||
|
.update(cx, |project, cx| {
|
||||||
|
project.open_uncommitted_changes(buffer.clone(), cx)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
change_set.read_with(cx, |change_set, cx| {
|
||||||
|
assert_eq!(change_set.base_text_string().unwrap(), text_1);
|
||||||
|
assert_eq!(
|
||||||
|
change_set
|
||||||
|
.unstaged_change_set
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.read(cx)
|
||||||
|
.base_text_string()
|
||||||
|
.unwrap(),
|
||||||
|
text_1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// stage the current buffer's contents
|
||||||
|
fs.set_index_for_repo(
|
||||||
|
Path::new("/code/project1/.git"),
|
||||||
|
&[("src/lib.rs".into(), text_2.clone())],
|
||||||
|
);
|
||||||
|
|
||||||
|
cx.executor().run_until_parked();
|
||||||
|
change_set.read_with(cx, |change_set, cx| {
|
||||||
|
assert_eq!(change_set.base_text_string().unwrap(), text_1);
|
||||||
|
assert_eq!(
|
||||||
|
change_set
|
||||||
|
.unstaged_change_set
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.read(cx)
|
||||||
|
.base_text_string()
|
||||||
|
.unwrap(),
|
||||||
|
text_2
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// commit the current buffer's contents
|
||||||
|
fs.set_head_for_repo(
|
||||||
|
Path::new("/code/project1/.git"),
|
||||||
|
&[("src/lib.rs".into(), text_2.clone())],
|
||||||
|
);
|
||||||
|
|
||||||
|
cx.executor().run_until_parked();
|
||||||
|
change_set.read_with(cx, |change_set, cx| {
|
||||||
|
assert_eq!(change_set.base_text_string().unwrap(), text_2);
|
||||||
|
assert_eq!(
|
||||||
|
change_set
|
||||||
|
.unstaged_change_set
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.read(cx)
|
||||||
|
.base_text_string()
|
||||||
|
.unwrap(),
|
||||||
|
text_2
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_remote_git_branches(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
|
async fn test_remote_git_branches(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
|
||||||
let fs = FakeFs::new(server_cx.executor());
|
let fs = FakeFs::new(server_cx.executor());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue