优化git处理

This commit is contained in:
yyimba@qq.com
2026-03-21 14:45:42 +08:00
parent 9e21ac439b
commit 107ee21a48
2 changed files with 37 additions and 29 deletions

View File

@@ -91,8 +91,10 @@ fn classify_remote_git_error(operation: &str, stderr: &[u8]) -> AppCommandError
|| lower.contains("could not read username")
|| lower.contains("could not read password")
|| lower.contains("logon failed")
|| lower.contains("401")
|| lower.contains("403")
|| lower.contains("terminal prompts disabled")
|| lower.contains("the requested url returned error: 401")
|| lower.contains("the requested url returned error: 403")
|| lower.contains("http basic: access denied")
{
return AppCommandError::authentication_failed(format!(
"git {operation}: authentication failed. Configure a GitHub account in Settings → Version Control."
@@ -565,6 +567,12 @@ fn classify_git_clone_error(stderr: &str) -> AppCommandError {
if normalized.contains("authentication failed")
|| normalized.contains("could not read username")
|| normalized.contains("could not read password")
|| normalized.contains("logon failed")
|| normalized.contains("terminal prompts disabled")
|| normalized.contains("the requested url returned error: 401")
|| normalized.contains("the requested url returned error: 403")
|| normalized.contains("http basic: access denied")
|| normalized.contains("permission denied (publickey)")
{
return AppCommandError::authentication_failed(

View File

@@ -325,6 +325,7 @@ export function GitCredentialProvider({
operation: (credentials?: GitCredentials) => Promise<T>,
hint: GitRemoteHint
): Promise<T> => {
// First attempt — no explicit credentials
try {
return await operation()
} catch (firstError) {
@@ -336,13 +337,6 @@ export function GitCredentialProvider({
? "github"
: "generic"
// Show credential dialog
const creds = await requestCredentials(dialogMode, host)
if (!creds) {
setOpen(false)
throw firstError
}
// Helper: save credentials after successful operation
const maybeSave = async (c: GitCredentials) => {
if (modeRef.current === "generic" && saveCredentialsRef.current) {
@@ -351,15 +345,31 @@ export function GitCredentialProvider({
// GitHub mode saves during handleGitHubSubmit, no extra work needed
}
// Retry with credentials
try {
const result = await operation(creds)
await maybeSave(creds)
// Show credential dialog for the first time
let creds = await requestCredentials(dialogMode, host)
if (!creds) {
setOpen(false)
return result
} catch (retryError) {
setSubmitting(false)
if (isAuthError(retryError)) {
throw firstError
}
// Retry loop — keep trying until success or user cancels
let lastError: unknown = firstError
// eslint-disable-next-line no-constant-condition
while (true) {
try {
const result = await operation(creds)
await maybeSave(creds)
setOpen(false)
return result
} catch (retryError) {
lastError = retryError
if (!isAuthError(retryError)) {
// Non-auth error — stop retrying
setOpen(false)
throw retryError
}
// Auth error — show error and let user try again
setSubmitting(false)
setError(t("invalidCredentials"))
const retryCreds = await new Promise<GitCredentials | null>(
(resolve) => {
@@ -368,20 +378,10 @@ export function GitCredentialProvider({
)
if (!retryCreds) {
setOpen(false)
throw retryError
}
try {
const result = await operation(retryCreds)
await maybeSave(retryCreds)
setOpen(false)
return result
} catch (thirdError) {
setOpen(false)
throw thirdError
throw lastError
}
creds = retryCreds
}
setOpen(false)
throw retryError
}
}
},