mirror of
https://github.com/jj-vcs/jj.git
synced 2026-07-04 06:29:55 +08:00
revset: drop support for Git ref symbol resolution
Follows the same reason as the git_head()/git_refs() removal. This patch introduces an immediate breaking change because there is no machinery to emit warnings during the symbol resolution stage. Hopefully, Git ref symbols were rarely used.
This commit is contained in:
@@ -20,6 +20,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
* The deprecated `git_head()` and `git_refs()` functions have been removed from
|
||||
revsets and templates.
|
||||
|
||||
* Git-like symbols (e.g. `refs/heads/main`) are no longer resolved to
|
||||
revisions. Use the bookmark/tag `<name>` or `<name>@<remote>` syntax instead.
|
||||
|
||||
* The deprecated `ui.revsets-use-glob-by-default` option has been removed.
|
||||
|
||||
* `jj bookmark track`/`untrack` no longer supports `<kind>:<bookmark>@<remote>`
|
||||
|
||||
@@ -53,8 +53,7 @@ Jujutsu attempts to resolve a symbol in the following order:
|
||||
|
||||
1. Tag name
|
||||
2. Bookmark name
|
||||
3. Git ref
|
||||
4. Commit ID or change ID
|
||||
3. Commit ID or change ID
|
||||
|
||||
To override the priority, use the appropriate [revset function](#functions). For
|
||||
example, to resolve `abc` as a commit ID even if there happens to be a bookmark
|
||||
|
||||
@@ -283,8 +283,8 @@ fn disambiguate_prefix_with_refs(view: &View, id_sym: &str, min_len: usize) -> u
|
||||
debug_assert!(id_sym.is_ascii());
|
||||
(min_len..id_sym.len())
|
||||
.find(|&n| {
|
||||
// Tags, bookmarks, and Git refs have higher priority, but Git refs
|
||||
// should include "/" char. Extension symbols have lower priority.
|
||||
// Tags and bookmarks have higher priority. Extension symbols have
|
||||
// lower priority.
|
||||
let prefix = &id_sym[..n];
|
||||
view.get_local_tag(prefix.as_ref()).is_absent()
|
||||
&& view.get_local_bookmark(prefix.as_ref()).is_absent()
|
||||
|
||||
@@ -2683,27 +2683,7 @@ impl PartialSymbolResolver for BookmarkResolver {
|
||||
}
|
||||
}
|
||||
|
||||
struct GitRefResolver;
|
||||
|
||||
impl PartialSymbolResolver for GitRefResolver {
|
||||
fn resolve_symbol(
|
||||
&self,
|
||||
repo: &dyn Repo,
|
||||
symbol: &str,
|
||||
) -> Result<Option<CommitId>, RevsetResolutionError> {
|
||||
let view = repo.view();
|
||||
for git_ref_prefix in &["", "refs/"] {
|
||||
let target = view.get_git_ref([git_ref_prefix, symbol].concat().as_ref());
|
||||
if let Some(id) = to_resolved_ref("git_ref", symbol, target)? {
|
||||
return Ok(Some(id));
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_RESOLVERS: &[&dyn PartialSymbolResolver] =
|
||||
&[&TagResolver, &BookmarkResolver, &GitRefResolver];
|
||||
const DEFAULT_RESOLVERS: &[&dyn PartialSymbolResolver] = &[&TagResolver, &BookmarkResolver];
|
||||
|
||||
struct CommitPrefixResolver<'a> {
|
||||
context_repo: &'a dyn Repo,
|
||||
|
||||
@@ -1051,114 +1051,6 @@ fn test_resolve_symbol_remote_tags_or_bookmarks() -> TestResult {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_resolve_symbol_git_refs() -> TestResult {
|
||||
let test_repo = TestRepo::init();
|
||||
let repo = &test_repo.repo;
|
||||
|
||||
let mut tx = repo.start_transaction();
|
||||
let mut_repo = tx.repo_mut();
|
||||
|
||||
// Create some commits and refs to work with and so the repo is not empty
|
||||
let commit1 = write_random_commit(mut_repo);
|
||||
let commit2 = write_random_commit(mut_repo);
|
||||
let commit3 = write_random_commit(mut_repo);
|
||||
let commit4 = write_random_commit(mut_repo);
|
||||
let commit5 = write_random_commit(mut_repo);
|
||||
mut_repo.set_git_ref_target(
|
||||
"refs/heads/bookmark1".as_ref(),
|
||||
RefTarget::normal(commit1.id().clone()),
|
||||
);
|
||||
mut_repo.set_git_ref_target(
|
||||
"refs/heads/bookmark2".as_ref(),
|
||||
RefTarget::normal(commit2.id().clone()),
|
||||
);
|
||||
mut_repo.set_git_ref_target(
|
||||
"refs/heads/conflicted".as_ref(),
|
||||
RefTarget::from_legacy_form(
|
||||
[commit2.id().clone()],
|
||||
[commit1.id().clone(), commit3.id().clone()],
|
||||
),
|
||||
);
|
||||
mut_repo.set_git_ref_target(
|
||||
"refs/tags/tag1".as_ref(),
|
||||
RefTarget::normal(commit2.id().clone()),
|
||||
);
|
||||
mut_repo.set_git_ref_target(
|
||||
"refs/tags/remotes/origin/bookmark1".as_ref(),
|
||||
RefTarget::normal(commit3.id().clone()),
|
||||
);
|
||||
|
||||
// Nonexistent ref
|
||||
assert_matches!(
|
||||
resolve_symbol(mut_repo, "nonexistent"),
|
||||
Err(RevsetResolutionError::NoSuchRevision{name, candidates})
|
||||
if name == "nonexistent" && candidates.is_empty()
|
||||
);
|
||||
|
||||
// Full ref
|
||||
mut_repo.set_git_ref_target(
|
||||
"refs/heads/bookmark".as_ref(),
|
||||
RefTarget::normal(commit4.id().clone()),
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_symbol(mut_repo, "refs/heads/bookmark")?,
|
||||
vec![commit4.id().clone()]
|
||||
);
|
||||
|
||||
// Qualified with only heads/
|
||||
mut_repo.set_git_ref_target(
|
||||
"refs/heads/bookmark".as_ref(),
|
||||
RefTarget::normal(commit5.id().clone()),
|
||||
);
|
||||
mut_repo.set_git_ref_target(
|
||||
"refs/tags/bookmark".as_ref(),
|
||||
RefTarget::normal(commit4.id().clone()),
|
||||
);
|
||||
// bookmark alone is not recognized
|
||||
insta::assert_debug_snapshot!(
|
||||
resolve_symbol(mut_repo, "bookmark").unwrap_err(), @r#"
|
||||
NoSuchRevision {
|
||||
name: "bookmark",
|
||||
candidates: [],
|
||||
}
|
||||
"#);
|
||||
// heads/bookmark does get resolved to the git ref refs/heads/bookmark
|
||||
assert_eq!(
|
||||
resolve_symbol(mut_repo, "heads/bookmark")?,
|
||||
vec![commit5.id().clone()]
|
||||
);
|
||||
|
||||
// Unqualified tag name
|
||||
mut_repo.set_git_ref_target(
|
||||
"refs/tags/tag".as_ref(),
|
||||
RefTarget::normal(commit4.id().clone()),
|
||||
);
|
||||
assert_matches!(
|
||||
resolve_symbol(mut_repo, "tag"),
|
||||
Err(RevsetResolutionError::NoSuchRevision { .. })
|
||||
);
|
||||
|
||||
// Unqualified remote-tracking bookmark name
|
||||
mut_repo.set_git_ref_target(
|
||||
"refs/remotes/origin/remote-bookmark".as_ref(),
|
||||
RefTarget::normal(commit2.id().clone()),
|
||||
);
|
||||
assert_matches!(
|
||||
resolve_symbol(mut_repo, "origin/remote-bookmark"),
|
||||
Err(RevsetResolutionError::NoSuchRevision { .. })
|
||||
);
|
||||
|
||||
// Conflicted ref is an error
|
||||
assert_matches!(
|
||||
resolve_symbol(mut_repo, "refs/heads/conflicted"),
|
||||
Err(RevsetResolutionError::ConflictedRef { kind: "git_ref", symbol, targets })
|
||||
if symbol == "refs/heads/conflicted"
|
||||
&& targets == vec![commit1.id().clone(), commit3.id().clone()]
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn resolve_commit_ids(repo: &dyn Repo, revset_str: &str) -> Vec<CommitId> {
|
||||
try_resolve_commit_ids(repo, revset_str).unwrap()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user