git-clone-resume 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +69 -0
- package/README.md +2 -0
- package/git-clone-resume.ps1 +65 -6
- package/git-clone-resume.tui.ps1 +31 -9
- package/package.json +3 -2
package/README.en.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Git Clone Resume for Windows
|
|
2
|
+
|
|
3
|
+
Resume-friendly partial cloning for GitHub and other unstable networks. The tool fetches commit/tree metadata first, then checks out files in batches. Run the same command again after an interruption to resume.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Git for Windows >= 2.19
|
|
8
|
+
- Windows PowerShell 5.1 or PowerShell 7+
|
|
9
|
+
- Optional: `git config --global core.longpaths true`
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
Install from npm:
|
|
14
|
+
|
|
15
|
+
```powershell
|
|
16
|
+
npm install -g git-clone-resume
|
|
17
|
+
gcr https://github.com/user/repo.git
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The package still requires Git for Windows and PowerShell. Release ZIP packages contain both `gcr` and `git-clone-resume` launchers.
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
Start the fullscreen wizard without a URL, or pass a URL directly:
|
|
25
|
+
|
|
26
|
+
```bat
|
|
27
|
+
git-clone-resume.cmd
|
|
28
|
+
git-clone-resume.cmd https://github.com/user/repo.git
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
PowerShell users can call the script directly:
|
|
32
|
+
|
|
33
|
+
```powershell
|
|
34
|
+
.\git-clone-resume.ps1 https://github.com/user/repo.git -Ref main -OutDir D:\src\repo
|
|
35
|
+
.\git-clone-resume.ps1 https://github.com/user/repo.git -Include src/*,docs/* -Exclude *.bin
|
|
36
|
+
.\git-clone-resume.ps1 https://github.com/user/repo.git -BatchSize 64 -MaxRetries 12
|
|
37
|
+
.\git-clone-resume.ps1 https://github.com/user/repo.git -Verify
|
|
38
|
+
.\git-clone-resume.ps1 https://github.com/user/repo.git -DryRun
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Use `-NoTui` in CI or when output is redirected. Use `-Tui` to force the fullscreen interface.
|
|
42
|
+
|
|
43
|
+
## Language
|
|
44
|
+
|
|
45
|
+
On the first wizard screen, select `Language` and choose Chinese or English. Press `L` in the wizard or progress panel to switch at any time. The command-line equivalent is:
|
|
46
|
+
|
|
47
|
+
```powershell
|
|
48
|
+
.\git-clone-resume.ps1 https://github.com/user/repo.git -Language en-US
|
|
49
|
+
.\git-clone-resume.ps1 https://github.com/user/repo.git -Language zh-CN
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Resume State
|
|
53
|
+
|
|
54
|
+
Progress is stored outside the worktree in `.git/partial-resume/`. Do not delete the target repository's `.git` directory. Completed files are skipped on subsequent runs; failed files are retried.
|
|
55
|
+
|
|
56
|
+
The tool skips submodule gitlinks. Run it separately for submodules. After checking out Git LFS files, run `git lfs pull` if actual LFS content is needed.
|
|
57
|
+
|
|
58
|
+
## TUI Keys
|
|
59
|
+
|
|
60
|
+
- `Q` / `Ctrl+C`: stop after the current Git command; press again to force stop
|
|
61
|
+
- `P` / `Esc`: pause after the current batch
|
|
62
|
+
- `Space`: resume from pause
|
|
63
|
+
- `F`: show failed files
|
|
64
|
+
- `L`: switch language
|
|
65
|
+
- `Up` / `Down` / `j` / `k`: scroll activity
|
|
66
|
+
- `?` / `H`: show help
|
|
67
|
+
- `Enter`: close the result screen
|
|
68
|
+
|
|
69
|
+
See the Chinese guide in [README.md](README.md) for the full implementation details and release channels.
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Git 断点续传克隆(Windows)
|
|
2
2
|
|
|
3
|
+
English documentation: [README.en.md](README.en.md). 启动向导时可选择语言,也可使用 `-Language en-US`;向导和克隆面板中按 `L` 可随时切换。
|
|
4
|
+
|
|
3
5
|
针对 GitHub 等网络不稳定场景:先用 **partial clone** 只拉 commit/tree 元数据,再 **按批 checkout 文件**。中断后用同一条命令再跑即可续传。
|
|
4
6
|
|
|
5
7
|
对应 Linux 参考脚本:<https://github.com/chaihahaha/git-cheatsheet> 中的 `clone_1by1.sh`。
|
package/git-clone-resume.ps1
CHANGED
|
@@ -105,6 +105,9 @@ param(
|
|
|
105
105
|
|
|
106
106
|
[switch]$NoTui,
|
|
107
107
|
|
|
108
|
+
[ValidateSet("zh-CN", "en-US")]
|
|
109
|
+
[string]$Language = "zh-CN",
|
|
110
|
+
|
|
108
111
|
[switch]$ResumeLast,
|
|
109
112
|
|
|
110
113
|
[switch]$Help
|
|
@@ -133,6 +136,57 @@ $script:StateDirName = "partial-resume"
|
|
|
133
136
|
$script:GcrTuiWanted = $false
|
|
134
137
|
$script:GcrExitCode = 0
|
|
135
138
|
$script:GcrUserStop = $false
|
|
139
|
+
$script:GcrLanguage = $Language
|
|
140
|
+
|
|
141
|
+
function Convert-GcrText {
|
|
142
|
+
param([AllowNull()][string]$Text)
|
|
143
|
+
if ($null -eq $Text -or $script:GcrLanguage -ne "en-US") { return $Text }
|
|
144
|
+
$pairs = @(
|
|
145
|
+
@("未找到 git。请先安装 Git for Windows", "Git was not found. Install Git for Windows"),
|
|
146
|
+
@("错误:", "Error:"), @("必须提供仓库 URL。", "A repository URL is required."),
|
|
147
|
+
@("无法读取历史记录。", "Could not read history."),
|
|
148
|
+
@("没有可恢复的历史记录。请先启动过一次克隆。", "No resumable history was found. Start a clone first."),
|
|
149
|
+
@("向导失败:", "Wizard failed:"), @("无法开始克隆", "Could not start clone"),
|
|
150
|
+
@("当前终端无法进入全屏 TUI,改用日志模式。Windows Terminal 下再试,或去掉 -Tui。", "This terminal cannot enter fullscreen TUI; using log mode. Try Windows Terminal or remove -Tui."),
|
|
151
|
+
@("已由用户停止。", "Stopped by user."), @("再次运行同一命令即可续传。", "Run the same command again to resume."),
|
|
152
|
+
@("使用 ", "Using "), @("仓库:", "Repository:"), @("目录:", "Directory:"), @("引用:", "Ref:"),
|
|
153
|
+
@("语言", "Language"), @("中文", "Chinese"), @("英文", "English"), @("开", "On"), @("关", "Off"),
|
|
154
|
+
@("目标 commit:", "Target commit:"), @("fetch 元数据:", "Fetching metadata:"), @("枚举文件树", "Enumerating file tree"),
|
|
155
|
+
@("树中条目:", "Tree entries:"), @("待处理文件:", "Pending files:"), @("工作区:", "Workspace:"),
|
|
156
|
+
@("全部文件已就绪。", "All files are ready."), @("完成", "Complete"), @("克隆完成", "Clone complete"),
|
|
157
|
+
@("部分文件失败", "Some files failed"), @("失败列表:", "Failure list:"), @("仍失败:", "Still failed:"),
|
|
158
|
+
@("批次", "Batch"), @("失败", "failed"), @("单文件失败:", "Single-file failure:"), @("出错", "Error"),
|
|
159
|
+
@("已停止", "Stopped"), @("中断后续传: ", "Resume after interruption: "), @("仓库目录:", "Repository directory:"),
|
|
160
|
+
@("文件数:", "Files:"), @("清单文件:", "List file:"), @("DryRun 完成", "DryRun complete"),
|
|
161
|
+
@("未下载 blob。去掉 -DryRun 后开始/继续克隆。", "No blobs were downloaded. Remove -DryRun to start or resume."),
|
|
162
|
+
@("检查工作区已有文件", "Checking existing workspace files"), @("进度: 已记录", "Progress: recorded"),
|
|
163
|
+
@("分 ", "Downloading in "), @(" 批下载,每批最多 ", " batches, up to "), @(" 个文件", " files each"),
|
|
164
|
+
@("跳过", "Skipped"), @("个子模块(gitlink)。需要的话请在对应目录单独再跑本脚本。", " submodules (gitlinks). Run this script separately if needed.")
|
|
165
|
+
,@("断点续传克隆", "Resumable clone"), @("按批 checkout", "batch checkout"), @("刚刚", "just now"),
|
|
166
|
+
@("分钟前", " minutes ago"), @("小时前", " hours ago"), @("天前", " days ago"),
|
|
167
|
+
@("就绪", "Ready"), @("设置", "Setup"), @("初始化仓库", "Initialize repository"), @("拉取元数据", "Fetch metadata"),
|
|
168
|
+
@("枚举文件树", "List file tree"), @("扫描已有文件", "Scan existing files"), @("下载文件", "Download files"),
|
|
169
|
+
@("修复 git index", "Repair git index"), @("快捷键说明。任意键关闭此帮助。", "Keyboard help. Press any key to close."),
|
|
170
|
+
@("失败文件列表。F 返回活动日志,再次运行同一命令会重试。", "Failed files. Press F to return; run the same command to retry."),
|
|
171
|
+
@("本次运行已结束。Enter 关闭界面,进度保留在 .git/partial-resume/。", "This run has ended. Press Enter to close; progress remains in .git/partial-resume/."),
|
|
172
|
+
@("已暂停:当前批次结束后停住。Space 继续,Q 停止。", "Paused after the current batch. Space resumes; Q stops."),
|
|
173
|
+
@("全部完成。工作区已可用。", "Everything is complete. The workspace is ready."),
|
|
174
|
+
@("出错或未完成。重新运行同一命令即可从断点继续。", "Failed or incomplete. Run the same command to resume."),
|
|
175
|
+
@("远程仓库地址,支持 https、ssh、git@ 以及本地路径。Ctrl+V 从剪贴板粘贴。", "Remote repository URL. Supports https, ssh, git@, and local paths. Ctrl+V pastes from the clipboard."),
|
|
176
|
+
@("工作区目录。留空则用仓库名。已有 .git/partial-resume 时自动续传。", "Workspace directory. Leave empty to use the repository name. Existing .git/partial-resume state resumes automatically."),
|
|
177
|
+
@("选择界面语言。可随时按 L 在中文和英文之间切换。", "Interface language. Press L at any time to switch between Chinese and English."),
|
|
178
|
+
@("最近任务", "Recent tasks"), @("切换", "switch"), @("填入", "fill in"), @("无。完成一次克隆后会出现在这里", "None. Completed clones appear here"),
|
|
179
|
+
@("Enter 编辑/开始", "Enter edit/start"), @("Space 开关", "Space toggle"), @("改批次", "change batch"), @("粘贴", "paste"), @("退出", "quit"),
|
|
180
|
+
@("按上面的设置开始或继续克隆。Enter 启动。中断后重跑即可续传。", "Start or resume with the settings above. Press Enter to begin; rerun after interruption."),
|
|
181
|
+
@("请填写仓库 URL(Ctrl+V 可从剪贴板粘贴)", "Enter a repository URL (Ctrl+V pastes from the clipboard)"),
|
|
182
|
+
@("语言", "Language"), @("中文", "Chinese"), @("英文", "English")
|
|
183
|
+
,@(" 仓库 ", " Repository "), @(" 目录 ", " Directory "), @(" 引用 ", " Ref "), @(" 阶段 ", " Phase "), @(" 当前 ", " Current "),
|
|
184
|
+
@("键盘", "Keyboard"), @("暂无失败文件。", "No failed files."), @("停止", "stop"), @("暂停", "pause"), @("帮助", "help"), @("日志", "log")
|
|
185
|
+
)
|
|
186
|
+
$result = $Text
|
|
187
|
+
foreach ($pair in $pairs) { $result = $result.Replace([string]$pair[0], [string]$pair[1]) }
|
|
188
|
+
return $result
|
|
189
|
+
}
|
|
136
190
|
|
|
137
191
|
$script:GcrTuiFile = Join-Path $PSScriptRoot "git-clone-resume.tui.ps1"
|
|
138
192
|
if (-not $PSScriptRoot) {
|
|
@@ -173,6 +227,7 @@ function Write-Log {
|
|
|
173
227
|
elseif ($Message -is [System.Array]) { $text = (@($Message | ForEach-Object { "$_" }) -join " ") }
|
|
174
228
|
else { $text = [string]$Message }
|
|
175
229
|
} catch { $text = "$Message" }
|
|
230
|
+
$text = Convert-GcrText $text
|
|
176
231
|
$ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
|
177
232
|
$color = switch ($Level) {
|
|
178
233
|
"INFO" { "Gray" }
|
|
@@ -218,6 +273,7 @@ function Show-Usage {
|
|
|
218
273
|
Write-Host " -DryRun List files, do not checkout blobs"
|
|
219
274
|
Write-Host " -Tui Force fullscreen TUI"
|
|
220
275
|
Write-Host " -NoTui Disable TUI (script/CI mode)"
|
|
276
|
+
Write-Host " -Language zh-CN|en-US User interface language"
|
|
221
277
|
Write-Host " -ResumeLast Resume the latest history entry"
|
|
222
278
|
Write-Host " -Help Show this help"
|
|
223
279
|
Write-Host ""
|
|
@@ -966,12 +1022,12 @@ if ($NoTui) {
|
|
|
966
1022
|
|
|
967
1023
|
if ($ResumeLast) {
|
|
968
1024
|
if (-not (Get-Command Get-GcrHistoryLast -ErrorAction SilentlyContinue)) {
|
|
969
|
-
Write-Host "错误: 无法读取历史记录。" -ForegroundColor Red
|
|
1025
|
+
Write-Host (Convert-GcrText "错误: 无法读取历史记录。") -ForegroundColor Red
|
|
970
1026
|
exit 2
|
|
971
1027
|
}
|
|
972
1028
|
$last = Get-GcrHistoryLast
|
|
973
1029
|
if ($null -eq $last) {
|
|
974
|
-
Write-Host "错误: 没有可恢复的历史记录。请先启动过一次克隆。" -ForegroundColor Red
|
|
1030
|
+
Write-Host (Convert-GcrText "错误: 没有可恢复的历史记录。请先启动过一次克隆。") -ForegroundColor Red
|
|
975
1031
|
exit 2
|
|
976
1032
|
}
|
|
977
1033
|
if ([string]::IsNullOrWhiteSpace($RepoUrl) -and $last.url) { $RepoUrl = [string]$last.url }
|
|
@@ -982,7 +1038,7 @@ if ($ResumeLast) {
|
|
|
982
1038
|
if ([string]::IsNullOrWhiteSpace($RepoUrl)) {
|
|
983
1039
|
if ($NoTui -or -not $script:GcrInteractive) {
|
|
984
1040
|
Show-Usage
|
|
985
|
-
Write-Host "错误: 必须提供仓库 URL。" -ForegroundColor Red
|
|
1041
|
+
Write-Host (Convert-GcrText "错误: 必须提供仓库 URL。") -ForegroundColor Red
|
|
986
1042
|
exit 2
|
|
987
1043
|
}
|
|
988
1044
|
$defaults = @{
|
|
@@ -1000,7 +1056,7 @@ if ([string]::IsNullOrWhiteSpace($RepoUrl)) {
|
|
|
1000
1056
|
if ($PSBoundParameters.ContainsKey("Depth")) { $defaults["Depth"] = $Depth }
|
|
1001
1057
|
if (-not (Get-Command Show-GcrInteractiveSetup -ErrorAction SilentlyContinue)) {
|
|
1002
1058
|
Show-Usage
|
|
1003
|
-
Write-Host "错误: 必须提供仓库 URL。" -ForegroundColor Red
|
|
1059
|
+
Write-Host (Convert-GcrText "错误: 必须提供仓库 URL。") -ForegroundColor Red
|
|
1004
1060
|
exit 2
|
|
1005
1061
|
}
|
|
1006
1062
|
$wiz = $null
|
|
@@ -1021,6 +1077,9 @@ if ([string]::IsNullOrWhiteSpace($RepoUrl)) {
|
|
|
1021
1077
|
}
|
|
1022
1078
|
try {
|
|
1023
1079
|
$RepoUrl = [string]$wiz.RepoUrl
|
|
1080
|
+
if ($wiz.Language -eq "en-US" -or $wiz.Language -eq "zh-CN") {
|
|
1081
|
+
$script:GcrLanguage = [string]$wiz.Language
|
|
1082
|
+
}
|
|
1024
1083
|
if ($wiz.OutDir) { $OutDir = [string]$wiz.OutDir }
|
|
1025
1084
|
if ($wiz.Ref) { $Ref = [string]$wiz.Ref }
|
|
1026
1085
|
if ($wiz.BatchSize) { $BatchSize = [int]$wiz.BatchSize }
|
|
@@ -1048,14 +1107,14 @@ if ([string]::IsNullOrWhiteSpace($RepoUrl)) {
|
|
|
1048
1107
|
if ([string]::IsNullOrWhiteSpace($RepoUrl)) {
|
|
1049
1108
|
if (Get-Command Close-GcrTui -ErrorAction SilentlyContinue) { Close-GcrTui }
|
|
1050
1109
|
Show-Usage
|
|
1051
|
-
Write-Host "错误: 必须提供仓库 URL。" -ForegroundColor Red
|
|
1110
|
+
Write-Host (Convert-GcrText "错误: 必须提供仓库 URL。") -ForegroundColor Red
|
|
1052
1111
|
exit 2
|
|
1053
1112
|
}
|
|
1054
1113
|
|
|
1055
1114
|
if ($script:GcrTuiWanted -and (Get-Command Initialize-GcrTui -ErrorAction SilentlyContinue)) {
|
|
1056
1115
|
if (-not (Test-GcrTuiActive)) { [void](Initialize-GcrTui) }
|
|
1057
1116
|
if ($Tui -and -not (Test-GcrTuiActive)) {
|
|
1058
|
-
Write-Host "当前终端无法进入全屏 TUI,改用日志模式。Windows Terminal 下再试,或去掉 -Tui。" -ForegroundColor Yellow
|
|
1117
|
+
Write-Host (Convert-GcrText "当前终端无法进入全屏 TUI,改用日志模式。Windows Terminal 下再试,或去掉 -Tui。") -ForegroundColor Yellow
|
|
1059
1118
|
}
|
|
1060
1119
|
}
|
|
1061
1120
|
|
package/git-clone-resume.tui.ps1
CHANGED
|
@@ -752,6 +752,10 @@ function Invoke-GcrTuiKey {
|
|
|
752
752
|
$script:GcrTui.Dirty = $true
|
|
753
753
|
}
|
|
754
754
|
"H" { $script:GcrTui.Help = $true; $script:GcrTui.Dirty = $true }
|
|
755
|
+
"L" {
|
|
756
|
+
$script:GcrLanguage = $(if ($script:GcrLanguage -eq "en-US") { "zh-CN" } else { "en-US" })
|
|
757
|
+
$script:GcrTui.Dirty = $true
|
|
758
|
+
}
|
|
755
759
|
"F" { $script:GcrTui.FailView = -not $script:GcrTui.FailView; $script:GcrTui.Dirty = $true }
|
|
756
760
|
"UpArrow" {
|
|
757
761
|
$script:GcrTui.LogOffset = [Math]::Min($script:GcrTui.Logs.Count, $script:GcrTui.LogOffset + 1)
|
|
@@ -902,6 +906,8 @@ function Render-GcrTui {
|
|
|
902
906
|
function Push-GcrRow {
|
|
903
907
|
param([string]$Left, [string]$Right = "", [string]$Color = "")
|
|
904
908
|
if (-not $Color) { $Color = $c.W }
|
|
909
|
+
$Left = Convert-GcrText $Left
|
|
910
|
+
$Right = Convert-GcrText $Right
|
|
905
911
|
$leftW = Get-GcrDisplayWidth $Left
|
|
906
912
|
$rightW = Get-GcrDisplayWidth $Right
|
|
907
913
|
$gap = $inner - $leftW - $rightW
|
|
@@ -1210,6 +1216,7 @@ function Convert-GcrWizardResult {
|
|
|
1210
1216
|
Add-Member -InputObject $obj -NotePropertyName Verify -NotePropertyValue ([bool]$St.Verify)
|
|
1211
1217
|
Add-Member -InputObject $obj -NotePropertyName ForceRefetch -NotePropertyValue ([bool]$St.ForceRefetch)
|
|
1212
1218
|
Add-Member -InputObject $obj -NotePropertyName DryRun -NotePropertyValue ([bool]$St.DryRun)
|
|
1219
|
+
Add-Member -InputObject $obj -NotePropertyName Language -NotePropertyValue ([string]$St.Language)
|
|
1213
1220
|
return ,$obj
|
|
1214
1221
|
}
|
|
1215
1222
|
|
|
@@ -1256,6 +1263,7 @@ function Render-GcrTuiWizard {
|
|
|
1256
1263
|
}
|
|
1257
1264
|
function WRow([string]$Text, [string]$Color, [switch]$Sel) {
|
|
1258
1265
|
if (-not $Color) { $Color = $c.W }
|
|
1266
|
+
$Text = Convert-GcrText $Text
|
|
1259
1267
|
$body = Format-GcrCell -Text $Text -Width $inner
|
|
1260
1268
|
if ($Sel) { $Color = (Get-GcrColor "rev") + $Color }
|
|
1261
1269
|
$row = $c.D + $box.V + $c.R + $Color + $body + $c.R + $c.D + $box.V + $c.R
|
|
@@ -1268,7 +1276,7 @@ function Render-GcrTuiWizard {
|
|
|
1268
1276
|
WRow " 断点续传克隆 · partial clone + 按批 checkout" $c.D
|
|
1269
1277
|
WBorder "mid"
|
|
1270
1278
|
|
|
1271
|
-
$formEnd =
|
|
1279
|
+
$formEnd = 12
|
|
1272
1280
|
$recent = @($St.Recent)
|
|
1273
1281
|
$maxFormVisible = [Math]::Max(6, $h - 10)
|
|
1274
1282
|
if ($maxFormVisible -gt ($formEnd + 1)) { $maxFormVisible = $formEnd + 1 }
|
|
@@ -1363,6 +1371,7 @@ function Get-GcrWizardItems {
|
|
|
1363
1371
|
@{ Id = "verify"; Kind = "bool"; Label = "哈希校验"; Value = ""; Flag = [bool]$St.Verify; Guide = "续传时对已有文件做 hash-object 校验,哈希不一致则重新下载。Space 开关。" }
|
|
1364
1372
|
@{ Id = "force"; Kind = "bool"; Label = "强制 refetch"; Value = ""; Flag = [bool]$St.ForceRefetch; Guide = "强制重新 fetch 目标 ref。换分支或更新到最新 commit 时打开。Space 开关。" }
|
|
1365
1373
|
@{ Id = "dry"; Kind = "bool"; Label = "DryRun"; Value = ""; Flag = [bool]$St.DryRun; Guide = "只列出将要处理的文件,不下载 blob。适合先看清单。Space 开关。" }
|
|
1374
|
+
@{ Id = "language"; Kind = "enum"; Label = "语言"; Value = $(if ($St.Language -eq "en-US") { "英文" } else { "中文" }); Flag = $false; Guide = "选择界面语言。可随时按 L 在中文和英文之间切换。" }
|
|
1366
1375
|
@{ Id = "start"; Kind = "start"; Label = "开始克隆"; Value = ""; Flag = $false; Guide = "按上面的设置开始或继续克隆。Enter 启动。中断后重跑即可续传。" }
|
|
1367
1376
|
)
|
|
1368
1377
|
}
|
|
@@ -1374,7 +1383,7 @@ function Apply-GcrRecentToWizard {
|
|
|
1374
1383
|
if ($Item.outDir) { $St.OutDir = [string]$Item.outDir; $St.OutDirAuto = $false }
|
|
1375
1384
|
if ($Item.ref) { $St.Ref = [string]$Item.ref }
|
|
1376
1385
|
$St.Focus = "form"
|
|
1377
|
-
$St.Sel =
|
|
1386
|
+
$St.Sel = 12
|
|
1378
1387
|
}
|
|
1379
1388
|
|
|
1380
1389
|
function Show-GcrTuiWizard {
|
|
@@ -1407,6 +1416,7 @@ function Show-GcrTuiWizard {
|
|
|
1407
1416
|
OutDir = $dir
|
|
1408
1417
|
OutDirAuto = $dirAuto
|
|
1409
1418
|
Ref = $ref
|
|
1419
|
+
Language = $(if ($script:GcrLanguage) { $script:GcrLanguage } else { "zh-CN" })
|
|
1410
1420
|
BatchSize = $batch
|
|
1411
1421
|
MaxRetries = $retries
|
|
1412
1422
|
Include = ""
|
|
@@ -1537,7 +1547,7 @@ function Show-GcrTuiWizard {
|
|
|
1537
1547
|
"UpArrow" {
|
|
1538
1548
|
if ($st.Focus -eq "recent") {
|
|
1539
1549
|
if ($st.RecentSel -gt 0) { $st.RecentSel-- }
|
|
1540
|
-
else { $st.Focus = "form"; $st.Sel =
|
|
1550
|
+
else { $st.Focus = "form"; $st.Sel = 12 }
|
|
1541
1551
|
} else {
|
|
1542
1552
|
if ($st.Sel -gt 0) { $st.Sel-- }
|
|
1543
1553
|
}
|
|
@@ -1546,7 +1556,7 @@ function Show-GcrTuiWizard {
|
|
|
1546
1556
|
if ($st.Focus -eq "recent") {
|
|
1547
1557
|
if ($st.RecentSel -lt ($st.Recent.Count - 1)) { $st.RecentSel++ }
|
|
1548
1558
|
} else {
|
|
1549
|
-
if ($st.Sel -lt
|
|
1559
|
+
if ($st.Sel -lt 12) { $st.Sel++ }
|
|
1550
1560
|
elseif ($st.Recent.Count -gt 0) { $st.Focus = "recent"; $st.RecentSel = 0 }
|
|
1551
1561
|
}
|
|
1552
1562
|
}
|
|
@@ -1557,10 +1567,13 @@ function Show-GcrTuiWizard {
|
|
|
1557
1567
|
}
|
|
1558
1568
|
"J" {
|
|
1559
1569
|
if ($k.KeyChar -eq "j") {
|
|
1560
|
-
if ($st.Focus -eq "form" -and $st.Sel -lt
|
|
1570
|
+
if ($st.Focus -eq "form" -and $st.Sel -lt 12) { $st.Sel++ }
|
|
1561
1571
|
}
|
|
1562
1572
|
}
|
|
1563
1573
|
"LeftArrow" {
|
|
1574
|
+
if ($st.Focus -eq "form" -and $st.Sel -eq 11) {
|
|
1575
|
+
$st.Language = "zh-CN"
|
|
1576
|
+
}
|
|
1564
1577
|
if ($st.Focus -eq "form" -and $st.Sel -eq 3) {
|
|
1565
1578
|
$idx = [array]::IndexOf($batches, [int]$st.BatchSize)
|
|
1566
1579
|
if ($idx -lt 0) { $idx = 2 }
|
|
@@ -1573,6 +1586,9 @@ function Show-GcrTuiWizard {
|
|
|
1573
1586
|
}
|
|
1574
1587
|
}
|
|
1575
1588
|
"RightArrow" {
|
|
1589
|
+
if ($st.Focus -eq "form" -and $st.Sel -eq 11) {
|
|
1590
|
+
$st.Language = "en-US"
|
|
1591
|
+
}
|
|
1576
1592
|
if ($st.Focus -eq "form" -and $st.Sel -eq 3) {
|
|
1577
1593
|
$idx = [array]::IndexOf($batches, [int]$st.BatchSize)
|
|
1578
1594
|
if ($idx -lt 0) { $idx = 2 }
|
|
@@ -1589,6 +1605,7 @@ function Show-GcrTuiWizard {
|
|
|
1589
1605
|
if ($st.Sel -eq 8) { $st.Verify = -not $st.Verify }
|
|
1590
1606
|
elseif ($st.Sel -eq 9) { $st.ForceRefetch = -not $st.ForceRefetch }
|
|
1591
1607
|
elseif ($st.Sel -eq 10) { $st.DryRun = -not $st.DryRun }
|
|
1608
|
+
elseif ($st.Sel -eq 11) { $st.Language = $(if ($st.Language -eq "en-US") { "zh-CN" } else { "en-US" }); $script:GcrLanguage = $st.Language }
|
|
1592
1609
|
}
|
|
1593
1610
|
}
|
|
1594
1611
|
"Enter" {
|
|
@@ -1617,6 +1634,7 @@ function Show-GcrTuiWizard {
|
|
|
1617
1634
|
} elseif ($id -eq "verify") { $st.Verify = -not $st.Verify }
|
|
1618
1635
|
elseif ($id -eq "force") { $st.ForceRefetch = -not $st.ForceRefetch }
|
|
1619
1636
|
elseif ($id -eq "dry") { $st.DryRun = -not $st.DryRun }
|
|
1637
|
+
elseif ($id -eq "language") { $st.Language = $(if ($st.Language -eq "en-US") { "zh-CN" } else { "en-US" }); $script:GcrLanguage = $st.Language }
|
|
1620
1638
|
elseif ($id -eq "batch" -or $id -eq "retry") { }
|
|
1621
1639
|
else {
|
|
1622
1640
|
$st.Edit = $true
|
|
@@ -1647,6 +1665,10 @@ function Show-GcrTuiWizard {
|
|
|
1647
1665
|
}
|
|
1648
1666
|
}
|
|
1649
1667
|
default {
|
|
1668
|
+
if ($k.KeyChar -eq "l" -or $k.KeyChar -eq "L") {
|
|
1669
|
+
$st.Language = $(if ($st.Language -eq "en-US") { "zh-CN" } else { "en-US" })
|
|
1670
|
+
$script:GcrLanguage = $st.Language
|
|
1671
|
+
}
|
|
1650
1672
|
if ($k.KeyChar -eq "?") { $st.Error = "Enter 编辑 · Space 开关 · Tab 最近任务 · S 开始 · Q 退出" }
|
|
1651
1673
|
}
|
|
1652
1674
|
}
|
|
@@ -1669,20 +1691,20 @@ function Show-GcrCliWizard {
|
|
|
1669
1691
|
}
|
|
1670
1692
|
$prompt = "仓库 URL"
|
|
1671
1693
|
if ($pre) { $prompt = "仓库 URL [$pre]" }
|
|
1672
|
-
$url = Read-Host $prompt
|
|
1694
|
+
$url = Read-Host (Convert-GcrText $prompt)
|
|
1673
1695
|
if ([string]::IsNullOrWhiteSpace($url)) { $url = $pre }
|
|
1674
1696
|
if ([string]::IsNullOrWhiteSpace($url)) { return $null }
|
|
1675
1697
|
$defDir = Get-GcrFolderNameSafe -Url $url
|
|
1676
1698
|
if ($Defaults -and $Defaults.ContainsKey("OutDir") -and $Defaults.OutDir) { $defDir = [string]$Defaults.OutDir }
|
|
1677
|
-
$dir = Read-Host "本地目录 [$defDir]"
|
|
1699
|
+
$dir = Read-Host (Convert-GcrText "本地目录 [$defDir]")
|
|
1678
1700
|
if ([string]::IsNullOrWhiteSpace($dir)) { $dir = $defDir }
|
|
1679
1701
|
$defRef = "HEAD"
|
|
1680
1702
|
if ($Defaults -and $Defaults.ContainsKey("Ref") -and $Defaults.Ref) { $defRef = [string]$Defaults.Ref }
|
|
1681
|
-
$ref = Read-Host "分支/标签/commit [$defRef]"
|
|
1703
|
+
$ref = Read-Host (Convert-GcrText "分支/标签/commit [$defRef]")
|
|
1682
1704
|
if ([string]::IsNullOrWhiteSpace($ref)) { $ref = $defRef }
|
|
1683
1705
|
$batch = 32
|
|
1684
1706
|
if ($Defaults -and $Defaults.ContainsKey("BatchSize") -and $Defaults.BatchSize) { $batch = [int]$Defaults.BatchSize }
|
|
1685
|
-
$batchText = Read-Host "每批文件数 [$batch]"
|
|
1707
|
+
$batchText = Read-Host (Convert-GcrText "每批文件数 [$batch]")
|
|
1686
1708
|
if ($batchText -match "^\d+$") { $batch = [int]$batchText }
|
|
1687
1709
|
return @{
|
|
1688
1710
|
RepoUrl = $url.Trim()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git-clone-resume",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Resume-friendly partial clone tool for Windows",
|
|
5
5
|
"bin": {
|
|
6
6
|
"gcr": "gcr.cmd",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"git-clone-resume.cmd",
|
|
12
12
|
"git-clone-resume.ps1",
|
|
13
13
|
"git-clone-resume.tui.ps1",
|
|
14
|
-
"README.md"
|
|
14
|
+
"README.md",
|
|
15
|
+
"README.en.md"
|
|
15
16
|
],
|
|
16
17
|
"engines": {
|
|
17
18
|
"node": ">=16"
|