diff --git a/lib/src/git.rs b/lib/src/git.rs index 6ddcc87e34..1a64bf8466 100644 --- a/lib/src/git.rs +++ b/lib/src/git.rs @@ -26,7 +26,7 @@ use crate::git_backend::NO_GC_REF_NAMESPACE; use crate::op_store::RefTarget; use crate::repo::{MutableRepo, Repo}; use crate::settings::GitSettings; -use crate::view::RefName; +use crate::view::{RefName, View}; #[derive(Error, Debug, PartialEq)] pub enum GitImportError { @@ -215,28 +215,37 @@ pub enum GitExportError { InternalGitError(#[from] git2::Error), } +// XXX: clean up API, maybe update all callers to pass old_view = None? +pub fn export_refs( + mut_repo: &mut MutableRepo, + git_repo: &git2::Repository, +) -> Result, GitExportError> { + export_refs2(mut_repo, git_repo, None) +} + /// Reflect changes made in the Jujutsu repo compared to our current view of the /// Git repo in `mut_repo.view().git_refs()`. Returns a list of names of /// branches that failed to export. // TODO: Also indicate why we failed to export these branches -pub fn export_refs( +pub fn export_refs2( mut_repo: &mut MutableRepo, git_repo: &git2::Repository, + maybe_old_view: Option<&View>, ) -> Result, GitExportError> { - // First find the changes we want need to make without modifying mut_repo let mut branches_to_update = BTreeMap::new(); let mut branches_to_delete = BTreeMap::new(); let mut failed_branches = vec![]; - let view = mut_repo.view(); - let all_branch_names: HashSet<&str> = view + let old_view = maybe_old_view.unwrap_or(mut_repo.view()); + let new_view = mut_repo.view(); + let all_branch_names: HashSet<&str> = old_view .git_refs() .keys() .filter_map(|git_ref| git_ref.strip_prefix("refs/heads/")) - .chain(view.branches().keys().map(AsRef::as_ref)) + .chain(new_view.branches().keys().map(AsRef::as_ref)) .collect(); for branch_name in all_branch_names { - let old_branch = view.get_git_ref(&format!("refs/heads/{branch_name}")); - let new_branch = view.get_local_branch(branch_name); + let old_branch = old_view.get_git_ref(&format!("refs/heads/{branch_name}")); + let new_branch = new_view.get_local_branch(branch_name); if new_branch == old_branch { continue; } diff --git a/src/cli_util.rs b/src/cli_util.rs index f06adb92c6..480f69b109 100644 --- a/src/cli_util.rs +++ b/src/cli_util.rs @@ -1073,8 +1073,10 @@ impl WorkspaceCommandHelper { } if self.working_copy_shared_with_git { self.export_head_to_git(mut_repo)?; + // Use the original view as the source of truth of the git repo. + let old_view = self.repo().view(); let git_repo = self.repo.store().git_repo().unwrap(); - let failed_branches = git::export_refs(mut_repo, &git_repo)?; + let failed_branches = git::export_refs2(mut_repo, &git_repo, Some(old_view))?; print_failed_git_export(ui, &failed_branches)?; } let maybe_old_commit = tx diff --git a/tests/test_git_colocated.rs b/tests/test_git_colocated.rs index 1cc6f90c13..ef9de7fbf7 100644 --- a/tests/test_git_colocated.rs +++ b/tests/test_git_colocated.rs @@ -287,13 +287,9 @@ fn test_git_colocated_squash_undo() { ◉ zzzzzzzzzzzz 000000000000 "###); test_env.jj_cmd_success(&repo_path, &["undo"]); - // TODO: There should be no divergence here; 2f376ea1478c should be hidden - // (#922) insta::assert_snapshot!(get_log_output_divergence(&test_env, &repo_path), @r###" - ◉ qpvuntsmwlqt 2f376ea1478c A master !divergence! - │ @ rlvkpnrzqnoo 8f71e3b6a3be - │ ◉ qpvuntsmwlqt a86754f975f9 A !divergence! - ├─╯ + @ rlvkpnrzqnoo 8f71e3b6a3be + ◉ qpvuntsmwlqt a86754f975f9 A master ◉ zzzzzzzzzzzz 000000000000 "###); }