git: skip branches on root commit on export

Git doesn't have a root commit, so we should skip branches pointing to
it on export, just like we do with conflicted branches (which Git also
doesn't support).
This commit is contained in:
Martin von Zweigbergk 2023-09-03 14:11:00 -07:00 committed by Martin von Zweigbergk
parent 4ea6b4a75b
commit f198a1e5f9
2 changed files with 35 additions and 2 deletions

View File

@ -395,6 +395,8 @@ pub enum FailedRefExportReason {
/// The ref was in a conflicted state from the last import. A re-import
/// should fix it.
ConflictedOldState,
/// The branch points to the root commit, which Git doesn't have
OnRootCommit,
/// We wanted to delete it, but it had been modified in Git.
DeletedInJjModifiedInGit,
/// We wanted to add it, but Git had added it with a different target
@ -435,6 +437,7 @@ pub fn export_some_refs(
let mut branches_to_update = BTreeMap::new();
let mut branches_to_delete = BTreeMap::new();
let mut failed_branches = vec![];
let root_commit_target = RefTarget::normal(mut_repo.store().root_commit_id().clone());
let view = mut_repo.view();
let jj_repo_iter_all_branches = view.branches().iter().flat_map(|(branch, target)| {
itertools::chain(
@ -483,6 +486,14 @@ pub fn export_some_refs(
if new_branch == old_branch {
continue;
}
if *new_branch == root_commit_target {
// Git doesn't have a root commit
failed_branches.push(FailedRefExport {
name: jj_known_ref,
reason: FailedRefExportReason::OnRootCommit,
});
continue;
}
let old_oid = if let Some(id) = old_branch.as_normal() {
Some(Oid::from_bytes(id.as_bytes()).unwrap())
} else if old_branch.has_conflict() {

View File

@ -27,8 +27,8 @@ use jj_lib::commit::Commit;
use jj_lib::commit_builder::CommitBuilder;
use jj_lib::git;
use jj_lib::git::{
FailedRefExportReason, GitFetchError, GitImportError, GitPushError, GitRefUpdate,
SubmoduleConfig,
FailedRefExport, FailedRefExportReason, GitFetchError, GitImportError, GitPushError,
GitRefUpdate, SubmoduleConfig,
};
use jj_lib::git_backend::GitBackend;
use jj_lib::op_store::{BranchTarget, RefTarget};
@ -1332,6 +1332,28 @@ fn test_export_conflicts() {
);
}
#[test]
fn test_export_branch_on_root_commit() {
// We skip export of branches pointing to the root commit
let test_data = GitRepoData::create();
let git_repo = test_data.git_repo;
let mut tx = test_data
.repo
.start_transaction(&test_data.settings, "test");
let mut_repo = tx.mut_repo();
mut_repo.set_local_branch_target(
"on_root",
RefTarget::normal(mut_repo.store().root_commit_id().clone()),
);
assert_eq!(
git::export_refs(mut_repo, &git_repo),
Ok(vec![FailedRefExport {
name: RefName::LocalBranch("on_root".to_string()),
reason: FailedRefExportReason::OnRootCommit,
}])
);
}
#[test]
fn test_export_partial_failure() {
// Check that we skip branches that fail to export