Skip to content

Commit

Permalink
git: on implicit git export, use original view as source of git refs …
Browse files Browse the repository at this point in the history
…(PoC)

(Partially?) fixes jj-vcs#922
  • Loading branch information
yuja committed Apr 20, 2023
1 parent 6445cce commit 002962e
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 15 deletions.
25 changes: 17 additions & 8 deletions lib/src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<Vec<String>, 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<Vec<String>, 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;
}
Expand Down
4 changes: 3 additions & 1 deletion src/cli_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 2 additions & 6 deletions tests/test_git_colocated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
"###);
}
Expand Down

0 comments on commit 002962e

Please sign in to comment.