zen-gitsync 2.13.23 → 2.13.24
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/package.json +1 -1
- package/scripts/README_COLOR_CONVERTER.md +196 -196
- package/scripts/README_FONTSIZE_CONVERTER.md +278 -278
- package/scripts/README_SPACING_CONVERTER.md +126 -126
- package/scripts/README_STYLE_VARS.md +180 -180
- package/src/gitCommit.js +2 -2
- package/src/ui/public/assets/{AppVersionBadge-BUS8w2f8.js → AppVersionBadge-CaVphp8E.js} +1 -1
- package/src/ui/public/assets/{BranchSelector-Dm7nENer.js → BranchSelector-B91Ylbas.js} +1 -1
- package/src/ui/public/assets/{CommandConsole-C1W9ZQkE.js → CommandConsole-bK4iwZvI.js} +2 -2
- package/src/ui/public/assets/{CommitForm-C76W1ZZH.js → CommitForm-zOCxmZ84.js} +1 -1
- package/src/ui/public/assets/{CustomCommandManager-JKx8JYqn.js → CustomCommandManager-C1lRrp5z.js} +1 -1
- package/src/ui/public/assets/{EditorView-CriUYDvi.js → EditorView-DYo2oYtk.js} +0 -0
- package/src/ui/public/assets/{FileDiffViewer-DNWsiIGt.js → FileDiffViewer-Ce17WOZ-.js} +1 -1
- package/src/ui/public/assets/{FlowExecutionViewer-CTDh2bCD.js → FlowExecutionViewer-CRK6lIul.js} +1 -1
- package/src/ui/public/assets/{FlowOrchestrationWorkspace-Chah2aGN.js → FlowOrchestrationWorkspace-BDw7ThWp.js} +1 -1
- package/src/ui/public/assets/{GitStatus-DP-DQsiS.js → GitStatus-DN4_m6sO.js} +1 -1
- package/src/ui/public/assets/{LogList-Z76_5USQ.js → LogList-BshRTCrE.js} +1 -1
- package/src/ui/public/assets/{ProjectStartupButton-C5oF4unq.js → ProjectStartupButton-C-dXxxMO.js} +1 -1
- package/src/ui/public/assets/{RemoteRepoCard-B-fGjb8Y.js → RemoteRepoCard-DDZcP5-V.js} +1 -1
- package/src/ui/public/assets/{ResetToRemoteButton-BixSoEVs.js → ResetToRemoteButton-TXJzvBxE.js} +1 -1
- package/src/ui/public/assets/{SourceMapView-C9HZiJ9N.js → SourceMapView-BUkB6h41.js} +1 -1
- package/src/ui/public/assets/{TemplateManager-C7SuKq0f.js → TemplateManager-DFVzDiu0.js} +1 -1
- package/src/ui/public/assets/{UserInputNode-CYy0UpzR.js → UserInputNode-CXyV1xG4.js} +1 -1
- package/src/ui/public/assets/{WorkbenchView-A9Oik707.js → WorkbenchView-CEYhsa4O.js} +1 -1
- package/src/ui/public/assets/{index-DPSGvy34.js → index-BGmxuKoN.js} +2 -2
- package/src/ui/public/favicon.svg +75 -75
- package/src/ui/public/index.html +18 -18
- package/src/ui/public/logo.svg +74 -74
- package/src/ui/server/index.js +3 -3
- package/src/ui/server/routes/branchStatus.js +4 -4
- package/src/ui/server/routes/config.js +8 -8
- package/src/ui/server/routes/exec.js +7 -1
- package/src/ui/server/routes/fs.js +2 -2
- package/src/ui/server/routes/git/diff.js +17 -16
- package/src/ui/server/routes/git/diffUtils.js +21 -2
- package/src/ui/server/routes/git/stash.js +38 -42
- package/src/ui/server/routes/git/tags.js +10 -10
- package/src/ui/server/routes/git.js +15 -26
- package/src/ui/server/routes/gitOps.js +91 -125
- package/src/ui/server/routes/status.js +3 -3
- package/src/utils/index.js +32 -29
|
@@ -31,8 +31,27 @@ export function createDiffHelpers({ execGitCommand }) {
|
|
|
31
31
|
|
|
32
32
|
// 2. 使用 --numstat 快速检查变更量(不获取实际内容,速度快)
|
|
33
33
|
try {
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
// 把传入的 diffCommand 字符串改写成 git diff/show 加 --numstat 的 argv 数组。
|
|
35
|
+
// 不再走 shell 模式,避免 Windows cmd.exe 下引号兼容问题(参 utils execGitCommand execFile 化)。
|
|
36
|
+
const numstatCommand = diffCommand.replace(/git (diff|show)/, 'git $1 --numstat')
|
|
37
|
+
const argvMatch = numstatCommand.trim().match(/^git\s+(\S+)\s*(.*)$/)
|
|
38
|
+
let numstatArgs
|
|
39
|
+
if (argvMatch) {
|
|
40
|
+
const subCmd = argvMatch[1]
|
|
41
|
+
const rest = argvMatch[2]
|
|
42
|
+
// 简单按空白拆分,带引号段整体保留 -- "--" + 路径
|
|
43
|
+
// 这里最常见形态是 'git diff/show -- "--path"' 或 'git diff/show hash -- "--path"'
|
|
44
|
+
const tokens = []
|
|
45
|
+
const re = /"([^"]*)"|(\S+)/g
|
|
46
|
+
let m
|
|
47
|
+
while ((m = re.exec(rest)) !== null) tokens.push(m[1] !== undefined ? m[1] : m[2])
|
|
48
|
+
// 找到 '--numstat' 位置,把它加到 subCmd 后面作为第一个参数
|
|
49
|
+
numstatArgs = [subCmd, '--numstat', ...tokens]
|
|
50
|
+
} else {
|
|
51
|
+
// fallback: 走旧逻辑(字符串)
|
|
52
|
+
numstatArgs = numstatCommand
|
|
53
|
+
}
|
|
54
|
+
const { stdout: numstat } = await execGitCommand(numstatArgs, { log: false });
|
|
36
55
|
|
|
37
56
|
if (numstat.trim()) {
|
|
38
57
|
const lines = numstat.trim().split('\n');
|
|
@@ -20,7 +20,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
20
20
|
// 获取stash列表
|
|
21
21
|
app.get('/api/stash-list', async (req, res) => {
|
|
22
22
|
try {
|
|
23
|
-
const { stdout } = await execGitCommand('
|
|
23
|
+
const { stdout } = await execGitCommand(['stash', 'list']);
|
|
24
24
|
|
|
25
25
|
// 解析stash列表
|
|
26
26
|
const stashList = stdout.split('\n')
|
|
@@ -53,7 +53,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
53
53
|
if (excludeLocked) {
|
|
54
54
|
const lockedFiles = await configManager.getLockedFiles();
|
|
55
55
|
// 包含未跟踪文件,确保状态与 UI 一致
|
|
56
|
-
const { stdout: statusStdout } = await execGitCommand('
|
|
56
|
+
const { stdout: statusStdout } = await execGitCommand(['status', '--porcelain', '--untracked-files=all'], { log: false });
|
|
57
57
|
const changedFiles = statusStdout
|
|
58
58
|
.split('\n')
|
|
59
59
|
.filter(line => line.trim())
|
|
@@ -100,7 +100,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
100
100
|
if (includeUntracked) {
|
|
101
101
|
try {
|
|
102
102
|
// 使用 git 列出该目录下的未跟踪和已修改文件
|
|
103
|
-
const { stdout: listStdout } = await execGitCommand(
|
|
103
|
+
const { stdout: listStdout } = await execGitCommand(['ls-files', '-mo', '--exclude-standard', '--', filename], { log: false });
|
|
104
104
|
const listed = listStdout
|
|
105
105
|
.split('\n')
|
|
106
106
|
.map(l => l.trim())
|
|
@@ -145,14 +145,13 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
145
145
|
// 在执行 stash 前进行候选校验:
|
|
146
146
|
// 1) 仍有跟踪差异的文件
|
|
147
147
|
try {
|
|
148
|
-
const
|
|
149
|
-
const { stdout: diffNames } = await execGitCommand(`git diff --name-only -- ${args}`, { log: false });
|
|
148
|
+
const { stdout: diffNames } = await execGitCommand(['diff', '--name-only', '--', ...filesToStash], { log: false });
|
|
150
149
|
const trackedChanged = new Set(diffNames.split('\n').map(s => s.trim()).filter(Boolean));
|
|
151
150
|
|
|
152
151
|
// 2) 仍为未跟踪的文件(当 includeUntracked 才检查)
|
|
153
152
|
let untrackedExisting = new Set();
|
|
154
153
|
if (includeUntracked) {
|
|
155
|
-
const { stdout: others } = await execGitCommand(
|
|
154
|
+
const { stdout: others } = await execGitCommand(['ls-files', '--others', '--exclude-standard', '--', ...filesToStash], { log: false });
|
|
156
155
|
untrackedExisting = new Set(others.split('\n').map(s => s.trim()).filter(Boolean));
|
|
157
156
|
}
|
|
158
157
|
|
|
@@ -174,27 +173,22 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
174
173
|
return res.json({ success: false, message: '没有可储藏的更改(可能刚刚已储藏,或被锁定过滤)' });
|
|
175
174
|
}
|
|
176
175
|
|
|
177
|
-
|
|
178
|
-
if (message)
|
|
179
|
-
if (includeUntracked)
|
|
180
|
-
|
|
181
|
-
command += ` -- ${args}`;
|
|
176
|
+
const stashArgs = ['stash', 'push'];
|
|
177
|
+
if (message) stashArgs.push('-m', message);
|
|
178
|
+
if (includeUntracked) stashArgs.push('--include-untracked');
|
|
179
|
+
if (filesToStash.length > 0) stashArgs.push('--', ...filesToStash);
|
|
182
180
|
|
|
183
|
-
const { stdout } = await execGitCommand(
|
|
181
|
+
const { stdout } = await execGitCommand(stashArgs);
|
|
184
182
|
if (stdout.includes('No local changes to save')) {
|
|
185
183
|
return res.json({ success: false, message: '没有本地更改需要保存' });
|
|
186
184
|
}
|
|
187
185
|
return res.json({ success: true, message: '成功保存未锁定的工作区更改', output: stdout });
|
|
188
186
|
}
|
|
189
187
|
|
|
190
|
-
|
|
191
|
-
if (message)
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
if (includeUntracked) {
|
|
195
|
-
command += ' --include-untracked';
|
|
196
|
-
}
|
|
197
|
-
const { stdout } = await execGitCommand(command);
|
|
188
|
+
const stashArgs = ['stash', 'push'];
|
|
189
|
+
if (message) stashArgs.push('-m', message);
|
|
190
|
+
if (includeUntracked) stashArgs.push('--include-untracked');
|
|
191
|
+
const { stdout } = await execGitCommand(stashArgs);
|
|
198
192
|
if (stdout.includes('No local changes to save')) {
|
|
199
193
|
return res.json({ success: false, message: '没有本地更改需要保存' });
|
|
200
194
|
}
|
|
@@ -220,19 +214,18 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
220
214
|
}
|
|
221
215
|
|
|
222
216
|
// 构建 git stash push 命令
|
|
223
|
-
|
|
217
|
+
const stashArgs = ['stash', 'push'];
|
|
224
218
|
if (message) {
|
|
225
|
-
|
|
219
|
+
stashArgs.push('-m', message);
|
|
226
220
|
}
|
|
227
221
|
if (includeUntracked) {
|
|
228
|
-
|
|
222
|
+
stashArgs.push('--include-untracked');
|
|
229
223
|
}
|
|
230
224
|
|
|
231
225
|
// 添加文件列表
|
|
232
|
-
|
|
233
|
-
command += ` -- ${args}`;
|
|
226
|
+
stashArgs.push('--', ...files);
|
|
234
227
|
|
|
235
|
-
const { stdout } = await execGitCommand(
|
|
228
|
+
const { stdout } = await execGitCommand(stashArgs);
|
|
236
229
|
|
|
237
230
|
if (stdout.includes('No local changes to save')) {
|
|
238
231
|
return res.json({ success: false, message: '没有本地更改需要保存' });
|
|
@@ -266,7 +259,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
266
259
|
}
|
|
267
260
|
|
|
268
261
|
// 决定是使用apply(保留stash)还是pop(应用后删除stash)
|
|
269
|
-
const command = pop ?
|
|
262
|
+
const command = pop ? ['stash', 'pop', stashId] : ['stash', 'apply', stashId];
|
|
270
263
|
|
|
271
264
|
try {
|
|
272
265
|
const { stdout } = await execGitCommand(command);
|
|
@@ -306,7 +299,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
306
299
|
});
|
|
307
300
|
}
|
|
308
301
|
|
|
309
|
-
const { stdout } = await execGitCommand(
|
|
302
|
+
const { stdout } = await execGitCommand(['stash', 'drop', stashId]);
|
|
310
303
|
|
|
311
304
|
res.json({
|
|
312
305
|
success: true,
|
|
@@ -322,7 +315,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
322
315
|
// 清空所有stash
|
|
323
316
|
app.post('/api/stash-clear', async (req, res) => {
|
|
324
317
|
try {
|
|
325
|
-
const { stdout } = await execGitCommand('
|
|
318
|
+
const { stdout } = await execGitCommand(['stash', 'clear']);
|
|
326
319
|
|
|
327
320
|
res.json({
|
|
328
321
|
success: true,
|
|
@@ -350,7 +343,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
350
343
|
console.log(`获取stash文件列表: stashId=${stashId}`);
|
|
351
344
|
|
|
352
345
|
// 0) 解析出当前 stash 提交及其父提交哈希,避免在 Windows 上使用 ^ 语法
|
|
353
|
-
const { stdout: parentsLine } = await execGitCommand(
|
|
346
|
+
const { stdout: parentsLine } = await execGitCommand(['rev-list', '--parents', '-n', '1', stashId], { log: false });
|
|
354
347
|
const hashes = parentsLine.trim().split(/\s+/).filter(Boolean);
|
|
355
348
|
const stashCommit = hashes[0] || '';
|
|
356
349
|
const parent1 = hashes[1] || '';
|
|
@@ -359,14 +352,14 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
359
352
|
// 1) 跟踪文件的变更列表:父1 与 stash 提交的差异(若无父1则为空)
|
|
360
353
|
let trackedFiles = [];
|
|
361
354
|
if (parent1) {
|
|
362
|
-
const { stdout: trackedOut } = await execGitCommand(
|
|
355
|
+
const { stdout: trackedOut } = await execGitCommand(['diff', '--name-only', parent1, stashCommit], { log: false });
|
|
363
356
|
trackedFiles = trackedOut.split('\n').map(s => s.trim()).filter(Boolean);
|
|
364
357
|
}
|
|
365
358
|
|
|
366
359
|
// 2) 未跟踪文件:来自第三父(若存在)
|
|
367
360
|
let untrackedFiles = [];
|
|
368
361
|
if (parent3) {
|
|
369
|
-
const { stdout: untrackedOut } = await execGitCommand(
|
|
362
|
+
const { stdout: untrackedOut } = await execGitCommand(['ls-tree', '-r', '--name-only', parent3], { log: false });
|
|
370
363
|
untrackedFiles = untrackedOut.split('\n').map(s => s.trim()).filter(Boolean);
|
|
371
364
|
}
|
|
372
365
|
|
|
@@ -403,7 +396,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
403
396
|
console.log(`获取stash文件差异: stashId=${stashId}, file=${file}`);
|
|
404
397
|
|
|
405
398
|
// 先解析父提交哈希,避免使用 ^ 语法
|
|
406
|
-
const { stdout: parentsLine } = await execGitCommand(
|
|
399
|
+
const { stdout: parentsLine } = await execGitCommand(['rev-list', '--parents', '-n', '1', stashId], { log: false });
|
|
407
400
|
const hashes = parentsLine.trim().split(/\s+/).filter(Boolean);
|
|
408
401
|
const stashCommit = hashes[0] || '';
|
|
409
402
|
const parent1 = hashes[1] || '';
|
|
@@ -413,7 +406,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
413
406
|
let isFromThirdParent = false;
|
|
414
407
|
if (parent3) {
|
|
415
408
|
try {
|
|
416
|
-
await execGitCommand(
|
|
409
|
+
await execGitCommand(['cat-file', '-e', `${parent3}:${file}`], { log: false });
|
|
417
410
|
isFromThirdParent = true;
|
|
418
411
|
} catch (_) {
|
|
419
412
|
isFromThirdParent = false;
|
|
@@ -422,7 +415,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
422
415
|
|
|
423
416
|
if (isFromThirdParent) {
|
|
424
417
|
// 未跟踪文件:读取第三父中的内容,构造新增文件的统一diff
|
|
425
|
-
const { stdout: blob } = await execGitCommand(
|
|
418
|
+
const { stdout: blob } = await execGitCommand(['show', `${parent3}:${file}`], { log: false });
|
|
426
419
|
|
|
427
420
|
// 检查文件大小
|
|
428
421
|
const sizeCheck = checkDiffSize(blob, 500);
|
|
@@ -457,10 +450,13 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
457
450
|
}
|
|
458
451
|
|
|
459
452
|
// 否则,使用原有方式获取与父1的变更
|
|
460
|
-
|
|
453
|
+
// checkShouldSkipDiff 接受字符串命令用于日志展示,这里只用于大小判断;
|
|
454
|
+
// 走 execGitCommand 时用 argv 数组,避免 Windows 下 cmd.exe 拼引号被破坏。
|
|
455
|
+
const diffCommandForCheck = `git show ${stashCommit} -- "${file}"`;
|
|
456
|
+
const diffCommandArgs = ['show', stashCommit, '--', file];
|
|
461
457
|
|
|
462
458
|
// 使用优化的检查函数
|
|
463
|
-
const skipCheck = await checkShouldSkipDiff(file,
|
|
459
|
+
const skipCheck = await checkShouldSkipDiff(file, diffCommandForCheck);
|
|
464
460
|
if (skipCheck.shouldSkip) {
|
|
465
461
|
return res.json({
|
|
466
462
|
success: true,
|
|
@@ -470,7 +466,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
470
466
|
});
|
|
471
467
|
}
|
|
472
468
|
|
|
473
|
-
const { stdout } = await execGitCommand(
|
|
469
|
+
const { stdout } = await execGitCommand(diffCommandArgs);
|
|
474
470
|
|
|
475
471
|
console.log(`获取到差异内容,长度: ${stdout.length}`);
|
|
476
472
|
|
|
@@ -503,7 +499,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
503
499
|
}
|
|
504
500
|
|
|
505
501
|
// 解析父提交哈希
|
|
506
|
-
const { stdout: parentsLine } = await execGitCommand(
|
|
502
|
+
const { stdout: parentsLine } = await execGitCommand(['rev-list', '--parents', '-n', '1', stashId], { log: false });
|
|
507
503
|
const hashes = parentsLine.trim().split(/\s+/).filter(Boolean);
|
|
508
504
|
const stashCommit = hashes[0] || '';
|
|
509
505
|
const parent1 = hashes[1] || '';
|
|
@@ -513,7 +509,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
513
509
|
let isFromThirdParent = false;
|
|
514
510
|
if (parent3) {
|
|
515
511
|
try {
|
|
516
|
-
await execGitCommand(
|
|
512
|
+
await execGitCommand(['cat-file', '-e', `${parent3}:${file}`], { log: false });
|
|
517
513
|
isFromThirdParent = true;
|
|
518
514
|
} catch (_) {
|
|
519
515
|
isFromThirdParent = false;
|
|
@@ -524,7 +520,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
524
520
|
let original = '';
|
|
525
521
|
if (!isFromThirdParent && parent1) {
|
|
526
522
|
try {
|
|
527
|
-
const { stdout: origOut } = await execGitCommand(
|
|
523
|
+
const { stdout: origOut } = await execGitCommand(['show', `${parent1}:${file}`], { log: false });
|
|
528
524
|
original = origOut ?? '';
|
|
529
525
|
} catch (_) {
|
|
530
526
|
original = ''; // 文件在储藏前不存在
|
|
@@ -536,7 +532,7 @@ export function registerGitStashRoutes({ app, execGitCommand, configManager }) {
|
|
|
536
532
|
const modRef = isFromThirdParent ? parent3 : stashCommit;
|
|
537
533
|
if (modRef) {
|
|
538
534
|
try {
|
|
539
|
-
const { stdout: modOut } = await execGitCommand(
|
|
535
|
+
const { stdout: modOut } = await execGitCommand(['show', `${modRef}:${file}`], { log: false });
|
|
540
536
|
modified = modOut ?? '';
|
|
541
537
|
} catch (_) {
|
|
542
538
|
modified = ''; // 文件已被删除
|
|
@@ -24,25 +24,25 @@ export function registerGitTagRoutes({ app, execGitCommand, clearCommandHistory
|
|
|
24
24
|
return res.status(400).json({ success: false, error: '缺少标签名称' });
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
const tagArgs = ['tag'];
|
|
28
28
|
|
|
29
29
|
if (type === 'annotated') {
|
|
30
30
|
// 附注标签
|
|
31
31
|
if (!message) {
|
|
32
32
|
return res.status(400).json({ success: false, error: '附注标签需要提供说明信息' });
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
tagArgs.push('-a', tagName, '-m', message);
|
|
35
35
|
} else {
|
|
36
36
|
// 轻量标签
|
|
37
|
-
|
|
37
|
+
tagArgs.push(tagName);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
// 如果指定了commit,添加到命令中
|
|
41
41
|
if (commit && commit.trim()) {
|
|
42
|
-
|
|
42
|
+
tagArgs.push(commit.trim());
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
const { stdout } = await execGitCommand(
|
|
45
|
+
const { stdout } = await execGitCommand(tagArgs);
|
|
46
46
|
|
|
47
47
|
res.json({
|
|
48
48
|
success: true,
|
|
@@ -60,7 +60,7 @@ export function registerGitTagRoutes({ app, execGitCommand, clearCommandHistory
|
|
|
60
60
|
try {
|
|
61
61
|
// 使用 git tag -n --format 获取详细信息
|
|
62
62
|
const { stdout } = await execGitCommand(
|
|
63
|
-
'
|
|
63
|
+
['tag', '-n', '--format=%(refname:short)|%(objectname:short)|%(creatordate:iso8601)|%(subject)']
|
|
64
64
|
);
|
|
65
65
|
|
|
66
66
|
if (!stdout.trim()) {
|
|
@@ -82,7 +82,7 @@ export function registerGitTagRoutes({ app, execGitCommand, clearCommandHistory
|
|
|
82
82
|
for (const tag of tags) {
|
|
83
83
|
try {
|
|
84
84
|
const { stdout: typeCheck } = await execGitCommand(
|
|
85
|
-
|
|
85
|
+
['cat-file', '-t', tag.name],
|
|
86
86
|
{ log: false }
|
|
87
87
|
);
|
|
88
88
|
if (typeCheck.trim() === 'tag') {
|
|
@@ -109,7 +109,7 @@ export function registerGitTagRoutes({ app, execGitCommand, clearCommandHistory
|
|
|
109
109
|
return res.status(400).json({ success: false, error: '缺少标签名称' });
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
const { stdout } = await execGitCommand(
|
|
112
|
+
const { stdout } = await execGitCommand(['push', 'origin', tagName]);
|
|
113
113
|
|
|
114
114
|
res.json({
|
|
115
115
|
success: true,
|
|
@@ -125,7 +125,7 @@ export function registerGitTagRoutes({ app, execGitCommand, clearCommandHistory
|
|
|
125
125
|
// 推送所有标签到远程
|
|
126
126
|
app.post('/api/push-all-tags', async (req, res) => {
|
|
127
127
|
try {
|
|
128
|
-
const { stdout } = await execGitCommand('
|
|
128
|
+
const { stdout } = await execGitCommand(['push', 'origin', '--tags']);
|
|
129
129
|
|
|
130
130
|
res.json({
|
|
131
131
|
success: true,
|
|
@@ -147,7 +147,7 @@ export function registerGitTagRoutes({ app, execGitCommand, clearCommandHistory
|
|
|
147
147
|
return res.status(400).json({ success: false, error: '缺少标签名称' });
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
const { stdout } = await execGitCommand(
|
|
150
|
+
const { stdout } = await execGitCommand(['tag', '-d', tagName]);
|
|
151
151
|
|
|
152
152
|
res.json({
|
|
153
153
|
success: true,
|
|
@@ -23,10 +23,10 @@ export function registerGitRoutes({
|
|
|
23
23
|
app.get('/api/branches', async (req, res) => {
|
|
24
24
|
try {
|
|
25
25
|
// 获取本地分支 - 使用简单的git branch命令
|
|
26
|
-
const { stdout: localBranches } = await execGitCommand('
|
|
26
|
+
const { stdout: localBranches } = await execGitCommand(['branch']);
|
|
27
27
|
|
|
28
28
|
// 获取远程分支
|
|
29
|
-
const { stdout: remoteBranches } = await execGitCommand('
|
|
29
|
+
const { stdout: remoteBranches } = await execGitCommand(['branch', '-r']);
|
|
30
30
|
|
|
31
31
|
// 处理本地分支 - 正确解析git branch的标准输出格式
|
|
32
32
|
const localBranchList = localBranches.split('\n')
|
|
@@ -63,18 +63,18 @@ export function registerGitRoutes({
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
// 构建创建分支的命令
|
|
66
|
-
let
|
|
66
|
+
let commandArgs = ['branch', newBranchName];
|
|
67
67
|
|
|
68
68
|
// 如果指定了基础分支,则基于该分支创建
|
|
69
69
|
if (baseBranch) {
|
|
70
|
-
|
|
70
|
+
commandArgs = ['branch', newBranchName, baseBranch];
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// 执行创建分支命令
|
|
74
|
-
await execGitCommand(
|
|
74
|
+
await execGitCommand(commandArgs);
|
|
75
75
|
|
|
76
76
|
// 切换到新创建的分支
|
|
77
|
-
await execGitCommand(
|
|
77
|
+
await execGitCommand(['checkout', newBranchName]);
|
|
78
78
|
|
|
79
79
|
// 清除分支缓存,因为分支已切换
|
|
80
80
|
clearBranchCache();
|
|
@@ -95,7 +95,7 @@ export function registerGitRoutes({
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
// 执行分支切换
|
|
98
|
-
await execGitCommand(
|
|
98
|
+
await execGitCommand(['checkout', branch]);
|
|
99
99
|
|
|
100
100
|
// 清除分支缓存,因为分支已切换
|
|
101
101
|
clearBranchCache();
|
|
@@ -117,28 +117,17 @@ export function registerGitRoutes({
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
// 构建Git合并命令 - 直接使用传入的分支名(可能包含origin/前缀)
|
|
120
|
-
|
|
120
|
+
const commandArgs = ['merge', branch];
|
|
121
121
|
|
|
122
122
|
// 添加可选参数
|
|
123
|
-
if (noCommit)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (noFf) {
|
|
128
|
-
command += ' --no-ff';
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (squash) {
|
|
132
|
-
command += ' --squash';
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (message) {
|
|
136
|
-
command += ` -m "${message}"`;
|
|
137
|
-
}
|
|
123
|
+
if (noCommit) commandArgs.push('--no-commit');
|
|
124
|
+
if (noFf) commandArgs.push('--no-ff');
|
|
125
|
+
if (squash) commandArgs.push('--squash');
|
|
126
|
+
if (message) commandArgs.push('-m', message);
|
|
138
127
|
|
|
139
128
|
try {
|
|
140
129
|
// 执行合并命令
|
|
141
|
-
const { stdout } = await execGitCommand(
|
|
130
|
+
const { stdout } = await execGitCommand(commandArgs);
|
|
142
131
|
|
|
143
132
|
res.json({
|
|
144
133
|
success: true,
|
|
@@ -175,9 +164,9 @@ export function registerGitRoutes({
|
|
|
175
164
|
app.get('/api/user-info', async (req, res) => {
|
|
176
165
|
try {
|
|
177
166
|
// 获取全局用户名
|
|
178
|
-
const { stdout: userName } = await execGitCommand('
|
|
167
|
+
const { stdout: userName } = await execGitCommand(['config', '--global', 'user.name']);
|
|
179
168
|
// 获取全局用户邮箱
|
|
180
|
-
const { stdout: userEmail } = await execGitCommand('
|
|
169
|
+
const { stdout: userEmail } = await execGitCommand(['config', '--global', 'user.email']);
|
|
181
170
|
|
|
182
171
|
res.json({
|
|
183
172
|
name: userName.trim(),
|