revset: do not suggest deleted local branches, suggest @remote branches

It seemed too verbose to always include @remote branches, so synced remotes
are omitted by default. If the given symbol contained '@', all remote symbols
are populated so that the distance of remote fragment is taken into account.
This commit is contained in:
Yuya Nishihara 2023-07-02 13:57:44 +09:00
parent 4a5060a618
commit 3e294ca2d6
3 changed files with 58 additions and 15 deletions

View file

@ -1659,6 +1659,24 @@ fn resolve_branch(repo: &dyn Repo, symbol: &str) -> Option<Vec<CommitId>> {
None
}
fn collect_branch_symbols(repo: &dyn Repo, include_synced_remotes: bool) -> Vec<String> {
// TODO: include "@git" branches
repo.view()
.branches()
.iter()
.flat_map(|(name, branch_target)| {
let local_target = branch_target.local_target.as_ref();
let local_symbol = local_target.is_some().then(|| name.to_owned());
let remote_symbols = branch_target
.remote_targets
.iter()
.filter(move |&(_, target)| include_synced_remotes || Some(target) != local_target)
.map(move |(remote_name, _)| format!("{name}@{remote_name}"));
local_symbol.into_iter().chain(remote_symbols)
})
.collect()
}
fn resolve_full_commit_id(
repo: &dyn Repo,
symbol: &str,
@ -1821,7 +1839,9 @@ impl SymbolResolver for DefaultSymbolResolver<'_> {
Err(RevsetResolutionError::NoSuchRevision {
name: symbol.to_owned(),
candidates: {
let branch_names = self.repo.view().branches().keys().collect_vec();
// TODO: include tags?
let mut branch_names = collect_branch_symbols(self.repo, symbol.contains('@'));
branch_names.sort_unstable();
collect_similar(symbol, &branch_names)
},
})

View file

@ -473,19 +473,21 @@ fn test_resolve_symbol_branches() {
name: "local@origin",
candidates: [
"local",
"local-remote@origin",
"remote@origin",
],
}
"###);
// Remote only (or locally deleted)
// TODO: shouldn't suggest deleted local branch
insta::assert_debug_snapshot!(
resolve_symbol(mut_repo, "remote", None).unwrap_err(), @r###"
NoSuchRevision {
name: "remote",
candidates: [
"remote",
"remote-conflicted",
"local-remote@origin",
"remote-conflicted@origin",
"remote@origin",
],
}
"###);
@ -518,7 +520,9 @@ fn test_resolve_symbol_branches() {
vec![commit5.id().clone(), commit4.id().clone()],
);
// Typo of local/remote branch name
// Typo of local/remote branch name:
// For "local-emote" (without @remote part), "local-remote@mirror" isn't
// suggested since it points to the same target as "local-remote".
insta::assert_debug_snapshot!(
resolve_symbol(mut_repo, "local-emote", None).unwrap_err(), @r###"
NoSuchRevision {
@ -527,6 +531,7 @@ fn test_resolve_symbol_branches() {
"local",
"local-conflicted",
"local-remote",
"local-remote@origin",
],
}
"###);
@ -537,10 +542,13 @@ fn test_resolve_symbol_branches() {
candidates: [
"local",
"local-remote",
"local-remote@mirror",
"local-remote@origin",
"remote-conflicted@origin",
"remote@origin",
],
}
"###);
// TODO: shouldn't suggest deleted local branch
insta::assert_debug_snapshot!(
resolve_symbol(mut_repo, "local-remote@origine", None).unwrap_err(), @r###"
NoSuchRevision {
@ -548,21 +556,34 @@ fn test_resolve_symbol_branches() {
candidates: [
"local",
"local-remote",
"remote",
"remote-conflicted",
"local-remote@mirror",
"local-remote@origin",
"remote-conflicted@origin",
"remote@origin",
],
}
"###);
// "local-remote@mirror" shouldn't be omitted just because it points to the same
// target as "local-remote".
insta::assert_debug_snapshot!(
resolve_symbol(mut_repo, "remote@mirror", None).unwrap_err(), @r###"
NoSuchRevision {
name: "remote@mirror",
candidates: [
"local-remote@mirror",
"remote@origin",
],
}
"###);
// Typo of remote-only branch name
// TODO: shouldn't suggest deleted local branch
insta::assert_debug_snapshot!(
resolve_symbol(mut_repo, "emote", None).unwrap_err(), @r###"
NoSuchRevision {
name: "emote",
candidates: [
"remote",
"remote-conflicted",
"remote-conflicted@origin",
"remote@origin",
],
}
"###);
@ -571,7 +592,8 @@ fn test_resolve_symbol_branches() {
NoSuchRevision {
name: "emote@origin",
candidates: [
"remote",
"local-remote@origin",
"remote@origin",
],
}
"###);
@ -580,8 +602,9 @@ fn test_resolve_symbol_branches() {
NoSuchRevision {
name: "remote@origine",
candidates: [
"remote",
"remote-conflicted",
"local-remote@origin",
"remote-conflicted@origin",
"remote@origin",
],
}
"###);

View file

@ -532,7 +532,7 @@ fn test_branch_list_filtered_by_revset() {
"###);
insta::assert_snapshot!(query_error("remote-delete"), @r###"
Error: Revision "remote-delete" doesn't exist
Hint: Did you mean "remote-delete", "remote-keep", "remote-rewrite"?
Hint: Did you mean "remote-delete@origin", "remote-keep", "remote-rewrite", "remote-rewrite@origin"?
"###);
}