lib/tests/test_git.rs: New test to demonstrate #864's root cause

This commit is contained in:
Ilya Grigoriev 2023-05-08 12:54:37 -07:00
parent bda3d3e50b
commit a0ee2b0dbd

View file

@ -398,6 +398,97 @@ fn test_import_refs_reimport_git_head_with_moved_ref() {
assert!(tx.mut_repo().view().heads().contains(commit2.id()));
}
#[test]
fn test_import_refs_reimport_with_deleted_remote_ref() {
let settings = testutils::user_settings();
let git_settings = GitSettings::default();
let test_workspace = TestRepo::init(true);
let repo = &test_workspace.repo;
let git_repo = get_git_repo(repo);
let commit_base = empty_git_commit(&git_repo, "refs/heads/main", &[]);
let commit_main = empty_git_commit(&git_repo, "refs/heads/main", &[&commit_base]);
let commit_remote_only = empty_git_commit(
&git_repo,
"refs/remotes/origin/feature-remote-only",
&[&commit_base],
);
let commit_remote_and_local = empty_git_commit(
&git_repo,
"refs/remotes/origin/feature-remote-and-local",
&[&commit_base],
);
git_ref(
&git_repo,
"refs/heads/feature-remote-and-local",
commit_remote_and_local.id(),
);
let mut tx = repo.start_transaction(&settings, "test");
git::import_refs(tx.mut_repo(), &git_repo, &git_settings).unwrap();
tx.mut_repo().rebase_descendants(&settings).unwrap();
let repo = tx.commit();
let expected_heads = hashset! {
jj_id(&commit_main),
jj_id(&commit_remote_only),
jj_id(&commit_remote_and_local),
};
let view = repo.view();
assert_eq!(*view.heads(), expected_heads);
assert_eq!(view.branches().len(), 3);
assert_eq!(
view.branches().get("feature-remote-only"),
Some(&BranchTarget {
// Even though the git repo does not have a local branch for `feature-remote-only`, jj
// creates one. This follows the model explained in docs/branches.md.
local_target: Some(RefTarget::Normal(jj_id(&commit_remote_only))),
remote_targets: btreemap! {
"origin".to_string() => RefTarget::Normal(jj_id(&commit_remote_only))
},
}),
);
assert_eq!(
view.branches().get("feature-remote-and-local"),
Some(&BranchTarget {
local_target: Some(RefTarget::Normal(jj_id(&commit_remote_and_local))),
remote_targets: btreemap! {
"origin".to_string() => RefTarget::Normal(jj_id(&commit_remote_and_local))
},
}),
);
view.branches().get("main").unwrap(); // branch #3 of 3
// Simulate fetching from a remote where feature-remote-only and
// feature-remote-and-local branches were deleted. This leads to the
// following import deleting the corresponding local branches.
delete_git_ref(&git_repo, "refs/remotes/origin/feature-remote-only");
delete_git_ref(&git_repo, "refs/remotes/origin/feature-remote-and-local");
let mut tx = repo.start_transaction(&settings, "test");
git::import_refs(tx.mut_repo(), &git_repo, &git_settings).unwrap();
tx.mut_repo().rebase_descendants(&settings).unwrap();
let repo = tx.commit();
let view = repo.view();
// The local branches were indeed deleted
assert_eq!(view.branches().len(), 1);
view.branches().get("main").unwrap(); // branch #1 of 1
assert_eq!(view.branches().get("feature-remote-local"), None);
assert_eq!(view.branches().get("feature-remote-and-local"), None);
let expected_heads = hashset! {
jj_id(&commit_main),
// Neither commit_remote_only nor commit_remote_and_local should be
// listed as a head. commit_remote_only was never affected by #864,
// but commit_remote_and_local is.
// BUG: commit_remote_and_local is still listed as a head (#864)
// even though the feature-remote branch was deleted as we'll see
// below.
jj_id(&commit_remote_and_local),
};
assert_eq!(*view.heads(), expected_heads);
}
#[test]
fn test_import_refs_reimport_git_head_with_fixed_ref() {
// Simulate external `git checkout` in colocated repo, from named branch.