Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 41 additions & 2 deletions src/adapter/history-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,20 @@ export function registerHistoryCommands(
favorites: BranchFavorites,
): vscode.Disposable[] {
const subs: vscode.Disposable[] = [];
const errMsg = (e: unknown): string => (e instanceof Error ? e.message : String(e));
// vscode.git 在 git 非零退出时抛出 GitError,其 .message 为通用串「Failed to execute git」,
// 真实原因落在 .stderr。优先暴露 stderr,使「无上游」「non-fast-forward」等失败可读。
const errMsg = (e: unknown): string => {
if (e && typeof e === 'object') {
const ge = e as { stderr?: unknown; message?: unknown };
if (typeof ge.stderr === 'string' && ge.stderr.trim()) {
return ge.stderr.trim();
}
if (typeof ge.message === 'string' && ge.message) {
return ge.message;
}
}
return String(e);
};

subs.push(vscode.commands.registerCommand('hyperGit.refreshLog', () => logTree.refresh()));
subs.push(vscode.commands.registerCommand('hyperGit.refreshBranches', () => branchesTree.refresh()));
Expand Down Expand Up @@ -212,9 +225,35 @@ export function registerHistoryCommands(
if (!repo) {
return;
}
const head = repo.state.HEAD;
if (!head?.name) {
void vscode.window.showWarningMessage('当前处于 detached HEAD,无法推送当前分支');
return;
}
try {
await repo.push();
if (head.upstream) {
// 已配置上游:按 push.default 推送到追踪分支(正确处理本地名/上游名不一致)。
await repo.push();
} else {
// 无上游:选定 remote 并以 -u 建立追踪(修复「Failed to execute git」根因)。
const remotes = repo.state.remotes.map((r) => r.name);
if (remotes.length === 0) {
void vscode.window.showWarningMessage('未配置远程仓库(remote),无法推送');
return;
}
const remote =
remotes.length === 1
? remotes[0]
: await vscode.window.showQuickPick(remotes, {
placeHolder: `为「${head.name}」选择推送目标 remote(将建立上游追踪 -u)`,
});
if (!remote) {
return;
}
await repo.push(remote, head.name, true);
}
branchesTree.refresh();
void vscode.window.showInformationMessage(`已推送 ${head.name}`);
} catch (e) {
void vscode.window.showErrorMessage(`Push 失败:${errMsg(e)}`);
}
Expand Down
14 changes: 13 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
const registry = new ChangelistRegistry(context.workspaceState, service.repoRoot ?? workspaceRoot);
const favorites = new BranchFavorites(context.workspaceState, service.repoRoot ?? workspaceRoot);
const tree = new ChangesTreeProvider(service, registry);
// createTreeView(registerTreeDataProvider 的超集)以获取 TreeView 句柄承载 .badge;
// 活动栏容器图标的数字角标 = 容器内各视图 badge.value 之和,故此处点亮即映射到 Hyper Git 图标。
const changesView = vscode.window.createTreeView('hyperGit.changes', { treeDataProvider: tree });

// AI 接缝注入(Null 实现,M5 替换为真实 provider)
const commit = new CommitService(context, service, context.workspaceState, {
Expand Down Expand Up @@ -90,7 +93,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
stashTree,
shelfTree,
blame,
vscode.window.registerTreeDataProvider('hyperGit.changes', tree),
changesView,
vscode.window.registerWebviewViewProvider(CommitWebviewProvider.viewType, commitView),
vscode.window.registerTreeDataProvider('hyperGit.log', logTree),
vscode.window.registerTreeDataProvider('hyperGit.branches', branchesTree),
Expand All @@ -116,12 +119,20 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
registerInlineCommitCommand(service, inlineLens),
);

// 活动栏角标:复用 service.getChanges() 计数(index+工作区+未跟踪去重),与 Changes 视图内容一致;
// 计数为 0 时清空,对齐原生 SCM 行为。
const updateChangesBadge = (): void => {
const count = service.getChanges().length;
changesView.badge = count > 0 ? { value: count, tooltip: `${count} 个未提交变更` } : undefined;
};

// git 状态变化频繁(add/checkout/diff 缓存失效均触发),防抖合并避免 log/stash 高频重拉。
let refreshTimer: ReturnType<typeof setTimeout> | undefined;
const refreshAll = (): void => {
clearTimeout(refreshTimer);
refreshTimer = setTimeout(() => {
tree.refresh();
updateChangesBadge();
commitView.refresh();
logTree.refresh();
branchesTree.refresh();
Expand All @@ -142,6 +153,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
setTimeout(() => {
branchesTree.refresh();
logTree.refresh();
updateChangesBadge();
}, 500);
}

Expand Down
Loading