From e7e49527efdfddf3eb29ce21e79b056c71c873d6 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Mon, 7 Aug 2023 19:48:55 +0900 Subject: [PATCH] git: ensure that remote branches never diverge I was considering how refs would be imported if we had a per-remote view of named branches (and tags): Each remote has a view, and jj remembers the last known view state to compute diffs. That's the same for the pseudo "git" remote. Under the current storage, these view states are represented as follows: git_refs["refs/heads/{name}"] # pseudo "git" remote branches git_refs["refs/tags/{name}"] # pseudo "git" remote tags git_refs["refs/remotes/{remote}/{name}"] # real remote branches and the diffs are merged in to branches[name].local_target and tags[name]. We also have branches[name].remote_targets[remote], but I think it's redundant because a tracking branch should also be the last known state, not something that can diverge from the actual state. To make that clear, this commit replaces the use of the "merge" API. --- lib/src/git.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/src/git.rs b/lib/src/git.rs index 29d9e8ff1..0b18f83b1 100644 --- a/lib/src/git.rs +++ b/lib/src/git.rs @@ -221,15 +221,18 @@ pub fn import_some_refs( // Apply the change that happened in git since last time we imported refs let full_name = to_git_ref_name(ref_name).unwrap(); mut_repo.set_git_ref_target(&full_name, new_git_target.clone()); - mut_repo.merge_single_ref(ref_name, old_git_target, new_git_target); - // If a git remote-tracking branch changed, apply the change to the local branch - // as well - if !git_settings.auto_local_branch { - continue; - } - if let RefName::RemoteBranch { branch, remote: _ } = ref_name { - let local_ref_name = RefName::LocalBranch(branch.clone()); - mut_repo.merge_single_ref(&local_ref_name, old_git_target, new_git_target); + if let RefName::RemoteBranch { branch, remote } = ref_name { + // Remote-tracking branch is the last known state of the branch in the remote. + // It shouldn't diverge even if we had inconsistent view. + mut_repo.set_remote_branch_target(branch, remote, new_git_target.clone()); + // If a git remote-tracking branch changed, apply the change to the local branch + // as well. + if git_settings.auto_local_branch { + let local_ref_name = RefName::LocalBranch(branch.clone()); + mut_repo.merge_single_ref(&local_ref_name, old_git_target, new_git_target); + } + } else { + mut_repo.merge_single_ref(ref_name, old_git_target, new_git_target); } }