支持实时处理Git凭证

This commit is contained in:
itpkcn@gmail.com
2026-03-21 13:20:46 +08:00
parent 59327f6e02
commit aaad19adb5
20 changed files with 919 additions and 40 deletions

View File

@@ -92,6 +92,7 @@ import { toast } from "sonner"
import { useFolderContext } from "@/contexts/folder-context"
import { useTaskContext } from "@/contexts/task-context"
import { useAlertContext } from "@/contexts/alert-context"
import { useGitCredential } from "@/contexts/git-credential-context"
interface BranchDropdownProps {
branch: string | null
@@ -120,6 +121,7 @@ export function BranchDropdown({
const folderPath = folder?.path ?? ""
const { addTask, updateTask, removeTask } = useTaskContext()
const { pushAlert } = useAlertContext()
const { withCredentialRetry } = useGitCredential()
const [branchList, setBranchList] = useState<GitBranchList>({
local: [],
remote: [],
@@ -335,7 +337,10 @@ export function BranchDropdown({
addTask(taskId, label)
updateTask(taskId, { status: "running" })
try {
const result = await gitPush(folderPath)
const result = await withCredentialRetry(
(creds) => gitPush(folderPath, creds),
{ folderPath }
)
updateTask(taskId, { status: "completed" })
onBranchChange()
let description: string | undefined
@@ -368,7 +373,10 @@ export function BranchDropdown({
status: "running",
})
try {
const pullResult = await gitPull(folderPath)
const pullResult = await withCredentialRetry(
(creds) => gitPull(folderPath, creds),
{ folderPath }
)
if (pullResult.conflict?.has_conflicts) {
removeTask(taskId)
onBranchChange()
@@ -376,7 +384,10 @@ export function BranchDropdown({
} else {
// Pull succeeded, retry push
updateTask(taskId, { status: "running" })
const pushResult = await gitPush(folderPath)
const pushResult = await withCredentialRetry(
(creds) => gitPush(folderPath, creds),
{ folderPath }
)
updateTask(taskId, { status: "completed" })
onBranchChange()
let description: string | undefined
@@ -686,7 +697,11 @@ export function BranchDropdown({
onSelect={() =>
runGitTask(
t("tasks.pullCode"),
() => gitPull(folderPath),
() =>
withCredentialRetry(
(creds) => gitPull(folderPath, creds),
{ folderPath }
),
(result) => {
if (result.conflict?.has_conflicts) {
setConflictInfo(result.conflict)
@@ -708,7 +723,12 @@ export function BranchDropdown({
<DropdownMenuItem
disabled={loading}
onSelect={() =>
runGitTask(t("tasks.fetchInfo"), () => gitFetch(folderPath))
runGitTask(t("tasks.fetchInfo"), () =>
withCredentialRetry(
(creds) => gitFetch(folderPath, creds),
{ folderPath }
)
)
}
>
<RefreshCw className="h-3.5 w-3.5" />

View File

@@ -5,6 +5,7 @@ import { open } from "@tauri-apps/plugin-dialog"
import { useTranslations } from "next-intl"
import { toast } from "sonner"
import { cloneRepository, openFolderWindow } from "@/lib/tauri"
import { useGitCredential } from "@/contexts/git-credential-context"
import {
Dialog,
DialogContent,
@@ -25,6 +26,7 @@ interface CloneDialogProps {
export function CloneDialog({ open: isOpen, onOpenChange }: CloneDialogProps) {
const t = useTranslations("WelcomePage")
const { withCredentialRetry } = useGitCredential()
const [url, setUrl] = useState("")
const [targetDir, setTargetDir] = useState("")
const [cloning, setCloning] = useState(false)
@@ -55,7 +57,10 @@ export function CloneDialog({ open: isOpen, onOpenChange }: CloneDialogProps) {
setError(null)
try {
await cloneRepository(url, fullPath)
await withCredentialRetry(
(creds) => cloneRepository(url, fullPath, creds),
{ remoteUrl: url }
)
await openFolderWindow(fullPath)
onOpenChange(false)
resetForm()