diff --git a/CHANGELOG.md b/CHANGELOG.md index 086ba09c4..7ba3d8fda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `jj debug completion`, `jj debug mangen` and `jj debug config-schema` have been moved from `jj debug` to `jj util`. +* `jj` will no longer parse `br` as a git_ref `refs/heads/br` when a branch `br` + does not exist but the git_ref does (this is rare). Use `br@git` instead. + ### New features * `jj git push --deleted` will remove all locally deleted branches from the remote. diff --git a/lib/src/revset.rs b/lib/src/revset.rs index 7dc407998..9fea5cc93 100644 --- a/lib/src/revset.rs +++ b/lib/src/revset.rs @@ -1617,7 +1617,9 @@ pub fn walk_revs<'index>( fn resolve_git_ref(repo: &dyn Repo, symbol: &str) -> Option> { let view = repo.view(); - for git_ref_prefix in &["", "refs/", "refs/heads/", "refs/tags/", "refs/remotes/"] { + // TODO: We should remove `refs/remotes` from this list once we have a better + // way to address local git repo's remote-tracking branches. + for git_ref_prefix in &["", "refs/", "refs/tags/", "refs/remotes/"] { if let Some(ref_target) = view.git_refs().get(&(git_ref_prefix.to_string() + symbol)) { return Some(ref_target.adds()); } diff --git a/lib/tests/test_revset.rs b/lib/tests/test_revset.rs index 3b1e1c87c..3aa0a3fc3 100644 --- a/lib/tests/test_revset.rs +++ b/lib/tests/test_revset.rs @@ -452,7 +452,8 @@ fn test_resolve_symbol_git_refs() { // Nonexistent ref assert_matches!( resolve_symbol(mut_repo, "nonexistent", None), - Err(RevsetResolutionError::NoSuchRevision{name, candidates}) if name == "nonexistent" && candidates.is_empty() + Err(RevsetResolutionError::NoSuchRevision{name, candidates}) + if name == "nonexistent" && candidates.is_empty() ); // Full ref @@ -470,29 +471,27 @@ fn test_resolve_symbol_git_refs() { "refs/heads/branch".to_string(), RefTarget::Normal(commit5.id().clone()), ); + // branch alone is not recognized + assert_matches!( + resolve_symbol(mut_repo, "branch", None), + Err(RevsetResolutionError::NoSuchRevision{name, candidates}) + if name == "branch" && candidates.is_empty() + ); mut_repo.set_git_ref( "refs/tags/branch".to_string(), RefTarget::Normal(commit4.id().clone()), ); + // The *tag* branch is recognized + assert_eq!( + resolve_symbol(mut_repo, "branch", None).unwrap(), + vec![commit4.id().clone()] + ); + // heads/branch does get resolved to the git ref refs/heads/branch assert_eq!( resolve_symbol(mut_repo, "heads/branch", None).unwrap(), vec![commit5.id().clone()] ); - // Unqualified branch name - mut_repo.set_git_ref( - "refs/heads/branch".to_string(), - RefTarget::Normal(commit3.id().clone()), - ); - mut_repo.set_git_ref( - "refs/tags/branch".to_string(), - RefTarget::Normal(commit4.id().clone()), - ); - assert_eq!( - resolve_symbol(mut_repo, "branch", None).unwrap(), - vec![commit3.id().clone()] - ); - // Unqualified tag name mut_repo.set_git_ref( "refs/tags/tag".to_string(), diff --git a/tests/test_branch_command.rs b/tests/test_branch_command.rs index ce8502b4a..d07214a57 100644 --- a/tests/test_branch_command.rs +++ b/tests/test_branch_command.rs @@ -140,11 +140,11 @@ fn test_branch_forget_export() { foo (deleted) @git: 65b6b74e0897 (no description set) "###); - - // Aside: the way we currently resolve git refs means that `foo` - // resolves to `foo@git` when actual `foo` doesn't exist. - // Short-term TODO: This behavior will be changed in a subsequent commit. - let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r=foo", "--no-graph"]); + 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 + "###); + let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r=foo@git", "--no-graph"]); insta::assert_snapshot!(stdout, @r###" rlvkpnrzqnoo test.user@example.com 2001-02-03 04:05:08.000 +07:00 65b6b74e0897 (empty) (no description set)