SSPC-Tester/git-manager.ps1
2026-06-30 12:10:29 +08:00

845 lines
31 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<#
.SYNOPSIS
Git 管理工具 — 查看状态、备份节点、管理分支
.DESCRIPTION
通用 Git 仓库管理脚本,适用于任何项目目录。
自动以脚本所在目录作为仓库根目录。
#>
param(
[Parameter(Position=0)]
[string]$Action = ""
)
$ErrorActionPreference = "Stop"
# 统一设置 UTF-8 编码,防止中文乱码
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
$env:LANG = "zh_CN.UTF-8"
Set-Location $PSScriptRoot
# Verify this is a git repo
$isRepo = Test-Path (Join-Path $PSScriptRoot ".git")
if (-not $isRepo) {
Write-Host ""
Write-Host " ╔══════════════════════════════════════╗" -ForegroundColor Cyan
Write-Host " ║ Git 管理工具 ║" -ForegroundColor Cyan
Write-Host " ╚══════════════════════════════════════╝" -ForegroundColor Cyan
Write-Host ""
Write-Host " ● 当前目录尚未初始化 Git 仓库" -ForegroundColor Yellow
Write-Host " ──────────────────────────────"
Write-Host " 路径: $PSScriptRoot" -ForegroundColor White
Write-Host ""
$confirm = Read-Host " 是否立即初始化并创建初始备份? (y/n)"
if ($confirm -ne 'y') {
Write-Host ""
Write-Host " 已取消。请先运行: git init" -ForegroundColor DarkGray
exit 0
}
Write-Host ""
Write-Host " 正在初始化仓库..." -ForegroundColor Yellow
git init
Write-Host " 正在配置本地用户身份..." -ForegroundColor Yellow
git config --local user.name "local"
git config --local user.email "local@localhost"
Write-Host " 正在创建初始备份提交..." -ForegroundColor Yellow
git add -A
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm"
$commitMsg = "[初始备份] $timestamp"
$commitResult = git commit -m $commitMsg 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host ""
Write-Host " ✗ 初始提交失败!" -ForegroundColor Red
Write-Host $commitResult -ForegroundColor Red
exit 1
}
$newHash = try { git rev-parse --short HEAD 2>$null } catch { "unknown" }
Write-Host ""
Write-Host " ✓ Git 仓库已初始化并完成初始备份!" -ForegroundColor Green
Write-Host " 提交: $newHash" -ForegroundColor White
Write-Host " 信息: $commitMsg" -ForegroundColor White
Write-Host ""
Read-Host " 按 Enter 继续进入菜单"
}
function Write-Banner {
Write-Host ""
Write-Host " ╔══════════════════════════════════════╗" -ForegroundColor Cyan
Write-Host " ║ Git 管理工具 ║" -ForegroundColor Cyan
Write-Host " ╚══════════════════════════════════════╝" -ForegroundColor Cyan
Write-Host ""
}
function Show-FullStatus {
Write-Host " ● 完整状态" -ForegroundColor Yellow
Write-Host " ────────────"
# Repo path
$repoPath = (Get-Location).Path
$repoName = Split-Path $repoPath -Leaf
Write-Host " 项目: " -NoNewline; Write-Host $repoName -ForegroundColor White
Write-Host " 仓库: " -NoNewline; Write-Host $repoPath -ForegroundColor White
# Branches
$branches = git branch 2>$null
if ($branches) {
Write-Host " 分支:"
foreach ($b in $branches) {
$b = $b.Trim()
if ($b.StartsWith("*")) { Write-Host " $b" -ForegroundColor Green }
else { Write-Host " $b" }
}
} else { Write-Host " 分支: 无" }
# Remote
$remotes = git remote 2>$null
if ($remotes) {
foreach ($r in $remotes) { Write-Host " 远程: $r" }
} else { Write-Host " 远程: 无(纯本地仓库)" -ForegroundColor DarkGray }
# Last commit
$lastCommit = try { git log -1 --oneline 2>$null } catch { $null }
if ($lastCommit) { Write-Host " 最新: " -NoNewline; Write-Host $lastCommit -ForegroundColor White }
else { Write-Host " 提交: 无(空仓库)" -ForegroundColor DarkGray }
# Commit count
$commitCount = try { git rev-list --count HEAD 2>$null } catch { $null }
if ($commitCount) { Write-Host (" 提交数: {0}" -f $commitCount) }
Write-Host ""
# Files
$tracked = (git ls-files 2>$null).Count
Write-Host " 跟踪: $tracked 个文件"
# Untracked (excluding .git, bin, obj, Logs)
$allFiles = @(Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue | Where-Object {
$_.FullName -notmatch '\\(\.git|bin|obj|Logs)\\?' -and
$_.FullName -notmatch '\\node_modules\\?' -and
$_.FullName -notmatch '\\__pycache__\\?'
}).Count
$untracked = $allFiles - $tracked
Write-Host " 未跟踪: $untracked 个文件"
# Repo size
$gitSize = (Get-ChildItem -Path .git -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
Write-Host (" 仓库: {0:N0} KB (.git)" -f ($gitSize / 1KB))
# Git objects
$objInfo = git count-objects -v 2>$null
$objCount = ($objInfo | Select-String "count:" | Out-String).Trim() -replace '\D',''
$objSize = ($objInfo | Select-String "size:" | Out-String).Trim() -replace '.*:\s*',''
if ($objCount) {
Write-Host (" 对象: {0} 个, {1}" -f $objCount, $objSize)
}
# Uncommitted changes
$changes = git status --short 2>$null
if ($changes) {
Write-Host ""
Write-Host " ● 未提交变更" -ForegroundColor Yellow
Write-Host " ────────────"
foreach ($c in $changes) { Write-Host " $c" }
}
# Stashes
$stashes = git stash list 2>$null
if ($stashes) {
Write-Host ""
Write-Host " ● 暂存 (Stash)" -ForegroundColor Yellow
Write-Host " ──────────────"
foreach ($s in $stashes) { Write-Host " $s" }
}
}
function Show-Branches {
Write-Host ""
Write-Host " ● 分支列表" -ForegroundColor Yellow
Write-Host " ──────────"
$branches = git branch 2>$null
if ($branches) {
Write-Host ""
Write-Host " 本地分支:" -ForegroundColor Cyan
foreach ($b in $branches) {
$b = $b.Trim()
if ($b.StartsWith("*")) {
Write-Host "" -NoNewline -ForegroundColor Green
Write-Host ($b.Substring(1).Trim()) -ForegroundColor Green
} else {
Write-Host " $b"
}
}
}
Write-Host ""
Write-Host " 分支提交:" -ForegroundColor Cyan
$allBranches = git branch 2>$null
foreach ($b in $allBranches) {
$b = $b.Trim().TrimStart('*').Trim()
if ($b) {
$count = try { git rev-list --count $b 2>$null } catch { "0" }
$last = try { git log $b -1 --oneline 2>$null } catch { "" }
Write-Host " $b" -NoNewline
Write-Host (" ({0} commits) " -f $count) -NoNewline -ForegroundColor DarkGray
Write-Host $last -ForegroundColor DarkGray
}
}
}
function Backup-Current {
param([string]$Message)
if (-not $Message) {
$Message = Read-Host " 输入备份信息(描述当前状态)"
if (-not $Message) { Write-Host " 已取消" -ForegroundColor Red; return }
}
Write-Host ""
Write-Host " ● 备份当前状态" -ForegroundColor Yellow
Write-Host " ──────────────"
$hasChanges = git status --porcelain 2>$null
if (-not $hasChanges) {
Write-Host " 工作区干净,无需备份。" -ForegroundColor DarkGray
return
}
Write-Host ""
Write-Host " 将要备份的变更:" -ForegroundColor Cyan
git status --short
Write-Host ""
$confirm = Read-Host " 确认备份? (y/n)"
if ($confirm -ne 'y') { Write-Host " 已取消" -ForegroundColor Red; return }
# 确保本地仓库有用户身份(纯本地备份,自动设置默认值)
$gitUserName = try { git config user.name 2>$null } catch { $null }
$gitUserEmail = try { git config user.email 2>$null } catch { $null }
if (-not $gitUserName) { git config --local user.name "local" }
if (-not $gitUserEmail) { git config --local user.email "local@localhost" }
git add -A
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm"
$commitMsg = "[备份] $timestamp - $Message"
$commitResult = git commit -m $commitMsg 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host ""
Write-Host " ✗ 备份失败!" -ForegroundColor Red
Write-Host $commitResult -ForegroundColor Red
return
}
$newHash = try { git rev-parse --short HEAD 2>$null } catch { "unknown" }
$fileCount = try { @(git diff-tree --no-commit-id --name-only -r HEAD 2>$null).Count } catch { 0 }
Write-Host ""
Write-Host " ✓ 备份完成!" -ForegroundColor Green
Write-Host " 提交: $newHash" -ForegroundColor White
Write-Host " 信息: $commitMsg" -ForegroundColor White
Write-Host " 文件: $fileCount 个文件已保存"
}
function New-Branch {
param([string]$Name)
if (-not $Name) { $Name = Read-Host " 输入新分支名称" }
if (-not $Name) { Write-Host " 已取消" -ForegroundColor Red; return }
$hasChanges = git status --porcelain 2>$null
if ($hasChanges) {
Write-Host " 当前有未提交变更,建议先备份。" -ForegroundColor Yellow
$confirm = Read-Host " 自动备份后创建分支? (y/n)"
if ($confirm -eq 'y') { Backup-Current -Message "创建分支 $Name 前的自动备份" }
else { Write-Host " 已取消" -ForegroundColor Red; return }
}
git checkout -b $Name
Write-Host " ✓ 已创建并切换到分支: $Name" -ForegroundColor Green
}
function Switch-Branch {
param([string]$Name)
if (-not $Name) {
Write-Host " 可用分支:" -ForegroundColor Cyan
git branch
$Name = Read-Host " 输入要切换的分支名"
}
if (-not $Name) { Write-Host " 已取消" -ForegroundColor Red; return }
$hasChanges = git status --porcelain 2>$null
if ($hasChanges) {
Write-Host " 当前有未提交变更!" -ForegroundColor Yellow
$confirm = Read-Host " 自动备份后切换? (y/n)"
if ($confirm -eq 'y') { Backup-Current -Message "切换到 $Name 前的自动备份" }
else { Write-Host " 已取消" -ForegroundColor Red; return }
}
git checkout $Name
Write-Host " ✓ 已切换到分支: $Name" -ForegroundColor Green
}
function Merge-Branch {
param([string]$Source)
if (-not $Source) {
Write-Host " 可用分支:" -ForegroundColor Cyan
git branch
$Source = Read-Host " 输入要合并的源分支名"
}
if (-not $Source) { Write-Host " 已取消" -ForegroundColor Red; return }
$currentBranch = git rev-parse --abbrev-ref HEAD
Write-Host " 将合并 " -NoNewline
Write-Host $Source -NoNewline -ForegroundColor Yellow
Write-Host "" -NoNewline
Write-Host $currentBranch -ForegroundColor Yellow
$hasChanges = git status --porcelain 2>$null
if ($hasChanges) {
Write-Host " 当前有未提交变更!" -ForegroundColor Yellow
$confirm = Read-Host " 自动备份后继续? (y/n)"
if ($confirm -eq 'y') { Backup-Current -Message "合并 $Source 前的自动备份" }
else { Write-Host " 已取消" -ForegroundColor Red; return }
}
$result = git merge $Source 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host " ✗ 合并冲突! 请手动解决。" -ForegroundColor Red
Write-Host ""
Write-Host " 冲突文件:" -ForegroundColor Yellow
git diff --name-only --diff-filter=U
Write-Host ""
Write-Host " 解决后运行: git add <文件> ; git commit" -ForegroundColor Cyan
} else {
Write-Host " ✓ 合并成功!" -ForegroundColor Green
}
}
function Delete-Branch {
param([string]$Name)
if (-not $Name) {
Write-Host " 可用分支:" -ForegroundColor Cyan
git branch
$Name = Read-Host " 输入要删除的分支名"
}
if (-not $Name) { Write-Host " 已取消" -ForegroundColor Red; return }
$currentBranch = git rev-parse --abbrev-ref HEAD
if ($Name -eq $currentBranch) {
Write-Host " 不能删除当前所在分支!" -ForegroundColor Red
return
}
$unmerged = try { git log $currentBranch..$Name --oneline 2>$null } catch { $null }
if ($unmerged) {
Write-Host " ⚠ 分支 $Name 有未合并的提交:" -ForegroundColor Yellow
Write-Host $unmerged
$confirm = Read-Host " 强制删除? (y/n)"
if ($confirm -eq 'y') { git branch -D $Name }
else { Write-Host " 已取消" -ForegroundColor Red; return }
} else {
git branch -d $Name
}
Write-Host " ✓ 已删除分支: $Name" -ForegroundColor Green
}
function Reset-Git {
Clear-Host
Write-Banner
Write-Host " ● 重置 Git 仓库" -ForegroundColor Red
Write-Host " ────────────────"
Write-Host ""
Write-Host " ⚠ 警告:此操作将删除所有 Git 历史记录!" -ForegroundColor Yellow
Write-Host " ⚠ 当前所有分支、提交、备份节点将永久丢失!" -ForegroundColor Yellow
Write-Host ""
Write-Host " 操作完成后将:" -ForegroundColor Cyan
Write-Host " 1. 删除 .git 目录(清除全部历史)"
Write-Host " 2. 重新执行 git init"
Write-Host " 3. 自动创建初始备份提交"
Write-Host ""
Write-Host " 如果确认,请输入 " -NoNewline
Write-Host "yes" -NoNewline -ForegroundColor Red
Write-Host "(其他任何输入均取消)"
Write-Host ""
$confirm = Read-Host " 请输入确认"
if ($confirm -ne 'yes') {
Write-Host ""
Write-Host " 已取消Git 历史未改变。" -ForegroundColor Green
return
}
Write-Host ""
Write-Host " 正在删除 .git 目录..." -ForegroundColor Yellow
Remove-Item -Recurse -Force (Join-Path $PSScriptRoot ".git")
Write-Host " 正在初始化新仓库..." -ForegroundColor Yellow
git init
Write-Host " 正在配置本地用户身份..." -ForegroundColor Yellow
git config --local user.name "local"
git config --local user.email "local@localhost"
Write-Host " 正在创建初始备份提交..." -ForegroundColor Yellow
git add -A
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm"
$commitMsg = "[初始备份] $timestamp"
$commitResult = git commit -m $commitMsg 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host ""
Write-Host " ✗ 初始提交失败!" -ForegroundColor Red
Write-Host $commitResult -ForegroundColor Red
return
}
$newHash = try { git rev-parse --short HEAD 2>$null } catch { "unknown" }
Write-Host ""
Write-Host " ✓ Git 仓库已重置并完成初始备份!" -ForegroundColor Green
Write-Host " 提交: $newHash" -ForegroundColor White
Write-Host " 信息: $commitMsg" -ForegroundColor White
}
function Show-Log {
Write-Host ""
Write-Host " ● 提交历史(最近 20 条)" -ForegroundColor Yellow
Write-Host " ────────────────────────"
Write-Host ""
git log --oneline --graph --decorate -20 --all
}
# ==================== 恢复相关函数 ====================
function Show-RecentCommits {
param([int]$Count = 15)
Write-Host " 最近 $Count 条提交:" -ForegroundColor Cyan
Write-Host " ────────────────"
$i = 0
$commits = git log --pretty=format:"%h|%ad|%s" --date=format:"%Y-%m-%d %H:%M" -$Count 2>$null
$list = @()
foreach ($line in $commits) {
$parts = $line -split '\|', 3
$i++
$list += [PSCustomObject]@{
Index = $i
Hash = $parts[0]
Date = $parts[1]
Subject = $parts[2]
}
$idxStr = "{0,2}" -f $i
Write-Host " [$idxStr] " -NoNewline -ForegroundColor Yellow
Write-Host $parts[0] -NoNewline -ForegroundColor Green
Write-Host " $($parts[1]) " -NoNewline -ForegroundColor DarkGray
Write-Host $parts[2] -ForegroundColor White
}
return ,$list
}
function Restore-Last {
Write-Host ""
Write-Host " ● 恢复到上一次备份(丢弃所有未提交修改)" -ForegroundColor Yellow
Write-Host " ─────────────────────────────────────────"
$hasChanges = git status --porcelain 2>$null
if (-not $hasChanges) {
Write-Host " 工作区干净,无需恢复。" -ForegroundColor DarkGray
return
}
Write-Host ""
Write-Host " 当前未提交变更:" -ForegroundColor Cyan
git status --short
Write-Host ""
Write-Host " ⚠ 执行后所有未提交修改将丢失!" -ForegroundColor Red
$confirm = Read-Host " 确认恢复到 HEAD? (y/n)"
if ($confirm -ne 'y') { Write-Host " 已取消" -ForegroundColor Red; return }
git reset --hard HEAD
git clean -fd
Write-Host ""
Write-Host " ✓ 已恢复到 HEAD!" -ForegroundColor Green
$head = try { git log -1 --oneline 2>$null } catch { "" }
Write-Host " 当前: $head" -ForegroundColor White
}
function Restore-Commit {
param([string]$Target)
Write-Host ""
Write-Host " ● 恢复到指定提交" -ForegroundColor Yellow
Write-Host " ────────────────"
Write-Host ""
$list = Show-RecentCommits -Count 20
if (-not $Target) {
Write-Host ""
$sel = Read-Host " 输入编号或 commit hash留空取消"
if (-not $sel) { Write-Host " 已取消" -ForegroundColor Red; return }
if ($sel -match '^\d+$') {
$idx = [int]$sel
$item = $list | Where-Object { $_.Index -eq $idx } | Select-Object -First 1
if (-not $item) { Write-Host " 无效编号" -ForegroundColor Red; return }
$Target = $item.Hash
} else {
$Target = $sel
}
}
# 验证提交存在
$exists = git rev-parse --verify "$Target^{commit}" 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Host " ✗ 提交不存在: $Target" -ForegroundColor Red
return
}
$shortHash = git rev-parse --short $Target
$subject = git log -1 --pretty=format:"%s" $Target
Write-Host ""
Write-Host " 目标提交: " -NoNewline
Write-Host $shortHash -NoNewline -ForegroundColor Green
Write-Host " $subject" -ForegroundColor White
Write-Host ""
Write-Host " 恢复模式:" -ForegroundColor Cyan
Write-Host " [1] 软恢复(仅移动 HEAD保留所有修改在暂存区"
Write-Host " [2] 混合恢复(移动 HEAD保留修改在工作区默认"
Write-Host " [3] 硬恢复(彻底回退,丢弃之后所有修改) " -NoNewline
Write-Host "[危险]" -ForegroundColor Red
Write-Host " [4] 检出文件(只把目标提交的文件覆盖到工作区,不动历史)"
Write-Host " [0] 取消"
$mode = Read-Host " 请选择恢复模式"
switch ($mode) {
"1" {
git reset --soft $Target
Write-Host " ✓ 已软恢复到 $shortHash" -ForegroundColor Green
}
"2" {
git reset --mixed $Target
Write-Host " ✓ 已混合恢复到 $shortHash" -ForegroundColor Green
}
"3" {
Write-Host " ⚠ 此操作不可恢复!" -ForegroundColor Red
$sure = Read-Host " 请输入 yes 确认硬恢复"
if ($sure -ne 'yes') { Write-Host " 已取消" -ForegroundColor Red; return }
$hasChanges = git status --porcelain 2>$null
if ($hasChanges) {
$bak = Read-Host " 执行前是否先备份当前状态? (y/n)"
if ($bak -eq 'y') { Backup-Current -Message "硬恢复到 $shortHash 前的自动备份" }
}
git reset --hard $Target
git clean -fd
Write-Host " ✓ 已硬恢复到 $shortHash" -ForegroundColor Green
}
"4" {
git checkout $Target -- .
Write-Host " ✓ 已检出 $shortHash 的全部文件到工作区" -ForegroundColor Green
Write-Host " 提示: 修改尚未提交,可用 [备份] 创建新提交" -ForegroundColor DarkGray
}
default { Write-Host " 已取消" -ForegroundColor Red }
}
}
function Restore-File {
Write-Host ""
Write-Host " ● 恢复指定文件" -ForegroundColor Yellow
Write-Host " ──────────────"
$file = Read-Host " 输入要恢复的文件路径(相对仓库根)"
if (-not $file) { Write-Host " 已取消" -ForegroundColor Red; return }
Write-Host ""
Write-Host " [1] 从 HEAD 恢复(撤销该文件未提交修改)"
Write-Host " [2] 从指定提交恢复"
$m = Read-Host " 选择来源"
if ($m -eq "1") {
git checkout HEAD -- $file
} elseif ($m -eq "2") {
$list = Show-RecentCommits -Count 15
$sel = Read-Host " 输入编号或 commit hash"
if (-not $sel) { Write-Host " 已取消" -ForegroundColor Red; return }
$target = $sel
if ($sel -match '^\d+$') {
$item = $list | Where-Object { $_.Index -eq [int]$sel } | Select-Object -First 1
if (-not $item) { Write-Host " 无效编号" -ForegroundColor Red; return }
$target = $item.Hash
}
git checkout $target -- $file
} else { Write-Host " 已取消" -ForegroundColor Red; return }
if ($LASTEXITCODE -eq 0) {
Write-Host " ✓ 文件已恢复: $file" -ForegroundColor Green
} else {
Write-Host " ✗ 恢复失败" -ForegroundColor Red
}
}
function Undo-LastCommit {
Write-Host ""
Write-Host " ● 撤销最后一次提交(保留修改在工作区)" -ForegroundColor Yellow
Write-Host " ──────────────────────────────────────"
$count = try { [int](git rev-list --count HEAD 2>$null) } catch { 0 }
if ($count -lt 1) { Write-Host " 无提交可撤销" -ForegroundColor Red; return }
$last = git log -1 --oneline
Write-Host " 最后一次提交: " -NoNewline
Write-Host $last -ForegroundColor White
Write-Host ""
Write-Host " [1] 撤销提交但保留修改git reset --soft HEAD~1"
Write-Host " [2] 撤销提交并丢弃修改git reset --hard HEAD~1 " -NoNewline
Write-Host "[危险]" -ForegroundColor Red
Write-Host " [0] 取消"
$m = Read-Host " 选择"
switch ($m) {
"1" {
git reset --soft HEAD~1
Write-Host " ✓ 已撤销提交,修改保留在暂存区。" -ForegroundColor Green
}
"2" {
$sure = Read-Host " 请输入 yes 确认丢弃"
if ($sure -ne 'yes') { Write-Host " 已取消" -ForegroundColor Red; return }
git reset --hard HEAD~1
Write-Host " ✓ 已撤销并丢弃修改。" -ForegroundColor Green
}
default { Write-Host " 已取消" -ForegroundColor Red }
}
}
# ==================== 子菜单 ====================
function Show-BranchMenu {
do {
Clear-Host
Write-Banner
Show-Branches
Write-Host ""
Write-Host " ● 分支操作菜单" -ForegroundColor Yellow
Write-Host " ──────────────"
Write-Host " [1] 创建新分支" -ForegroundColor White
Write-Host " [2] 切换分支" -ForegroundColor White
Write-Host " [3] 合并分支" -ForegroundColor White
Write-Host " [4] 删除分支" -ForegroundColor White
Write-Host " [5] 刷新列表" -ForegroundColor DarkGray
Write-Host " [0] 返回主菜单" -ForegroundColor DarkGray
Write-Host ""
$c = Read-Host " 请选择 [0-5]"
switch ($c) {
"1" { New-Branch; Read-Host "`n 按 Enter 继续" }
"2" { Switch-Branch; Read-Host "`n 按 Enter 继续" }
"3" { Merge-Branch; Read-Host "`n 按 Enter 继续" }
"4" { Delete-Branch; Read-Host "`n 按 Enter 继续" }
"5" { continue }
"0" { return }
default { Write-Host " 无效选择" -ForegroundColor Red; Start-Sleep -Seconds 1 }
}
} while ($true)
}
function Show-RestoreMenu {
do {
Clear-Host
Write-Banner
Write-Host " 当前分支: " -NoNewline
Write-Host (git rev-parse --abbrev-ref HEAD) -ForegroundColor Yellow
$head = try { git log -1 --oneline 2>$null } catch { "" }
Write-Host " 当前 HEAD: " -NoNewline; Write-Host $head -ForegroundColor White
$changes = git status --short 2>$null
if ($changes) {
Write-Host ""
Write-Host " 未提交变更:" -ForegroundColor Cyan
foreach ($l in $changes) { Write-Host " $l" }
}
Write-Host ""
Write-Host " ● 恢复操作菜单" -ForegroundColor Yellow
Write-Host " ──────────────"
Write-Host " [1] 恢复到上一次备份(丢弃未提交修改)" -ForegroundColor White
Write-Host " [2] 恢复到指定提交(软/混合/硬/检出文件)" -ForegroundColor White
Write-Host " [3] 恢复指定文件" -ForegroundColor White
Write-Host " [4] 撤销最后一次提交" -ForegroundColor White
Write-Host " [5] 查看提交历史" -ForegroundColor DarkGray
Write-Host " [0] 返回主菜单" -ForegroundColor DarkGray
Write-Host ""
$c = Read-Host " 请选择 [0-5]"
switch ($c) {
"1" { Restore-Last; Read-Host "`n 按 Enter 继续" }
"2" { Restore-Commit; Read-Host "`n 按 Enter 继续" }
"3" { Restore-File; Read-Host "`n 按 Enter 继续" }
"4" { Undo-LastCommit; Read-Host "`n 按 Enter 继续" }
"5" { Show-Log; Read-Host "`n 按 Enter 继续" }
"0" { return }
default { Write-Host " 无效选择" -ForegroundColor Red; Start-Sleep -Seconds 1 }
}
} while ($true)
}
# ==================== 交互菜单 ====================
function Show-Menu {
Show-FullStatus
Write-Host ""
Write-Host " ● 操作菜单" -ForegroundColor Yellow
Write-Host " ──────────"
Write-Host " [1] 备份当前状态(手动输入描述信息)" -ForegroundColor White
Write-Host " [2] 查看分支详情" -ForegroundColor White
Write-Host " [3] 分支操作(创建/切换/合并/删除) →" -ForegroundColor White
Write-Host " [4] 恢复操作(上一次/指定提交/文件/撤销)→" -ForegroundColor White
Write-Host " [5] 查看提交历史" -ForegroundColor White
Write-Host " [9] 重置 Git 仓库(清除全部历史)" -ForegroundColor DarkRed
Write-Host " [0] 退出" -ForegroundColor DarkGray
Write-Host ""
}
function Show-Help {
Write-Host "Git 管理工具 — 通用仓库管理脚本"
Write-Host ""
Write-Host "用法: .\git-manager.ps1 [操作] [参数]"
Write-Host ""
Write-Host "命令行操作:"
Write-Host " (无参数) 交互模式"
Write-Host " status 查看完整仓库状态"
Write-Host " branches 查看分支详情"
Write-Host " backup <信息> 备份当前状态"
Write-Host " new <分支名> 创建新分支"
Write-Host " switch <分支名> 切换分支"
Write-Host " merge <分支名> 合并分支"
Write-Host " delete <分支名> 删除分支"
Write-Host " restore 打开恢复子菜单"
Write-Host " restore-last 恢复到上一次备份(丢弃未提交修改)"
Write-Host " restore-commit <hash> 恢复到指定提交"
Write-Host " undo 撤销最后一次提交"
Write-Host " log 查看提交历史"
Write-Host " help 显示帮助"
Write-Host ""
Write-Host "示例:"
Write-Host " .\git-manager.ps1 status"
Write-Host " .\git-manager.ps1 backup '修复播放器bug美化界面'"
Write-Host " .\git-manager.ps1 new feature-audio"
Write-Host " .\git-manager.ps1 restore-last"
Write-Host " .\git-manager.ps1 restore-commit a1b2c3d"
}
# ==================== 入口 ====================
# Normalize action
$action = $Action.ToLower().Trim()
if ($action -eq "" -or $action -eq "menu") {
# Interactive mode
do {
Clear-Host
Write-Banner
Show-Menu
$choice = Read-Host " 请选择操作 [0-9]"
switch ($choice) {
"1" {
Clear-Host
Write-Banner
Show-FullStatus
Backup-Current
Read-Host "`n 按 Enter 返回菜单"
}
"2" {
Clear-Host
Write-Banner
Show-Branches
Show-Log
Read-Host "`n 按 Enter 返回菜单"
}
"3" {
Show-BranchMenu
}
"4" {
Show-RestoreMenu
}
"5" {
Clear-Host
Write-Banner
Show-Log
Read-Host "`n 按 Enter 返回菜单"
}
"9" {
Reset-Git
Read-Host "`n 按 Enter 返回菜单"
}
"0" {
Write-Host "`n 再见!" -ForegroundColor Cyan
break
}
default {
Write-Host "`n 无效选择,请重试。" -ForegroundColor Red
Start-Sleep -Seconds 1
}
}
} while ($choice -ne "0")
}
else {
# Command-line mode
switch ($action) {
"status" {
Write-Banner
Show-FullStatus
Show-Log
}
"branches" {
Write-Banner
Show-Branches
}
"backup" {
Write-Banner
$msg = $args -join " "
Backup-Current -Message $msg
}
"new" {
Write-Banner
New-Branch -Name $args[0]
}
"switch" {
Write-Banner
Switch-Branch -Name $args[0]
}
"merge" {
Write-Banner
Merge-Branch -Source $args[0]
}
"delete" {
Write-Banner
Delete-Branch -Name $args[0]
}
"restore" {
Show-RestoreMenu
}
"restore-last" {
Write-Banner
Restore-Last
}
"restore-commit" {
Write-Banner
Restore-Commit -Target $args[0]
}
"undo" {
Write-Banner
Undo-LastCommit
}
"log" {
Write-Banner
Show-Log
}
"help" {
Show-Help
}
default {
Write-Host "未知操作: $Action" -ForegroundColor Red
Write-Host ""
Show-Help
}
}
}