🥇 export from upstream (bb29385)

This commit is contained in:
2026-05-23 20:06:39 +02:00
parent d39d0ac7de
commit 21681a7a4f
+49 -29
View File
@@ -823,7 +823,8 @@ pub fn build_ssh_discovery(
git_remote_hosts: &[String],
ssh_dir: &Path,
) -> Vec<SshDiscoveryEntry> {
// Keyed by display_host for deduplication and sorted output.
// Keyed by Host alias (not resolved HostName) to preserve distinct blocks
// that point to the same server with different keys.
let mut map: BTreeMap<String, SshDiscoveryEntry> = BTreeMap::new();
// 1. Add SSH config blocks where user is git.
@@ -831,19 +832,18 @@ pub fn build_ssh_discovery(
if !block.is_git_user() {
continue;
}
// display_host = HostName directive, or first alias as fallback.
let alias = match block.aliases.first() {
Some(a) => a.clone(),
None => continue,
};
let display_host = block
.hostname()
.unwrap_or_else(|| block.aliases.first().map(|s| s.as_str()).unwrap_or(""))
.unwrap_or(alias.as_str())
.to_string();
if display_host.is_empty() {
continue;
}
let ssh_host_alias = block.aliases.first().cloned();
let identity_file = block.identity_file().map(|s| s.to_string());
map.entry(display_host.clone()).or_insert_with(|| SshDiscoveryEntry {
map.entry(alias.clone()).or_insert_with(|| SshDiscoveryEntry {
display_host,
ssh_host_alias,
ssh_host_alias: Some(alias),
identity_file,
host_block: Some(block.clone()),
source: SshDiscoverySource::SshConfig,
@@ -852,9 +852,13 @@ pub fn build_ssh_discovery(
// 2. Process git remote hosts.
for git_host in git_remote_hosts {
if let Some(entry) = map.get_mut(git_host.as_str()) {
// Hostname already present via SSH config — upgrade source.
entry.source = SshDiscoverySource::Both;
// Check if this hostname matches any existing entry (by alias or display_host).
let existing_key = map.iter()
.find(|(_, e)| e.display_host == *git_host || e.ssh_host_alias.as_deref() == Some(git_host))
.map(|(k, _)| k.clone());
if let Some(key) = existing_key {
map.get_mut(&key).unwrap().source = SshDiscoverySource::Both;
} else {
// Check if any SSH block has this git_host as an alias.
let alias_match = ssh_blocks.iter().find(|b| {
@@ -862,24 +866,9 @@ pub fn build_ssh_discovery(
});
if let Some(block) = alias_match {
// The display_host should already be in the map via step 1, but just in case
// the block wasn't added (e.g., HostName was set and we keyed on HostName),
// upgrade source on whichever entry owns this block's alias.
let display = block
.hostname()
.unwrap_or_else(|| block.aliases.first().map(|s| s.as_str()).unwrap_or(""))
.to_string();
if let Some(existing) = map.get_mut(&display) {
let alias = block.aliases.first().cloned().unwrap_or_default();
if let Some(existing) = map.get_mut(&alias) {
existing.source = SshDiscoverySource::Both;
} else {
// Shouldn't normally happen, but handle gracefully.
map.insert(display.clone(), SshDiscoveryEntry {
display_host: display,
ssh_host_alias: block.aliases.first().cloned(),
identity_file: block.identity_file().map(|s| s.to_string()),
host_block: Some(block.clone()),
source: SshDiscoverySource::Both,
});
}
} else {
// No SSH config match — pure git remote entry.
@@ -1310,6 +1299,37 @@ Host myserver
assert!(gitlab.ssh_host_alias.is_none());
}
#[test]
fn discover_preserves_distinct_aliases_for_same_hostname() {
use crate::ssh_config::parse_ssh_config;
let ssh_config_text = "\
Host sparkle.g4b.org
Hostname git.g4b.org
User git
IdentityFile ~/.ssh/id_rsa_sparkle
Host git.g4b.org
User git
IdentityFile ~/.ssh/id_rsa
";
let blocks = parse_ssh_config(ssh_config_text);
let git_remote_hosts = vec!["git.g4b.org".to_string()];
let ssh_dir = Path::new("/nonexistent/.ssh");
let entries = build_ssh_discovery(&blocks, &git_remote_hosts, ssh_dir);
assert_eq!(entries.len(), 2, "both aliases should be preserved");
let sparkle = entries.iter().find(|e| e.ssh_host_alias.as_deref() == Some("sparkle.g4b.org")).unwrap();
assert_eq!(sparkle.display_host, "git.g4b.org");
assert_eq!(sparkle.identity_file.as_deref(), Some("~/.ssh/id_rsa_sparkle"));
let direct = entries.iter().find(|e| e.ssh_host_alias.as_deref() == Some("git.g4b.org")).unwrap();
assert_eq!(direct.display_host, "git.g4b.org");
assert_eq!(direct.identity_file.as_deref(), Some("~/.ssh/id_rsa"));
assert_eq!(direct.source, SshDiscoverySource::Both);
}
// -- has_legacy_ssh_mount tests --
#[test]