Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 47 additions & 8 deletions src/daemon/git_backend.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::daemon::domain::FamilyKey;
use crate::error::GitAiError;
use crate::git::cli_parser::parse_git_cli_args;
use crate::git::find_repository_in_path;
use crate::git::repo_state::common_dir_for_worktree;
use crate::git::repo_state::{common_dir_for_repo_path, common_dir_for_worktree};
use crate::git::repository::discover_repository_in_path_no_git_exec;
use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -327,12 +326,13 @@ fn is_builtin_primary_command(command: &str) -> bool {

impl GitBackend for SystemGitBackend {
fn resolve_family(&self, worktree: &Path) -> Result<FamilyKey, GitAiError> {
let worktree_str = worktree.to_string_lossy().to_string();
let repo = find_repository_in_path(&worktree_str)?;
let common = repo
.common_dir()
.canonicalize()
.unwrap_or_else(|_| repo.common_dir().to_path_buf());
let common = common_dir_for_repo_path(worktree).ok_or_else(|| {
GitAiError::Generic(format!(
"Failed to resolve git common dir for repo path {}",
worktree.display()
))
})?;
let common = common.canonicalize().unwrap_or(common);
Ok(FamilyKey::new(common.to_string_lossy().to_string()))
}

Expand Down Expand Up @@ -564,6 +564,7 @@ mod tests {
use super::{
GitBackend, SystemGitBackend, clone_init_positionals, default_clone_target_from_source,
};
use std::fs;
use std::path::PathBuf;

fn argv(args: &[&str]) -> Vec<String> {
Expand Down Expand Up @@ -726,6 +727,44 @@ mod tests {
assert_eq!(resolved.as_deref(), Some("commit"));
}

#[test]
fn resolve_family_uses_worktree_filesystem_without_git_config() {
let temp = tempfile::tempdir().expect("tempdir");
let git_dir = temp.path().join(".git");
fs::create_dir_all(&git_dir).expect("create git dir");
fs::write(git_dir.join("HEAD"), "ref: refs/heads/main\n").expect("write HEAD");

let family = SystemGitBackend::new()
.resolve_family(temp.path())
.expect("resolve family");

assert_eq!(
family.0,
git_dir
.canonicalize()
.expect("canonical git dir")
.to_string_lossy()
);
}

#[test]
fn resolve_family_accepts_bare_repo_path_without_git_spawn() {
let bare = tempfile::tempdir().expect("bare tempdir");
fs::write(bare.path().join("HEAD"), "ref: refs/heads/main\n").expect("write HEAD");

let family = SystemGitBackend::new()
.resolve_family(bare.path())
.expect("resolve family");

assert_eq!(
family.0,
bare.path()
.canonicalize()
.expect("canonical bare dir")
.to_string_lossy()
);
}

#[test]
fn default_clone_target_from_url() {
assert_eq!(
Expand Down
35 changes: 27 additions & 8 deletions tests/integration/tls_native_certs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,32 @@ fn test_build_agent_default_config() {
/// native TLS stack and system certificate store are working correctly.
#[test]
fn test_https_request_uses_system_certs() {
let agent = git_ai::http::build_agent(Some(10));
let result = git_ai::http::send(agent.get("https://example.com"));
assert!(
result.is_ok(),
"HTTPS request to example.com failed — native TLS certs not working: {:?}",
result.err()
const URLS: &[&str] = &[
"https://example.com",
"https://www.rust-lang.org",
"https://github.com",
];
const ATTEMPTS_PER_URL: usize = 3;

let mut failures = Vec::new();
for url in URLS {
for attempt in 1..=ATTEMPTS_PER_URL {
let agent = git_ai::http::build_agent(Some(10));
match git_ai::http::send(agent.get(url)) {
Ok(response) if (200..400).contains(&response.status_code) => return,
Ok(response) => failures.push(format!(
"{} attempt {} returned status {}",
url, attempt, response.status_code
)),
Err(error) => {
failures.push(format!("{} attempt {} failed: {}", url, attempt, error))
}
}
}
}

panic!(
"HTTPS requests to trusted public endpoints failed; native TLS certs may be broken or the network is unavailable:\n{}",
failures.join("\n")
);
let response = result.unwrap();
assert_eq!(response.status_code, 200);
}
Loading