Tests demonstrating a similar bug with moved rather than deleted branch

This commit is contained in:
Ilya Grigoriev 2023-05-15 21:34:13 -07:00
parent a0ee2b0dbd
commit cf4a603eb4
2 changed files with 137 additions and 10 deletions

View file

@ -489,6 +489,124 @@ fn test_import_refs_reimport_with_deleted_remote_ref() {
assert_eq!(*view.heads(), expected_heads);
}
/// This test is nearly identical to the previous one, except the branches are
/// moved sideways instead of being deleted.
#[test]
fn test_import_refs_reimport_with_moved_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(dbg!(&commit_remote_only)),
jj_id(dbg!(&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 moved. This leads to the
// following import moving 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 new_commit_remote_only = empty_git_commit(
&git_repo,
"refs/remotes/origin/feature-remote-only",
&[&commit_base],
);
let new_commit_remote_and_local = empty_git_commit(
&git_repo,
"refs/remotes/origin/feature-remote-and-local",
&[&commit_base],
);
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();
assert_eq!(view.branches().len(), 3);
// The local branches are moved
assert_eq!(
view.branches().get("feature-remote-only"),
Some(&BranchTarget {
local_target: Some(RefTarget::Normal(jj_id(&new_commit_remote_only))),
remote_targets: btreemap! {
"origin".to_string() => RefTarget::Normal(jj_id(&new_commit_remote_only))
},
}),
);
assert_eq!(
view.branches().get("feature-remote-and-local"),
Some(&BranchTarget {
local_target: Some(RefTarget::Normal(jj_id(&new_commit_remote_and_local))),
remote_targets: btreemap! {
"origin".to_string() => RefTarget::Normal(jj_id(&new_commit_remote_and_local))
},
}),
);
view.branches().get("main").unwrap(); // branch #3 of 3
let expected_heads = hashset! {
jj_id(&commit_main),
jj_id(&new_commit_remote_and_local),
jj_id(&new_commit_remote_only),
// 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.
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.

View file

@ -234,36 +234,45 @@ fn test_git_colocated_conflicting_git_refs() {
}
#[test]
fn test_git_colocated_fetch_deleted_branch() {
fn test_git_colocated_fetch_deleted_or_moved_branch() {
let test_env = TestEnvironment::default();
let origin_path = test_env.env_root().join("origin");
git2::Repository::init(&origin_path).unwrap();
test_env.jj_cmd_success(&origin_path, &["init", "--git-repo=."]);
test_env.jj_cmd_success(&origin_path, &["describe", "-m=A"]);
test_env.jj_cmd_success(&origin_path, &["branch", "create", "A"]);
test_env.jj_cmd_success(&origin_path, &["new", "-m=B"]);
test_env.jj_cmd_success(&origin_path, &["branch", "create", "B"]);
test_env.jj_cmd_success(&origin_path, &["new", "-m=C"]);
test_env.jj_cmd_success(&origin_path, &["new", "-m=B_to_delete"]);
test_env.jj_cmd_success(&origin_path, &["branch", "create", "B_to_delete"]);
test_env.jj_cmd_success(&origin_path, &["new", "-m=original C", "@-"]);
test_env.jj_cmd_success(&origin_path, &["branch", "create", "C_to_move"]);
let clone_path = test_env.env_root().join("clone");
git2::Repository::clone(origin_path.to_str().unwrap(), &clone_path).unwrap();
test_env.jj_cmd_success(&clone_path, &["init", "--git-repo=."]);
test_env.jj_cmd_success(&clone_path, &["new", "A"]);
insta::assert_snapshot!(get_log_output(&test_env, &clone_path), @r###"
@ 1fa8b2e27c8c3da9764bda953dd81a06fb292d1a
e1f4268fabd2c84e880c5eb5bd87e076180fc8e3 B
@ 0335878796213c3a701f1c9c34dcae242bee4131
8d4e006fd63547965fbc3a26556a9aa531076d32 C_to_move
929e298ae9edf969b405a304c75c10457c47d52c B_to_delete
a86754f975f953fa25da4265764adc0c62e9ce6b A master HEAD@git
0000000000000000000000000000000000000000
"###);
test_env.jj_cmd_success(&origin_path, &["branch", "delete", "B"]);
test_env.jj_cmd_success(&origin_path, &["branch", "delete", "B_to_delete"]);
// Move branch C sideways
test_env.jj_cmd_success(&origin_path, &["describe", "C_to_move", "-m", "moved C"]);
let stdout = test_env.jj_cmd_success(&clone_path, &["git", "fetch"]);
insta::assert_snapshot!(stdout, @"");
// TODO: e1f4 should have been abandoned (#864)
// TODO: 929e and 8d4e should have been abandoned (#864)
insta::assert_snapshot!(get_log_output(&test_env, &clone_path), @r###"
@ 1fa8b2e27c8c3da9764bda953dd81a06fb292d1a
e1f4268fabd2c84e880c5eb5bd87e076180fc8e3
04fd29df05638156b20044b3b6136b42abcb09ab C_to_move
@ 0335878796213c3a701f1c9c34dcae242bee4131
8d4e006fd63547965fbc3a26556a9aa531076d32
929e298ae9edf969b405a304c75c10457c47d52c
a86754f975f953fa25da4265764adc0c62e9ce6b A master HEAD@git
0000000000000000000000000000000000000000