feat: edit working-checkout comparisons with normal editor actions
This commit is contained in:
+123
-15
@@ -237,9 +237,15 @@ fn git_working_reads_disk_and_handles_ranges_ignored_files_binary_links_and_odd_
|
||||
&& r.category == Category::Tags
|
||||
&& r.target == RevisionTarget::Commit(id.clone())));
|
||||
let comparison = repository
|
||||
.compare(&revision(&id, RepoKind::Git), &working(RepoKind::Git))
|
||||
.compare(&revision(&id, RepoKind::Git), &working(RepoKind::Git), &[])
|
||||
.unwrap();
|
||||
let text = changed(&comparison, Path::new("text"));
|
||||
assert_eq!(comparison.root, fs::canonicalize(&root).unwrap());
|
||||
assert!(comparison.editable_paths.contains(Path::new("text")));
|
||||
assert!(comparison.editable_paths.contains(Path::new("empty-added")));
|
||||
for path in ["binary", "link", "removed", "type-switch"] {
|
||||
assert!(!comparison.editable_paths.contains(Path::new(path)));
|
||||
}
|
||||
assert_eq!(text.after, ["one", "two", "three"]);
|
||||
assert_eq!(
|
||||
(
|
||||
@@ -338,15 +344,16 @@ fn git_working_reads_disk_and_handles_ranges_ignored_files_binary_links_and_odd_
|
||||
assert_eq!(moved.before, moved.after);
|
||||
assert!(moved.hunks.is_empty());
|
||||
let reverse = repository
|
||||
.compare(&working(RepoKind::Git), &revision(&id, RepoKind::Git))
|
||||
.compare(&working(RepoKind::Git), &revision(&id, RepoKind::Git), &[])
|
||||
.unwrap();
|
||||
assert!(reverse.editable_paths.is_empty());
|
||||
assert_eq!(
|
||||
changed(&reverse, Path::new("added")).status,
|
||||
FileStatus::Removed
|
||||
);
|
||||
assert!(
|
||||
repository
|
||||
.compare(&working(RepoKind::Git), &working(RepoKind::Git))
|
||||
.compare(&working(RepoKind::Git), &working(RepoKind::Git), &[])
|
||||
.unwrap()
|
||||
.files
|
||||
.is_empty()
|
||||
@@ -433,17 +440,22 @@ fn git_remote_refs_and_annotated_tags_are_discovered_before_fetch_and_history_st
|
||||
.success()
|
||||
);
|
||||
let comparison = repository
|
||||
.compare(&revision(&local, RepoKind::Git), &remote)
|
||||
.compare(
|
||||
&revision(&local, RepoKind::Git),
|
||||
&remote,
|
||||
&[(active.join("file"), "unsaved local text\n".into())],
|
||||
)
|
||||
.unwrap();
|
||||
assert!(comparison.editable_paths.is_empty());
|
||||
assert_eq!(changed(&comparison, Path::new("file")).before, ["local"]);
|
||||
assert_eq!(
|
||||
changed(&comparison, Path::new("file")).after,
|
||||
["remote tip"]
|
||||
);
|
||||
let comparison = repository.compare(&tag, &remote).unwrap();
|
||||
let comparison = repository.compare(&tag, &remote, &[]).unwrap();
|
||||
assert_eq!(changed(&comparison, Path::new("file")).before, ["ancestor"]);
|
||||
let comparison = repository
|
||||
.compare(&remote, &working(RepoKind::Git))
|
||||
.compare(&remote, &working(RepoKind::Git), &[])
|
||||
.unwrap();
|
||||
assert_eq!(changed(&comparison, Path::new("file")).after, ["local"]);
|
||||
let loaded = repository.fetch_remote("origin").unwrap();
|
||||
@@ -457,7 +469,7 @@ fn git_remote_refs_and_annotated_tags_are_discovered_before_fetch_and_history_st
|
||||
assert_eq!(historic.label, ancestor);
|
||||
assert_eq!(historic.description, "remote ancestor needle");
|
||||
let comparison = repository
|
||||
.compare(historic, &revision(&local, RepoKind::Git))
|
||||
.compare(historic, &revision(&local, RepoKind::Git), &[])
|
||||
.unwrap();
|
||||
assert_eq!(changed(&comparison, Path::new("file")).before, ["ancestor"]);
|
||||
assert!(
|
||||
@@ -530,7 +542,7 @@ fn jj_catalog_and_working_comparisons_prefer_jj_and_never_snapshot_or_merge_oper
|
||||
.any(|r| r.label == "baseline" && r.category == Category::Bookmarks)
|
||||
);
|
||||
let comparison = repository
|
||||
.compare(baseline, &working(RepoKind::Jujutsu))
|
||||
.compare(baseline, &working(RepoKind::Jujutsu), &[])
|
||||
.unwrap();
|
||||
assert_eq!(changed(&comparison, Path::new("file")).after, ["disk"]);
|
||||
assert_eq!(
|
||||
@@ -652,7 +664,7 @@ fn jj_private_fetch_discovers_never_fetched_bookmark_and_searchable_remote_chang
|
||||
.any(|r| r.target == RevisionTarget::Commit(ancestor.clone()))
|
||||
);
|
||||
let comparison = repository
|
||||
.compare(&remote, &working(RepoKind::Jujutsu))
|
||||
.compare(&remote, &working(RepoKind::Jujutsu), &[])
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
changed(&comparison, Path::new("file")).before,
|
||||
@@ -670,7 +682,7 @@ fn jj_private_fetch_discovers_never_fetched_bookmark_and_searchable_remote_chang
|
||||
.unwrap();
|
||||
assert!(historic.label.contains(&ancestor) && historic.label.contains(&change));
|
||||
assert_eq!(historic.description, "remote historic needle");
|
||||
let comparison = repository.compare(historic, &remote).unwrap();
|
||||
let comparison = repository.compare(historic, &remote, &[]).unwrap();
|
||||
assert_eq!(
|
||||
changed(&comparison, Path::new("file")).before,
|
||||
["remote ancestor"]
|
||||
@@ -733,7 +745,11 @@ fn errors_are_explicit_and_do_not_modify_active_repository() {
|
||||
);
|
||||
assert!(
|
||||
repository
|
||||
.compare(&revision("--bad", RepoKind::Git), &working(RepoKind::Git))
|
||||
.compare(
|
||||
&revision("--bad", RepoKind::Git),
|
||||
&working(RepoKind::Git),
|
||||
&[]
|
||||
)
|
||||
.unwrap_err()
|
||||
.contains("Invalid immutable commit")
|
||||
);
|
||||
@@ -741,7 +757,8 @@ fn errors_are_explicit_and_do_not_modify_active_repository() {
|
||||
repository
|
||||
.compare(
|
||||
&revision(&"f".repeat(40), RepoKind::Git),
|
||||
&working(RepoKind::Git)
|
||||
&working(RepoKind::Git),
|
||||
&[],
|
||||
)
|
||||
.unwrap_err()
|
||||
.contains("unavailable")
|
||||
@@ -752,7 +769,7 @@ fn errors_are_explicit_and_do_not_modify_active_repository() {
|
||||
};
|
||||
assert!(
|
||||
repository
|
||||
.compare(&loader, &revision(&id, RepoKind::Git))
|
||||
.compare(&loader, &revision(&id, RepoKind::Git), &[])
|
||||
.unwrap_err()
|
||||
.contains("history loader")
|
||||
);
|
||||
@@ -792,7 +809,11 @@ fn unchanged_submodules_are_not_false_changes_and_changed_pointers_are_explicit(
|
||||
let mut repository = open(&root);
|
||||
assert!(
|
||||
repository
|
||||
.compare(&revision(&baseline, RepoKind::Git), &working(RepoKind::Git))
|
||||
.compare(
|
||||
&revision(&baseline, RepoKind::Git),
|
||||
&working(RepoKind::Git),
|
||||
&[]
|
||||
)
|
||||
.unwrap()
|
||||
.files
|
||||
.is_empty()
|
||||
@@ -804,7 +825,11 @@ fn unchanged_submodules_are_not_false_changes_and_changed_pointers_are_explicit(
|
||||
git(&root.join("nested"), &["checkout", "--detach", &second]);
|
||||
let state = disk_state(&root);
|
||||
let comparison = repository
|
||||
.compare(&revision(&baseline, RepoKind::Git), &working(RepoKind::Git))
|
||||
.compare(
|
||||
&revision(&baseline, RepoKind::Git),
|
||||
&working(RepoKind::Git),
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
let submodule = changed(&comparison, Path::new("nested"));
|
||||
assert_eq!(submodule.status, FileStatus::Modified);
|
||||
@@ -876,6 +901,7 @@ fn multiple_remotes_retain_tag_only_history_even_when_tag_names_collide() {
|
||||
.compare(
|
||||
&revision(&ids[0], RepoKind::Git),
|
||||
&revision(&ids[1], RepoKind::Git),
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(changed(&comparison, Path::new("file")).before, ["one"]);
|
||||
@@ -989,6 +1015,7 @@ fn jj_conflicted_revisions_show_cli_projection_and_keep_ordinary_files_navigable
|
||||
.compare(
|
||||
&revision(&base, RepoKind::Jujutsu),
|
||||
&revision(&merged, RepoKind::Jujutsu),
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
let conflict = changed(&comparison, Path::new("conflict"));
|
||||
@@ -1009,6 +1036,7 @@ fn jj_conflicted_revisions_show_cli_projection_and_keep_ordinary_files_navigable
|
||||
.compare(
|
||||
&revision(&merged, RepoKind::Jujutsu),
|
||||
&working(RepoKind::Jujutsu),
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
assert!(
|
||||
@@ -1020,3 +1048,83 @@ fn jj_conflicted_revisions_show_cli_projection_and_keep_ordinary_files_navigable
|
||||
);
|
||||
assert_eq!(disk_state(&root), state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsaved_overlays_are_working_after_only_and_cannot_follow_nonregular_paths() {
|
||||
let fixture = Fixture::new();
|
||||
let root = fs::canonicalize(fixture.dir("overlay")).unwrap();
|
||||
init_git(&root);
|
||||
fs::create_dir(root.join("sub")).unwrap();
|
||||
fs::write(root.join("file"), "base\n").unwrap();
|
||||
fs::write(root.join("sub/file"), "nested\n").unwrap();
|
||||
fs::write(root.join("binary"), b"\0binary").unwrap();
|
||||
git(&root, &["add", "."]);
|
||||
git(&root, &["commit", "-m", "base"]);
|
||||
let id = git(&root, &["rev-parse", "HEAD"]);
|
||||
let outside = fixture.dir("outside");
|
||||
fs::write(outside.join("file"), "outside\n").unwrap();
|
||||
symlink(&outside, root.join("linked")).unwrap();
|
||||
symlink("file", root.join("link")).unwrap();
|
||||
let state = disk_state(&root);
|
||||
let buffers = vec![
|
||||
(root.join("file"), "unsaved\n".into()),
|
||||
(root.join("binary"), "not binary\n".into()),
|
||||
(root.join("missing"), "not on disk\n".into()),
|
||||
(root.join("link"), "not a regular file\n".into()),
|
||||
(root.join("linked/file"), "outside via link\n".into()),
|
||||
(outside.join("file"), "outside\n".into()),
|
||||
(root.join("sub/../../outside/file"), "escaped\n".into()),
|
||||
(root.join(".git/config"), "metadata\n".into()),
|
||||
];
|
||||
let mut repository = open(&root.join("sub"));
|
||||
let base = revision(&id, RepoKind::Git);
|
||||
let checkout = working(RepoKind::Git);
|
||||
let comparison = repository.compare(&base, &checkout, &buffers).unwrap();
|
||||
assert_eq!(comparison.root, fs::canonicalize(&root).unwrap());
|
||||
assert_eq!(changed(&comparison, Path::new("file")).after, ["unsaved"]);
|
||||
assert!(comparison.editable_paths.contains(Path::new("file")));
|
||||
for path in [
|
||||
"binary",
|
||||
"missing",
|
||||
"link",
|
||||
"linked",
|
||||
"linked/file",
|
||||
".git/config",
|
||||
] {
|
||||
assert!(!comparison.editable_paths.contains(Path::new(path)));
|
||||
}
|
||||
assert!(
|
||||
!comparison
|
||||
.files
|
||||
.iter()
|
||||
.any(|file| file.path == Path::new("binary")
|
||||
|| file.path == Path::new("missing")
|
||||
|| file.path == Path::new("linked/file"))
|
||||
);
|
||||
let immutable = repository.compare(&checkout, &base, &buffers).unwrap();
|
||||
assert!(immutable.editable_paths.is_empty());
|
||||
assert!(
|
||||
!immutable
|
||||
.files
|
||||
.iter()
|
||||
.any(|file| file.path == Path::new("file"))
|
||||
);
|
||||
assert!(
|
||||
repository
|
||||
.compare(&base, &base, &buffers)
|
||||
.unwrap()
|
||||
.files
|
||||
.is_empty()
|
||||
);
|
||||
let same_checkout = repository.compare(&checkout, &checkout, &buffers).unwrap();
|
||||
assert_eq!(changed(&same_checkout, Path::new("file")).before, ["base"]);
|
||||
assert_eq!(
|
||||
changed(&same_checkout, Path::new("file")).after,
|
||||
["unsaved"]
|
||||
);
|
||||
assert_eq!(disk_state(&root), state);
|
||||
assert_eq!(
|
||||
fs::read_to_string(outside.join("file")).unwrap(),
|
||||
"outside\n"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user