修复git凭证的使用问题

This commit is contained in:
xintaofei
2026-03-21 16:49:48 +08:00
parent 51e9d15c8e
commit 44f812c8d2
2 changed files with 35 additions and 4 deletions

View File

@@ -84,6 +84,7 @@ async fn prepare_remote_git_cmd_for_url(
/// Classify a git remote command error, detecting authentication failures.
fn classify_remote_git_error(operation: &str, stderr: &[u8]) -> AppCommandError {
let msg = String::from_utf8_lossy(stderr).trim().to_string();
eprintln!("[GIT_CMD] {} failed, stderr: {}", operation, msg);
let lower = msg.to_lowercase();
if lower.contains("authentication failed")

View File

@@ -198,7 +198,14 @@ pub fn inject_credentials(
token: &str,
askpass_path: &Path,
) {
cmd.env("GIT_ASKPASS", askpass_path)
// Clear all system credential helpers (e.g. macOS Keychain `osxkeychain`)
// so git falls through to GIT_ASKPASS. Without this, a system credential
// helper may return stale/wrong credentials and GIT_ASKPASS is never called.
// Per git docs, setting credential.helper="" resets the helper list.
cmd.env("GIT_CONFIG_COUNT", "1")
.env("GIT_CONFIG_KEY_0", "credential.helper")
.env("GIT_CONFIG_VALUE_0", "")
.env("GIT_ASKPASS", askpass_path)
.env("CODEG_GIT_USERNAME", username)
.env("CODEG_GIT_PASSWORD", token)
.env("GIT_TERMINAL_PROMPT", "0");
@@ -335,22 +342,41 @@ pub async fn try_inject_for_repo(
) -> bool {
let settings = match load_github_accounts(conn).await {
Some(s) if !s.accounts.is_empty() => s,
_ => return false,
_ => {
eprintln!("[GIT_CRED] no accounts configured");
return false;
}
};
let remote_url = match get_remote_url(repo_path).await {
Some(url) => url,
None => return false,
None => {
eprintln!("[GIT_CRED] no remote URL found for {}", repo_path);
return false;
}
};
// Only inject for HTTPS URLs (SSH uses keys, not tokens)
if !remote_url.starts_with("https://") && !remote_url.starts_with("http://") {
eprintln!("[GIT_CRED] skipping non-HTTPS URL: {}", remote_url);
return false;
}
let account = match find_matching_account(&settings.accounts, &remote_url) {
Some(a) => a,
None => return false,
None => {
eprintln!(
"[GIT_CRED] no matching account for remote {}. Available hosts: {}",
remote_url,
settings
.accounts
.iter()
.map(|a| a.server_url.as_str())
.collect::<Vec<_>>()
.join(", ")
);
return false;
}
};
let askpass = match ensure_askpass_script(app_data_dir) {
@@ -361,6 +387,10 @@ pub async fn try_inject_for_repo(
}
};
eprintln!(
"[GIT_CRED] injecting credentials for {} (user: {})",
remote_url, account.username
);
inject_credentials(cmd, &account.username, &account.token, &askpass);
true
}