git: on import, only add ref target as head if target changed (#44)

If you import Git refs, then rebase a commit pointed to by some Git
ref, and then re-import Git refs, you don't want the old commit to be
made a visible head again. That's particularly annoying when Git refs
are automatically updated by every command.
This commit is contained in:
Martin von Zweigbergk 2021-12-05 12:15:53 -08:00
parent 63d1a87ef3
commit ccfaf0f601
2 changed files with 24 additions and 3 deletions

View File

@ -83,14 +83,14 @@ pub fn import_refs(
} }
}; };
let id = CommitId::from_bytes(git_commit.id().as_bytes()); let id = CommitId::from_bytes(git_commit.id().as_bytes());
let commit = store.get_commit(&id).unwrap();
mut_repo.add_head(&commit);
// TODO: Make it configurable which remotes are publishing and update public // TODO: Make it configurable which remotes are publishing and update public
// heads here. // heads here.
mut_repo.set_git_ref(full_name.clone(), RefTarget::Normal(id.clone())); mut_repo.set_git_ref(full_name.clone(), RefTarget::Normal(id.clone()));
let old_target = existing_git_refs.remove(&full_name); let old_target = existing_git_refs.remove(&full_name);
let new_target = Some(RefTarget::Normal(id)); let new_target = Some(RefTarget::Normal(id.clone()));
if new_target != old_target { if new_target != old_target {
let commit = store.get_commit(&id).unwrap();
mut_repo.add_head(&commit);
changed_git_refs.insert(full_name, (old_target, new_target)); changed_git_refs.insert(full_name, (old_target, new_target));
} }
} }

View File

@ -236,6 +236,27 @@ fn test_import_refs_reimport() {
); );
} }
#[test]
fn test_import_refs_reimport_head_removed() {
// Test that re-importing refs doesn't cause a deleted head to come back
let settings = testutils::user_settings();
let test_workspace = testutils::init_repo(&settings, true);
let repo = &test_workspace.repo;
let git_repo = repo.store().git_repo().unwrap();
let commit = empty_git_commit(&git_repo, "refs/heads/main", &[]);
let mut tx = repo.start_transaction("test");
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
let commit_id = CommitId::from_bytes(commit.id().as_bytes());
// Test the setup
assert!(tx.mut_repo().view().heads().contains(&commit_id));
// Remove the head and re-import
tx.mut_repo().remove_head(&commit_id);
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
assert!(!tx.mut_repo().view().heads().contains(&commit_id));
}
fn git_ref(git_repo: &git2::Repository, name: &str, target: Oid) { fn git_ref(git_repo: &git2::Repository, name: &str, target: Oid) {
git_repo.reference(name, target, true, "").unwrap(); git_repo.reference(name, target, true, "").unwrap();
} }