ok/jj
1
0
Fork 0
forked from mirrors/jj

git: look up "git" remote branches normally

This commit is contained in:
Yuya Nishihara 2023-09-25 23:34:09 +09:00
parent 717d0d3d6d
commit d0bc34e0f2
7 changed files with 15 additions and 68 deletions

View file

@ -320,7 +320,7 @@ fn cmd_branch_list(
) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?;
let repo = workspace_command.repo();
let mut all_branches = git::build_unified_branches_map(repo.view());
let mut all_branches = repo.view().branches().clone(); // TODO: useless clone
if !args.revisions.is_empty() {
// Match against local targets only, which is consistent with "jj git push".
fn local_targets(branch_target: &BranchTarget) -> impl Iterator<Item = &CommitId> {

View file

@ -24,7 +24,7 @@ use jj_lib::hex_util::to_reverse_hex;
use jj_lib::id_prefix::IdPrefixContext;
use jj_lib::op_store::{RefTarget, WorkspaceId};
use jj_lib::repo::Repo;
use jj_lib::{git, rewrite};
use jj_lib::rewrite;
use once_cell::unsync::OnceCell;
use crate::formatter::Formatter;
@ -358,8 +358,7 @@ impl RefNamesIndex {
fn build_branches_index(repo: &dyn Repo) -> RefNamesIndex {
let mut index = RefNamesIndex::default();
let all_branches = git::build_unified_branches_map(repo.view());
for (branch_name, branch_target) in &all_branches {
for (branch_name, branch_target) in repo.view().branches() {
let local_target = &branch_target.local_target;
let mut unsynced_remote_targets = branch_target
.remote_targets

View file

@ -239,25 +239,13 @@ fn test_branch_forget_export() {
insta::assert_snapshot!(stdout, @"");
let stdout = test_env.jj_cmd_success(&repo_path, &["branch", "forget", "foo"]);
insta::assert_snapshot!(stdout, @"");
// Forgetting a branch does not delete its local-git tracking branch. The
// git-tracking branch is kept.
// TODO: Actually git-tracking branch is forgotten. Update the branch
// resolution code to not shadow the real @git branch.
// Forgetting a branch deletes local and remote-tracking branches including
// the corresponding git-tracking branch.
let stdout = test_env.jj_cmd_success(&repo_path, &["branch", "list"]);
insta::assert_snapshot!(stdout, @r###"
foo (forgotten)
@git: rlvkpnrz 65b6b74e (empty) (no description set)
(this branch will be deleted from the underlying Git repo on the next `jj git export`)
"###);
insta::assert_snapshot!(stdout, @"");
let stderr = test_env.jj_cmd_failure(&repo_path, &["log", "-r=foo", "--no-graph"]);
insta::assert_snapshot!(stderr, @r###"
Error: Revision "foo" doesn't exist
Hint: Did you mean "foo@git"?
"###);
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r=foo@git", "--no-graph"]);
insta::assert_snapshot!(stdout, @r###"
rlvkpnrz test.user@example.com 2001-02-03 04:05:08.000 +07:00 foo@git 65b6b74e
(empty) (no description set)
"###);
// `jj git export` will delete the branch from git. In a colocated repo,

View file

@ -157,21 +157,13 @@ fn test_git_import_undo() {
);
insta::assert_snapshot!(stdout, @r###"
"###);
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
a (forgotten)
@git: qpvuntsm 230dd059 (empty) (no description set)
(this branch will be deleted from the underlying Git repo on the next `jj git export`)
"###);
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @"");
// Try "git import" again, which should *not* re-import the branch "a" and be a
// no-op.
insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["git", "import"]), @r###"
Nothing changed.
"###);
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
a (forgotten)
@git: qpvuntsm 230dd059 (empty) (no description set)
(this branch will be deleted from the underlying Git repo on the next `jj git export`)
"###);
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @"");
// We can restore *only* the git refs to make an import re-import the branch
let stdout = test_env.jj_cmd_success(

View file

@ -28,7 +28,7 @@ use thiserror::Error;
use crate::backend::{BackendError, CommitId, ObjectId};
use crate::commit::Commit;
use crate::git_backend::GitBackend;
use crate::op_store::{BranchTarget, RefTarget, RefTargetOptionExt};
use crate::op_store::{RefTarget, RefTargetOptionExt};
use crate::repo::{MutableRepo, Repo};
use crate::revset::{self, RevsetExpression};
use crate::settings::GitSettings;
@ -155,33 +155,6 @@ fn resolve_git_ref_to_commit_id(
Some(CommitId::from_bytes(git_commit.id().as_bytes()))
}
/// Builds a map of branches which also includes pseudo `@git` remote.
pub fn build_unified_branches_map(view: &View) -> BTreeMap<String, BranchTarget> {
let mut all_branches = view.branches().clone();
for (branch_name, git_tracking_target) in local_branch_git_tracking_refs(view) {
// There may be a "git" remote if the view has been stored by older jj versions,
// but we override it anyway.
let branch_target = all_branches.entry(branch_name.to_owned()).or_default();
branch_target.remote_targets.insert(
REMOTE_NAME_FOR_LOCAL_GIT_REPO.to_owned(),
git_tracking_target.clone(),
);
}
all_branches
}
fn local_branch_git_tracking_refs(view: &View) -> impl Iterator<Item = (&str, &RefTarget)> {
view.git_refs().iter().filter_map(|(ref_name, target)| {
ref_name
.strip_prefix("refs/heads/")
.map(|branch_name| (branch_name, target))
})
}
pub fn get_local_git_tracking_branch<'a>(view: &'a View, branch: &str) -> &'a RefTarget {
view.get_git_ref(&format!("refs/heads/{branch}"))
}
/// Reflect changes made in the underlying Git repo in the Jujutsu repo.
///
/// This function detects conflicts (if both Git and JJ modified a branch) and

View file

@ -34,7 +34,7 @@ use thiserror::Error;
use crate::backend::{BackendError, BackendResult, ChangeId, CommitId};
use crate::commit::Commit;
use crate::git::{self, get_local_git_tracking_branch};
use crate::git;
use crate::hex_util::to_forward_hex;
use crate::index::{HexPrefix, PrefixResolution};
use crate::op_store::WorkspaceId;
@ -2018,7 +2018,6 @@ fn resolve_remote_branch(repo: &dyn Repo, name: &str, remote: &str) -> Option<Ve
let view = repo.view();
let target = match (name, remote) {
("HEAD", git::REMOTE_NAME_FOR_LOCAL_GIT_REPO) => view.git_head(),
(name, git::REMOTE_NAME_FOR_LOCAL_GIT_REPO) => get_local_git_tracking_branch(view, name),
(name, remote) => view.get_remote_branch(name, remote),
};
target
@ -2028,8 +2027,7 @@ fn resolve_remote_branch(repo: &dyn Repo, name: &str, remote: &str) -> Option<Ve
fn collect_branch_symbols(repo: &dyn Repo, include_synced_remotes: bool) -> Vec<String> {
let view = repo.view();
let all_branches = git::build_unified_branches_map(view);
all_branches
view.branches()
.iter()
.flat_map(|(name, branch_target)| {
let local_target = &branch_target.local_target;

View file

@ -409,8 +409,9 @@ fn test_resolve_symbol_branches() {
"mirror",
mut_repo.get_local_branch("local-remote"),
);
mut_repo.set_git_ref_target(
"refs/heads/local-remote",
mut_repo.set_remote_branch_target(
"local-remote",
git::REMOTE_NAME_FOR_LOCAL_GIT_REPO,
mut_repo.get_local_branch("local-remote"),
);
@ -739,11 +740,7 @@ fn test_resolve_symbol_git_refs() {
resolve_symbol(mut_repo, "branch").unwrap_err(), @r###"
NoSuchRevision {
name: "branch",
candidates: [
"branch1@git",
"branch2@git",
"branch@git",
],
candidates: [],
}
"###);
// heads/branch does get resolved to the git ref refs/heads/branch