megit-app 0.7.0 → 0.8.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 +15 -1
- package/README.md +1 -1
- package/dist/assets/{ConflictView-CHWx-7wL.js → ConflictView-byGnGUbJ.js} +1 -1
- package/dist/assets/{DiffView-DXXDhOBr.js → DiffView-Bhp7PsF3.js} +1 -1
- package/dist/assets/{TerminalPanel-DI0qzKCw.js → TerminalPanel-C5ck3msS.js} +1 -1
- package/dist/assets/{index-C5YS6cns.css → index-ByiPZ5H3.css} +1 -1
- package/dist/assets/index-j_kzUnBQ.js +251 -0
- package/dist/index.html +2 -2
- package/dist-server/index.js +29 -7
- package/package.json +2 -2
- package/dist/assets/index-Ch9W5KCh.js +0 -251
package/dist/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
|
|
7
7
|
<title>megit</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-j_kzUnBQ.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-ByiPZ5H3.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
package/dist-server/index.js
CHANGED
|
@@ -271,6 +271,14 @@ async function revParse(repo, ref) {
|
|
|
271
271
|
const out = await git(repo, ['rev-parse', '--verify', '--quiet', ref], [0, 1]);
|
|
272
272
|
return out.trim() || null;
|
|
273
273
|
}
|
|
274
|
+
// Remote branches that already contain this sha. Rewriting such a commit leaves the
|
|
275
|
+
// remote needing a force push, which megit never does — so both amend paths ask first.
|
|
276
|
+
async function pushedTo(repo, sha) {
|
|
277
|
+
return (await git(repo, ['branch', '-r', '--contains', sha]))
|
|
278
|
+
.split('\n').map(s => s.trim())
|
|
279
|
+
// drop the "origin/HEAD -> origin/main" symref line: it's a pointer, not a second branch
|
|
280
|
+
.filter(r => r && !r.includes(' -> '));
|
|
281
|
+
}
|
|
274
282
|
// Uncommitted work goes to a stash before anything that moves the worktree, so no
|
|
275
283
|
// path can fail on (or silently carry over) a dirty tree. Returns whether it stashed.
|
|
276
284
|
async function stashIfDirty(repo, why) {
|
|
@@ -542,12 +550,7 @@ app.post('/api/commit', repoGuard, async (req, res) => {
|
|
|
542
550
|
if (!message)
|
|
543
551
|
throw httpError(400, 'empty commit message');
|
|
544
552
|
if (req.body.force !== true) {
|
|
545
|
-
|
|
546
|
-
// megit never does — so the client has to ask again before this proceeds
|
|
547
|
-
const onRemote = (await git(repo, ['branch', '-r', '--contains', sha]))
|
|
548
|
-
.split('\n').map(s => s.trim())
|
|
549
|
-
// drop the "origin/HEAD -> origin/main" symref line: it's a pointer, not a second branch
|
|
550
|
-
.filter(r => r && !r.includes(' -> '));
|
|
553
|
+
const onRemote = await pushedTo(repo, sha);
|
|
551
554
|
if (onRemote.length)
|
|
552
555
|
throw httpError(409, `already pushed to ${onRemote.join(', ')}`);
|
|
553
556
|
}
|
|
@@ -653,9 +656,28 @@ app.post('/api/wip', repoGuard, async (req, res) => {
|
|
|
653
656
|
const message = String(req.body.message ?? '').trim();
|
|
654
657
|
if (!message)
|
|
655
658
|
throw httpError(400, 'empty commit message');
|
|
659
|
+
const amend = req.body.amend === true;
|
|
660
|
+
if (amend) {
|
|
661
|
+
// amend rewrites HEAD, so there has to be a HEAD, and a branch to move
|
|
662
|
+
if (!(await git(repo, ['branch', '--show-current'])).trim())
|
|
663
|
+
throw httpError(409, 'detached HEAD — check out a branch first');
|
|
664
|
+
const head = await revParse(repo, 'HEAD');
|
|
665
|
+
if (!head)
|
|
666
|
+
throw httpError(409, 'no commit to amend');
|
|
667
|
+
// mid-merge/rebase the staged tree belongs to the operation in progress:
|
|
668
|
+
// folding it into the previous commit would swallow that commit whole
|
|
669
|
+
const op = await readOperation(repo);
|
|
670
|
+
if (op)
|
|
671
|
+
throw httpError(409, `${op.kind} in progress — finish it first`);
|
|
672
|
+
if (req.body.force !== true) {
|
|
673
|
+
const onRemote = await pushedTo(repo, head);
|
|
674
|
+
if (onRemote.length)
|
|
675
|
+
throw httpError(409, `already pushed to ${onRemote.join(', ')}`);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
656
678
|
// hooks run as they would in a terminal — this commit has real content —
|
|
657
679
|
// but a hook that blocks on stdin gets killed rather than wedging the request
|
|
658
|
-
await git(repo, ['commit', `--message=${message}`], [0], NET_TIMEOUT);
|
|
680
|
+
await git(repo, amend ? ['commit', '--amend', `--message=${message}`] : ['commit', `--message=${message}`], [0], NET_TIMEOUT);
|
|
659
681
|
res.json({ ok: true, hash: (await git(repo, ['rev-parse', 'HEAD'])).trim() });
|
|
660
682
|
return;
|
|
661
683
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "megit-app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.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",
|
|
@@ -60,6 +60,6 @@
|
|
|
60
60
|
"react-dom": "^19.2.8",
|
|
61
61
|
"typescript": "^7.0.2",
|
|
62
62
|
"vite": "^8.2.1",
|
|
63
|
-
"vitest": "^4.1.
|
|
63
|
+
"vitest": "^4.1.11"
|
|
64
64
|
}
|
|
65
65
|
}
|