revset: resolve "HEAD@git" just like other pseudo @git branches

I don't think this would be practically useful, but consistent UX is
important.

Fixes #1843
This commit is contained in:
Yuya Nishihara 2023-07-11 13:44:17 +09:00
parent 79955d9cb3
commit f5f61f6bfe
3 changed files with 54 additions and 3 deletions

View file

@ -102,7 +102,8 @@ revsets (expressions) as arguments.
possible targets are included.
* `git_refs()`: All Git ref targets as of the last import. If a Git ref
is in a conflicted state, all its possible targets are included.
* `git_head()`: The Git `HEAD` target as of the last import.
* `git_head()`: The Git `HEAD` target as of the last import. Equivalent to
`present(HEAD@git)`.
* `visible_heads()`: All visible heads (same as `heads(all())`).
* `heads(x)`: Commits in `x` that are not ancestors of other commits in `x`.
Note that this is different from

View file

@ -1653,7 +1653,11 @@ fn resolve_branch(repo: &dyn Repo, symbol: &str) -> Option<Vec<CommitId>> {
}
// A remote with name "git" will shadow local-git tracking branches
if remote_name == "git" {
if let Some(target) = get_local_git_tracking_branch(view, name) {
let maybe_target = match name {
"HEAD" => view.git_head(),
_ => get_local_git_tracking_branch(view, name),
};
if let Some(target) = maybe_target {
return Some(target.adds().to_vec());
}
}
@ -1662,7 +1666,8 @@ fn resolve_branch(repo: &dyn Repo, symbol: &str) -> Option<Vec<CommitId>> {
}
fn collect_branch_symbols(repo: &dyn Repo, include_synced_remotes: bool) -> Vec<String> {
let (all_branches, _) = git::build_unified_branches_map(repo.view());
let view = repo.view();
let (all_branches, _) = git::build_unified_branches_map(view);
all_branches
.iter()
.flat_map(|(name, branch_target)| {
@ -1675,6 +1680,7 @@ fn collect_branch_symbols(repo: &dyn Repo, include_synced_remotes: bool) -> Vec<
.map(move |(remote_name, _)| format!("{name}@{remote_name}"));
local_symbol.into_iter().chain(remote_symbols)
})
.chain(view.git_head().is_some().then(|| "HEAD@git".to_owned()))
.collect()
}

View file

@ -621,6 +621,50 @@ fn test_resolve_symbol_branches() {
"###);
}
#[test]
fn test_resolve_symbol_git_head() {
let settings = testutils::user_settings();
let test_repo = TestRepo::init(true);
let repo = &test_repo.repo;
let mut tx = repo.start_transaction(&settings, "test");
let mut_repo = tx.mut_repo();
let commit1 = write_random_commit(mut_repo, &settings);
// Without HEAD@git
insta::assert_debug_snapshot!(
resolve_symbol(mut_repo, "HEAD", None).unwrap_err(), @r###"
NoSuchRevision {
name: "HEAD",
candidates: [],
}
"###);
insta::assert_debug_snapshot!(
resolve_symbol(mut_repo, "HEAD@git", None).unwrap_err(), @r###"
NoSuchRevision {
name: "HEAD@git",
candidates: [],
}
"###);
// With HEAD@git
mut_repo.set_git_head(RefTarget::Normal(commit1.id().clone()));
insta::assert_debug_snapshot!(
resolve_symbol(mut_repo, "HEAD", None).unwrap_err(), @r###"
NoSuchRevision {
name: "HEAD",
candidates: [
"HEAD@git",
],
}
"###);
assert_eq!(
resolve_symbol(mut_repo, "HEAD@git", None).unwrap(),
vec![commit1.id().clone()],
);
}
#[test]
fn test_resolve_symbol_git_refs() {
let settings = testutils::user_settings();