megit-app 0.1.0 → 0.3.0
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/CHANGELOG.md +30 -1
- package/README.md +16 -10
- package/dist/assets/{DiffView-CJb6qgum.js → DiffView-BNnSrWMx.js} +1 -1
- package/dist/assets/{TerminalPanel-Cwtdgirw.js → TerminalPanel-54--lgXp.js} +11 -11
- package/dist/assets/index-CjT1mano.css +1 -0
- package/dist/assets/index-WjpXTtcO.js +249 -0
- package/dist/index.html +2 -2
- package/dist-server/index.js +9 -1
- package/dist-server/term.js +28 -11
- package/package.json +2 -2
- package/dist/assets/index-CfQ1U4Ld.js +0 -249
- package/dist/assets/index-DZyh3SKi.css +0 -1
package/dist/index.html
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
9
|
<link href="https://fonts.googleapis.com/css2?family=Ubuntu+Mono:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet" />
|
|
10
10
|
<title>megit</title>
|
|
11
|
-
<script type="module" crossorigin src="/assets/index-
|
|
12
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
11
|
+
<script type="module" crossorigin src="/assets/index-WjpXTtcO.js"></script>
|
|
12
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CjT1mano.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<div id="root"></div>
|
package/dist-server/index.js
CHANGED
|
@@ -428,7 +428,9 @@ app.post('/api/branch', repoGuard, async (req, res) => {
|
|
|
428
428
|
}
|
|
429
429
|
case 'merge':
|
|
430
430
|
case 'rebase': {
|
|
431
|
-
|
|
431
|
+
// remote-tracking refs count: once a local branch has diverged from its
|
|
432
|
+
// upstream, origin/x is its own chip and merging it is the point
|
|
433
|
+
const branch = mustExist([...await locals(), ...await knownRefs(repo, 'refs/remotes')], req.body.branch, 'branch');
|
|
432
434
|
// --autostash, matching the auto-stash /api/checkout does — git's flag,
|
|
433
435
|
// not our own stash dance. A conflict stops and stays stopped: the files
|
|
434
436
|
// show up in the WIP row and get resolved in the terminal.
|
|
@@ -441,6 +443,12 @@ app.post('/api/branch', repoGuard, async (req, res) => {
|
|
|
441
443
|
await git(repo, ['branch', `--set-upstream-to=${upstream}`, branch]);
|
|
442
444
|
break;
|
|
443
445
|
}
|
|
446
|
+
case 'fetch':
|
|
447
|
+
// --prune so remote-tracking chips don't outlive branches deleted upstream.
|
|
448
|
+
// ponytail: no --all — the default remote is the one Pull/Push and the
|
|
449
|
+
// ahead/behind badges act on, so it's the one the badges need fresh.
|
|
450
|
+
await git(repo, ['fetch', '--prune'], [0], NET_TIMEOUT);
|
|
451
|
+
break;
|
|
444
452
|
case 'pull':
|
|
445
453
|
await git(repo, ['pull', '--ff-only', '--autostash'], [0], NET_TIMEOUT);
|
|
446
454
|
break;
|
package/dist-server/term.js
CHANGED
|
@@ -25,8 +25,18 @@ export function pushCapped(buf, size, chunk, cap = MAX_BUFFER) {
|
|
|
25
25
|
return size;
|
|
26
26
|
}
|
|
27
27
|
const sessions = new Map();
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
// Split panes are numbered 0..MAX_PANES-1 and each gets its own shell. The bound is
|
|
29
|
+
// enforced here, not by the client: this socket spawns login shells, so an unvalidated
|
|
30
|
+
// pane param is an unbounded shell factory for anything that reaches the upgrade.
|
|
31
|
+
export const MAX_PANES = 4;
|
|
32
|
+
export function termKey(repo, pane) {
|
|
33
|
+
const p = pane ?? '0';
|
|
34
|
+
if (!/^\d$/.test(p) || Number(p) >= MAX_PANES)
|
|
35
|
+
return null;
|
|
36
|
+
return `${repo}\0${p}`;
|
|
37
|
+
}
|
|
38
|
+
async function getSession(key, repo) {
|
|
39
|
+
const existing = sessions.get(key);
|
|
30
40
|
if (existing)
|
|
31
41
|
return existing;
|
|
32
42
|
// dynamic import: the native module never loads until a terminal is actually opened
|
|
@@ -40,25 +50,25 @@ async function getSession(repo) {
|
|
|
40
50
|
env: process.env,
|
|
41
51
|
});
|
|
42
52
|
const s = { pty, buffer: [], size: 0, clients: new Set() };
|
|
43
|
-
sessions.set(
|
|
53
|
+
sessions.set(key, s);
|
|
44
54
|
pty.onData(d => {
|
|
45
55
|
s.size = pushCapped(s.buffer, s.size, d);
|
|
46
56
|
for (const ws of s.clients)
|
|
47
57
|
ws.send(d);
|
|
48
58
|
});
|
|
49
59
|
pty.onExit(() => {
|
|
50
|
-
sessions.delete(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
sessions.delete(key);
|
|
61
|
+
// 4000 tells the client "the shell is gone" (vs. a plain close, which is the
|
|
62
|
+
// server going away) so it can drop the pane instead of showing a reconnect hint
|
|
63
|
+
for (const ws of s.clients)
|
|
64
|
+
ws.close(4000, 'exit');
|
|
55
65
|
});
|
|
56
66
|
return s;
|
|
57
67
|
}
|
|
58
|
-
async function attach(repo, ws) {
|
|
68
|
+
async function attach(key, repo, ws) {
|
|
59
69
|
let s;
|
|
60
70
|
try {
|
|
61
|
-
s = await getSession(repo);
|
|
71
|
+
s = await getSession(key, repo);
|
|
62
72
|
}
|
|
63
73
|
catch {
|
|
64
74
|
// resolve() said the package is there but the native binding failed to load
|
|
@@ -85,6 +95,8 @@ async function attach(repo, ws) {
|
|
|
85
95
|
s.buffer.length = 0;
|
|
86
96
|
s.size = 0;
|
|
87
97
|
}
|
|
98
|
+
else if (msg.t === 'k')
|
|
99
|
+
s.pty.kill(); // pane closed by its ✕ — onExit does the cleanup
|
|
88
100
|
});
|
|
89
101
|
ws.on('close', () => s.clients.delete(ws));
|
|
90
102
|
}
|
|
@@ -108,6 +120,11 @@ export function wireTerminal(server) {
|
|
|
108
120
|
socket.destroy();
|
|
109
121
|
return;
|
|
110
122
|
}
|
|
111
|
-
|
|
123
|
+
const key = termKey(repo, url.searchParams.get('pane'));
|
|
124
|
+
if (!key) {
|
|
125
|
+
socket.destroy();
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
wss.handleUpgrade(req, socket, head, ws => { void attach(key, repo, ws); });
|
|
112
129
|
});
|
|
113
130
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "megit-app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Git repository viewer in the browser: commit graph with branch lanes, diffs, stashes and WIP",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Hoang Vuong Vu",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"CHANGELOG.md"
|
|
30
30
|
],
|
|
31
31
|
"engines": {
|
|
32
|
-
"node": ">=
|
|
32
|
+
"node": ">=22"
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
35
|
"dev": "PORT=4500 UI_PORT=4000 concurrently -k \"node --watch server/index.ts\" \"vite\"",
|