feat: 开发者面板页面git工具支持推送远程仓库
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { GitBranch, GitCommit as GitCommitIcon, CornerRightUp, RotateCcw, AlertTriangle, RefreshCw, GitCommit } from 'lucide-react'
|
||||
import { GitBranch, GitCommit as GitCommitIcon, CornerRightUp, RotateCcw, AlertTriangle, RefreshCw, GitCommit, Upload } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
import { trpc } from '@/lib/trpc'
|
||||
@@ -73,7 +73,7 @@ export function VersionControl({ isOpen }: { isOpen: boolean }) {
|
||||
const [isLoadingMore, setIsLoadingMore] = React.useState(false)
|
||||
const [commitType, setCommitType] = React.useState<'normal' | 'amend' | null>(null)
|
||||
const [confirmAction, setConfirmAction] = React.useState<{
|
||||
type: 'checkout' | 'checkout-branch' | 'revert' | 'reset'
|
||||
type: 'checkout' | 'checkout-branch' | 'revert' | 'reset' | 'push'
|
||||
commitId?: string
|
||||
message?: string
|
||||
title?: string
|
||||
@@ -191,6 +191,17 @@ export function VersionControl({ isOpen }: { isOpen: boolean }) {
|
||||
},
|
||||
})
|
||||
|
||||
// 推送远程仓库mutation
|
||||
const pushToRemoteMutation = trpc.devPanel!.pushToRemote.useMutation({
|
||||
onSuccess: (data) => {
|
||||
toast.success(data.message)
|
||||
setConfirmAction(null)
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error(error.message)
|
||||
},
|
||||
})
|
||||
|
||||
// 处理分支选择(仅用于查看历史,不切换实际分支)
|
||||
const handleBranchChange = (branchName: string | null) => {
|
||||
if (!branchName) return
|
||||
@@ -306,9 +317,21 @@ export function VersionControl({ isOpen }: { isOpen: boolean }) {
|
||||
resetToCommitMutation.mutate({ commitId: confirmAction.commitId })
|
||||
}
|
||||
break
|
||||
case 'push':
|
||||
pushToRemoteMutation.mutate({ branchName: selectedBranch })
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 处理推送远程仓库
|
||||
const handlePushToRemote = () => {
|
||||
setConfirmAction({
|
||||
type: 'push',
|
||||
title: '推送到远程仓库',
|
||||
description: `确定要将分支 "${selectedBranch}" 的最新提交推送到远程仓库吗?`,
|
||||
})
|
||||
}
|
||||
|
||||
// 手动刷新所有数据
|
||||
const handleRefresh = () => {
|
||||
refetchBranches()
|
||||
@@ -357,7 +380,7 @@ export function VersionControl({ isOpen }: { isOpen: boolean }) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右半部分:Commit按钮和刷新按钮 */}
|
||||
{/* 右半部分:Commit按钮、推送按钮和刷新按钮 */}
|
||||
<div className="flex items-center gap-2 flex-1 justify-end">
|
||||
<Button
|
||||
onClick={() => setShowCommitDialog(true)}
|
||||
@@ -367,6 +390,16 @@ export function VersionControl({ isOpen }: { isOpen: boolean }) {
|
||||
<GitCommit className="mr-2 h-4 w-4" />
|
||||
提交更改
|
||||
</Button>
|
||||
{selectedBranch && !selectedBranch.startsWith('origin/') && (
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handlePushToRemote}
|
||||
disabled={pushToRemoteMutation.isPending}
|
||||
title="推送到远程仓库"
|
||||
>
|
||||
<Upload className={cn("h-4 w-4", pushToRemoteMutation.isPending && "animate-pulse")} />
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handleRefresh}
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
resetToCommit,
|
||||
getCurrentBranch,
|
||||
hasUncommittedChanges,
|
||||
pushToRemote,
|
||||
} from '@/server/utils/git-helper'
|
||||
|
||||
|
||||
@@ -224,6 +225,25 @@ export const devPanelRouter = createTRPCRouter({
|
||||
})
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* 推送分支到远程仓库
|
||||
*/
|
||||
pushToRemote: permissionRequiredProcedure('SUPER_ADMIN_ONLY')
|
||||
.input(z.object({
|
||||
branchName: z.string().min(1, '分支名称不能为空'),
|
||||
}))
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
await pushToRemote(input.branchName)
|
||||
return { success: true, message: `已推送分支 ${input.branchName} 到远程仓库` }
|
||||
} catch (error: any) {
|
||||
throw new TRPCError({
|
||||
code: 'INTERNAL_SERVER_ERROR',
|
||||
message: `推送失败: ${error.message}`,
|
||||
})
|
||||
}
|
||||
}),
|
||||
})
|
||||
|
||||
export type DevPanelRouter = typeof devPanelRouter
|
||||
@@ -632,3 +632,19 @@ export async function hasUncommittedChanges(): Promise<boolean> {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送当前分支到远程仓库
|
||||
* @param branchName 分支名称
|
||||
*/
|
||||
export async function pushToRemote(branchName: string): Promise<void> {
|
||||
try {
|
||||
await execAsync(`git push origin "${branchName}"`, {
|
||||
cwd: process.cwd(),
|
||||
encoding: 'utf-8',
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('推送到远程仓库失败:', error)
|
||||
throw new Error(`无法推送到远程仓库: ${error instanceof Error ? error.message : String(error)}`)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user