dsh-git-branch-manage 1.0.3 → 1.0.4
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/lib/client.js +331 -169
- package/lib/git.d.ts +5 -3
- package/lib/git.js +9 -7
- package/lib/routes.d.ts +6 -1
- package/lib/routes.js +7 -2
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -391,6 +391,21 @@ window.__ModuleLoader__.load({
|
|
|
391
391
|
return post(ROUTE_AI_COMMIT_MESSAGE, body);
|
|
392
392
|
}
|
|
393
393
|
//#endregion
|
|
394
|
+
//#region src/client/git-events.ts
|
|
395
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
396
|
+
/** Announce that a surface changed repository state (checkout, rename,
|
|
397
|
+
* delete, create, commit, fetch, update, push). */
|
|
398
|
+
function emitGitMutated() {
|
|
399
|
+
for (const listener of [...listeners]) listener();
|
|
400
|
+
}
|
|
401
|
+
/** Subscribe; returns the unsubscribe function. */
|
|
402
|
+
function onGitMutated(listener) {
|
|
403
|
+
listeners.add(listener);
|
|
404
|
+
return () => {
|
|
405
|
+
listeners.delete(listener);
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
//#endregion
|
|
394
409
|
//#region src/client/branch-tree.ts
|
|
395
410
|
/** Whether a bare `git push` has a known upstream and local commits ahead. */
|
|
396
411
|
function hasPushableCommits(rows, currentBranch) {
|
|
@@ -2735,6 +2750,12 @@ window.__ModuleLoader__.load({
|
|
|
2735
2750
|
document.removeEventListener("visibilitychange", onVisibility);
|
|
2736
2751
|
};
|
|
2737
2752
|
}, [refresh]);
|
|
2753
|
+
(0, react.useEffect)(() => {
|
|
2754
|
+
return onGitMutated(() => {
|
|
2755
|
+
if (busyRef.current) return;
|
|
2756
|
+
refresh();
|
|
2757
|
+
});
|
|
2758
|
+
}, [refresh]);
|
|
2738
2759
|
const showError = (0, react.useCallback)((message) => {
|
|
2739
2760
|
pushToast(t("errorGeneric", { message }));
|
|
2740
2761
|
}, [pushToast, t]);
|
|
@@ -2756,6 +2777,7 @@ window.__ModuleLoader__.load({
|
|
|
2756
2777
|
setConfirm(null);
|
|
2757
2778
|
if (!keepOpen) setMenuOpen(false);
|
|
2758
2779
|
onSettled?.();
|
|
2780
|
+
emitGitMutated();
|
|
2759
2781
|
}, [showError]);
|
|
2760
2782
|
/** In-place switch flow: POST /switch, then refetch the status. */
|
|
2761
2783
|
const doSwitch = (0, react.useCallback)((branch, keepOpen = false) => runGuarded(async () => {
|
|
@@ -3459,6 +3481,17 @@ window.__ModuleLoader__.load({
|
|
|
3459
3481
|
if (needle === "") return [...commits];
|
|
3460
3482
|
return commits.filter((commit) => commit.subject.toLowerCase().includes(needle) || commit.authorName.toLowerCase().includes(needle));
|
|
3461
3483
|
}
|
|
3484
|
+
/**
|
|
3485
|
+
* Case-insensitive substring filter over the branch name — the branch card's
|
|
3486
|
+
* head search box. A remote row matches on its full `remote/name`, which
|
|
3487
|
+
* contains the prefix-stripped short name the tree renders, so searching what
|
|
3488
|
+
* the user sees and searching the remote prefix both hit.
|
|
3489
|
+
*/
|
|
3490
|
+
function filterBranches(rows, query) {
|
|
3491
|
+
const needle = query.trim().toLowerCase();
|
|
3492
|
+
if (needle === "") return [...rows];
|
|
3493
|
+
return rows.filter((row) => row.name.toLowerCase().includes(needle));
|
|
3494
|
+
}
|
|
3462
3495
|
/** Merge the next page into the accumulated list, dropping hash duplicates
|
|
3463
3496
|
* (a ref moved between fetches must not duplicate rows). */
|
|
3464
3497
|
function appendPage(current, page) {
|
|
@@ -3520,9 +3553,19 @@ window.__ModuleLoader__.load({
|
|
|
3520
3553
|
branches
|
|
3521
3554
|
})).sort((left, right) => left.remote.localeCompare(right.remote));
|
|
3522
3555
|
}
|
|
3556
|
+
/** Every group key the branch tree renders — the collapse-all target set.
|
|
3557
|
+
* The bare `remote` key folds the whole remote tree; the nested
|
|
3558
|
+
* `remote:<name>` keys matter only for the groups it re-opens. */
|
|
3559
|
+
function branchGroupKeys(remotes) {
|
|
3560
|
+
return [
|
|
3561
|
+
"local",
|
|
3562
|
+
"remote",
|
|
3563
|
+
...groupRemotes(remotes).map((group) => `remote:${group.remote}`)
|
|
3564
|
+
];
|
|
3565
|
+
}
|
|
3523
3566
|
//#endregion
|
|
3524
3567
|
//#region \0git-worktree-css:/home/runner/work/dsh-git-branch/dsh-git-branch/src/client/GitHistoryPanel.module.css?inline
|
|
3525
|
-
const css$2 = "/* Git panel (sidebar global panel). Three stacked sections over the main\n * column: uncommitted changes + commit box, branches, commit history. Host\n * tokens only; the few status colors fall back to the same literals the\n * settings card uses. */\n\n.page_427795137 {\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n}\n\n.topbar_427795137 {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 16px 8px;\n}\n\n.back_427795137 {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n border: 0;\n background: none;\n cursor: pointer;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary);\n padding: 4px 8px;\n border-radius: 8px;\n}\n\n.back_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.title_427795137 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n.repoPill_427795137 {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n font-size: 12px;\n line-height: 1.4;\n color: var(--dsw-alias-label-secondary);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 999px;\n padding: 3px 10px;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.repoName_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.branchName_427795137 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n.track_427795137 {\n font-variant-numeric: tabular-nums;\n}\n\n.topbarActions_427795137 {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n flex: none;\n}\n\n.refreshBtn_427795137 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 0;\n border-radius: 8px;\n background: none;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n.refreshBtn_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.refreshBtn_427795137[disabled] {\n opacity: 0.5;\n cursor: default;\n}\n\n.scroll_427795137 {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 0 16px 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n/* Sections NEVER flex-shrink: the scroll container is a definite-height\n * flex column, and a shrinkable child collapses to a fraction of its\n * content while the overflow paints over the following sections (the\n * branch section went empty and the commit box drifted into the history).\n * Natural heights; the container scrolls as a whole. */\n.section_427795137 {\n flex: none;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-2);\n display: flex;\n flex-direction: column;\n}\n\n.sectionHead_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.sectionTitle_427795137 {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n.countBadge_427795137 {\n font-size: 10px;\n line-height: 1;\n border-radius: 999px;\n padding: 3px 7px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-secondary);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.sectionTools_427795137 {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.sectionBody_427795137 {\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* Small action chip used across the section heads and the commit row. */\n.act_427795137 {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n cursor: pointer;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 7px;\n padding: 4px 10px;\n white-space: nowrap;\n}\n\n.act_427795137:hover:not([disabled]) {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.act_427795137[disabled] {\n opacity: 0.45;\n cursor: default;\n}\n\n.actPrimary_427795137 {\n /* Hardcoded blue by request — the brand token does not resolve reliably\n * inside the better-sidebar panel. */\n background: #4c6bf5;\n border-color: transparent;\n color: #fff;\n}\n\n.actPrimary_427795137:hover:not([disabled]) {\n border-color: transparent;\n filter: brightness(1.06);\n}\n\n/* Uncommitted changes */\n\n.groupTitleRow_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.linkBtn_427795137 {\n margin-left: auto;\n background: none;\n border: 0;\n padding: 2px 4px;\n font: inherit;\n font-size: 12px;\n color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n border-radius: 5px;\n}\n\n.linkBtn_427795137:hover:not([disabled]) {\n text-decoration: underline;\n}\n\n.linkBtn_427795137[disabled] {\n opacity: 0.5;\n cursor: default;\n}\n\n.changeRow_427795137 {\n display: grid;\n grid-template-columns: 16px 18px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 3px 6px;\n border-radius: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.changeRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.changeCheck_427795137 {\n width: 14px;\n height: 14px;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n margin: 0;\n}\n\n.statusBadge_427795137 {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n font-size: 10px;\n line-height: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n color: #fff;\n box-sizing: border-box;\n}\n\n.statusA_427795137 { background: var(--dsw-alias-status-success, #218358); }\n.statusM_427795137 { background: var(--dsw-alias-label-warning, #b07000); }\n.statusD_427795137 { background: var(--dsw-alias-status-danger, #d5304f); }\n.statusR_427795137 { background: #8350d8; }\n.statusC_427795137 { background: #8350d8; }\n.statusT_427795137 { background: #5b7a9d; }\n.statusQ_427795137 { background: var(--dsw-alias-label-dimmed, #9aa0aa); }\n.statusU_427795137 { background: #d5502e; }\n\n.changePath_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: ui-monospace, Consolas, monospace;\n font-size: 11.5px;\n direction: rtl;\n text-align: left;\n}\n\n.stageHint_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n flex: none;\n}\n\n.commitBox_427795137 {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 4px;\n}\n\n.commitInput_427795137 {\n width: 100%;\n box-sizing: border-box;\n resize: vertical;\n min-height: 52px;\n font: inherit;\n font-size: 12.5px;\n line-height: 1.5;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n padding: 7px 10px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n outline: none;\n}\n\n.commitInput_427795137:focus {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.commitActions_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.commitHint_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n min-height: 16px;\n}\n\n.split_427795137 {\n margin-left: auto;\n display: flex;\n position: relative;\n}\n\n.splitMain_427795137 {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n padding: 6px 16px;\n font-size: 13px;\n}\n\n.splitCaret_427795137 {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n margin-left: 1px;\n padding: 6px 6px;\n}\n\n.menu_427795137 {\n position: absolute;\n right: 0;\n top: calc(100% + 4px);\n z-index: 40;\n width: max-content;\n min-width: 0;\n background: var(--dsw-alias-surface-raised, var(--dsw-alias-bg-layer-3));\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n box-shadow: var(--dsw-shadow-lv3);\n backdrop-filter: var(--dsw-menu-backdrop-filter);\n padding: 3px;\n display: flex;\n flex-direction: column;\n}\n\n.menuItem_427795137 {\n display: block;\n width: 100%;\n text-align: left;\n background: none;\n border: 0;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n padding: 5px 10px;\n border-radius: 5px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.menuItem_427795137:hover:not([disabled]) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.menuItem_427795137[disabled] {\n opacity: 0.5;\n cursor: default;\n}\n\n.menuSub_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n margin-top: 1px;\n}\n\n/* Branch section — two IDEA-style trees: 本地 → branches, 远程 → per-remote → branches */\n\n.treeHead_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 6px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-label-secondary);\n user-select: none;\n}\n\n.treeHead_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.treeChevron_427795137 {\n display: inline-flex;\n align-items: center;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.treeChildren_427795137 {\n display: flex;\n flex-direction: column;\n margin-left: 12px;\n}\n\n.treeHeadNest_427795137 {\n font-weight: 400;\n}\n\n.treeNest_427795137 {\n margin-left: 12px;\n}\n\n.branchRow_427795137 {\n display: grid;\n grid-template-columns: 20px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 5px 8px;\n border-radius: 7px;\n cursor: pointer;\n font-size: 12.5px;\n color: var(--dsw-alias-label-primary);\n}\n\n.branchRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.branchRowCurrent_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n cursor: default;\n}\n\n.branchRowCurrent_427795137:hover {\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.branchMark_427795137 {\n color: var(--dsw-alias-brand-primary);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.branchName_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: 500;\n}\n\n.branchKind_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n margin-left: 6px;\n}\n\n.branchTrack_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n font-variant-numeric: tabular-nums;\n flex: none;\n}\n\n/* The branch action menu is portaled; fixed positioning by row rect. */\n.floatMenu_427795137 {\n position: fixed;\n z-index: 60;\n min-width: 190px;\n}\n\n.menuHead_427795137 {\n padding: 6px 10px 5px;\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n margin-bottom: 3px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.menuHeadStrong_427795137 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n.menuDanger_427795137 {\n color: var(--dsw-alias-status-danger, #d5304f);\n}\n\n.formField_427795137 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.formLabel_427795137 {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.formInput_427795137 {\n font: inherit;\n font-size: 13px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n padding: 7px 10px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n outline: none;\n}\n\n.formInput_427795137:focus {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.formError_427795137 {\n font-size: 12px;\n color: var(--dsw-alias-status-danger, #d5304f);\n min-height: 16px;\n}\n\n/* Commit history */\n\n.historyHead_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.searchBox_427795137 {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n flex: 1;\n max-width: 300px;\n min-width: 140px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 7px;\n padding: 0 9px;\n height: 28px;\n color: var(--dsw-alias-label-tertiary);\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.searchInput_427795137 {\n flex: 1;\n min-width: 0;\n border: 0;\n background: none;\n outline: none;\n font: inherit;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.searchInput_427795137::placeholder {\n color: var(--dsw-alias-label-tertiary);\n}\n\n.commitRow_427795137 {\n position: relative;\n display: grid;\n grid-template-columns: 22px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 6px 8px 6px 2px;\n cursor: pointer;\n border-radius: 7px;\n}\n\n.commitRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.commitRowOpen_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.commitRowOpen_427795137:hover {\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.commitGraph_427795137 {\n position: relative;\n align-self: stretch;\n min-height: 34px;\n}\n\n.commitGraph_427795137::before {\n content: \"\";\n position: absolute;\n left: 10px;\n top: 0;\n bottom: 0;\n width: 2px;\n background: var(--dsw-alias-border-l2);\n}\n\n.commitRowFirst_427795137 .commitGraph_427795137::before {\n top: 50%;\n}\n\n.commitRowLast_427795137 .commitGraph_427795137::before {\n bottom: 50%;\n}\n\n.commitDot_427795137 {\n position: absolute;\n left: 5px;\n top: 50%;\n transform: translateY(-50%);\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--dsw-alias-brand-primary);\n border: 3px solid var(--dsw-alias-bg-layer-2);\n box-sizing: content-box;\n margin-left: -3px;\n}\n\n.commitDotMerge_427795137 {\n background: #8350d8;\n}\n\n.commitMain_427795137 {\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n\n.commitSubject_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n font-size: 12.5px;\n color: var(--dsw-alias-label-primary);\n}\n\n.commitSubjectText_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.commitRowOpen_427795137 .commitSubjectText_427795137 {\n font-weight: 600;\n}\n\n.refBadges_427795137 {\n display: inline-flex;\n gap: 4px;\n flex: none;\n}\n\n.refBadge_427795137 {\n font-size: 10px;\n line-height: 1;\n border-radius: 4px;\n padding: 3px 5px;\n font-weight: 500;\n white-space: nowrap;\n max-width: 140px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.refHead_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary-bluish);\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.refTag_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-warning, #b07000);\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.refRemote_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: #8350d8;\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.refLocal_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-status-success, #218358);\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.commitMeta_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11.5px;\n}\n\n.authorDot_427795137 {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--dsw-alias-brand-primary);\n color: #fff;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 9px;\n flex: none;\n}\n\n.commitSide_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11.5px;\n flex: none;\n}\n\n.commitHash_427795137 {\n font-family: ui-monospace, Consolas, monospace;\n}\n\n.commitExpand_427795137 {\n grid-column: 1 / -1;\n padding: 2px 4px 8px 28px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.commitExpandTitle_427795137 {\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n margin-bottom: 3px;\n}\n\n.fileRow_427795137 {\n display: grid;\n grid-template-columns: 18px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 3px 6px;\n border-radius: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.fileRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.filePath_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: ui-monospace, Consolas, monospace;\n font-size: 11.5px;\n direction: rtl;\n text-align: left;\n}\n\n.fileNums_427795137 {\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-tertiary);\n flex: none;\n}\n\n.fileAdd_427795137 { color: var(--dsw-alias-status-success, #218358); }\n.fileDel_427795137 { color: var(--dsw-alias-status-danger, #d5304f); }\n\n.empty_427795137 {\n padding: 28px 16px;\n text-align: center;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12.5px;\n}\n\n.errorText_427795137 {\n padding: 20px 16px;\n text-align: center;\n color: var(--dsw-alias-status-danger, #d5304f);\n font-size: 12.5px;\n}\n\n.moreRow_427795137 {\n display: flex;\n justify-content: center;\n padding: 8px 0 2px;\n}\n";
|
|
3568
|
+
const css$2 = "/* Git panel (sidebar global panel). Three stacked sections over the main\n * column: uncommitted changes + commit box, branches, commit history. Host\n * tokens only; the few status colors fall back to the same literals the\n * settings card uses. */\n\n.page_427795137 {\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n}\n\n.topbar_427795137 {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 16px 8px;\n}\n\n.back_427795137 {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n border: 0;\n background: none;\n cursor: pointer;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary);\n padding: 4px 8px;\n border-radius: 8px;\n}\n\n.back_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.title_427795137 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n.repoPill_427795137 {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n font-size: 12px;\n line-height: 1.4;\n color: var(--dsw-alias-label-secondary);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 999px;\n padding: 3px 10px;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.repoName_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.branchName_427795137 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n.track_427795137 {\n font-variant-numeric: tabular-nums;\n}\n\n.topbarActions_427795137 {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n flex: none;\n}\n\n.refreshBtn_427795137 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 0;\n border-radius: 8px;\n background: none;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n.refreshBtn_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.refreshBtn_427795137[disabled] {\n opacity: 0.5;\n cursor: default;\n}\n\n.scroll_427795137 {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 0 16px 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n/* The page column below the topbar is a definite-height flex column and the\n * three cards split it 2:1:2 (uncommitted : branches : history) — five\n * shares, the topbar and gaps taking their natural height first. Each body\n * scrolls INSIDE its share — min-height: 0 is what lets a flex child shrink\n * below its content (the old natural-height model painted overflowing rows\n * over the sections below). A floor keeps a very short panel from\n * collapsing a card to its bare head; past the floor the column itself\n * scrolls. */\n.section_427795137 {\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-2);\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.sectionFill_427795137 {\n flex: 1 1 0;\n min-height: 84px;\n}\n\n/* The three flex-grow overrides of the 2:1:2 split. */\n.sectionChanges_427795137 {\n flex-grow: 2;\n}\n\n.sectionBranches_427795137 {\n flex-grow: 1;\n}\n\n.sectionHistory_427795137 {\n flex-grow: 2;\n}\n\n.sectionHead_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.sectionTitle_427795137 {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n.countBadge_427795137 {\n font-size: 10px;\n line-height: 1;\n border-radius: 999px;\n padding: 3px 7px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-secondary);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.sectionTools_427795137 {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.sectionBody_427795137 {\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n flex: 1 1 auto;\n min-height: 0;\n}\n\n/* The branch and history bodies scroll as a whole inside their share. */\n.sectionBodyScroll_427795137 {\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n/* Inside the uncommitted card only the file lists scroll; the commit box\n * below stays pinned however long the change tree is. */\n.changeList_427795137 {\n display: flex;\n flex-direction: column;\n gap: 8px;\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n/* The 全部展开/全部折叠 text chips in the branch card head. */\n.treeToggle_427795137 {\n background: none;\n border: 0;\n padding: 2px 5px;\n font: inherit;\n font-size: 11.5px;\n line-height: 1.4;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n border-radius: 5px;\n white-space: nowrap;\n}\n\n.treeToggle_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-brand-primary);\n}\n\n/* Small action chip used across the section heads and the commit row. */\n.act_427795137 {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n cursor: pointer;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 7px;\n padding: 4px 10px;\n white-space: nowrap;\n}\n\n.act_427795137:hover:not([disabled]) {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.act_427795137[disabled] {\n opacity: 0.45;\n cursor: default;\n}\n\n.actPrimary_427795137 {\n /* Hardcoded blue by request — the brand token does not resolve reliably\n * inside the better-sidebar panel. */\n background: #4c6bf5;\n border-color: transparent;\n color: #fff;\n}\n\n.actPrimary_427795137:hover:not([disabled]) {\n border-color: transparent;\n filter: brightness(1.06);\n}\n\n/* Uncommitted changes */\n\n.groupTitleRow_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.linkBtn_427795137 {\n margin-left: auto;\n background: none;\n border: 0;\n padding: 2px 4px;\n font: inherit;\n font-size: 12px;\n color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n border-radius: 5px;\n}\n\n.linkBtn_427795137:hover:not([disabled]) {\n text-decoration: underline;\n}\n\n.linkBtn_427795137[disabled] {\n opacity: 0.5;\n cursor: default;\n}\n\n.changeRow_427795137 {\n display: grid;\n grid-template-columns: 16px 18px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 3px 6px;\n border-radius: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.changeRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.changeCheck_427795137 {\n width: 14px;\n height: 14px;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n margin: 0;\n}\n\n.statusBadge_427795137 {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n font-size: 10px;\n line-height: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n color: #fff;\n box-sizing: border-box;\n}\n\n.statusA_427795137 { background: var(--dsw-alias-status-success, #218358); }\n.statusM_427795137 { background: var(--dsw-alias-label-warning, #b07000); }\n.statusD_427795137 { background: var(--dsw-alias-status-danger, #d5304f); }\n.statusR_427795137 { background: #8350d8; }\n.statusC_427795137 { background: #8350d8; }\n.statusT_427795137 { background: #5b7a9d; }\n.statusQ_427795137 { background: var(--dsw-alias-label-dimmed, #9aa0aa); }\n.statusU_427795137 { background: #d5502e; }\n\n.changePath_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: ui-monospace, Consolas, monospace;\n font-size: 11.5px;\n direction: rtl;\n text-align: left;\n}\n\n.stageHint_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n flex: none;\n}\n\n.commitBox_427795137 {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 4px;\n flex: none;\n}\n\n.commitInput_427795137 {\n width: 100%;\n box-sizing: border-box;\n resize: vertical;\n min-height: 52px;\n font: inherit;\n font-size: 12.5px;\n line-height: 1.5;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n padding: 7px 10px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n outline: none;\n}\n\n.commitInput_427795137:focus {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.commitActions_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.commitHint_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n min-height: 16px;\n}\n\n.split_427795137 {\n margin-left: auto;\n display: flex;\n position: relative;\n}\n\n.splitMain_427795137 {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n padding: 6px 16px;\n font-size: 13px;\n}\n\n.splitCaret_427795137 {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n margin-left: 1px;\n padding: 6px 6px;\n}\n\n.menu_427795137 {\n position: absolute;\n right: 0;\n top: calc(100% + 4px);\n z-index: 40;\n width: max-content;\n min-width: 0;\n background: var(--dsw-alias-surface-raised, var(--dsw-alias-bg-layer-3));\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n box-shadow: var(--dsw-shadow-lv3);\n backdrop-filter: var(--dsw-menu-backdrop-filter);\n padding: 3px;\n display: flex;\n flex-direction: column;\n}\n\n.menuItem_427795137 {\n display: block;\n width: 100%;\n text-align: left;\n background: none;\n border: 0;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n padding: 5px 10px;\n border-radius: 5px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.menuItem_427795137:hover:not([disabled]) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.menuItem_427795137[disabled] {\n opacity: 0.5;\n cursor: default;\n}\n\n.menuSub_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n margin-top: 1px;\n}\n\n/* Branch section — two IDEA-style trees: 本地 → branches, 远程 → per-remote → branches */\n\n.treeHead_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 6px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-label-secondary);\n user-select: none;\n}\n\n.treeHead_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.treeChevron_427795137 {\n display: inline-flex;\n align-items: center;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.treeChildren_427795137 {\n display: flex;\n flex-direction: column;\n margin-left: 12px;\n}\n\n.treeHeadNest_427795137 {\n font-weight: 400;\n}\n\n.treeNest_427795137 {\n margin-left: 12px;\n}\n\n.branchRow_427795137 {\n display: grid;\n grid-template-columns: 20px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 5px 8px;\n border-radius: 7px;\n /* The action menu opens on RIGHT-CLICK (Enter/Space for keyboard) — an\n * arrow, not the pointing hand a left-click affordance would promise. */\n cursor: default;\n font-size: 12.5px;\n color: var(--dsw-alias-label-primary);\n}\n\n.branchRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n/* Whole-row highlight for the current branch: the ✓ alone read as too\n * quiet inside the tree. A translucent brand-blue wash plus the inset left\n * accent and a colored name survives both themes; #4c6bf5 is the same\n * hardcoded blue actPrimary uses (the brand token does not resolve\n * reliably inside the better-sidebar panel). */\n.branchRowCurrent_427795137 {\n background: rgba(76, 107, 245, 0.16);\n box-shadow: inset 2px 0 0 #4c6bf5;\n cursor: default;\n}\n\n.branchRowCurrent_427795137:hover {\n background: rgba(76, 107, 245, 0.16);\n}\n\n.branchRowCurrent_427795137 .branchName_427795137 {\n color: #4c6bf5;\n font-weight: 600;\n}\n\n.branchMark_427795137 {\n color: var(--dsw-alias-brand-primary);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.branchName_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: 500;\n}\n\n.branchKind_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n margin-left: 6px;\n}\n\n.branchTrack_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n font-variant-numeric: tabular-nums;\n flex: none;\n}\n\n/* The branch action menu is portaled; fixed positioning by row rect. */\n.floatMenu_427795137 {\n position: fixed;\n z-index: 60;\n min-width: 190px;\n}\n\n.menuHead_427795137 {\n padding: 6px 10px 5px;\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n margin-bottom: 3px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.menuHeadStrong_427795137 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n.menuDanger_427795137 {\n color: var(--dsw-alias-status-danger, #d5304f);\n}\n\n.formField_427795137 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.formLabel_427795137 {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.formInput_427795137 {\n font: inherit;\n font-size: 13px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n padding: 7px 10px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n outline: none;\n}\n\n.formInput_427795137:focus {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.formError_427795137 {\n font-size: 12px;\n color: var(--dsw-alias-status-danger, #d5304f);\n min-height: 16px;\n}\n\n/* Commit history */\n\n.historyHead_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.searchBox_427795137 {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n flex: 1;\n max-width: 300px;\n min-width: 140px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 7px;\n padding: 0 9px;\n height: 28px;\n color: var(--dsw-alias-label-tertiary);\n background: var(--dsw-alias-bg-layer-3);\n}\n\n/* The branch card's head variant: sits right of the title and grows toward\n * the tools instead of being right-aligned by `margin-left: auto`. The\n * overrides win because both selectors are single classes and this one is\n * declared later. */\n.searchBoxHead_427795137 {\n margin-left: 0;\n flex: 1 1 auto;\n max-width: 320px;\n min-width: 90px;\n}\n\n.searchInput_427795137 {\n flex: 1;\n min-width: 0;\n border: 0;\n background: none;\n outline: none;\n font: inherit;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.searchInput_427795137::placeholder {\n color: var(--dsw-alias-label-tertiary);\n}\n\n.commitRow_427795137 {\n position: relative;\n display: grid;\n grid-template-columns: 22px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 6px 8px 6px 2px;\n cursor: pointer;\n border-radius: 7px;\n}\n\n.commitRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.commitRowOpen_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.commitRowOpen_427795137:hover {\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.commitGraph_427795137 {\n position: relative;\n align-self: stretch;\n min-height: 34px;\n}\n\n.commitGraph_427795137::before {\n content: \"\";\n position: absolute;\n left: 10px;\n top: 0;\n bottom: 0;\n width: 2px;\n background: var(--dsw-alias-border-l2);\n}\n\n.commitRowFirst_427795137 .commitGraph_427795137::before {\n top: 50%;\n}\n\n.commitRowLast_427795137 .commitGraph_427795137::before {\n bottom: 50%;\n}\n\n/* A small plain dot on the rail — the old 10px dot with a fat card-colored\n * ring read as a heavy black blob. #4c6bf5 for the same reason actPrimary\n * hardcodes it (the brand token does not resolve reliably in this panel). */\n.commitDot_427795137 {\n position: absolute;\n left: 8px;\n top: 50%;\n transform: translateY(-50%);\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: #4c6bf5;\n}\n\n.commitDotMerge_427795137 {\n background: #8350d8;\n}\n\n.commitMain_427795137 {\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n\n.commitSubject_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n font-size: 12.5px;\n color: var(--dsw-alias-label-primary);\n}\n\n.commitSubjectText_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.commitRowOpen_427795137 .commitSubjectText_427795137 {\n font-weight: 600;\n}\n\n.refBadges_427795137 {\n display: inline-flex;\n gap: 4px;\n flex: none;\n}\n\n.refBadge_427795137 {\n font-size: 10px;\n line-height: 1;\n border-radius: 4px;\n padding: 3px 5px;\n font-weight: 500;\n white-space: nowrap;\n max-width: 140px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.refHead_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary-bluish);\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.refTag_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-warning, #b07000);\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.refRemote_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: #8350d8;\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.refLocal_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-status-success, #218358);\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.commitMeta_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11.5px;\n}\n\n.commitSide_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11.5px;\n flex: none;\n}\n\n.commitHash_427795137 {\n font-family: ui-monospace, Consolas, monospace;\n}\n\n.commitExpand_427795137 {\n grid-column: 1 / -1;\n padding: 2px 4px 8px 28px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.commitExpandTitle_427795137 {\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n margin-bottom: 3px;\n}\n\n.fileRow_427795137 {\n display: grid;\n grid-template-columns: 18px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 3px 6px;\n border-radius: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.fileRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.filePath_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: ui-monospace, Consolas, monospace;\n font-size: 11.5px;\n direction: rtl;\n text-align: left;\n}\n\n.fileNums_427795137 {\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-tertiary);\n flex: none;\n}\n\n.fileAdd_427795137 { color: var(--dsw-alias-status-success, #218358); }\n.fileDel_427795137 { color: var(--dsw-alias-status-danger, #d5304f); }\n\n.empty_427795137 {\n padding: 28px 16px;\n text-align: center;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12.5px;\n}\n\n.errorText_427795137 {\n padding: 20px 16px;\n text-align: center;\n color: var(--dsw-alias-status-danger, #d5304f);\n font-size: 12.5px;\n}\n\n.moreRow_427795137 {\n display: flex;\n justify-content: center;\n padding: 8px 0 2px;\n}\n";
|
|
3526
3569
|
const tagId$2 = "dsh-git-branch-manage/GitHistoryPanel.module.css";
|
|
3527
3570
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"" + tagId$2 + "\"]") === null) {
|
|
3528
3571
|
const tag = document.createElement("style");
|
|
@@ -3544,11 +3587,18 @@ window.__ModuleLoader__.load({
|
|
|
3544
3587
|
"refreshBtn": "refreshBtn_427795137",
|
|
3545
3588
|
"scroll": "scroll_427795137",
|
|
3546
3589
|
"section": "section_427795137",
|
|
3590
|
+
"sectionFill": "sectionFill_427795137",
|
|
3591
|
+
"sectionChanges": "sectionChanges_427795137",
|
|
3592
|
+
"sectionBranches": "sectionBranches_427795137",
|
|
3593
|
+
"sectionHistory": "sectionHistory_427795137",
|
|
3547
3594
|
"sectionHead": "sectionHead_427795137",
|
|
3548
3595
|
"sectionTitle": "sectionTitle_427795137",
|
|
3549
3596
|
"countBadge": "countBadge_427795137",
|
|
3550
3597
|
"sectionTools": "sectionTools_427795137",
|
|
3551
3598
|
"sectionBody": "sectionBody_427795137",
|
|
3599
|
+
"sectionBodyScroll": "sectionBodyScroll_427795137",
|
|
3600
|
+
"changeList": "changeList_427795137",
|
|
3601
|
+
"treeToggle": "treeToggle_427795137",
|
|
3552
3602
|
"act": "act_427795137",
|
|
3553
3603
|
"actPrimary": "actPrimary_427795137",
|
|
3554
3604
|
"groupTitleRow": "groupTitleRow_427795137",
|
|
@@ -3596,6 +3646,7 @@ window.__ModuleLoader__.load({
|
|
|
3596
3646
|
"formError": "formError_427795137",
|
|
3597
3647
|
"historyHead": "historyHead_427795137",
|
|
3598
3648
|
"searchBox": "searchBox_427795137",
|
|
3649
|
+
"searchBoxHead": "searchBoxHead_427795137",
|
|
3599
3650
|
"searchInput": "searchInput_427795137",
|
|
3600
3651
|
"commitRow": "commitRow_427795137",
|
|
3601
3652
|
"commitRowOpen": "commitRowOpen_427795137",
|
|
@@ -3614,7 +3665,6 @@ window.__ModuleLoader__.load({
|
|
|
3614
3665
|
"refRemote": "refRemote_427795137",
|
|
3615
3666
|
"refLocal": "refLocal_427795137",
|
|
3616
3667
|
"commitMeta": "commitMeta_427795137",
|
|
3617
|
-
"authorDot": "authorDot_427795137",
|
|
3618
3668
|
"commitSide": "commitSide_427795137",
|
|
3619
3669
|
"commitHash": "commitHash_427795137",
|
|
3620
3670
|
"commitExpand": "commitExpand_427795137",
|
|
@@ -3632,18 +3682,36 @@ window.__ModuleLoader__.load({
|
|
|
3632
3682
|
//#region src/client/panel/BranchSection.tsx
|
|
3633
3683
|
/**
|
|
3634
3684
|
* BranchSection: the panel's middle block — the branch list with an IDEA-style
|
|
3635
|
-
* action menu.
|
|
3636
|
-
* new branch from here, rename, delete, copy name — remote rows
|
|
3637
|
-
* the actions a remote branch can take); the CURRENT branch's
|
|
3638
|
-
* checkout and delete, so rename/new-from/copy stay
|
|
3639
|
-
*
|
|
3640
|
-
*
|
|
3641
|
-
*
|
|
3642
|
-
*
|
|
3643
|
-
*
|
|
3685
|
+
* action menu. RIGHT-CLICKING any row opens a small menu anchored to it
|
|
3686
|
+
* (checkout, new branch from here, rename, delete, copy name — remote rows
|
|
3687
|
+
* narrow it to the actions a remote branch can take); the CURRENT branch's
|
|
3688
|
+
* menu hides only checkout and delete, so rename/new-from/copy stay
|
|
3689
|
+
* reachable. Keyboard rows keep Enter/Space as the menu opener — a context
|
|
3690
|
+
* menu has no keyboard twin. Rename and create run through the Modal
|
|
3691
|
+
* primitive with the same client-side name validation the composer chip
|
|
3692
|
+
* applies; delete confirms first and always uses the safe `-d` form (git
|
|
3693
|
+
* refuses unmerged). Presentational: every action arrives as a callback; the
|
|
3694
|
+
* menu/dialog state is local and resets when the branch list identity
|
|
3695
|
+
* changes.
|
|
3696
|
+
*
|
|
3697
|
+
* The tree opens on 本地 only (the current branch lives there) and the card
|
|
3698
|
+
* takes one share of the panel's fixed 2:1:2 split (its body scrolls inside
|
|
3699
|
+
* it), so a branch-heavy repository can no longer push the other cards off
|
|
3700
|
+
* screen. 全部展开/全部折叠 drive every group at once, and after a checkout
|
|
3701
|
+
* (or expand-all) the card re-centers on the current branch row.
|
|
3702
|
+
*
|
|
3703
|
+
* The head carries a search box: it filters both trees by branch name
|
|
3704
|
+
* (case-insensitive substring), and while a query is active every matching
|
|
3705
|
+
* group renders expanded with its count following the filter — the folded
|
|
3706
|
+
* state the user set is untouched and comes back when the query clears.
|
|
3644
3707
|
*
|
|
3645
3708
|
* @module git-worktree/client/panel/BranchSection
|
|
3646
3709
|
*/
|
|
3710
|
+
/** Groups folded when the card mounts: the remote tree only. The current
|
|
3711
|
+
* branch lives at the TOP of the local group (buildBranchRows sorts it
|
|
3712
|
+
* first), so 本地 stays open — the card opens showing what the panel is
|
|
3713
|
+
* about, without the wall of remote branches. */
|
|
3714
|
+
const COLLAPSED_ON_MOUNT = /* @__PURE__ */ new Set(["remote"]);
|
|
3647
3715
|
/** The action menu as a body portal, fixed-positioned next to the row. */
|
|
3648
3716
|
function BranchFloatMenu(props) {
|
|
3649
3717
|
const { state, t, busy, onAction, onClose } = props;
|
|
@@ -3739,7 +3807,16 @@ window.__ModuleLoader__.load({
|
|
|
3739
3807
|
const [menu, setMenu] = (0, react.useState)(null);
|
|
3740
3808
|
const [dialog, setDialog] = (0, react.useState)(null);
|
|
3741
3809
|
const [draft, setDraft] = (0, react.useState)("");
|
|
3742
|
-
const [
|
|
3810
|
+
const [query, setQuery] = (0, react.useState)("");
|
|
3811
|
+
const [collapsedGroups, setCollapsedGroups] = (0, react.useState)(COLLAPSED_ON_MOUNT);
|
|
3812
|
+
/** The card's scroll body — the locate math centers rows inside it. */
|
|
3813
|
+
const bodyRef = (0, react.useRef)(null);
|
|
3814
|
+
/** The current branch this mount last centered on. A refresh re-centers
|
|
3815
|
+
* only when the checkout moved; a same-branch refresh (stage, commit…)
|
|
3816
|
+
* keeps the scroll where the user left it. */
|
|
3817
|
+
const locatedRef = (0, react.useRef)(null);
|
|
3818
|
+
/** Expand-all asks for one more locate — its rows mount on the next commit. */
|
|
3819
|
+
const pendingLocateRef = (0, react.useRef)(false);
|
|
3743
3820
|
const toggleGroup = (key) => {
|
|
3744
3821
|
setCollapsedGroups((prev) => {
|
|
3745
3822
|
const next = new Set(prev);
|
|
@@ -3748,7 +3825,41 @@ window.__ModuleLoader__.load({
|
|
|
3748
3825
|
return next;
|
|
3749
3826
|
});
|
|
3750
3827
|
};
|
|
3828
|
+
const expandAll = () => {
|
|
3829
|
+
pendingLocateRef.current = true;
|
|
3830
|
+
setCollapsedGroups(/* @__PURE__ */ new Set());
|
|
3831
|
+
};
|
|
3832
|
+
const collapseAll = () => {
|
|
3833
|
+
setCollapsedGroups(new Set(branchGroupKeys(remotes)));
|
|
3834
|
+
};
|
|
3835
|
+
/** Center the current branch row in the card body (no scroll when the
|
|
3836
|
+
* body is shorter than its cap). Rect arithmetic, not offsetTop: no
|
|
3837
|
+
* positioned ancestor is guaranteed between the row and the body. */
|
|
3838
|
+
const locateCurrent = () => {
|
|
3839
|
+
const body = bodyRef.current;
|
|
3840
|
+
if (body === null) return;
|
|
3841
|
+
const row = body.querySelector("[data-current=\"true\"]");
|
|
3842
|
+
if (!(row instanceof HTMLElement)) return;
|
|
3843
|
+
const top = row.getBoundingClientRect().top - body.getBoundingClientRect().top + body.scrollTop;
|
|
3844
|
+
body.scrollTop = Math.max(0, top - (body.clientHeight - row.offsetHeight) / 2);
|
|
3845
|
+
};
|
|
3846
|
+
(0, react.useLayoutEffect)(() => {
|
|
3847
|
+
const current = locals.find((row) => row.current)?.name;
|
|
3848
|
+
if (current === void 0) return;
|
|
3849
|
+
if (!pendingLocateRef.current && current === locatedRef.current) return;
|
|
3850
|
+
pendingLocateRef.current = false;
|
|
3851
|
+
locatedRef.current = current;
|
|
3852
|
+
locateCurrent();
|
|
3853
|
+
});
|
|
3751
3854
|
const total = locals.length + remotes.length;
|
|
3855
|
+
/** The head search: name-substring rows only. A live query opens every
|
|
3856
|
+
* group whatever the folded state is (a hidden match reads as a bug),
|
|
3857
|
+
* without touching that state — clearing the query restores it. */
|
|
3858
|
+
const searching = query.trim() !== "";
|
|
3859
|
+
const visibleLocals = filterBranches(locals, query);
|
|
3860
|
+
const visibleRemotes = filterBranches(remotes, query);
|
|
3861
|
+
const openGroup = (key) => searching || !collapsedGroups.has(key);
|
|
3862
|
+
const matched = visibleLocals.length + visibleRemotes.length;
|
|
3752
3863
|
const openMenu = (branch, event) => {
|
|
3753
3864
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
3754
3865
|
setMenu({
|
|
@@ -3803,7 +3914,7 @@ window.__ModuleLoader__.load({
|
|
|
3803
3914
|
className: `${GitHistoryPanel_module_default.treeHead} ${nested ? GitHistoryPanel_module_default.treeHeadNest : ""}`,
|
|
3804
3915
|
role: "button",
|
|
3805
3916
|
tabIndex: 0,
|
|
3806
|
-
"aria-expanded":
|
|
3917
|
+
"aria-expanded": openGroup(key),
|
|
3807
3918
|
onClick: () => toggleGroup(key),
|
|
3808
3919
|
onKeyDown: (event) => {
|
|
3809
3920
|
if (event.key === "Enter" || event.key === " ") {
|
|
@@ -3814,7 +3925,7 @@ window.__ModuleLoader__.load({
|
|
|
3814
3925
|
children: [
|
|
3815
3926
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3816
3927
|
className: GitHistoryPanel_module_default.treeChevron,
|
|
3817
|
-
children:
|
|
3928
|
+
children: openGroup(key) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { size: 12 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, { size: 12 })
|
|
3818
3929
|
}),
|
|
3819
3930
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label }),
|
|
3820
3931
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -3825,9 +3936,13 @@ window.__ModuleLoader__.load({
|
|
|
3825
3936
|
});
|
|
3826
3937
|
const renderBranchRow = (row, displayName) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3827
3938
|
className: `${GitHistoryPanel_module_default.branchRow} ${row.current ? GitHistoryPanel_module_default.branchRowCurrent : ""}`,
|
|
3939
|
+
"data-current": row.current ? "true" : void 0,
|
|
3828
3940
|
role: "button",
|
|
3829
3941
|
tabIndex: 0,
|
|
3830
|
-
|
|
3942
|
+
onContextMenu: (event) => {
|
|
3943
|
+
event.preventDefault();
|
|
3944
|
+
openMenu(row, event);
|
|
3945
|
+
},
|
|
3831
3946
|
onKeyDown: (event) => {
|
|
3832
3947
|
if (event.key === "Enter" || event.key === " ") {
|
|
3833
3948
|
event.preventDefault();
|
|
@@ -3851,39 +3966,75 @@ window.__ModuleLoader__.load({
|
|
|
3851
3966
|
]
|
|
3852
3967
|
}, row.name);
|
|
3853
3968
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
3854
|
-
className: GitHistoryPanel_module_default.section
|
|
3969
|
+
className: `${GitHistoryPanel_module_default.section} ${GitHistoryPanel_module_default.sectionFill} ${GitHistoryPanel_module_default.sectionBranches}`,
|
|
3855
3970
|
"aria-label": t("panel.branches"),
|
|
3856
3971
|
children: [
|
|
3857
3972
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3858
3973
|
className: GitHistoryPanel_module_default.sectionHead,
|
|
3859
|
-
children: [
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3974
|
+
children: [
|
|
3975
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
3976
|
+
className: GitHistoryPanel_module_default.sectionTitle,
|
|
3977
|
+
children: t("panel.branches")
|
|
3978
|
+
}),
|
|
3979
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3980
|
+
className: `${GitHistoryPanel_module_default.searchBox} ${GitHistoryPanel_module_default.searchBoxHead}`,
|
|
3981
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3982
|
+
"aria-hidden": "true",
|
|
3983
|
+
children: "⌕"
|
|
3984
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
3985
|
+
type: "text",
|
|
3986
|
+
className: GitHistoryPanel_module_default.searchInput,
|
|
3987
|
+
value: query,
|
|
3988
|
+
placeholder: t("menuSearchPlaceholder"),
|
|
3989
|
+
"aria-label": t("menuSearchPlaceholder"),
|
|
3990
|
+
onChange: (event) => setQuery(event.target.value)
|
|
3991
|
+
})]
|
|
3992
|
+
}),
|
|
3993
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3994
|
+
className: GitHistoryPanel_module_default.sectionTools,
|
|
3995
|
+
children: [
|
|
3996
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3997
|
+
type: "button",
|
|
3998
|
+
className: GitHistoryPanel_module_default.treeToggle,
|
|
3999
|
+
onClick: expandAll,
|
|
4000
|
+
children: t("menuExpandAll")
|
|
4001
|
+
}),
|
|
4002
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4003
|
+
type: "button",
|
|
4004
|
+
className: GitHistoryPanel_module_default.treeToggle,
|
|
4005
|
+
onClick: collapseAll,
|
|
4006
|
+
children: t("menuCollapseAll")
|
|
4007
|
+
}),
|
|
4008
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4009
|
+
type: "button",
|
|
4010
|
+
className: GitHistoryPanel_module_default.act,
|
|
4011
|
+
disabled: busy,
|
|
4012
|
+
onClick: () => openDialog("new"),
|
|
4013
|
+
children: ["+ ", t("panel.branchNew")]
|
|
4014
|
+
})
|
|
4015
|
+
]
|
|
3870
4016
|
})
|
|
3871
|
-
|
|
4017
|
+
]
|
|
3872
4018
|
}),
|
|
3873
4019
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3874
|
-
className: GitHistoryPanel_module_default.sectionBody
|
|
4020
|
+
className: `${GitHistoryPanel_module_default.sectionBody} ${GitHistoryPanel_module_default.sectionBodyScroll}`,
|
|
4021
|
+
ref: bodyRef,
|
|
3875
4022
|
children: [
|
|
3876
4023
|
total === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3877
4024
|
className: GitHistoryPanel_module_default.empty,
|
|
3878
4025
|
children: t("menuNoBranches")
|
|
3879
4026
|
}) : null,
|
|
3880
|
-
|
|
4027
|
+
total > 0 && matched === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4028
|
+
className: GitHistoryPanel_module_default.empty,
|
|
4029
|
+
children: t("menuNoMatches")
|
|
4030
|
+
}) : null,
|
|
4031
|
+
visibleLocals.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [groupHead("local", t("panel.branchLocals"), visibleLocals.length, false), openGroup("local") ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3881
4032
|
className: GitHistoryPanel_module_default.treeChildren,
|
|
3882
|
-
children:
|
|
4033
|
+
children: visibleLocals.map((row) => renderBranchRow(row))
|
|
3883
4034
|
}) : null] }) : null,
|
|
3884
|
-
|
|
4035
|
+
visibleRemotes.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [groupHead("remote", t("panel.branchRemotes"), visibleRemotes.length, false), openGroup("remote") ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3885
4036
|
className: GitHistoryPanel_module_default.treeNest,
|
|
3886
|
-
children: groupRemotes(
|
|
4037
|
+
children: groupRemotes(visibleRemotes).map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [groupHead(`remote:${group.remote}`, group.remote, group.branches.length, true), openGroup(`remote:${group.remote}`) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3887
4038
|
className: GitHistoryPanel_module_default.treeChildren,
|
|
3888
4039
|
children: group.branches.map((row) => renderBranchRow(row, row.short))
|
|
3889
4040
|
}) : null] }, group.remote))
|
|
@@ -4024,7 +4175,6 @@ window.__ModuleLoader__.load({
|
|
|
4024
4175
|
const badges = classifyRefs(commit.refs);
|
|
4025
4176
|
const when = new Date(commit.date);
|
|
4026
4177
|
const absolute = Number.isFinite(commit.date) && commit.date > 0 ? `${when.toLocaleDateString()} ${when.toLocaleTimeString()}` : "";
|
|
4027
|
-
const authorInitial = commit.authorName.slice(0, 1);
|
|
4028
4178
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4029
4179
|
ref,
|
|
4030
4180
|
className: [
|
|
@@ -4069,15 +4219,7 @@ window.__ModuleLoader__.load({
|
|
|
4069
4219
|
})]
|
|
4070
4220
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4071
4221
|
className: GitHistoryPanel_module_default.commitMeta,
|
|
4072
|
-
children: [
|
|
4073
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4074
|
-
className: GitHistoryPanel_module_default.authorDot,
|
|
4075
|
-
"aria-hidden": "true",
|
|
4076
|
-
children: authorInitial
|
|
4077
|
-
}),
|
|
4078
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: commit.authorName }),
|
|
4079
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: timeLabelFor(commit.date) })
|
|
4080
|
-
]
|
|
4222
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: commit.authorName }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: timeLabelFor(commit.date) })]
|
|
4081
4223
|
})]
|
|
4082
4224
|
}),
|
|
4083
4225
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -4122,7 +4264,7 @@ window.__ModuleLoader__.load({
|
|
|
4122
4264
|
const needle = query.trim().toLowerCase();
|
|
4123
4265
|
const visible = filterCommits(commits, query);
|
|
4124
4266
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
4125
|
-
className: GitHistoryPanel_module_default.section
|
|
4267
|
+
className: `${GitHistoryPanel_module_default.section} ${GitHistoryPanel_module_default.sectionFill} ${GitHistoryPanel_module_default.sectionHistory}`,
|
|
4126
4268
|
"aria-label": t("panel.history"),
|
|
4127
4269
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4128
4270
|
className: GitHistoryPanel_module_default.historyHead,
|
|
@@ -4144,7 +4286,7 @@ window.__ModuleLoader__.load({
|
|
|
4144
4286
|
})]
|
|
4145
4287
|
})]
|
|
4146
4288
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4147
|
-
className: GitHistoryPanel_module_default.sectionBody
|
|
4289
|
+
className: `${GitHistoryPanel_module_default.sectionBody} ${GitHistoryPanel_module_default.sectionBodyScroll}`,
|
|
4148
4290
|
children: [loadError !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4149
4291
|
className: GitHistoryPanel_module_default.errorText,
|
|
4150
4292
|
children: loadError
|
|
@@ -4191,6 +4333,11 @@ window.__ModuleLoader__.load({
|
|
|
4191
4333
|
* the draft, and every action arrive as props from the panel state owner, so
|
|
4192
4334
|
* this file renders and never talks to git itself.
|
|
4193
4335
|
*
|
|
4336
|
+
* The card takes two shares of the panel's fixed 2:1:2 split: the file
|
|
4337
|
+
* lists scroll inside their own region while the commit box stays pinned
|
|
4338
|
+
* below — a 500-change tree must not bury the commit affordance, and a
|
|
4339
|
+
* clean tree must not float it up either.
|
|
4340
|
+
*
|
|
4194
4341
|
* The commit affordance is a split button: the main face commits, the caret
|
|
4195
4342
|
* opens the two op variants (commit; commit and push). The AI button fills
|
|
4196
4343
|
* the draft from the host's one-shot llm route — it renders only when the
|
|
@@ -4263,7 +4410,7 @@ window.__ModuleLoader__.load({
|
|
|
4263
4410
|
const hint = staged.length === 0 ? t("panel.commitNeedsStaged") : commitDraft.trim() === "" ? t("panel.commitNeedsMessage") : "";
|
|
4264
4411
|
const aiReady = aiAvailable && total > 0;
|
|
4265
4412
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
4266
|
-
className: GitHistoryPanel_module_default.section
|
|
4413
|
+
className: `${GitHistoryPanel_module_default.section} ${GitHistoryPanel_module_default.sectionFill} ${GitHistoryPanel_module_default.sectionChanges}`,
|
|
4267
4414
|
"aria-label": t("panel.uncommitted"),
|
|
4268
4415
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4269
4416
|
className: GitHistoryPanel_module_default.sectionHead,
|
|
@@ -4308,129 +4455,131 @@ window.__ModuleLoader__.load({
|
|
|
4308
4455
|
]
|
|
4309
4456
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4310
4457
|
className: GitHistoryPanel_module_default.sectionBody,
|
|
4311
|
-
children: [
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
children: [
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
disabled: busy,
|
|
4332
|
-
onClick: onUnstageAll,
|
|
4333
|
-
children: t("panel.unstageAll")
|
|
4334
|
-
})
|
|
4335
|
-
]
|
|
4336
|
-
}), staged.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChangeRowView, {
|
|
4337
|
-
row,
|
|
4338
|
-
disabled: busy,
|
|
4339
|
-
onToggle: onToggleRow,
|
|
4340
|
-
t
|
|
4341
|
-
}, `${row.staged}:${row.path}:${row.oldPath ?? ""}`))] }) : null,
|
|
4342
|
-
unstaged.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4343
|
-
className: GitHistoryPanel_module_default.groupTitleRow,
|
|
4344
|
-
children: [
|
|
4345
|
-
t("panel.unstaged"),
|
|
4346
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4347
|
-
className: GitHistoryPanel_module_default.countBadge,
|
|
4348
|
-
children: String(unstaged.length)
|
|
4349
|
-
}),
|
|
4350
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4351
|
-
type: "button",
|
|
4352
|
-
className: GitHistoryPanel_module_default.linkBtn,
|
|
4353
|
-
disabled: busy,
|
|
4354
|
-
onClick: onStageAll,
|
|
4355
|
-
children: t("panel.stageAll")
|
|
4356
|
-
})
|
|
4357
|
-
]
|
|
4358
|
-
}), unstaged.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChangeRowView, {
|
|
4359
|
-
row,
|
|
4360
|
-
disabled: busy,
|
|
4361
|
-
onToggle: onToggleRow,
|
|
4362
|
-
t
|
|
4363
|
-
}, `u:${row.path}:${row.oldPath ?? ""}`))] }) : null,
|
|
4364
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4365
|
-
className: GitHistoryPanel_module_default.commitBox,
|
|
4366
|
-
children: [
|
|
4367
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
4368
|
-
className: GitHistoryPanel_module_default.commitInput,
|
|
4369
|
-
value: commitDraft,
|
|
4370
|
-
placeholder: t("panel.commitPlaceholder"),
|
|
4371
|
-
"aria-label": t("panel.commitPlaceholder"),
|
|
4372
|
-
rows: 2,
|
|
4373
|
-
maxLength: COMMIT_MESSAGE_LIMIT,
|
|
4374
|
-
onChange: (event) => onCommitDraft(event.target.value)
|
|
4375
|
-
}),
|
|
4376
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4377
|
-
className: GitHistoryPanel_module_default.commitActions,
|
|
4378
|
-
children: [aiAvailable ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4458
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4459
|
+
className: GitHistoryPanel_module_default.changeList,
|
|
4460
|
+
children: [
|
|
4461
|
+
total === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4462
|
+
className: GitHistoryPanel_module_default.empty,
|
|
4463
|
+
children: t("panel.clean")
|
|
4464
|
+
}) : null,
|
|
4465
|
+
truncated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4466
|
+
className: GitHistoryPanel_module_default.empty,
|
|
4467
|
+
children: t("panel.changesTruncated")
|
|
4468
|
+
}) : null,
|
|
4469
|
+
staged.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4470
|
+
className: GitHistoryPanel_module_default.groupTitleRow,
|
|
4471
|
+
children: [
|
|
4472
|
+
t("panel.staged"),
|
|
4473
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4474
|
+
className: GitHistoryPanel_module_default.countBadge,
|
|
4475
|
+
children: String(staged.length)
|
|
4476
|
+
}),
|
|
4477
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4379
4478
|
type: "button",
|
|
4380
|
-
className: GitHistoryPanel_module_default.
|
|
4381
|
-
disabled: busy
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4479
|
+
className: GitHistoryPanel_module_default.linkBtn,
|
|
4480
|
+
disabled: busy,
|
|
4481
|
+
onClick: onUnstageAll,
|
|
4482
|
+
children: t("panel.unstageAll")
|
|
4483
|
+
})
|
|
4484
|
+
]
|
|
4485
|
+
}), staged.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChangeRowView, {
|
|
4486
|
+
row,
|
|
4487
|
+
disabled: busy,
|
|
4488
|
+
onToggle: onToggleRow,
|
|
4489
|
+
t
|
|
4490
|
+
}, `${row.staged}:${row.path}:${row.oldPath ?? ""}`))] }) : null,
|
|
4491
|
+
unstaged.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4492
|
+
className: GitHistoryPanel_module_default.groupTitleRow,
|
|
4493
|
+
children: [
|
|
4494
|
+
t("panel.unstaged"),
|
|
4495
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4496
|
+
className: GitHistoryPanel_module_default.countBadge,
|
|
4497
|
+
children: String(unstaged.length)
|
|
4498
|
+
}),
|
|
4499
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4500
|
+
type: "button",
|
|
4501
|
+
className: GitHistoryPanel_module_default.linkBtn,
|
|
4502
|
+
disabled: busy,
|
|
4503
|
+
onClick: onStageAll,
|
|
4504
|
+
children: t("panel.stageAll")
|
|
4505
|
+
})
|
|
4506
|
+
]
|
|
4507
|
+
}), unstaged.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChangeRowView, {
|
|
4508
|
+
row,
|
|
4509
|
+
disabled: busy,
|
|
4510
|
+
onToggle: onToggleRow,
|
|
4511
|
+
t
|
|
4512
|
+
}, `u:${row.path}:${row.oldPath ?? ""}`))] }) : null
|
|
4513
|
+
]
|
|
4514
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4515
|
+
className: GitHistoryPanel_module_default.commitBox,
|
|
4516
|
+
children: [
|
|
4517
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
4518
|
+
className: GitHistoryPanel_module_default.commitInput,
|
|
4519
|
+
value: commitDraft,
|
|
4520
|
+
placeholder: t("panel.commitPlaceholder"),
|
|
4521
|
+
"aria-label": t("panel.commitPlaceholder"),
|
|
4522
|
+
rows: 2,
|
|
4523
|
+
maxLength: COMMIT_MESSAGE_LIMIT,
|
|
4524
|
+
onChange: (event) => onCommitDraft(event.target.value)
|
|
4525
|
+
}),
|
|
4526
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4527
|
+
className: GitHistoryPanel_module_default.commitActions,
|
|
4528
|
+
children: [aiAvailable ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4529
|
+
type: "button",
|
|
4530
|
+
className: GitHistoryPanel_module_default.act,
|
|
4531
|
+
disabled: busy || aiBusy || !aiReady,
|
|
4532
|
+
title: !aiReady ? t("panel.aiNeedsChanges") : void 0,
|
|
4533
|
+
onClick: onAiGenerate,
|
|
4534
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSparkleRegular, { size: 13 }), aiBusy ? t("panel.aiBusy") : t("panel.aiGenerate")]
|
|
4535
|
+
}) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4536
|
+
className: GitHistoryPanel_module_default.split,
|
|
4537
|
+
ref: menuRef,
|
|
4538
|
+
children: [
|
|
4539
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4540
|
+
type: "button",
|
|
4541
|
+
className: `${GitHistoryPanel_module_default.act} ${GitHistoryPanel_module_default.actPrimary} ${GitHistoryPanel_module_default.splitMain}`,
|
|
4542
|
+
disabled: !canCommit || busy,
|
|
4543
|
+
onClick: () => onCommit(false),
|
|
4544
|
+
children: busy ? t("panel.commitBusy") : t("panel.commit")
|
|
4545
|
+
}),
|
|
4546
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4547
|
+
type: "button",
|
|
4548
|
+
className: `${GitHistoryPanel_module_default.act} ${GitHistoryPanel_module_default.actPrimary} ${GitHistoryPanel_module_default.splitCaret}`,
|
|
4549
|
+
"aria-label": t("panel.commitMoreAria"),
|
|
4550
|
+
"aria-expanded": commitMenuOpen,
|
|
4551
|
+
disabled: !canCommit || busy,
|
|
4552
|
+
onClick: onToggleCommitMenu,
|
|
4553
|
+
children: "▾"
|
|
4554
|
+
}),
|
|
4555
|
+
commitMenuOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4556
|
+
className: GitHistoryPanel_module_default.menu,
|
|
4557
|
+
role: "menu",
|
|
4558
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4390
4559
|
type: "button",
|
|
4391
|
-
|
|
4392
|
-
|
|
4560
|
+
role: "menuitem",
|
|
4561
|
+
className: GitHistoryPanel_module_default.menuItem,
|
|
4562
|
+
disabled: !canCommit,
|
|
4393
4563
|
onClick: () => onCommit(false),
|
|
4394
|
-
children:
|
|
4395
|
-
}),
|
|
4396
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4564
|
+
children: t("panel.commit")
|
|
4565
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4397
4566
|
type: "button",
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
children: t("panel.commit")
|
|
4415
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4416
|
-
type: "button",
|
|
4417
|
-
role: "menuitem",
|
|
4418
|
-
className: GitHistoryPanel_module_default.menuItem,
|
|
4419
|
-
disabled: !canCommit,
|
|
4420
|
-
onClick: () => onCommit(true),
|
|
4421
|
-
children: t("panel.commitPush")
|
|
4422
|
-
})]
|
|
4423
|
-
}) : null
|
|
4424
|
-
]
|
|
4425
|
-
})]
|
|
4426
|
-
}),
|
|
4427
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4428
|
-
className: GitHistoryPanel_module_default.commitHint,
|
|
4429
|
-
children: hint
|
|
4430
|
-
})
|
|
4431
|
-
]
|
|
4432
|
-
})
|
|
4433
|
-
]
|
|
4567
|
+
role: "menuitem",
|
|
4568
|
+
className: GitHistoryPanel_module_default.menuItem,
|
|
4569
|
+
disabled: !canCommit,
|
|
4570
|
+
onClick: () => onCommit(true),
|
|
4571
|
+
children: t("panel.commitPush")
|
|
4572
|
+
})]
|
|
4573
|
+
}) : null
|
|
4574
|
+
]
|
|
4575
|
+
})]
|
|
4576
|
+
}),
|
|
4577
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4578
|
+
className: GitHistoryPanel_module_default.commitHint,
|
|
4579
|
+
children: hint
|
|
4580
|
+
})
|
|
4581
|
+
]
|
|
4582
|
+
})]
|
|
4434
4583
|
})]
|
|
4435
4584
|
});
|
|
4436
4585
|
}
|
|
@@ -4572,16 +4721,20 @@ window.__ModuleLoader__.load({
|
|
|
4572
4721
|
const refresh = (0, react.useCallback)(() => {
|
|
4573
4722
|
loadAll();
|
|
4574
4723
|
}, [loadAll]);
|
|
4724
|
+
(0, react.useEffect)(() => onGitMutated(refresh), [refresh]);
|
|
4575
4725
|
(0, react.useImperativeHandle)(ref, () => ({ refresh }), [refresh]);
|
|
4576
4726
|
const repo = status !== null && status.repo ? status : null;
|
|
4577
4727
|
/** Run one mutating verb with the section-busy guard and error toast.
|
|
4578
4728
|
* Mutations refresh through `loadAll` so their re-read bumps the request
|
|
4579
4729
|
* sequence — an older in-flight snapshot can never land over the fresh
|
|
4580
|
-
* post-mutation state.
|
|
4730
|
+
* post-mutation state. A SUCCESS also emits the cross-surface notice so
|
|
4731
|
+
* the composer chip drops the branch git just left (stage toggles ride
|
|
4732
|
+
* along — one extra idempotent /status beats per-verb wiring). */
|
|
4581
4733
|
const runGuarded = (0, react.useCallback)(async (verb) => {
|
|
4582
4734
|
setSectionBusy(true);
|
|
4583
4735
|
try {
|
|
4584
4736
|
await verb();
|
|
4737
|
+
emitGitMutated();
|
|
4585
4738
|
} catch (error) {
|
|
4586
4739
|
pushToast(t("errorGeneric", { message: failureText(error) }), "error");
|
|
4587
4740
|
} finally {
|
|
@@ -4703,7 +4856,10 @@ window.__ModuleLoader__.load({
|
|
|
4703
4856
|
try {
|
|
4704
4857
|
const result = await requestFetch(cwd);
|
|
4705
4858
|
if (!result.ok) pushToast(t("errorGeneric", { message: result.error }), "error");
|
|
4706
|
-
else
|
|
4859
|
+
else {
|
|
4860
|
+
pushToast(t("fetchDone"), "success");
|
|
4861
|
+
emitGitMutated();
|
|
4862
|
+
}
|
|
4707
4863
|
await loadAll();
|
|
4708
4864
|
} finally {
|
|
4709
4865
|
setSyncBusy(false);
|
|
@@ -4721,7 +4877,10 @@ window.__ModuleLoader__.load({
|
|
|
4721
4877
|
try {
|
|
4722
4878
|
const result = await requestUpdate(cwd);
|
|
4723
4879
|
if (!result.ok) pushToast(t("errorGeneric", { message: result.error }), "error");
|
|
4724
|
-
else
|
|
4880
|
+
else {
|
|
4881
|
+
pushToast(result.updated ? t("updateDone", { branch: result.branch }) : t("updateUpToDate"), "success");
|
|
4882
|
+
emitGitMutated();
|
|
4883
|
+
}
|
|
4725
4884
|
await loadAll();
|
|
4726
4885
|
} finally {
|
|
4727
4886
|
setSyncBusy(false);
|
|
@@ -4739,7 +4898,10 @@ window.__ModuleLoader__.load({
|
|
|
4739
4898
|
try {
|
|
4740
4899
|
const result = await requestPush(cwd);
|
|
4741
4900
|
if (!result.ok) pushToast(t("errorGeneric", { message: result.error }), "error");
|
|
4742
|
-
else
|
|
4901
|
+
else {
|
|
4902
|
+
pushToast(result.pushed ? t("pushDone", { branch: result.branch }) : t("pushUpToDate"), "success");
|
|
4903
|
+
emitGitMutated();
|
|
4904
|
+
}
|
|
4743
4905
|
await loadAll();
|
|
4744
4906
|
} finally {
|
|
4745
4907
|
setSyncBusy(false);
|
package/lib/git.d.ts
CHANGED
|
@@ -148,15 +148,17 @@ export declare function cutoutBranchName(exec: Exec, repoRoot: string, base: str
|
|
|
148
148
|
*/
|
|
149
149
|
export declare function addWorktreeCutout(exec: Exec, repoRoot: string, base: string, newBranch: string, targetPath: string): Promise<void>;
|
|
150
150
|
/**
|
|
151
|
-
* In-place branch switch of
|
|
151
|
+
* In-place branch switch of one checkout. A remote display name relies
|
|
152
152
|
* on git's dwim: `git switch <local>` creates the tracking branch when
|
|
153
153
|
* exactly one remote has it.
|
|
154
154
|
* @param exec - executor seam.
|
|
155
|
-
* @param
|
|
155
|
+
* @param checkoutDir - the directory whose OWN checkout moves: the queried
|
|
156
|
+
* session's toplevel, so a linked worktree switches itself rather than the
|
|
157
|
+
* main checkout. `worktree prune` still runs here (it is repo-wide).
|
|
156
158
|
* @param branch - branch display name.
|
|
157
159
|
* @returns the local branch name now checked out.
|
|
158
160
|
*/
|
|
159
|
-
export declare function switchBranch(exec: Exec,
|
|
161
|
+
export declare function switchBranch(exec: Exec, checkoutDir: string, branch: string): Promise<string>;
|
|
160
162
|
/**
|
|
161
163
|
* Create a NEW branch. Three shapes:
|
|
162
164
|
*
|
package/lib/git.js
CHANGED
|
@@ -374,20 +374,22 @@ export async function addWorktreeCutout(exec, repoRoot, base, newBranch, targetP
|
|
|
374
374
|
await git(exec, repoRoot, ['worktree', 'add', targetPath, '-b', newBranch, base]);
|
|
375
375
|
}
|
|
376
376
|
/**
|
|
377
|
-
* In-place branch switch of
|
|
377
|
+
* In-place branch switch of one checkout. A remote display name relies
|
|
378
378
|
* on git's dwim: `git switch <local>` creates the tracking branch when
|
|
379
379
|
* exactly one remote has it.
|
|
380
380
|
* @param exec - executor seam.
|
|
381
|
-
* @param
|
|
381
|
+
* @param checkoutDir - the directory whose OWN checkout moves: the queried
|
|
382
|
+
* session's toplevel, so a linked worktree switches itself rather than the
|
|
383
|
+
* main checkout. `worktree prune` still runs here (it is repo-wide).
|
|
382
384
|
* @param branch - branch display name.
|
|
383
385
|
* @returns the local branch name now checked out.
|
|
384
386
|
*/
|
|
385
|
-
export async function switchBranch(exec,
|
|
386
|
-
const resolved = await resolveBranch(exec,
|
|
387
|
+
export async function switchBranch(exec, checkoutDir, branch) {
|
|
388
|
+
const resolved = await resolveBranch(exec, checkoutDir, branch);
|
|
387
389
|
if (resolved === undefined)
|
|
388
390
|
throw new GitError(['switch'], 1, `branch "${branch}" not found`);
|
|
389
391
|
try {
|
|
390
|
-
await git(exec,
|
|
392
|
+
await git(exec, checkoutDir, ['switch', resolved.local]);
|
|
391
393
|
}
|
|
392
394
|
catch (error) {
|
|
393
395
|
// A stale worktree registration claims the branch; prune (no-op on a
|
|
@@ -395,8 +397,8 @@ export async function switchBranch(exec, repoRoot, branch) {
|
|
|
395
397
|
const stale = error instanceof GitError && error.stderr.includes('already used by worktree');
|
|
396
398
|
if (!stale)
|
|
397
399
|
throw error;
|
|
398
|
-
await git(exec,
|
|
399
|
-
await git(exec,
|
|
400
|
+
await git(exec, checkoutDir, ['worktree', 'prune']);
|
|
401
|
+
await git(exec, checkoutDir, ['switch', resolved.local]);
|
|
400
402
|
}
|
|
401
403
|
return resolved.local;
|
|
402
404
|
}
|
package/lib/routes.d.ts
CHANGED
|
@@ -120,7 +120,12 @@ export declare function handleStatus(deps: RouteDeps, path: string | undefined):
|
|
|
120
120
|
*/
|
|
121
121
|
export declare function handleCreateWorktree(deps: RouteDeps, body: unknown): Promise<RouteOutcome>;
|
|
122
122
|
/**
|
|
123
|
-
* POST /switch
|
|
123
|
+
* POST /switch — in-place branch switch of the QUERIED directory's own
|
|
124
|
+
* checkout. A main-checkout session switches the main checkout; a linked
|
|
125
|
+
* worktree session switches ITS worktree. (It used to always run in the
|
|
126
|
+
* main checkout: a worktree session's checkout appeared to succeed while its
|
|
127
|
+
* own branch never moved. git itself refuses a branch another worktree
|
|
128
|
+
* holds — an honest error beats moving a checkout nobody was looking at.)
|
|
124
129
|
* @param deps - host dependencies.
|
|
125
130
|
* @param body - parsed request body.
|
|
126
131
|
*/
|
package/lib/routes.js
CHANGED
|
@@ -471,7 +471,12 @@ export async function handleCreateWorktree(deps, body) {
|
|
|
471
471
|
}
|
|
472
472
|
}
|
|
473
473
|
/**
|
|
474
|
-
* POST /switch
|
|
474
|
+
* POST /switch — in-place branch switch of the QUERIED directory's own
|
|
475
|
+
* checkout. A main-checkout session switches the main checkout; a linked
|
|
476
|
+
* worktree session switches ITS worktree. (It used to always run in the
|
|
477
|
+
* main checkout: a worktree session's checkout appeared to succeed while its
|
|
478
|
+
* own branch never moved. git itself refuses a branch another worktree
|
|
479
|
+
* holds — an honest error beats moving a checkout nobody was looking at.)
|
|
475
480
|
* @param deps - host dependencies.
|
|
476
481
|
* @param body - parsed request body.
|
|
477
482
|
*/
|
|
@@ -488,7 +493,7 @@ export async function handleSwitch(deps, body) {
|
|
|
488
493
|
const facts = await probeRepo(deps.exec, repoPath, deps.dirExists);
|
|
489
494
|
if (facts === undefined)
|
|
490
495
|
return fail(400, `"${repoPath}" is not inside a git repository`);
|
|
491
|
-
const switched = await switchBranch(deps.exec, facts.
|
|
496
|
+
const switched = await switchBranch(deps.exec, facts.toplevel, branch);
|
|
492
497
|
const result = { branch: switched };
|
|
493
498
|
return { status: 200, body: result };
|
|
494
499
|
}
|
package/package.json
CHANGED