zen-gitsync 2.11.25 → 2.11.28
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 +2 -1
- package/src/ui/public/assets/index-BB9I3v_D.css +1 -0
- package/src/ui/public/assets/index-DDdb_xTM.js +94 -0
- package/src/ui/public/assets/{vendor-CjiV6IT4.css → vendor-BzVBPsHF.css} +1 -1
- package/src/ui/public/assets/{vendor-CsS_wI9o.js → vendor-D3pt-bg1.js} +210 -210
- package/src/ui/public/index.html +4 -4
- package/src/ui/server/index.js +5 -32
- package/src/ui/server/routes/branchStatus.js +28 -109
- package/src/ui/public/assets/index-ECLMif0J.css +0 -1
- package/src/ui/public/assets/index-wOJowcbr.js +0 -93
package/src/ui/public/index.html
CHANGED
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
11
11
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
12
12
|
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,400&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
13
|
-
<script type="module" crossorigin src="/assets/index-
|
|
13
|
+
<script type="module" crossorigin src="/assets/index-DDdb_xTM.js"></script>
|
|
14
14
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-BM3Ffeng.js">
|
|
15
|
-
<link rel="modulepreload" crossorigin href="/assets/vendor-
|
|
16
|
-
<link rel="stylesheet" crossorigin href="/assets/vendor-
|
|
17
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
15
|
+
<link rel="modulepreload" crossorigin href="/assets/vendor-D3pt-bg1.js">
|
|
16
|
+
<link rel="stylesheet" crossorigin href="/assets/vendor-BzVBPsHF.css">
|
|
17
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BB9I3v_D.css">
|
|
18
18
|
</head>
|
|
19
19
|
<body>
|
|
20
20
|
<div id="app"></div>
|
package/src/ui/server/index.js
CHANGED
|
@@ -29,6 +29,7 @@ import { registerCodeRoutes } from './routes/code.js';
|
|
|
29
29
|
import { registerCodeAnalysisRoutes } from './routes/codeAnalysis.js';
|
|
30
30
|
import { createSavePortToFile } from './utils/createSavePortToFile.js';
|
|
31
31
|
import { startServerOnAvailablePort } from './utils/startServerOnAvailablePort.js';
|
|
32
|
+
import { createFilePickerMiddleware } from 'local-file-picker';
|
|
32
33
|
|
|
33
34
|
const __filename = fileURLToPath(import.meta.url);
|
|
34
35
|
const __dirname = path.dirname(__filename);
|
|
@@ -48,22 +49,6 @@ let branchStatusCache = {
|
|
|
48
49
|
cacheTimeout: 5000 // 5秒缓存
|
|
49
50
|
};
|
|
50
51
|
|
|
51
|
-
// 当前分支缓存 - 只在特定情况下更新
|
|
52
|
-
let currentBranchCache = {
|
|
53
|
-
branchName: null,
|
|
54
|
-
lastUpdate: 0,
|
|
55
|
-
// 分支名缓存时间更长,因为分支切换不频繁
|
|
56
|
-
cacheTimeout: 300000 // 5分钟缓存,或者直到主动清除
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// 上游分支缓存 - 只在特定情况下更新
|
|
60
|
-
let upstreamBranchCache = {
|
|
61
|
-
upstreamBranch: null,
|
|
62
|
-
lastUpdate: 0,
|
|
63
|
-
// 上游分支缓存时间也较长,因为上游分支设置不频繁
|
|
64
|
-
cacheTimeout: 300000 // 5分钟缓存,或者直到主动清除
|
|
65
|
-
};
|
|
66
|
-
|
|
67
52
|
// 推送状态标记 - 用于优化推送后的分支状态查询
|
|
68
53
|
let recentPushStatus = {
|
|
69
54
|
justPushed: false,
|
|
@@ -153,10 +138,6 @@ async function startUIServer(noOpen = false, savePort = false) {
|
|
|
153
138
|
app,
|
|
154
139
|
execGitCommand,
|
|
155
140
|
getIsGitRepo: () => isGitRepo,
|
|
156
|
-
getCurrentBranchCache: () => currentBranchCache,
|
|
157
|
-
setCurrentBranchCache: (v) => { currentBranchCache = v; },
|
|
158
|
-
getUpstreamBranchCache: () => upstreamBranchCache,
|
|
159
|
-
setUpstreamBranchCache: (v) => { upstreamBranchCache = v; },
|
|
160
141
|
getBranchStatusCache: () => branchStatusCache,
|
|
161
142
|
setBranchStatusCache: (v) => { branchStatusCache = v; },
|
|
162
143
|
getRecentPushStatus: () => recentPushStatus,
|
|
@@ -166,18 +147,7 @@ async function startUIServer(noOpen = false, savePort = false) {
|
|
|
166
147
|
// 清除分支缓存的函数(在分支切换时调用)
|
|
167
148
|
function clearBranchCache() {
|
|
168
149
|
console.log('清除分支缓存');
|
|
169
|
-
|
|
170
|
-
branchName: null,
|
|
171
|
-
lastUpdate: 0,
|
|
172
|
-
cacheTimeout: 300000
|
|
173
|
-
};
|
|
174
|
-
// 清除上游分支缓存
|
|
175
|
-
upstreamBranchCache = {
|
|
176
|
-
upstreamBranch: null,
|
|
177
|
-
lastUpdate: 0,
|
|
178
|
-
cacheTimeout: 300000
|
|
179
|
-
};
|
|
180
|
-
// 同时清除分支状态缓存
|
|
150
|
+
// 清除5秒分支状态缓存
|
|
181
151
|
branchStatusCache = {
|
|
182
152
|
currentBranch: null,
|
|
183
153
|
upstreamBranch: null,
|
|
@@ -224,6 +194,9 @@ async function startUIServer(noOpen = false, savePort = false) {
|
|
|
224
194
|
app
|
|
225
195
|
});
|
|
226
196
|
|
|
197
|
+
// local-file-picker 中间件,提供 /api/fs/* 文件浏览路由
|
|
198
|
+
app.use('/api', createFilePickerMiddleware());
|
|
199
|
+
|
|
227
200
|
registerCodeAnalysisRoutes({ app, configManager });
|
|
228
201
|
|
|
229
202
|
registerGitOpsRoutes({
|
|
@@ -2,77 +2,22 @@ export function registerBranchStatusRoutes({
|
|
|
2
2
|
app,
|
|
3
3
|
execGitCommand,
|
|
4
4
|
getIsGitRepo,
|
|
5
|
-
getCurrentBranchCache,
|
|
6
|
-
setCurrentBranchCache,
|
|
7
|
-
getUpstreamBranchCache,
|
|
8
|
-
setUpstreamBranchCache,
|
|
9
5
|
getBranchStatusCache,
|
|
10
6
|
setBranchStatusCache,
|
|
11
7
|
getRecentPushStatus,
|
|
12
8
|
setRecentPushStatus
|
|
13
9
|
}) {
|
|
14
|
-
|
|
15
|
-
const now = Date.now();
|
|
16
|
-
const currentBranchCache = getCurrentBranchCache();
|
|
17
|
-
|
|
18
|
-
if (!forceRefresh &&
|
|
19
|
-
currentBranchCache.branchName &&
|
|
20
|
-
(now - currentBranchCache.lastUpdate) < currentBranchCache.cacheTimeout) {
|
|
21
|
-
console.log(`使用缓存的分支名: ${currentBranchCache.branchName}`);
|
|
22
|
-
return currentBranchCache.branchName;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const { stdout } = await execGitCommand('git symbolic-ref --short HEAD');
|
|
26
|
-
const branchName = stdout.trim();
|
|
27
|
-
|
|
28
|
-
setCurrentBranchCache({
|
|
29
|
-
branchName,
|
|
30
|
-
lastUpdate: now,
|
|
31
|
-
cacheTimeout: 300000
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
return branchName;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async function getUpstreamBranchOptimized(forceRefresh = false) {
|
|
38
|
-
const now = Date.now();
|
|
39
|
-
const upstreamBranchCache = getUpstreamBranchCache();
|
|
40
|
-
|
|
41
|
-
if (!forceRefresh &&
|
|
42
|
-
upstreamBranchCache.upstreamBranch !== null &&
|
|
43
|
-
(now - upstreamBranchCache.lastUpdate) < upstreamBranchCache.cacheTimeout) {
|
|
44
|
-
console.log(`使用缓存的上游分支: ${upstreamBranchCache.upstreamBranch}`);
|
|
45
|
-
return upstreamBranchCache.upstreamBranch;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
console.log('重新获取上游分支...');
|
|
49
|
-
const { stdout: upstreamOutput } = await execGitCommand(
|
|
50
|
-
'git rev-parse --abbrev-ref --symbolic-full-name @{u}',
|
|
51
|
-
{ ignoreError: true }
|
|
52
|
-
);
|
|
53
|
-
const upstreamBranch = upstreamOutput.trim() || null;
|
|
54
|
-
|
|
55
|
-
setUpstreamBranchCache({
|
|
56
|
-
upstreamBranch,
|
|
57
|
-
lastUpdate: now,
|
|
58
|
-
cacheTimeout: 300000
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
return upstreamBranch;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// 获取当前分支 - 使用缓存优化
|
|
10
|
+
// 获取当前分支 - 直接读取,不缓存(git symbolic-ref 极快,<5ms)
|
|
65
11
|
app.get('/api/branch', async (req, res) => {
|
|
66
12
|
try {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
res.json({ branch });
|
|
13
|
+
const { stdout } = await execGitCommand('git symbolic-ref --short HEAD');
|
|
14
|
+
res.json({ branch: stdout.trim() });
|
|
70
15
|
} catch (error) {
|
|
71
16
|
res.status(500).json({ error: error.message });
|
|
72
17
|
}
|
|
73
18
|
});
|
|
74
19
|
|
|
75
|
-
//
|
|
20
|
+
// 获取分支与远程的差异状态(领先/落后提交数)
|
|
76
21
|
app.get('/api/branch-status', async (req, res) => {
|
|
77
22
|
try {
|
|
78
23
|
if (!getIsGitRepo()) {
|
|
@@ -81,11 +26,11 @@ export function registerBranchStatusRoutes({
|
|
|
81
26
|
|
|
82
27
|
const now = Date.now();
|
|
83
28
|
const forceRefresh = req.query.force === 'true';
|
|
84
|
-
const refreshCountOnly = req.query.countOnly === 'true';
|
|
85
29
|
|
|
86
30
|
const recentPushStatus = getRecentPushStatus();
|
|
87
31
|
const branchStatusCache = getBranchStatusCache();
|
|
88
32
|
|
|
33
|
+
// push 后10秒内直接返回同步状态
|
|
89
34
|
if (recentPushStatus.justPushed &&
|
|
90
35
|
(now - recentPushStatus.pushTime) < recentPushStatus.validDuration) {
|
|
91
36
|
console.log('检测到最近推送过,直接返回同步状态');
|
|
@@ -97,69 +42,43 @@ export function registerBranchStatusRoutes({
|
|
|
97
42
|
});
|
|
98
43
|
}
|
|
99
44
|
|
|
100
|
-
|
|
45
|
+
// 5秒缓存分支名,防止短时间内重复执行 git symbolic-ref / git rev-parse
|
|
46
|
+
const branchInfoCacheValid = !forceRefresh &&
|
|
47
|
+
branchStatusCache.currentBranch &&
|
|
101
48
|
branchStatusCache.upstreamBranch &&
|
|
102
49
|
(now - branchStatusCache.lastUpdate) < branchStatusCache.cacheTimeout;
|
|
103
50
|
|
|
104
|
-
|
|
105
|
-
const { stdout: aheadBehindOutput } = await execGitCommand(
|
|
106
|
-
`git rev-list --left-right --count ${branchStatusCache.currentBranch}...${branchStatusCache.upstreamBranch}`
|
|
107
|
-
);
|
|
108
|
-
const [ahead, behind] = aheadBehindOutput.trim().split('\t').map(Number);
|
|
109
|
-
|
|
110
|
-
console.log(`使用缓存的分支信息: ${branchStatusCache.currentBranch} -> ${branchStatusCache.upstreamBranch} (${refreshCountOnly ? '只刷新计数' : '缓存有效'})`);
|
|
111
|
-
|
|
112
|
-
return res.json({
|
|
113
|
-
hasUpstream: true,
|
|
114
|
-
upstreamBranch: branchStatusCache.upstreamBranch,
|
|
115
|
-
ahead,
|
|
116
|
-
behind
|
|
117
|
-
});
|
|
118
|
-
}
|
|
51
|
+
let currentBranch, upstreamBranch;
|
|
119
52
|
|
|
120
|
-
|
|
121
|
-
|
|
53
|
+
if (branchInfoCacheValid) {
|
|
54
|
+
currentBranch = branchStatusCache.currentBranch;
|
|
55
|
+
upstreamBranch = branchStatusCache.upstreamBranch;
|
|
56
|
+
console.log(`使用5秒缓存的分支名: ${currentBranch} -> ${upstreamBranch}`);
|
|
57
|
+
} else {
|
|
58
|
+
// 直接读取,不再走5分钟长缓存
|
|
59
|
+
const { stdout: branchOut } = await execGitCommand('git symbolic-ref --short HEAD');
|
|
60
|
+
currentBranch = branchOut.trim();
|
|
122
61
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const shouldForceRefreshUpstream = forceRefresh &&
|
|
130
|
-
(upstreamBranchCache.upstreamBranch === null ||
|
|
131
|
-
(Date.now() - upstreamBranchCache.lastUpdate) >= upstreamBranchCache.cacheTimeout);
|
|
62
|
+
const { stdout: upstreamOut } = await execGitCommand(
|
|
63
|
+
'git rev-parse --abbrev-ref --symbolic-full-name @{u}',
|
|
64
|
+
{ ignoreError: true }
|
|
65
|
+
);
|
|
66
|
+
upstreamBranch = upstreamOut.trim() || null;
|
|
132
67
|
|
|
133
|
-
|
|
68
|
+
if (!upstreamBranch) {
|
|
69
|
+
setBranchStatusCache({ currentBranch: null, upstreamBranch: null, lastUpdate: 0, cacheTimeout: 5000 });
|
|
70
|
+
return res.json({ hasUpstream: false, ahead: 0, behind: 0 });
|
|
71
|
+
}
|
|
134
72
|
|
|
135
|
-
|
|
136
|
-
setBranchStatusCache({
|
|
137
|
-
currentBranch: null,
|
|
138
|
-
upstreamBranch: null,
|
|
139
|
-
lastUpdate: 0,
|
|
140
|
-
cacheTimeout: 5000
|
|
141
|
-
});
|
|
142
|
-
return res.json({ hasUpstream: false, ahead: 0, behind: 0 });
|
|
73
|
+
setBranchStatusCache({ currentBranch, upstreamBranch, lastUpdate: now, cacheTimeout: 5000 });
|
|
143
74
|
}
|
|
144
75
|
|
|
145
|
-
setBranchStatusCache({
|
|
146
|
-
currentBranch,
|
|
147
|
-
upstreamBranch,
|
|
148
|
-
lastUpdate: now,
|
|
149
|
-
cacheTimeout: 5000
|
|
150
|
-
});
|
|
151
|
-
|
|
152
76
|
const { stdout: aheadBehindOutput } = await execGitCommand(
|
|
153
77
|
`git rev-list --left-right --count ${currentBranch}...${upstreamBranch}`
|
|
154
78
|
);
|
|
155
79
|
const [ahead, behind] = aheadBehindOutput.trim().split('\t').map(Number);
|
|
156
80
|
|
|
157
|
-
res.json({
|
|
158
|
-
hasUpstream: true,
|
|
159
|
-
upstreamBranch,
|
|
160
|
-
ahead,
|
|
161
|
-
behind
|
|
162
|
-
});
|
|
81
|
+
res.json({ hasUpstream: true, upstreamBranch, ahead, behind });
|
|
163
82
|
} catch (error) {
|
|
164
83
|
console.error('获取分支状态失败:', error);
|
|
165
84
|
res.status(500).json({ error: error.message });
|