zen-gitsync 2.1.14 → 2.1.26
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/index.js +10 -1
- package/package.json +75 -71
- package/scripts/release.bat +22 -0
- package/scripts/release.js +541 -0
- package/src/gitCommit.js +1 -1
- package/src/ui/public/assets/index-Cj-n4CZW.css +1 -0
- package/src/ui/public/assets/index-LmXVzmKV.js +22 -0
- package/src/ui/public/assets/{vendor-CzPWr9Sn.js → vendor-LDRpPx4a.js} +4 -4
- package/src/ui/public/index.html +3 -3
- package/src/ui/server/index.js +176 -2
- package/src/ui/public/assets/index-B7uieYQ1.css +0 -1
- package/src/ui/public/assets/index-DwFC9vFg.js +0 -22
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 发布前准备工作
|
|
5
|
+
* 1. 更新版本号(最后一位加1)
|
|
6
|
+
* 2. 构建前端项目
|
|
7
|
+
* 3. 提交更改到git
|
|
8
|
+
* 4. 发布到npm
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
import { fileURLToPath } from 'url';
|
|
14
|
+
import { execSync } from 'child_process';
|
|
15
|
+
import chalk from 'chalk';
|
|
16
|
+
import readline from 'readline/promises';
|
|
17
|
+
|
|
18
|
+
// 获取项目根目录
|
|
19
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
20
|
+
const __dirname = path.dirname(__filename);
|
|
21
|
+
const rootDir = path.resolve(__dirname, '..');
|
|
22
|
+
|
|
23
|
+
// 创建readline接口函数
|
|
24
|
+
function createReadlineInterface() {
|
|
25
|
+
return readline.createInterface({
|
|
26
|
+
input: process.stdin,
|
|
27
|
+
output: process.stdout
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 读取package.json
|
|
32
|
+
const packageJsonPath = path.join(rootDir, 'package.json');
|
|
33
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
34
|
+
|
|
35
|
+
// 尝试终止可能正在运行的Git进程
|
|
36
|
+
function terminateGitProcesses() {
|
|
37
|
+
console.log(chalk.yellow('尝试终止可能正在运行的Git进程...'));
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
// 在Windows上
|
|
41
|
+
if (process.platform === 'win32') {
|
|
42
|
+
try {
|
|
43
|
+
execSync('taskkill /f /im git.exe /t', { stdio: 'ignore' });
|
|
44
|
+
console.log(chalk.green('已终止Git进程'));
|
|
45
|
+
} catch (e) {
|
|
46
|
+
// 可能没有正在运行的进程,忽略错误
|
|
47
|
+
console.log(chalk.gray('没有找到正在运行的Git进程'));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// 在Linux/MacOS上
|
|
51
|
+
else {
|
|
52
|
+
try {
|
|
53
|
+
execSync("pkill -f 'git' || true", { stdio: 'ignore' });
|
|
54
|
+
console.log(chalk.green('已终止Git进程'));
|
|
55
|
+
} catch (e) {
|
|
56
|
+
// 忽略错误
|
|
57
|
+
console.log(chalk.gray('没有找到正在运行的Git进程'));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 等待进程终止
|
|
62
|
+
console.log(chalk.gray('等待进程终止...'));
|
|
63
|
+
execSync('sleep 2 || ping -n 3 127.0.0.1 > nul', { stdio: 'ignore' });
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.log(chalk.yellow('终止Git进程失败,但将继续尝试清理锁文件'));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 询问是否继续执行
|
|
70
|
+
async function askContinue(message) {
|
|
71
|
+
const rl = createReadlineInterface();
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const answer = await rl.question(message);
|
|
75
|
+
// 如果是空字符串(直接回车)或者是"y",都返回true
|
|
76
|
+
return answer.toLowerCase() === 'y' || answer.trim() === '';
|
|
77
|
+
} finally {
|
|
78
|
+
rl.close();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 检查并清理Git锁文件
|
|
83
|
+
async function checkAndCleanGitLocks() {
|
|
84
|
+
console.log(chalk.gray('检查Git锁文件...'));
|
|
85
|
+
|
|
86
|
+
const gitDir = path.join(rootDir, '.git');
|
|
87
|
+
|
|
88
|
+
// 可能的锁文件列表
|
|
89
|
+
const lockFiles = [
|
|
90
|
+
path.join(gitDir, 'index.lock'),
|
|
91
|
+
path.join(gitDir, 'HEAD.lock'),
|
|
92
|
+
path.join(gitDir, 'config.lock'),
|
|
93
|
+
path.join(gitDir, 'refs', 'heads', '*.lock'),
|
|
94
|
+
path.join(gitDir, 'packed-refs.lock')
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
// 检查并清理每个锁文件
|
|
98
|
+
let foundLocks = false;
|
|
99
|
+
let hasBusyLocks = false;
|
|
100
|
+
|
|
101
|
+
lockFiles.forEach(lockPattern => {
|
|
102
|
+
// 处理通配符模式
|
|
103
|
+
if (lockPattern.includes('*')) {
|
|
104
|
+
const baseDir = path.dirname(lockPattern);
|
|
105
|
+
const pattern = path.basename(lockPattern);
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
// 确保目录存在
|
|
109
|
+
if (fs.existsSync(baseDir)) {
|
|
110
|
+
const files = fs.readdirSync(baseDir);
|
|
111
|
+
files.forEach(file => {
|
|
112
|
+
if (file.endsWith('.lock')) {
|
|
113
|
+
const lockPath = path.join(baseDir, file);
|
|
114
|
+
foundLocks = true;
|
|
115
|
+
console.log(chalk.yellow(`发现Git锁文件: ${lockPath}`));
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
fs.unlinkSync(lockPath);
|
|
119
|
+
console.log(chalk.green(`成功删除Git锁文件: ${lockPath}`));
|
|
120
|
+
} catch (error) {
|
|
121
|
+
hasBusyLocks = true;
|
|
122
|
+
console.error(chalk.red(`无法删除Git锁文件 ${lockPath}:`), error);
|
|
123
|
+
console.log(chalk.yellow('文件可能正被进程使用,尝试终止Git进程后重试'));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.log(chalk.gray(`无法检查目录 ${baseDir}: ${error.message}`));
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
// 直接检查具体路径
|
|
133
|
+
if (fs.existsSync(lockPattern)) {
|
|
134
|
+
foundLocks = true;
|
|
135
|
+
console.log(chalk.yellow(`发现Git锁文件: ${lockPattern}`));
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
fs.unlinkSync(lockPattern);
|
|
139
|
+
console.log(chalk.green(`成功删除Git锁文件: ${lockPattern}`));
|
|
140
|
+
} catch (error) {
|
|
141
|
+
hasBusyLocks = true;
|
|
142
|
+
console.error(chalk.red(`无法删除Git锁文件 ${lockPattern}:`), error);
|
|
143
|
+
console.log(chalk.yellow('文件可能正被进程使用,尝试终止Git进程后重试'));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
if (hasBusyLocks) {
|
|
150
|
+
// 尝试终止Git进程
|
|
151
|
+
terminateGitProcesses();
|
|
152
|
+
|
|
153
|
+
// 再次尝试删除锁文件
|
|
154
|
+
let stillHasBusyLocks = false;
|
|
155
|
+
|
|
156
|
+
lockFiles.forEach(lockPattern => {
|
|
157
|
+
if (!lockPattern.includes('*') && fs.existsSync(lockPattern)) {
|
|
158
|
+
try {
|
|
159
|
+
fs.unlinkSync(lockPattern);
|
|
160
|
+
console.log(chalk.green(`成功删除Git锁文件: ${lockPattern}`));
|
|
161
|
+
} catch (error) {
|
|
162
|
+
stillHasBusyLocks = true;
|
|
163
|
+
console.error(chalk.red(`仍然无法删除Git锁文件 ${lockPattern}`));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
if (stillHasBusyLocks) {
|
|
169
|
+
console.log(chalk.yellow('警告:一些Git锁文件无法删除。建议:'));
|
|
170
|
+
console.log(chalk.yellow('1. 关闭所有可能使用Git的应用程序'));
|
|
171
|
+
console.log(chalk.yellow('2. 手动删除上述锁文件'));
|
|
172
|
+
console.log(chalk.yellow('3. 重新运行发布脚本'));
|
|
173
|
+
|
|
174
|
+
// 询问是否要继续
|
|
175
|
+
const shouldContinue = await askContinue(chalk.yellow('是否尝试继续执行?(Y/n): '));
|
|
176
|
+
|
|
177
|
+
if (!shouldContinue) {
|
|
178
|
+
console.log(chalk.yellow('用户选择终止发布过程'));
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
console.log(chalk.yellow('尝试继续执行,但可能会失败...'));
|
|
183
|
+
}
|
|
184
|
+
} else if (!foundLocks) {
|
|
185
|
+
console.log(chalk.gray('未发现Git锁文件,继续执行...'));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// 等待一下,确保文件系统操作完成
|
|
189
|
+
execSync('sleep 1 || ping -n 2 127.0.0.1 > nul', { stdio: 'ignore' });
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// 检查发布环境
|
|
193
|
+
async function checkEnvironment() {
|
|
194
|
+
console.log(chalk.blue('=== 检查发布环境 ==='));
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
// 检查Git是否可用
|
|
198
|
+
execSync('git --version', { stdio: 'ignore' });
|
|
199
|
+
|
|
200
|
+
// 检查是否在Git仓库中
|
|
201
|
+
execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
|
|
202
|
+
|
|
203
|
+
// 清理可能的Git锁文件
|
|
204
|
+
await checkAndCleanGitLocks();
|
|
205
|
+
|
|
206
|
+
// 检查当前分支
|
|
207
|
+
const currentBranch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
|
|
208
|
+
console.log(chalk.gray(`当前Git分支: ${currentBranch}`));
|
|
209
|
+
|
|
210
|
+
// 如果不在主分支上,询问是否继续
|
|
211
|
+
if (currentBranch !== 'main' && currentBranch !== 'master') {
|
|
212
|
+
const rl = createReadlineInterface();
|
|
213
|
+
|
|
214
|
+
try {
|
|
215
|
+
const answer = await rl.question(chalk.yellow(`当前不在主分支上,是否继续在 ${currentBranch} 分支上发布? (Y/n): `));
|
|
216
|
+
if (answer.toLowerCase() === 'n') {
|
|
217
|
+
throw '用户选择取消发布';
|
|
218
|
+
}
|
|
219
|
+
} finally {
|
|
220
|
+
rl.close();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 检查工作区是否干净
|
|
225
|
+
try {
|
|
226
|
+
execSync('git diff --quiet && git diff --staged --quiet', { stdio: 'ignore' });
|
|
227
|
+
console.log(chalk.green('Git工作区干净'));
|
|
228
|
+
} catch (e) {
|
|
229
|
+
console.log(chalk.yellow('Git工作区有未提交的更改'));
|
|
230
|
+
|
|
231
|
+
// 显示未提交的更改
|
|
232
|
+
console.log(chalk.gray('\n未提交的更改:'));
|
|
233
|
+
execSync('git status -s', { stdio: 'inherit' });
|
|
234
|
+
console.log(''); // 空行
|
|
235
|
+
|
|
236
|
+
const rl = createReadlineInterface();
|
|
237
|
+
|
|
238
|
+
try {
|
|
239
|
+
const answer = await rl.question(chalk.yellow('有未提交的更改,是否继续发布? (Y/n): '));
|
|
240
|
+
if (answer.toLowerCase() === 'n') {
|
|
241
|
+
throw '用户选择取消发布';
|
|
242
|
+
}
|
|
243
|
+
} finally {
|
|
244
|
+
rl.close();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
console.log(chalk.green('环境检查通过'));
|
|
249
|
+
} catch (error) {
|
|
250
|
+
if (error === '用户选择取消发布') {
|
|
251
|
+
console.log(chalk.yellow('发布已取消'));
|
|
252
|
+
process.exit(0);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
console.error(chalk.red('环境检查失败:'), error);
|
|
256
|
+
process.exit(1);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// 更新版本号
|
|
261
|
+
function updateVersion() {
|
|
262
|
+
console.log(chalk.blue('=== 更新版本号 ==='));
|
|
263
|
+
|
|
264
|
+
const currentVersion = packageJson.version;
|
|
265
|
+
console.log(chalk.gray(`当前版本: ${currentVersion}`));
|
|
266
|
+
|
|
267
|
+
// 拆分版本号
|
|
268
|
+
const versionParts = currentVersion.split('.');
|
|
269
|
+
|
|
270
|
+
// 递增最后一位版本号
|
|
271
|
+
const lastPart = parseInt(versionParts[versionParts.length - 1], 10);
|
|
272
|
+
versionParts[versionParts.length - 1] = (lastPart + 1).toString();
|
|
273
|
+
|
|
274
|
+
// 重组版本号
|
|
275
|
+
const newVersion = versionParts.join('.');
|
|
276
|
+
packageJson.version = newVersion;
|
|
277
|
+
|
|
278
|
+
// 写回package.json
|
|
279
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf8');
|
|
280
|
+
|
|
281
|
+
console.log(chalk.green(`版本号已更新: ${currentVersion} -> ${newVersion}`));
|
|
282
|
+
return newVersion;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// 构建前端项目
|
|
286
|
+
async function buildFrontend() {
|
|
287
|
+
console.log(chalk.blue('\n=== 构建前端项目 ==='));
|
|
288
|
+
|
|
289
|
+
try {
|
|
290
|
+
// 检查前端项目目录是否存在
|
|
291
|
+
const frontendDir = path.join(rootDir, 'src', 'ui', 'client');
|
|
292
|
+
if (!fs.existsSync(frontendDir)) {
|
|
293
|
+
console.log(chalk.yellow('前端项目目录不存在,跳过构建'));
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// 检查前端依赖是否安装
|
|
298
|
+
console.log(chalk.gray('检查前端依赖...'));
|
|
299
|
+
const nodeModulesPath = path.join(frontendDir, 'node_modules');
|
|
300
|
+
if (!fs.existsSync(nodeModulesPath)) {
|
|
301
|
+
console.log(chalk.yellow('未找到前端依赖,开始安装...'));
|
|
302
|
+
execSync('cd ./src/ui/client && npm install', { stdio: 'inherit' });
|
|
303
|
+
console.log(chalk.green('前端依赖安装完成'));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// 安装Node.js类型定义(如果需要)
|
|
307
|
+
try {
|
|
308
|
+
const typesNodePath = path.join(nodeModulesPath, '@types', 'node');
|
|
309
|
+
if (!fs.existsSync(typesNodePath)) {
|
|
310
|
+
console.log(chalk.yellow('安装Node.js类型定义...'));
|
|
311
|
+
execSync('cd ./src/ui/client && npm install --save-dev @types/node', { stdio: 'inherit' });
|
|
312
|
+
}
|
|
313
|
+
} catch (error) {
|
|
314
|
+
console.log(chalk.yellow('安装Node.js类型定义失败,继续构建...'));
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// 更新tsconfig.app.json以包含node类型(如果需要)
|
|
318
|
+
try {
|
|
319
|
+
const tsconfigAppPath = path.join(frontendDir, 'tsconfig.app.json');
|
|
320
|
+
if (fs.existsSync(tsconfigAppPath)) {
|
|
321
|
+
const tsconfig = JSON.parse(fs.readFileSync(tsconfigAppPath, 'utf8'));
|
|
322
|
+
let needsUpdate = false;
|
|
323
|
+
|
|
324
|
+
if (!tsconfig.compilerOptions) {
|
|
325
|
+
tsconfig.compilerOptions = {};
|
|
326
|
+
needsUpdate = true;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (!tsconfig.compilerOptions.types) {
|
|
330
|
+
tsconfig.compilerOptions.types = ['node'];
|
|
331
|
+
needsUpdate = true;
|
|
332
|
+
} else if (!tsconfig.compilerOptions.types.includes('node')) {
|
|
333
|
+
tsconfig.compilerOptions.types.push('node');
|
|
334
|
+
needsUpdate = true;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (needsUpdate) {
|
|
338
|
+
console.log(chalk.yellow('更新tsconfig.app.json以包含Node.js类型...'));
|
|
339
|
+
fs.writeFileSync(tsconfigAppPath, JSON.stringify(tsconfig, null, 2), 'utf8');
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
} catch (error) {
|
|
343
|
+
console.log(chalk.yellow('更新tsconfig失败,继续构建...'));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// 执行构建命令
|
|
347
|
+
console.log(chalk.gray('执行构建命令...'));
|
|
348
|
+
execSync('cd ./src/ui/client && npm run build', { stdio: 'inherit' });
|
|
349
|
+
console.log(chalk.green('前端项目构建完成'));
|
|
350
|
+
} catch (error) {
|
|
351
|
+
console.error(chalk.red('前端项目构建失败:'), error);
|
|
352
|
+
|
|
353
|
+
// 询问用户是否继续发布过程
|
|
354
|
+
console.log(chalk.yellow('\n前端构建失败,但您可以选择继续发布过程。'));
|
|
355
|
+
const rl = createReadlineInterface();
|
|
356
|
+
|
|
357
|
+
try {
|
|
358
|
+
const answer = await rl.question(chalk.yellow('是否继续发布流程?(Y/n): '));
|
|
359
|
+
if (answer.toLowerCase() === 'n') {
|
|
360
|
+
console.log(chalk.red('发布流程已取消'));
|
|
361
|
+
process.exit(1);
|
|
362
|
+
}
|
|
363
|
+
console.log(chalk.yellow('继续发布流程...'));
|
|
364
|
+
} finally {
|
|
365
|
+
rl.close();
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// 提交更改到git
|
|
371
|
+
async function commitChanges(version) {
|
|
372
|
+
console.log(chalk.blue('\n=== 提交更改到Git ==='));
|
|
373
|
+
|
|
374
|
+
try {
|
|
375
|
+
// 检查并清理可能的Git锁文件
|
|
376
|
+
await checkAndCleanGitLocks();
|
|
377
|
+
|
|
378
|
+
// 创建提交信息,包含版本号
|
|
379
|
+
const commitMessage = `chore: 发布版本 v${version}`;
|
|
380
|
+
|
|
381
|
+
// 禁用Git钩子以确保没有其他脚本干扰
|
|
382
|
+
console.log(chalk.gray('临时禁用Git钩子...'));
|
|
383
|
+
const gitHooksDir = path.join(rootDir, '.git', 'hooks');
|
|
384
|
+
let renamedHooks = [];
|
|
385
|
+
|
|
386
|
+
console.log(chalk.gray('添加更改文件...'));
|
|
387
|
+
// 使用--force参数,避免可能的锁文件问题,但排除node_modules目录
|
|
388
|
+
execSync('git add .', { stdio: 'inherit' });
|
|
389
|
+
|
|
390
|
+
// 等待一下,确保文件系统同步
|
|
391
|
+
console.log(chalk.gray('等待文件系统同步...'));
|
|
392
|
+
execSync('sleep 1 || ping -n 2 127.0.0.1 > nul', { stdio: 'ignore' });
|
|
393
|
+
|
|
394
|
+
console.log(chalk.gray('提交更改...'));
|
|
395
|
+
|
|
396
|
+
// 尝试提交,如果失败则重试
|
|
397
|
+
let committed = false;
|
|
398
|
+
let attempts = 0;
|
|
399
|
+
const maxAttempts = 3;
|
|
400
|
+
|
|
401
|
+
while (!committed && attempts < maxAttempts) {
|
|
402
|
+
attempts++;
|
|
403
|
+
|
|
404
|
+
try {
|
|
405
|
+
// 检查并清理Git锁文件
|
|
406
|
+
if (attempts > 1) {
|
|
407
|
+
await checkAndCleanGitLocks();
|
|
408
|
+
console.log(chalk.yellow(`重试提交 (${attempts}/${maxAttempts})...`));
|
|
409
|
+
// 稍等更长时间
|
|
410
|
+
execSync('sleep 2 || ping -n 3 127.0.0.1 > nul', { stdio: 'ignore' });
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// 使用--no-verify参数跳过钩子,避免可能的挂起
|
|
414
|
+
execSync(`git commit --no-verify -m "${commitMessage}"`, { stdio: 'inherit' });
|
|
415
|
+
committed = true;
|
|
416
|
+
} catch (error) {
|
|
417
|
+
if (attempts >= maxAttempts) {
|
|
418
|
+
throw error; // 重试次数用完,抛出错误
|
|
419
|
+
}
|
|
420
|
+
console.log(chalk.yellow(`提交失败,将在2秒后重试...`));
|
|
421
|
+
// 等待2秒后重试
|
|
422
|
+
execSync('sleep 2 || ping -n 3 127.0.0.1 > nul', { stdio: 'ignore' });
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
console.log(chalk.green(`更改已提交到Git,提交信息: "${commitMessage}"`));
|
|
427
|
+
|
|
428
|
+
// 创建版本标签
|
|
429
|
+
console.log(chalk.gray('创建版本标签...'));
|
|
430
|
+
execSync(`git tag v${version}`, { stdio: 'inherit' });
|
|
431
|
+
console.log(chalk.green(`已创建标签: v${version}`));
|
|
432
|
+
|
|
433
|
+
// 询问是否推送到远程
|
|
434
|
+
const rl = createReadlineInterface();
|
|
435
|
+
|
|
436
|
+
try {
|
|
437
|
+
const answer = await rl.question(chalk.yellow('是否推送代码和标签到远程仓库? (Y/n): '));
|
|
438
|
+
|
|
439
|
+
if (answer.toLowerCase() !== 'n') {
|
|
440
|
+
try {
|
|
441
|
+
// 获取当前分支
|
|
442
|
+
const branch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
|
|
443
|
+
|
|
444
|
+
console.log(chalk.gray(`推送代码到远程仓库,分支: ${branch}...`));
|
|
445
|
+
execSync(`git push origin ${branch}`, { stdio: 'inherit' });
|
|
446
|
+
|
|
447
|
+
console.log(chalk.gray('推送标签到远程仓库...'));
|
|
448
|
+
execSync('git push origin --tags', { stdio: 'inherit' });
|
|
449
|
+
|
|
450
|
+
console.log(chalk.green('代码和标签已成功推送到远程仓库'));
|
|
451
|
+
} catch (pushError) {
|
|
452
|
+
console.error(chalk.red('推送到远程仓库失败:'), pushError);
|
|
453
|
+
// 继续发布过程,不终止
|
|
454
|
+
}
|
|
455
|
+
} else {
|
|
456
|
+
console.log(chalk.yellow('跳过推送到远程仓库'));
|
|
457
|
+
}
|
|
458
|
+
} finally {
|
|
459
|
+
rl.close();
|
|
460
|
+
|
|
461
|
+
// 恢复Git钩子
|
|
462
|
+
if (renamedHooks.length > 0) {
|
|
463
|
+
console.log(chalk.gray('恢复Git钩子...'));
|
|
464
|
+
for (const hook of renamedHooks) {
|
|
465
|
+
try {
|
|
466
|
+
fs.renameSync(hook.disabled, hook.original);
|
|
467
|
+
} catch (e) {
|
|
468
|
+
console.log(chalk.yellow(`无法恢复Git钩子: ${path.basename(hook.original)}`));
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
console.log(chalk.gray(`已恢复 ${renamedHooks.length} 个Git钩子`));
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
} catch (error) {
|
|
475
|
+
console.error(chalk.red('Git提交失败:'), error);
|
|
476
|
+
process.exit(1);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// 发布到NPM
|
|
481
|
+
async function publishToNpm() {
|
|
482
|
+
console.log(chalk.blue('\n=== 发布到NPM ==='));
|
|
483
|
+
|
|
484
|
+
// 创建readline接口
|
|
485
|
+
const rl = createReadlineInterface();
|
|
486
|
+
|
|
487
|
+
try {
|
|
488
|
+
// 等待用户确认
|
|
489
|
+
const answer = await rl.question(chalk.yellow('是否发布到NPM? (Y/n): '));
|
|
490
|
+
|
|
491
|
+
if (answer.toLowerCase() === 'n') {
|
|
492
|
+
console.log(chalk.yellow('跳过发布到NPM'));
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// 执行npm发布
|
|
497
|
+
console.log(chalk.gray('执行npm发布...'));
|
|
498
|
+
try {
|
|
499
|
+
execSync('npm publish', { stdio: 'inherit' });
|
|
500
|
+
console.log(chalk.green('已成功发布到NPM'));
|
|
501
|
+
} catch (error) {
|
|
502
|
+
console.error(chalk.red('发布到NPM失败:'), error);
|
|
503
|
+
throw error;
|
|
504
|
+
}
|
|
505
|
+
} finally {
|
|
506
|
+
rl.close();
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// 主流程
|
|
511
|
+
async function main() {
|
|
512
|
+
console.log(chalk.cyan('\n🚀 开始发布流程...\n'));
|
|
513
|
+
|
|
514
|
+
try {
|
|
515
|
+
// 1. 检查环境
|
|
516
|
+
await checkEnvironment();
|
|
517
|
+
|
|
518
|
+
// 2. 更新版本号
|
|
519
|
+
const newVersion = updateVersion();
|
|
520
|
+
|
|
521
|
+
// 3. 构建前端项目
|
|
522
|
+
await buildFrontend();
|
|
523
|
+
|
|
524
|
+
// 4. 提交更改到Git
|
|
525
|
+
await commitChanges(newVersion);
|
|
526
|
+
|
|
527
|
+
// 5. 发布到NPM
|
|
528
|
+
await publishToNpm();
|
|
529
|
+
|
|
530
|
+
console.log(chalk.green('\n🎉 发布完成!'));
|
|
531
|
+
} catch (error) {
|
|
532
|
+
console.error(chalk.red('\n❌ 发布失败:'), error);
|
|
533
|
+
process.exit(1);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// 启动流程
|
|
538
|
+
main().catch(error => {
|
|
539
|
+
console.error(chalk.red('\n❌ 未捕获的错误:'), error);
|
|
540
|
+
process.exit(1);
|
|
541
|
+
});
|
package/src/gitCommit.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.card[data-v-c005b533]{background-color:#fff;border-radius:12px;box-shadow:0 2px 12px #0000000a;border:1px solid rgba(0,0,0,.03);height:100%;width:100%;display:flex;flex-direction:column;overflow:hidden;transition:all .3s ease;position:relative}.status-header[data-v-c005b533]{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid #f0f0f0}.status-header h2[data-v-c005b533]{margin:0;font-size:16px;font-weight:500;color:#303133}.header-actions[data-v-c005b533]{display:flex;align-items:center;gap:8px}.card-content[data-v-c005b533]{padding:16px;overflow-y:auto;overflow-x:hidden;flex:1;display:flex;flex-direction:column}.status-box[data-v-c005b533]{white-space:pre-wrap;font-family:monospace;background-color:#f8f9fa;padding:16px;border-radius:8px;margin-bottom:20px;max-height:200px;overflow-y:auto;overflow-x:hidden;border:1px solid #f0f0f0;font-size:14px;line-height:1.5;width:100%;box-sizing:border-box}.file-list-container[data-v-c005b533]{flex:1;overflow:hidden;display:flex;flex-direction:column;gap:16px;height:auto;min-height:100px;width:100%;box-sizing:border-box}.file-group[data-v-c005b533]{background-color:#f8f9fa;border-radius:8px;overflow:hidden;border:1px solid #ebeef5;margin-bottom:0;display:flex;flex-direction:column;transition:box-shadow .3s ease}.file-group[data-v-c005b533]:hover{box-shadow:0 4px 12px #0000000d}.file-group[data-v-c005b533]{flex:0 1 auto}.file-group[data-v-c005b533]:last-child{margin-bottom:0;flex:1 1 auto}.file-group-header[data-v-c005b533]{font-size:14px;font-weight:700;padding:10px 16px;background-color:#f0f2f5;color:#606266;border-bottom:1px solid #ebeef5;flex-shrink:0}.file-list[data-v-c005b533]{overflow-y:auto;min-height:40px;max-height:200px;flex-grow:1;padding:0;margin:0;scrollbar-width:thin;scrollbar-color:rgba(144,147,153,.3) transparent}.file-list[data-v-c005b533]::-webkit-scrollbar{width:6px;height:6px}.file-list[data-v-c005b533]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px}.file-list[data-v-c005b533]::-webkit-scrollbar-thumb:hover{background-color:#90939980}.file-list[data-v-c005b533]::-webkit-scrollbar-track{background-color:transparent}.file-list[data-v-c005b533]:empty{display:none}.empty-file-container[data-v-c005b533]{overflow-y:hidden!important;display:flex;flex-direction:column;align-items:stretch;flex:1}.empty-file-group[data-v-c005b533]{padding:16px;text-align:center;color:#909399;font-size:13px;font-style:italic;display:flex;align-items:center;justify-content:center;min-height:50px;background-color:#f8f9fa;border-radius:4px;margin:8px}.file-item[data-v-c005b533]{padding:10px 16px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #ebeef5;cursor:pointer;transition:all .2s ease}.file-item[data-v-c005b533]:last-child{border-bottom:none}.file-item[data-v-c005b533]:hover{background-color:#ecf5ff}.file-info[data-v-c005b533]{display:flex;align-items:center;flex-grow:1;overflow:hidden;white-space:nowrap;gap:10px}.file-status-indicator[data-v-c005b533]{width:8px;height:8px;border-radius:50%;background-color:#409eff;flex-shrink:0}.file-status-indicator.added[data-v-c005b533]{background-color:#67c23a}.file-status-indicator.modified[data-v-c005b533]{background-color:#409eff}.file-status-indicator.deleted[data-v-c005b533]{background-color:#f56c6c}.file-status-indicator.untracked[data-v-c005b533]{background-color:#e6a23c}.file-path-container[data-v-c005b533]{display:flex;flex-direction:column;overflow:hidden}.file-name[data-v-c005b533]{font-weight:500;color:#303133;overflow:hidden;text-overflow:ellipsis;line-height:1.4}.file-directory[data-v-c005b533]{font-size:12px;color:#909399;max-width:200px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.file-actions[data-v-c005b533]{display:flex;gap:8px;opacity:0;transition:opacity .2s ease}.file-item:hover .file-actions[data-v-c005b533]{opacity:1}.empty-status[data-v-c005b533]{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;text-align:center;background-color:#f9f9f9;border-radius:8px;flex-grow:1}.empty-icon[data-v-c005b533]{width:64px;height:64px;display:flex;align-items:center;justify-content:center;background-color:#f0f2f5;border-radius:50%;margin-bottom:16px;font-size:28px;color:#909399;animation:pulse-c005b533 2s infinite ease-in-out}@keyframes pulse-c005b533{0%{transform:scale(1);opacity:.7}50%{transform:scale(1.05);opacity:1}to{transform:scale(1);opacity:.7}}.empty-text[data-v-c005b533]{font-size:18px;font-weight:500;color:#606266;margin-bottom:8px}.empty-subtext[data-v-c005b533]{font-size:14px;color:#909399;margin-bottom:20px}.status-box-wrap[data-v-c005b533]{height:100%;display:flex;flex-direction:column;gap:16px}.branch-status-info[data-v-c005b533]{margin-bottom:0;background-color:#f8f9fa;border-radius:8px;overflow:hidden;border:1px solid #ebeef5;transition:all .3s ease}.branch-status-info[data-v-c005b533]:hover{box-shadow:0 4px 12px #0000000d}.branch-sync-status[data-v-c005b533]{display:flex;align-items:center;padding:12px 16px;border-left:3px solid #e6a23c;margin-bottom:0;background-color:#fdf6ec}.sync-status-content[data-v-c005b533]{display:flex;align-items:center;flex-wrap:wrap;gap:10px;width:100%}.status-badges[data-v-c005b533]{display:flex;flex-direction:column;gap:8px;width:100%}.status-badge[data-v-c005b533]{display:flex;align-items:center;width:100%;border-radius:4px;padding:8px 12px;transition:all .3s ease}.status-badge.el-tag--warning[data-v-c005b533]{background-color:#fdf6ec;border-color:#faecd8}.status-badge.el-tag--info[data-v-c005b533]{background-color:#f4f4f5;border-color:#e9e9eb}.status-badge[data-v-c005b533]:hover{transform:translateY(-2px);box-shadow:0 2px 8px #0000000d}.badge-content[data-v-c005b533]{display:flex;align-items:center;gap:8px;font-size:13px}.diff-dialog[data-v-c005b533]{height:calc(100vh - 150px)}[data-v-c005b533] .el-dialog__body{height:calc(100vh - 320px);overflow:auto;padding:0}.diff-content[data-v-c005b533]{flex:1;overflow-y:auto;padding:16px 20px;background-color:#fafafa;height:100%}.diff-formatted[data-v-c005b533]{font-family:JetBrains Mono,Fira Code,Consolas,Courier New,monospace;font-size:14px;line-height:1.6;white-space:pre-wrap;padding-bottom:20px}.no-diff[data-v-c005b533]{display:flex;align-items:center;justify-content:center;height:100%;color:#909399;font-size:14px}.file-navigation[data-v-c005b533]{display:flex;justify-content:space-between;align-items:center;padding:12px 20px;border-top:1px solid #ebeef5;background-color:#f9f9fb}.counter-tag[data-v-c005b533]{font-family:monospace;font-size:14px;padding:6px 12px;min-width:80px;text-align:center}.nav-button[data-v-c005b533]{min-width:120px;transition:all .3s ease}.nav-button[data-v-c005b533]:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 2px 8px #0000001a}.diff-formatted[data-v-c005b533]::-webkit-scrollbar,.diff-content[data-v-c005b533]::-webkit-scrollbar{width:6px;height:6px}.diff-formatted[data-v-c005b533]::-webkit-scrollbar-thumb,.diff-content[data-v-c005b533]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px}.diff-formatted[data-v-c005b533]::-webkit-scrollbar-thumb:hover,.diff-content[data-v-c005b533]::-webkit-scrollbar-thumb:hover{background-color:#90939980}.diff-formatted[data-v-c005b533]::-webkit-scrollbar-track,.diff-content[data-v-c005b533]::-webkit-scrollbar-track{background-color:transparent}.diff-formatted[data-v-c005b533],.diff-content[data-v-c005b533]{scrollbar-width:thin;scrollbar-color:rgba(144,147,153,.3) transparent}.auto-update-switch[data-v-c005b533] .el-switch__core{transition:all .3s ease-in-out;box-shadow:0 2px 5px #0000001a}.auto-update-switch[data-v-c005b533] .el-switch__core:hover{box-shadow:0 2px 8px #0003}.auto-update-switch.is-checked[data-v-c005b533] .el-switch__core{box-shadow:0 2px 5px #67c23a4d}.auto-update-switch.is-checked[data-v-c005b533] .el-switch__core:hover{box-shadow:0 2px 8px #67c23a80}.el-button[data-v-c005b533]{transition:all .3s ease}.el-button[data-v-c005b533]:not(:disabled):hover{transform:translateY(-2px);box-shadow:0 2px 8px #0000001a}.card-content[data-v-c005b533] .el-loading-mask{background-color:#fffc;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);z-index:10}.card-content[data-v-c005b533] .el-loading-spinner{transform:scale(1.2)}.card-content[data-v-c005b533] .el-loading-text{font-size:16px;color:#409eff;font-weight:700;margin-top:10px}.diff-header{font-weight:700;background-color:#e6f1fc;padding:8px 12px;margin:10px 0;border-radius:6px;color:#0366d6;border-bottom:1px solid #c8e1ff}.diff-old-file,.diff-new-file{color:#586069;padding:4px 8px;font-family:monospace}.diff-hunk-header{color:#6f42c1;background-color:#f1f8ff;padding:4px 8px;margin:8px 0;border-radius:4px;font-family:monospace}.diff-added{background-color:#e6ffed;color:#22863a;padding:2px 8px;border-left:4px solid #22863a;font-family:monospace;display:block;margin:2px 0}.diff-removed{background-color:#ffeef0;color:#cb2431;padding:2px 8px;border-left:4px solid #cb2431;font-family:monospace;display:block;margin:2px 0}.diff-context{color:#444;padding:2px 8px;font-family:monospace;display:block;margin:2px 0;background-color:#fafbfc}@keyframes snakeBorder-5f34e2c0{0%,to{border-top:2px solid #409EFF;border-right:2px solid transparent;border-bottom:2px solid transparent;border-left:2px solid transparent}25%{border-top:2px solid #409EFF;border-right:2px solid #67C23A;border-bottom:2px solid transparent;border-left:2px solid transparent}50%{border-top:2px solid transparent;border-right:2px solid #67C23A;border-bottom:2px solid #409EFF;border-left:2px solid transparent}75%{border-top:2px solid transparent;border-right:2px solid transparent;border-bottom:2px solid #409EFF;border-left:2px solid #67C23A}}@keyframes glowPulse-5f34e2c0{0%,to{box-shadow:0 0 8px #409eff66}50%{box-shadow:0 0 12px #67c23a80}}.card[data-v-5f34e2c0]{background-color:#fff;border-radius:8px;box-shadow:0 2px 10px #00000008;border:1px solid rgba(0,0,0,.03);height:100%;width:100%;display:flex;flex-direction:column;overflow:hidden;position:relative}.card-header[data-v-5f34e2c0]{padding:8px 16px;border-bottom:1px solid #f0f0f0;display:flex;justify-content:space-between;align-items:center}.card-header h2[data-v-5f34e2c0]{margin:0;font-size:16px;font-weight:500;color:#303133}.card-content[data-v-5f34e2c0]{padding:15px;overflow-y:auto;flex:1}.layout-container[data-v-5f34e2c0]{display:flex;flex-direction:column;gap:15px;height:100%}.commit-section[data-v-5f34e2c0]{flex:1;min-width:0}.actions-section[data-v-5f34e2c0]{width:100%;flex-shrink:0}.actions-section h3[data-v-5f34e2c0]{margin-top:0;margin-bottom:10px;padding-bottom:8px;border-bottom:1px solid #dcdfe6;font-size:16px;color:#303133;font-weight:500}.operations-wrapper[data-v-5f34e2c0]{display:flex;gap:10px}.action-groups[data-v-5f34e2c0]{display:flex;flex-direction:column;gap:12px}.action-group[data-v-5f34e2c0]{background-color:#f9f9f9;border-radius:6px;padding:8px 10px;box-shadow:0 1px 3px #0000000d;border-left:3px solid #409EFF;flex:1}.action-group[data-v-5f34e2c0]:nth-child(2){border-left-color:#e6a23c}.action-group[data-v-5f34e2c0]:nth-child(3){border-left-color:#909399}.group-title[data-v-5f34e2c0]{font-size:13px;font-weight:700;margin-bottom:8px;color:#606266;text-align:left;display:block;position:relative;padding-left:6px;border-bottom:1px solid rgba(0,0,0,.06);padding-bottom:6px}.group-buttons[data-v-5f34e2c0]{display:flex;flex-direction:row;flex-wrap:wrap;gap:8px;padding:0}.action-button[data-v-5f34e2c0]{font-size:14px;font-weight:500;flex:1;min-width:100px;border-radius:4px;height:36px;padding:0 10px}.action-button[data-v-5f34e2c0]:hover{transform:translateY(-1px);box-shadow:0 2px 5px #00000026}.action-button[data-v-5f34e2c0]:active{transform:translateY(0)}.command-text[data-v-5f34e2c0],.command-text-long[data-v-5f34e2c0]{display:none}.standard-commit-form[data-v-5f34e2c0]{display:flex;flex-direction:column;gap:15px;margin-bottom:15px}.standard-commit-header[data-v-5f34e2c0]{display:flex;flex-direction:column;gap:10px;width:100%}.type-scope-container[data-v-5f34e2c0]{display:flex;gap:10px;width:100%;margin-bottom:10px}.type-select[data-v-5f34e2c0]{width:35%}.scope-wrapper[data-v-5f34e2c0]{display:flex;align-items:center;gap:5px;width:65%}.description-container[data-v-5f34e2c0]{display:flex;align-items:center;gap:5px;width:100%}.scope-input[data-v-5f34e2c0],.description-input[data-v-5f34e2c0]{flex-grow:1}.settings-button[data-v-5f34e2c0]{flex-shrink:0}.preview-section[data-v-5f34e2c0]{background-color:#f5f7fa;padding:10px;border-radius:4px}.preview-title[data-v-5f34e2c0]{font-weight:700;margin-bottom:5px}.preview-content[data-v-5f34e2c0]{white-space:pre-wrap;font-family:monospace;margin:0;padding:10px;background-color:#ebeef5;border-radius:4px}.template-container[data-v-5f34e2c0]{display:flex;flex-direction:column;height:calc(85vh - 100px);overflow-y:auto;padding:5px}.template-form[data-v-5f34e2c0]{margin-bottom:20px;background-color:#f8f9fa;padding:15px;border-radius:6px;border:1px solid #ebeef5}.template-form-buttons[data-v-5f34e2c0]{display:flex;gap:10px;margin-top:12px;justify-content:flex-end}.template-input[data-v-5f34e2c0]{flex-grow:1}.template-list[data-v-5f34e2c0]{overflow-y:auto;height:100%}.template-list h3[data-v-5f34e2c0]{margin-top:0;margin-bottom:15px;font-size:16px;font-weight:500;color:#303133;padding-bottom:8px;border-bottom:1px solid #ebeef5}.template-item[data-v-5f34e2c0]{margin-bottom:10px;transition:all .2s ease;border:1px solid #ebeef5}.template-item[data-v-5f34e2c0]:hover{background-color:#f5f7fa;transform:translateY(-2px);box-shadow:0 2px 12px #0000001a}.template-content[data-v-5f34e2c0]{flex-grow:1;margin-right:10px;word-break:break-all;padding:5px 0;color:#303133;font-weight:500}.template-actions[data-v-5f34e2c0]{display:flex;gap:8px;justify-content:flex-end;min-width:180px;flex-shrink:0}.options-row[data-v-5f34e2c0]{display:flex;justify-content:space-between;align-items:center;margin-bottom:15px}.code-command[data-v-5f34e2c0]{background-color:#2d2d2d;color:#f8f8f2;font-family:Courier New,Courier,monospace;padding:10px;border-radius:4px;overflow-x:auto;white-space:pre;font-size:14px}@media (min-width: 768px){.layout-container[data-v-5f34e2c0]{flex-direction:row}.commit-section[data-v-5f34e2c0]{flex:3}.actions-section[data-v-5f34e2c0]{width:320px}.operations-wrapper[data-v-5f34e2c0]{flex-direction:column}}.git-config-warning[data-v-5f34e2c0]{width:100%}.config-command[data-v-5f34e2c0]{background-color:#2d2d2d;color:#f8f8f2;font-family:Courier New,Courier,monospace;padding:10px;border-radius:4px;margin-top:10px;white-space:pre}@keyframes pushing-pulse-5f34e2c0{0%{box-shadow:0 0 #67c23a66}70%{box-shadow:0 0 0 15px #67c23a00}to{box-shadow:0 0 #67c23a00}}@keyframes pushing-border-5f34e2c0{0%{border-color:#67c23a}50%{border-color:#85ce61}to{border-color:#67c23a}}.card.is-pushing[data-v-5f34e2c0]{animation:pushing-border-5f34e2c0 1.5s infinite ease-in-out;box-shadow:0 4px 12px #0000001a;transition:all .3s ease}.push-button[data-v-5f34e2c0]{background-color:#67c23a;border-color:#67c23a}.push-button[data-v-5f34e2c0]:hover{background-color:#85ce61;border-color:#85ce61}.push-button.is-loading[data-v-5f34e2c0],.push-button.is-loading[data-v-5f34e2c0]:hover,.push-button.is-loading[data-v-5f34e2c0]:focus{animation:pushing-pulse-5f34e2c0 1.5s infinite;background-color:#67c23a!important;border-color:#67c23a!important}.el-button.push-button.is-loading .el-loading-spinner[data-v-5f34e2c0]{color:#fff!important}@keyframes one-click-push-glow-5f34e2c0{0%{box-shadow:0 0 5px #67c23a80}50%{box-shadow:0 0 20px #67c23acc}to{box-shadow:0 0 5px #67c23a80}}.action-button.one-click-push[data-v-5f34e2c0]{position:relative;overflow:hidden}.action-button.one-click-push.is-loading[data-v-5f34e2c0],.action-button.one-click-push.is-loading[data-v-5f34e2c0]:hover{animation:one-click-push-glow-5f34e2c0 1.5s infinite;background-color:#67c23a!important;border-color:#67c23a!important}@keyframes push-success-5f34e2c0{0%{transform:scale(1)}50%{transform:scale(1.1)}to{transform:scale(1)}}.push-success-indicator[data-v-5f34e2c0]{position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;background-color:#fff;border-radius:12px;padding:20px 30px;box-shadow:0 8px 24px #00000026;display:flex;flex-direction:column;align-items:center;justify-content:center;animation:push-success-5f34e2c0 .5s ease-out;z-index:9999;width:200px;height:200px}.push-success-icon[data-v-5f34e2c0]{font-size:64px;color:#67c23a;margin-bottom:16px;animation:bounce-5f34e2c0 .8s ease-in-out}@keyframes bounce-5f34e2c0{0%,20%,50%,80%,to{transform:translateY(0)}40%{transform:translateY(-20px)}60%{transform:translateY(-10px)}}.push-success-text[data-v-5f34e2c0]{font-size:20px;font-weight:700;color:#303133;text-align:center}.reset-button[data-v-5f34e2c0]{background-color:#909399;border-color:#909399}.reset-button[data-v-5f34e2c0]:hover{background-color:#a6a9ad;border-color:#a6a9ad}.el-button+.el-button[data-v-5f34e2c0]{margin-left:0}.pushing-indicator[data-v-5f34e2c0]{position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;background-color:#409eff;border-radius:12px;padding:20px 30px;box-shadow:0 8px 24px #00000026;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:9999;width:200px;height:200px;color:#fff}.form-bottom-actions[data-v-5f34e2c0]{display:flex;flex-direction:column;gap:10px;margin-top:15px;padding:12px;background-color:#f5f7fa;border-radius:6px;box-shadow:0 1px 3px #0000000d;border-left:3px solid #67C23A}.button-row[data-v-5f34e2c0]{display:flex;justify-content:space-between;gap:10px;width:100%}.button-row .el-button[data-v-5f34e2c0]{flex:1;min-width:100px}.full-width-button[data-v-5f34e2c0]{width:100%;margin-top:5px;font-weight:500;height:40px}.form-bottom-actions .el-button[data-v-5f34e2c0]{font-weight:500;border-radius:4px;transition:all .3s}.form-bottom-actions .el-button[data-v-5f34e2c0]:hover{transform:translateY(-1px);box-shadow:0 2px 5px #00000026}.pushing-text[data-v-5f34e2c0]{font-size:20px;font-weight:700;text-align:center}.pushing-spinner[data-v-5f34e2c0]{margin-bottom:16px}.circular[data-v-5f34e2c0]{height:64px;width:64px;animation:pushing-rotate-5f34e2c0 2s linear infinite}.path[data-v-5f34e2c0]{stroke:#fff;stroke-width:4;stroke-linecap:round;stroke-dasharray:90,150;stroke-dashoffset:0;animation:pushing-dash-5f34e2c0 1.5s ease-in-out infinite}@keyframes pushing-rotate-5f34e2c0{to{transform:rotate(360deg)}}@keyframes pushing-dash-5f34e2c0{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}.message-template-container[data-v-5f34e2c0]{display:flex;flex-direction:column;height:calc(100vh - 278px);overflow:hidden}.templates-container[data-v-5f34e2c0]{display:flex;gap:20px;margin-top:15px;flex:1;overflow:hidden}.message-templates-list[data-v-5f34e2c0]{flex:3;display:flex;flex-direction:column;border-right:1px solid #ebeef5;padding-right:15px;height:calc(100vh - 432px)}.message-templates-list h3[data-v-5f34e2c0]{margin-top:0;margin-bottom:15px;font-size:16px;font-weight:500;color:#303133;padding-bottom:8px;border-bottom:1px solid #ebeef5}.current-default-message[data-v-5f34e2c0]{flex:2;display:flex;flex-direction:column;gap:15px;padding-left:15px}.current-default-message h3[data-v-5f34e2c0]{margin-top:0;margin-bottom:15px;font-size:16px;font-weight:500;color:#303133;padding-bottom:8px;border-bottom:1px solid #ebeef5}.templates-scroll-area[data-v-5f34e2c0]{overflow-y:auto;padding-right:5px;flex:1}.default-message-card[data-v-5f34e2c0]{margin-bottom:15px;box-shadow:0 2px 8px #00000014;border-radius:4px;transition:all .3s ease}.default-message-card[data-v-5f34e2c0]:hover{box-shadow:0 4px 12px #0000001f}.default-message-content[data-v-5f34e2c0]{padding:12px 15px;background-color:#f0f9eb;border-left:3px solid #67c23a;font-weight:500;word-break:break-all;min-height:60px;display:flex;align-items:center;border-radius:0 4px 4px 0;color:#303133}.message-help-text[data-v-5f34e2c0]{background-color:#f8f9fa;border-radius:4px;padding:15px;font-size:14px;color:#606266;border-left:3px solid #909399;margin-top:auto;box-shadow:0 2px 8px #0000000d}.message-help-text h4[data-v-5f34e2c0]{margin-top:0;margin-bottom:10px;color:#303133;font-size:15px}.message-help-text p[data-v-5f34e2c0]{margin:8px 0;line-height:1.5}.advanced-options-toggle[data-v-5f34e2c0]{display:flex;align-items:center;justify-content:center;padding:8px 0;background-color:#f5f7fa;border-radius:4px;cursor:pointer;transition:all .3s ease;-webkit-user-select:none;user-select:none}.advanced-options-toggle[data-v-5f34e2c0]:hover{background-color:#ebeef5;color:#409eff}.toggle-icon[data-v-5f34e2c0]{margin-left:8px;transition:transform .3s ease}.toggle-icon.is-active[data-v-5f34e2c0]{transform:rotate(180deg)}.advanced-fields[data-v-5f34e2c0]{margin-top:10px;display:flex;flex-direction:column;gap:15px;animation:fade-in-5f34e2c0 .3s ease-in-out}@keyframes fade-in-5f34e2c0{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.merge-dialog-content[data-v-5f34e2c0]{padding:0 10px}.merge-intro[data-v-5f34e2c0]{margin-bottom:20px;color:#606266}.merge-options[data-v-5f34e2c0]{display:flex;flex-direction:column;gap:10px}.dialog-footer[data-v-5f34e2c0]{display:flex;justify-content:flex-end;gap:10px}.merge-confirm-btn[data-v-5f34e2c0]{margin-left:10px}.merge-button[data-v-5f34e2c0]{background-color:#409eff;border-color:#409eff}.branch-group[data-v-5f34e2c0]{border-top:1px solid #f0f0f0;padding-top:16px}.branch-group .group-title[data-v-5f34e2c0]{color:#606266;font-weight:500;margin-bottom:12px}[data-v-5f34e2c0] .el-checkbox__label{white-space:normal;line-height:1.4}.stash-list-content[data-v-5f34e2c0]{padding:20px 0}.stash-list-actions[data-v-5f34e2c0]{margin-top:20px;display:flex;justify-content:flex-end}.stash-dialog-content p[data-v-5f34e2c0]{margin-bottom:20px;color:#606266}.git-cmd-tooltip{font-family:Consolas,Courier New,monospace!important;font-size:13px!important;font-weight:500!important;color:#303133!important;background-color:#f5f7fa!important;border:1px solid #dcdfe6!important;border-radius:4px!important;padding:8px 12px!important;box-shadow:0 2px 12px #0000001a!important}.template-dialog .el-dialog__header,.message-template-dialog .el-dialog__header,.merge-dialog .el-dialog__header{padding:15px 20px;margin-right:0;border-bottom:1px solid #ebeef5;background-color:#f8f9fa}.template-dialog .el-dialog__title,.message-template-dialog .el-dialog__title,.merge-dialog .el-dialog__title{font-size:16px;font-weight:600;color:#303133}.template-dialog .el-dialog__body,.message-template-dialog .el-dialog__body,.merge-dialog .el-dialog__body{padding:20px}.merge-dialog .el-dialog__footer{padding:15px 20px;border-top:1px solid #f0f0f0}.template-dialog .el-dialog__headerbtn,.message-template-dialog .el-dialog__headerbtn,.merge-dialog .el-dialog__headerbtn{top:15px;right:20px}.template-dialog .el-input__inner,.message-template-dialog .el-input__inner,.merge-dialog .el-input__inner{height:40px;line-height:40px}.template-dialog .el-button,.message-template-dialog .el-button{border-radius:4px;font-weight:500}.template-dialog .el-card,.message-template-dialog .el-card{border-radius:4px;overflow:hidden}.template-dialog .el-card__body,.message-template-dialog .el-card__body{padding:12px 15px}.template-dialog .el-empty__image,.message-template-dialog .el-empty__image{width:80px;height:80px}.card[data-v-f12ff603]{background-color:#fff;border-radius:8px;box-shadow:0 2px 12px #0000001a;margin-bottom:20px;display:flex;flex-direction:column;height:100%;overflow:hidden;position:relative}.log-header[data-v-f12ff603]{display:flex;justify-content:space-between;align-items:center;padding:16px;margin-bottom:16px;border-bottom:1px solid #ebeef5;position:sticky;top:0;background-color:#fff;z-index:100}.fullscreen-mode .log-header[data-v-f12ff603]{margin-bottom:10px;box-shadow:0 2px 8px #0000000d}.header-left[data-v-f12ff603]{display:flex;align-items:center;gap:16px}.header-left h2[data-v-f12ff603]{margin:0;font-size:20px;font-weight:600;color:#303133}.log-actions[data-v-f12ff603]{display:flex;align-items:center;gap:12px}.action-button[data-v-f12ff603]{transition:all .3s ease;border-radius:8px;border:1px solid transparent;box-shadow:0 2px 4px #0000001a;font-weight:500;padding:8px 16px;display:flex;align-items:center;justify-content:center;gap:8px}.action-button[data-v-f12ff603]:hover{transform:translateY(-2px);box-shadow:0 4px 8px #00000026}.filter-button[data-v-f12ff603]{background:linear-gradient(135deg,#e6a23c,#f0c78a);color:#fff;min-width:90px}.filter-button.active-filter[data-v-f12ff603]{background:linear-gradient(135deg,#d48806,#e6a23c)}.filter-button .filter-badge[data-v-f12ff603] .el-badge__content{background-color:#f56c6c;color:#fff;border:2px solid white;box-shadow:0 0 0 1px #e6a23c}.view-mode-button[data-v-f12ff603]{background:linear-gradient(135deg,#409eff,#53a8ff);color:#fff}.view-mode-button.active-view[data-v-f12ff603]{background:linear-gradient(135deg,#1890ff,#096dd9)}.commit-display-button[data-v-f12ff603]{background:linear-gradient(135deg,#67c23a,#85ce61);color:#fff}.commit-display-button.active-commits[data-v-f12ff603]{background:linear-gradient(135deg,#52c41a,#389e0d)}.refresh-button[data-v-f12ff603]{background:linear-gradient(135deg,#909399,#c0c4cc);color:#fff;min-width:unset;padding:8px;border-radius:50%;width:36px;height:36px}.refresh-button[data-v-f12ff603]:hover{background:linear-gradient(135deg,#606266,#909399)}.refresh-button-animated[data-v-f12ff603]{animation:spin-f12ff603 1s linear}@keyframes spin-f12ff603{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.content-area[data-v-f12ff603]{padding:10px 16px;flex:1;min-height:100px;height:calc(100% - 52px);display:flex;flex-direction:column;overflow:auto}.content-area-content[data-v-f12ff603]{height:100%;display:flex;flex-direction:column}.content-area.with-filter[data-v-f12ff603]{height:calc(100% - 112px);padding-top:0}.content-area>div[data-v-f12ff603]{flex:1;display:flex;flex-direction:column}.el-table[data-v-f12ff603]{--el-table-border-color: #f0f0f0;--el-table-header-bg-color: #f8f9fa;border-radius:8px;overflow:hidden}[data-v-f12ff603] .el-table__header-wrapper{background-color:#f8f9fa}[data-v-f12ff603] .el-table__header th{background-color:#f8f9fa;color:#606266;font-weight:600;height:48px}[data-v-f12ff603] .el-table__row{transition:all .2s ease}[data-v-f12ff603] .el-table__row:hover{background-color:#ecf5ff!important}[data-v-f12ff603] .el-table--striped .el-table__row--striped{background-color:#fafafa}[data-v-f12ff603] .el-table__cell{padding:8px 0}.branch-container[data-v-f12ff603]{display:flex;flex-wrap:wrap;gap:6px}.branch-tag[data-v-f12ff603]{margin-right:0;border-radius:4px;transition:all .2s ease}.branch-tag[data-v-f12ff603]:hover{transform:translateY(-1px);box-shadow:0 2px 4px #0000001a}.commit-count[data-v-f12ff603]{margin-bottom:12px;font-size:14px;color:#606266;text-align:right}.graph-view[data-v-f12ff603]{width:100%;flex:1;display:flex;flex-direction:column;overflow-y:auto;padding:0 8px}.graph-container[data-v-f12ff603]{width:100%;flex:1;min-height:500px;border:1px solid #ebeef5;border-radius:8px;padding:16px;background-color:#fff;position:relative;box-shadow:0 2px 8px #00000008}.graph-container svg[data-v-f12ff603]{transform-origin:top left;transition:transform .2s ease}.graph-controls[data-v-f12ff603]{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;background-color:#f8f9fa;padding:12px;border-radius:8px;border:1px solid #ebeef5}.zoom-controls[data-v-f12ff603]{display:flex;gap:12px;align-items:center}.zoom-slider[data-v-f12ff603]{width:200px}.scale-info[data-v-f12ff603]{font-size:14px;color:#606266;background-color:#fff;padding:4px 10px;border-radius:4px;border:1px solid #ebeef5}.refresh-notification[data-v-f12ff603]{background-color:#f0f9eb;color:#67c23a;padding:10px 15px;border-radius:8px;font-size:14px;border-left:4px solid #67c23a;animation:fadeOut-f12ff603 2s forwards;position:fixed;top:20px;right:20px;z-index:9999;box-shadow:0 4px 12px #0000001a;max-width:300px;text-align:center}@keyframes fadeOut-f12ff603{0%{opacity:0;transform:translateY(-20px)}20%{opacity:1;transform:translateY(0)}80%{opacity:1}to{opacity:0}}.author-name[data-v-f12ff603]{cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:inline-block;max-width:100%;font-weight:500}.commit-hash[data-v-f12ff603]{cursor:pointer;color:#409eff;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-weight:500;border-radius:4px;padding:2px 4px;background-color:#ecf5ff;transition:all .2s ease}.commit-hash[data-v-f12ff603]:hover{text-decoration:none;background-color:#d9ecff;box-shadow:0 2px 4px #0000000d}.commit-detail-container[data-v-f12ff603]{display:flex;flex-direction:column;gap:20px}.commit-info[data-v-f12ff603]{padding:16px;background-color:#f5f7fa;border-radius:8px;font-size:14px;display:flex;flex-direction:column;gap:16px}.commit-info-header[data-v-f12ff603]{display:flex;flex-wrap:wrap;gap:16px;align-items:center;background-color:#fff;padding:16px;border-radius:8px;border:1px solid #e4e7ed}.info-item[data-v-f12ff603]{display:flex;align-items:center;gap:8px}.item-label[data-v-f12ff603]{font-weight:700;color:#606266;white-space:nowrap}.item-value[data-v-f12ff603]{color:#333;word-break:break-all}.commit-message-container[data-v-f12ff603]{display:flex;flex-direction:column;gap:8px}.message-label[data-v-f12ff603]{font-weight:700;color:#606266}.message-content[data-v-f12ff603]{background-color:#fff;padding:16px;border-radius:8px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;white-space:pre-wrap;line-height:1.6;border:1px solid #e4e7ed;border-left:4px solid #409eff}.commit-files-diff[data-v-f12ff603]{margin-top:8px;display:flex;gap:20px;height:60vh}.files-list[data-v-f12ff603]{width:25%;overflow-y:auto;background-color:#f5f7fa;border-radius:8px;padding:16px}.files-list h3[data-v-f12ff603]{margin-top:0;padding-bottom:12px;border-bottom:1px solid #dcdfe6;font-size:16px;font-weight:500}.files-list ul[data-v-f12ff603]{list-style:none;padding:0;margin:0}.files-list li[data-v-f12ff603]{padding:10px 12px;cursor:pointer;border-radius:4px;margin-bottom:6px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:13px;transition:all .2s ease;border:1px solid transparent}.files-list li[data-v-f12ff603]:hover{background-color:#ecf5ff;border-color:#d9ecff}.files-list li.active-file[data-v-f12ff603]{background-color:#409eff;color:#fff;box-shadow:0 2px 6px #409eff4d}.file-diff[data-v-f12ff603]{flex:1;display:flex;flex-direction:column;background-color:#f5f7fa;border-radius:8px;padding:16px;overflow:hidden}.file-diff h3[data-v-f12ff603]{margin-top:0;padding-bottom:12px;border-bottom:1px solid #dcdfe6;font-size:16px;font-weight:500}.diff-content[data-v-f12ff603]{flex:1;overflow-y:auto;background-color:#fff;padding:16px;border-radius:8px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:13px;line-height:1.6;border:1px solid #ebeef5}.diff-content[data-v-f12ff603]::-webkit-scrollbar,.files-list[data-v-f12ff603]::-webkit-scrollbar{width:6px;height:6px}.diff-content[data-v-f12ff603]::-webkit-scrollbar-thumb,.files-list[data-v-f12ff603]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px}.diff-content[data-v-f12ff603]::-webkit-scrollbar-thumb:hover,.files-list[data-v-f12ff603]::-webkit-scrollbar-thumb:hover{background-color:#90939980}.diff-content[data-v-f12ff603]::-webkit-scrollbar-track,.files-list[data-v-f12ff603]::-webkit-scrollbar-track{background-color:transparent}.diff-content[data-v-f12ff603],.files-list[data-v-f12ff603]{scrollbar-width:thin;scrollbar-color:rgba(144,147,153,.3) transparent}[data-v-f12ff603] .commit-detail-dialog{--el-dialog-margin-top: 7vh}[data-v-f12ff603] .commit-detail-dialog .el-dialog__body{padding:16px}.filter-panel-header[data-v-f12ff603]{background-color:#f5f7fa;padding:16px;margin-bottom:16px;border-radius:8px;box-shadow:0 2px 12px #0000000d;transition:all .3s ease;width:100%;position:sticky;top:36px;z-index:99}.fullscreen-mode .filter-panel-header[data-v-f12ff603]{position:sticky;top:60px;z-index:9;background-color:#fff;width:100%;border-radius:0;border-bottom:1px solid #ebeef5;box-shadow:0 2px 8px #0000000d}.filter-form[data-v-f12ff603]{display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between}.filter-item[data-v-f12ff603]{flex:1;min-width:200px}.filter-actions[data-v-f12ff603]{display:flex;align-items:center;gap:10px;white-space:nowrap;flex-shrink:0}.filter-input[data-v-f12ff603]{width:100%}.filter-input.date-range[data-v-f12ff603]{width:100%;max-width:280px}.compact-label[data-v-f12ff603]{color:#909399;font-size:12px;margin-right:6px;white-space:nowrap;font-weight:700;border-right:1px solid #dcdfe6;padding-right:8px}.filter-action-button[data-v-f12ff603]{padding:8px 16px;border-radius:6px;transition:all .3s;min-width:70px;font-weight:500}.filter-action-button[data-v-f12ff603]:hover{transform:translateY(-2px);box-shadow:0 2px 8px #0000001a}.table-view-container[data-v-f12ff603]{height:100%;display:flex;flex-direction:column;flex:1}.log-table[data-v-f12ff603]{flex:1;width:100%}.fullscreen-mode .table-view-container[data-v-f12ff603]{height:calc(100vh - 160px)}.fullscreen-mode .log-table[data-v-f12ff603]{height:100%}.load-more-container[data-v-f12ff603]{display:flex;flex-direction:column;align-items:center;padding:8px 0;border-top:1px dashed #ebeef5;gap:8px}.pagination-info[data-v-f12ff603]{font-size:13px;color:#909399;margin-bottom:4px}.loading-more[data-v-f12ff603]{display:flex;align-items:center;color:#909399;font-size:13px;gap:8px}.loading-spinner[data-v-f12ff603]{width:16px;height:16px;border:2px solid #dcdfe6;border-top-color:#409eff;border-radius:50%;animation:spinner-f12ff603 1s linear infinite}@keyframes spinner-f12ff603{to{transform:rotate(360deg)}}.load-more-button[data-v-f12ff603]{cursor:pointer;color:#409eff;font-size:13px;padding:6px 16px;border:1px solid #d9ecff;background-color:#ecf5ff;border-radius:4px;transition:all .3s;font-weight:500}.no-more-data[data-v-f12ff603]{color:#909399;font-size:13px;font-style:italic;display:flex;flex-direction:column;align-items:center}.total-loaded[data-v-f12ff603]{font-size:12px;margin-top:4px;color:#c0c4cc}@keyframes fadeIn-f12ff603{0%{opacity:0;transform:translateY(5px)}to{opacity:1;transform:translateY(0)}}.context-menu-item[data-v-f12ff603]{padding:10px 16px;cursor:pointer;font-size:14px;display:flex;align-items:center;transition:all .2s ease;color:#606266}.context-menu-item[data-v-f12ff603]:hover{background-color:#f5f7fa;color:#409eff}.context-menu-item i[data-v-f12ff603]{margin-right:10px;font-size:16px}.branch-graph-column[data-v-f12ff603]{padding:0!important;overflow:visible}.branch-graph-cell[data-v-f12ff603]{height:40px;width:100%;position:relative;padding:0;margin:0}.branch-graph-column .cell[data-v-f12ff603]{padding:0!important;height:100%;margin:0;overflow:visible}.el-table .branch-graph-column[data-v-f12ff603]{width:60px!important;padding:0!important}[data-v-f12ff603] .el-table .el-table__cell{padding:0!important}[data-v-f12ff603] .branch-graph-cell svg{display:block!important;width:100%!important;height:100%!important;overflow:visible!important;z-index:10!important}[data-v-f12ff603] .branch-graph-cell svg line,[data-v-f12ff603] .branch-graph-cell svg path{stroke-width:2!important}[data-v-f12ff603] .branch-graph-cell svg circle{r:6!important;stroke-width:2!important}.branch-graph-column[data-v-f12ff603]{min-width:60px!important;width:60px!important}.branch-graph-cell[data-v-f12ff603]{position:relative!important;overflow:visible!important;z-index:1!important}[data-v-f12ff603] .el-table--border .el-table__inner-wrapper tr{border:none!important}[data-v-f12ff603] .el-table--border .el-table__inner-wrapper td{border-right:none!important;border-bottom:none!important}[data-v-f12ff603] .el-table--border .el-table__inner-wrapper th{border-right:none!important}[data-v-f12ff603] .el-table--border,[data-v-f12ff603] .el-table--border .el-table__inner-wrapper{border:none!important}[data-v-f12ff603] .el-table--border:after,[data-v-f12ff603] .el-table--border:before,[data-v-f12ff603] .el-table__inner-wrapper:after,[data-v-f12ff603] .el-table__inner-wrapper:before{display:none!important}[data-v-f12ff603] .el-table tr{background-color:transparent!important}[data-v-f12ff603] .el-table--striped .el-table__body tr.el-table__row--striped td{background-color:#00000005!important}.fullscreen-mode[data-v-f12ff603]{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999;margin:0;border-radius:0;border:none;box-shadow:none;background-color:#fff;display:flex;flex-direction:column;padding:16px;overflow:auto}.fullscreen-mode .log-header[data-v-f12ff603]{position:sticky;top:0;z-index:10;background-color:#fff;padding:16px;margin-bottom:10px;width:100%}.fullscreen-mode .filter-panel-header[data-v-f12ff603]{position:sticky;top:60px;z-index:9;background-color:#fff;width:100%}.fullscreen-mode .content-area[data-v-f12ff603]{height:100vh;max-height:none;flex:1;overflow:auto}.fullscreen-mode .el-table[data-v-f12ff603]{height:calc(100vh - 60px)}.fullscreen-mode .graph-view[data-v-f12ff603]{height:calc(100vh - 140px)}.fullscreen-button[data-v-f12ff603]{background:linear-gradient(135deg,#909399,#c0c4cc);color:#fff}.fullscreen-button.active-fullscreen[data-v-f12ff603]{background:linear-gradient(135deg,#606266,#909399)}.context-menu[data-v-f12ff603]{position:fixed;background:#fff;border:1px solid #dcdfe6;border-radius:8px;box-shadow:0 4px 16px #0000001a;padding:6px 0;z-index:3000;min-width:200px;animation:fadeIn-f12ff603 .15s ease-out}.fullscreen-context-menu[data-v-f12ff603]{z-index:999999}.icon-only-button[data-v-f12ff603]{min-width:unset;width:36px;height:36px;padding:8px;border-radius:8px;display:flex;align-items:center;justify-content:center}.icon-only-button .el-icon[data-v-f12ff603]{margin-right:0}.el-table .el-table__cell .cell{word-break:break-all}.diff-header{font-weight:700;background-color:#e6f1fc;padding:10px 16px;margin:12px 0;border-radius:6px;color:#0366d6;border-bottom:1px solid #c8e1ff}.diff-old-file,.diff-new-file{color:#586069;padding:4px 8px;font-family:JetBrains Mono,Fira Code,Consolas,monospace}.diff-old-file{color:#cb2431}.diff-new-file{color:#22863a}.diff-hunk-header{color:#6f42c1;background-color:#f1f8ff;padding:4px 8px;margin:8px 0;border-radius:4px;font-family:JetBrains Mono,Fira Code,Consolas,monospace}.diff-added{background-color:#e6ffed;color:#22863a;padding:2px 8px;border-left:4px solid #22863a;font-family:JetBrains Mono,Fira Code,Consolas,monospace;display:block;margin:2px 0}.diff-removed{background-color:#ffeef0;color:#cb2431;padding:2px 8px;border-left:4px solid #cb2431;font-family:JetBrains Mono,Fira Code,Consolas,monospace;display:block;margin:2px 0}.diff-context{color:#444;padding:2px 8px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;display:block;margin:2px 0;background-color:#fafbfc}.load-more-button:hover{background-color:#d9ecff;box-shadow:0 2px 6px #409eff26;transform:translateY(-1px)}body{font-family:Arial,sans-serif;margin:0;padding:0;background-color:#f5f5f5;overflow:hidden;height:100vh}.main-container{position:fixed;top:60px;bottom:60px;left:0;right:0;padding:10px;overflow:hidden;z-index:1001}.grid-layout{display:grid;grid-template-columns:2fr 8px 3fr;grid-template-rows:1fr 8px 1fr;grid-template-areas:"git-status v-resizer commit-form" "h-resizer h-resizer h-resizer" "log-list log-list log-list";gap:10px;height:100%}.git-status-panel{grid-area:git-status;overflow:hidden;max-height:100%;padding:0}.commit-form-panel{grid-area:commit-form;overflow:hidden;max-height:100%;padding:0}.log-list-panel{grid-area:log-list;overflow:hidden;max-height:100%;padding:0}.card{background-color:#fff;border-radius:8px;box-shadow:0 4px 12px #0000000d;border:1px solid rgba(0,0,0,.03);height:100%;overflow:hidden;display:flex;flex-direction:column}.main-header{background-color:#24292e;color:#fff;padding:0 20px;display:flex;justify-content:space-between;align-items:center;position:fixed;top:0;left:0;right:0;z-index:1000;box-shadow:0 2px 10px #0003;height:60px;box-sizing:border-box}.header-left{display:flex;align-items:center;gap:10px;min-width:220px;flex:1}.logo{height:32px;width:auto}h1{margin:0;font-size:24px}.header-info{display:flex;align-items:center;gap:10px;justify-content:flex-end}#user-info{display:flex;align-items:center;background-color:#282c34b3;padding:6px 10px;border-radius:4px;border:1px solid rgba(255,255,255,.15);margin-right:10px;flex-shrink:0}.directory-selector{display:flex;flex-direction:row;justify-content:space-between;align-items:center;background-color:#282c34b3;border-radius:4px;padding:6px 10px;border:1px solid rgba(255,255,255,.15);box-shadow:0 2px 8px #00000026;flex-shrink:0}.directory-display{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.directory-path{font-family:monospace;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:14px;font-weight:500;background-color:#0003;padding:4px 8px;border-radius:3px;border-left:3px solid #409EFF;flex:1;min-width:0;max-width:500px}.branch-label,.user-label,.user-name{font-weight:700;margin-right:5px}.user-email{color:#e0e0e0}.branch-name{font-family:monospace}.status-box{background-color:#f6f8fa;border:1px solid #e1e4e8;border-radius:3px;padding:15px;white-space:pre-wrap;font-family:monospace;overflow-y:auto}.tips{margin-top:20px;padding:15px;background-color:#f5f7fa;border-radius:5px;border-left:4px solid #409eff}.tips h3{margin-top:0;font-size:16px;margin-bottom:10px}.code-block{background-color:#2d2d2d;color:#f8f8f2;font-family:monospace;padding:10px 15px;border-radius:4px;margin-bottom:10px}.loading-container{display:flex;justify-content:center;align-items:center;height:100%}.loading-card{width:300px;text-align:center;padding:30px}.loading-spinner{font-size:48px;margin-bottom:20px;color:#409eff}.loading-text{font-size:18px;color:#606266}.user-settings-btn{margin-left:10px}.user-warning{color:#e6a23c;font-weight:700}.main-footer{background-color:#24292e;color:#fff;padding:10px 20px;display:flex;justify-content:space-between;align-items:center;position:fixed;bottom:0;left:0;right:0;z-index:100;box-shadow:0 -2px 10px #0000001a;height:60px;box-sizing:border-box}@media (max-width: 768px){.grid-layout{grid-template-columns:1fr;grid-template-rows:auto auto auto auto auto;grid-template-areas:"git-status" "v-resizer" "commit-form" "h-resizer" "log-list";gap:10px}.vertical-resizer{height:10px;cursor:row-resize}.vertical-resizer:after{width:30px;height:4px}.git-status-panel,.commit-form-panel,.log-list-panel{padding:0;max-height:none}.git-status-panel,.commit-form-panel{max-height:30vh}.log-list-panel{max-height:40vh}}.logo[data-v-3f7f4444]{will-change:filter;transition:filter .3s}.logo[data-v-3f7f4444]:hover{filter:drop-shadow(0 0 2em #42b883aa)}.branch-info[data-v-3f7f4444]{display:flex;align-items:center;gap:10px}.branch-wrapper[data-v-3f7f4444]{display:flex;align-items:center;background-color:#ffffff26;border-radius:4px;padding:8px 12px;box-shadow:0 2px 4px #0003;transition:all .3s}.branch-wrapper[data-v-3f7f4444]:hover{background-color:#fff3}.branch-label[data-v-3f7f4444]{font-weight:700;margin-right:10px;color:#fff}.branch-select[data-v-3f7f4444]{width:200px;margin-right:10px}.create-branch-btn[data-v-3f7f4444]{background-color:#2ea44f;border-color:#2ea44f;transition:all .3s;box-shadow:0 2px 4px #0003}.create-branch-btn[data-v-3f7f4444]:hover{background-color:#3bbc63;border-color:#3bbc63;transform:translateY(-2px);box-shadow:0 4px 8px #0003}.footer-right[data-v-3f7f4444]{display:flex;align-items:center;gap:10px;color:#ffffffe6;font-size:13px;background-color:#ffffff1a;padding:8px 12px;border-radius:4px;box-shadow:0 2px 4px #0003}.repo-url-label[data-v-3f7f4444]{font-weight:700;margin-right:8px;color:#fff}.repo-url[data-v-3f7f4444]{color:#e6f7ff;font-family:monospace;max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.copy-url-btn[data-v-3f7f4444]{transition:all .3s;background-color:#1890ff;border-color:#1890ff;box-shadow:0 2px 4px #0003}.copy-url-btn[data-v-3f7f4444]:hover{background-color:#40a9ff;border-color:#40a9ff;transform:translateY(-2px);box-shadow:0 4px 8px #0003}.vertical-resizer[data-v-3f7f4444]{grid-area:v-resizer;background-color:#e8e8e8;cursor:col-resize;transition:background-color .2s,box-shadow .2s;position:relative;z-index:10;border-radius:8px;box-shadow:0 0 3px #0000001a}.vertical-resizer[data-v-3f7f4444]:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:4px;height:50px;background-color:#a0a0a0;border-radius:4px;transition:background-color .2s,width .2s,box-shadow .2s}.vertical-resizer[data-v-3f7f4444]:hover,.vertical-resizer.active[data-v-3f7f4444]{background-color:#d0d0d0;box-shadow:0 0 5px #0003}.vertical-resizer[data-v-3f7f4444]:hover:after,.vertical-resizer.active[data-v-3f7f4444]:after{background-color:#409eff;width:6px;box-shadow:0 0 8px #409eff99}.horizontal-resizer[data-v-3f7f4444]{grid-area:h-resizer;background-color:#e8e8e8;cursor:row-resize;transition:background-color .2s,box-shadow .2s;position:relative;z-index:10;border-radius:8px;box-shadow:0 0 3px #0000001a}.horizontal-resizer[data-v-3f7f4444]:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:50px;height:4px;background-color:#a0a0a0;border-radius:4px;transition:background-color .2s,height .2s,box-shadow .2s}.horizontal-resizer[data-v-3f7f4444]:hover,.horizontal-resizer.active[data-v-3f7f4444]{background-color:#d0d0d0;box-shadow:0 0 5px #0003}.horizontal-resizer[data-v-3f7f4444]:hover:after,.horizontal-resizer.active[data-v-3f7f4444]:after{background-color:#409eff;height:6px;box-shadow:0 0 8px #409eff99}.directory-selector[data-v-3f7f4444]{display:flex;flex-direction:row;justify-content:space-between;align-items:center;background-color:#282c34b3;border-radius:4px;padding:8px 12px;margin-bottom:8px;border:1px solid rgba(255,255,255,.2);box-shadow:0 2px 8px #0003}.directory-display[data-v-3f7f4444]{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.directory-path[data-v-3f7f4444]{font-family:monospace;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:14px;font-weight:500;background-color:#0003;padding:4px 8px;border-radius:3px;border-left:3px solid #409EFF;flex:1;min-width:0;max-width:350px}.directory-actions[data-v-3f7f4444]{display:flex;gap:4px;margin-left:8px}.dir-button[data-v-3f7f4444]{padding:6px;height:28px;width:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#409eff,#53a8ff);color:#fff;border:none;box-shadow:0 2px 4px #0003;transition:all .3s}.dir-button[data-v-3f7f4444]:hover{transform:translateY(-1px);box-shadow:0 3px 6px #0000004d;background:linear-gradient(135deg,#53a8ff,#66b1ff)}.dir-button.el-button--info[data-v-3f7f4444]{background:linear-gradient(135deg,#909399,#a6a9ad)}.dir-button.el-button--info[data-v-3f7f4444]:hover{background:linear-gradient(135deg,#a6a9ad,#c0c4cc)}.directory-icon[data-v-3f7f4444]{display:flex;justify-content:center;align-items:center;width:24px;height:24px;border-radius:3px;background-color:#409eff1a;color:#409eff;margin-right:2px}.directory-input-group[data-v-3f7f4444]{display:flex;align-items:center;gap:8px;width:100%}.recent-directories[data-v-3f7f4444]{display:flex;flex-wrap:wrap;gap:4px}.recent-dir-tag[data-v-3f7f4444]{cursor:pointer;background-color:#e6f7ff;border:1px solid #91d5ff;padding:4px 8px;border-radius:4px}.directory-browser[data-v-3f7f4444]{width:100%;height:400px;overflow:auto}.current-path[data-v-3f7f4444]{padding:10px;background-color:#f5f7fa;border-radius:4px;margin-bottom:10px;border:1px solid #e4e7ed;display:flex;align-items:center;width:100%;box-sizing:border-box}.path-label[data-v-3f7f4444]{font-weight:700;margin-right:5px;white-space:nowrap;flex-shrink:0}.path-value[data-v-3f7f4444]{font-family:monospace;word-break:break-all;flex:1;min-width:0;background-color:#fff;padding:5px 8px;border-radius:3px;border:1px solid #dcdfe6;box-shadow:inset 0 1px 2px #0000000d;width:100%}.directory-list[data-v-3f7f4444]{list-style:none!important;padding:0;margin:0;border:1px solid #e4e7ed;border-radius:4px;max-height:300px;overflow-y:auto;background-color:#fff;display:flex;flex-direction:column;width:100%;box-sizing:border-box}.directory-item[data-v-3f7f4444]{padding:10px 12px;border-bottom:1px solid #ebeef5;cursor:pointer;display:flex;align-items:center;transition:all .2s ease;position:relative;width:100%;box-sizing:border-box;list-style:none!important}.directory-item[data-v-3f7f4444]:hover{background-color:#ecf5ff}.directory-item[data-v-3f7f4444]:last-child{border-bottom:none}.parent-dir[data-v-3f7f4444]{background-color:#f5f7fa;font-weight:500}.dir-icon[data-v-3f7f4444]{margin-right:12px;display:flex;align-items:center;justify-content:center;width:24px;height:24px;flex-shrink:0}.dir-name[data-v-3f7f4444]{display:flex;align-items:center;font-size:14px;line-height:1.4}.folder-icon[data-v-3f7f4444]{filter:drop-shadow(0 1px 2px rgba(0,0,0,.1));transition:all .2s ease}.directory-item:hover .folder-icon[data-v-3f7f4444]{transform:scale(1.1)}[data-v-3f7f4444] .directory-browser-dialog{border-radius:8px;overflow:hidden}[data-v-3f7f4444] .directory-browser-dialog .el-message-box__header{background-color:#f5f7fa;padding:15px 20px;border-bottom:1px solid #e4e7ed;position:relative}[data-v-3f7f4444] .directory-browser-dialog .el-message-box__title{color:#409eff;font-weight:500;font-size:18px}[data-v-3f7f4444] .directory-browser-dialog .el-message-box__headerbtn{position:absolute;top:15px;right:15px;width:24px;height:24px;border-radius:50%;background-color:#0000000d;transition:all .3s;display:flex;align-items:center;justify-content:center}[data-v-3f7f4444] .directory-browser-dialog .el-message-box__headerbtn:hover{background-color:#0000001a;transform:rotate(90deg)}[data-v-3f7f4444] .directory-browser-dialog .el-message-box__headerbtn .el-message-box__close{color:#606266;font-weight:700;font-size:16px}[data-v-3f7f4444] .directory-browser-dialog .el-message-box__headerbtn:hover .el-message-box__close{color:#409eff}[data-v-3f7f4444] .directory-browser-dialog .el-message-box__content{padding:20px}.el-message-box__message{width:100%}.directory-browser-dialog{border-radius:8px;overflow:hidden}.directory-browser-dialog .el-message-box__header{background-color:#f5f7fa;padding:15px 20px;border-bottom:1px solid #e4e7ed;position:relative}.directory-browser-dialog .el-message-box__title{color:#409eff;font-weight:500;font-size:18px}.directory-browser-dialog .el-message-box__headerbtn{position:absolute;top:15px;right:15px;width:24px;height:24px;border-radius:50%;background-color:#0000000d;transition:all .3s;display:flex;align-items:center;justify-content:center}.directory-browser-dialog .el-message-box__headerbtn:hover{background-color:#0000001a;transform:rotate(90deg)}.directory-browser-dialog .el-message-box__headerbtn .el-message-box__close{color:#606266;font-weight:700;font-size:16px}.directory-browser-dialog .el-message-box__headerbtn:hover .el-message-box__close{color:#409eff}.directory-browser-dialog .el-message-box__content{padding:20px}.directory-browser-dialog .el-message-box__btns{padding:10px 20px 15px;border-top:1px solid #e4e7ed}.directory-browser{width:100%;height:400px;overflow:auto}.current-path{padding:10px;background-color:#f5f7fa;border-radius:4px;margin-bottom:10px;border:1px solid #e4e7ed;display:flex;align-items:center;width:100%;box-sizing:border-box}.path-label{font-weight:700;margin-right:5px;white-space:nowrap;flex-shrink:0}.path-value{font-family:monospace;word-break:break-all;flex:1;min-width:0;background-color:#fff;padding:5px 8px;border-radius:3px;border:1px solid #dcdfe6;box-shadow:inset 0 1px 2px #0000000d;width:100%}.directory-list{list-style:none!important;padding:0;margin:0;border:1px solid #e4e7ed;border-radius:4px;max-height:300px;overflow-y:auto;background-color:#fff;display:flex;flex-direction:column;width:100%;box-sizing:border-box}.directory-item{padding:10px 12px;border-bottom:1px solid #ebeef5;cursor:pointer;display:flex;align-items:center;transition:all .2s ease;position:relative;width:100%;box-sizing:border-box;list-style:none!important}.directory-item:hover{background-color:#ecf5ff}.directory-item:last-child{border-bottom:none}.parent-dir{background-color:#f5f7fa;font-weight:500}.dir-icon{margin-right:12px;display:flex;align-items:center;justify-content:center;width:24px;height:24px;flex-shrink:0}.dir-name{display:flex;align-items:center;font-size:14px;line-height:1.4}.folder-icon{filter:drop-shadow(0 1px 2px rgba(0,0,0,.1));transition:all .2s ease}.directory-item:hover .folder-icon{transform:scale(1.1)}*{margin:0;padding:0}div{box-sizing:border-box}
|