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
288 changes: 153 additions & 135 deletions package.json

Large diffs are not rendered by default.

48 changes: 24 additions & 24 deletions src/adapter/advanced-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ export function registerAdvancedCommands(service: GitRepositoryService, branches
if (!repo) {
return;
}
const ok = await vscode.window.showWarningMessage('撤销最近一次提交(soft reset,保留改动到暂存区)?', { modal: true }, '撤销');
if (ok !== '撤销') {
const ok = await vscode.window.showWarningMessage('Undo the last commit (soft reset, keeps changes in the index)?', { modal: true }, 'Undo');
if (ok !== 'Undo') {
return;
}
try {
await service.execGit(['reset', '--soft', 'HEAD~1']);
branchesTree.refresh();
void vscode.window.showInformationMessage('已撤销最近提交(soft');
void vscode.window.showInformationMessage('Undo last commit complete (soft)');
} catch (e) {
void vscode.window.showErrorMessage(`撤销失败:${errMsg(e)}`);
void vscode.window.showErrorMessage(`Failed to undo: ${errMsg(e)}`);
}
}),
);
Expand All @@ -46,19 +46,19 @@ export function registerAdvancedCommands(service: GitRepositoryService, branches
return;
}
const ok = await vscode.window.showWarningMessage(
`删除提交 ${hash.slice(0, 7)}?将用 rebase 重写历史(可能冲突;已推送的提交勿用)。`,
`Drop commit ${hash.slice(0, 7)}? This rewrites history via rebase (may conflict; do not use on pushed commits).`,
{ modal: true },
'删除提交',
'Drop commit',
);
if (ok !== '删除提交') {
if (ok !== 'Drop commit') {
return;
}
try {
await service.execGit(['rebase', '--onto', `${hash}^`, hash]);
branchesTree.refresh();
void vscode.window.showInformationMessage(`已删除提交 ${hash.slice(0, 7)}`);
void vscode.window.showInformationMessage(`Dropped commit ${hash.slice(0, 7)}`);
} catch (e) {
void vscode.window.showErrorMessage(`删除失败(可能需手动解冲突):${errMsg(e)}`);
void vscode.window.showErrorMessage(`Failed to drop (may need manual conflict resolution): ${errMsg(e)}`);
}
}),
);
Expand All @@ -74,7 +74,7 @@ export function registerAdvancedCommands(service: GitRepositoryService, branches
return;
}
const ok = await vscode.window.showWarningMessage(
`将当前已暂存改动 fixup 到 ${hash.slice(0, 7)}?将重写历史(autosquash rebase)。`,
`Fixup the currently staged changes into ${hash.slice(0, 7)}? This rewrites history (autosquash rebase).`,
{ modal: true },
'Fixup',
);
Expand All @@ -87,9 +87,9 @@ export function registerAdvancedCommands(service: GitRepositoryService, branches
env: { ...process.env, GIT_SEQUENCE_EDITOR: ':' },
});
branchesTree.refresh();
void vscode.window.showInformationMessage(`已 fixup 到 ${hash.slice(0, 7)}`);
void vscode.window.showInformationMessage(`Fixup into ${hash.slice(0, 7)} complete`);
} catch (e) {
void vscode.window.showErrorMessage(`Fixup 失败:${errMsg(e)}`);
void vscode.window.showErrorMessage(`Fixup failed: ${errMsg(e)}`);
}
}),
);
Expand All @@ -107,16 +107,16 @@ export function registerAdvancedCommands(service: GitRepositoryService, branches
const out = await service.execGit(['branch', '--merged', base]);
merged = filterMergeable(out, base, headName ? [headName] : []);
} catch (e) {
void vscode.window.showErrorMessage(`查询已合并分支失败:${errMsg(e)}`);
void vscode.window.showErrorMessage(`Failed to query merged branches: ${errMsg(e)}`);
return;
}
if (merged.length === 0) {
void vscode.window.showInformationMessage('无可清理的已合并分支');
void vscode.window.showInformationMessage('No merged branches to clean up');
return;
}
const picks = await vscode.window.showQuickPick(
merged.map((b) => ({ label: b, picked: true })),
{ canPickMany: true, title: `已合并到 ${base} 的本地分支(勾选删除)` },
{ canPickMany: true, title: `Local branches merged into ${base} (check to delete)` },
);
if (!picks || picks.length === 0) {
return;
Expand All @@ -131,7 +131,7 @@ export function registerAdvancedCommands(service: GitRepositoryService, branches
}
}
branchesTree.refresh();
void vscode.window.showInformationMessage(`已删除 ${deleted} 个已合并分支`);
void vscode.window.showInformationMessage(`Deleted ${deleted} merged branch(es)`);
}),
);

Expand All @@ -145,7 +145,7 @@ export function registerAdvancedCommands(service: GitRepositoryService, branches
return;
}
await vscode.env.clipboard.writeText(names.join('\n'));
void vscode.window.showInformationMessage(names.length === 1 ? `已复制 ${names[0]}` : `已复制 ${names.length} 个引用`);
void vscode.window.showInformationMessage(names.length === 1 ? `Copied ${names[0]}` : `Copied ${names.length} refs`);
}),
);

Expand All @@ -159,21 +159,21 @@ export function registerAdvancedCommands(service: GitRepositoryService, branches
const staged = await service.execGit(['diff', '--cached', '--stat']);
const working = await service.execGit(['diff', '--stat']);
const content = [
'# 3-way Diff 概览(HEAD ↔ Staged ↔ Working',
'# 3-way Diff Overview (HEAD ↔ Staged ↔ Working)',
'',
'## 已暂存改动(HEAD ↔ Staged',
'## Staged Changes (HEAD ↔ Staged)',
'',
staged.trim() || '_()_)',
staged.trim() || '_(none)_)',
'',
'## 未暂存改动(Staged ↔ Working',
'## Unstaged Changes (Staged ↔ Working)',
'',
working.trim() || '_()_',
working.trim() || '_(none)_',
'',
].join('\n');
const doc = await vscode.workspace.openTextDocument({ content, language: 'markdown' });
await vscode.window.showTextDocument(doc, { preview: true });
} catch (e) {
void vscode.window.showErrorMessage(`3-way diff 失败:${errMsg(e)}`);
void vscode.window.showErrorMessage(`3-way diff failed: ${errMsg(e)}`);
}
}),
);
Expand All @@ -192,6 +192,6 @@ async function pickCommitHash(service: GitRepositoryService): Promise<string | u
description: `${c.authorName ?? ''} · ${c.hash.slice(0, 7)}`,
hash: c.hash,
}));
const pick = await vscode.window.showQuickPick(items, { placeHolder: '选择 commit' });
const pick = await vscode.window.showQuickPick(items, { placeHolder: 'Select a commit' });
return pick?.hash;
}
4 changes: 2 additions & 2 deletions src/adapter/ci/github-ci-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export class GitHubCiService implements vscode.Disposable {
return { available: false, needsAuth: false };
}
if (typeof globalThis.fetch !== 'function') {
return { available: false, needsAuth: false, error: '当前运行时无全局 fetch' };
return { available: false, needsAuth: false, error: 'No global fetch in current runtime' };
}
try {
const session = await this.auth.peek(provider);
Expand Down Expand Up @@ -308,7 +308,7 @@ export class GitHubCiService implements vscode.Disposable {
return undefined;
}
const secs = Math.ceil((this.cooldownUntil - Date.now()) / 1000);
return `GitHub 限流,约 ${secs}s 后恢复`;
return `GitHub rate limited, resumes in ~${secs}s`;
}

// ─── 取数 ────────────────────────────────────────────────────────────────
Expand Down
20 changes: 10 additions & 10 deletions src/adapter/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function registerChangesCommands(

subs.push(
vscode.commands.registerCommand('hyperGit.newChangelist', async () => {
const name = await vscode.window.showInputBox({ prompt: '新建 Changelist 名称', placeHolder: '例如 feature-x' });
const name = await vscode.window.showInputBox({ prompt: 'New Changelist name', placeHolder: 'e.g. feature-x' });
if (name && name.trim()) {
registry.create(name.trim());
}
Expand All @@ -43,7 +43,7 @@ export function registerChangesCommands(
return;
}
const def = registry.getDef(node.id);
const name = await vscode.window.showInputBox({ prompt: '重命名 Changelist', value: def?.name });
const name = await vscode.window.showInputBox({ prompt: 'Rename Changelist', value: def?.name });
if (name && name.trim()) {
registry.rename(node.id, name.trim());
}
Expand All @@ -56,11 +56,11 @@ export function registerChangesCommands(
return;
}
const choice = await vscode.window.showWarningMessage(
`删除 Changelist${node.name}」?其下文件将归入默认列表。`,
`Delete Changelist "${node.name}"? Files under it will be moved to the default list.`,
{ modal: true },
'删除',
'Delete',
);
if (choice === '删除') {
if (choice === 'Delete') {
registry.remove(node.id);
}
}),
Expand All @@ -75,7 +75,7 @@ export function registerChangesCommands(
const picks = registry
.listDefs()
.map((d) => ({ label: d.name, id: d.id, description: d.id === active ? 'active' : undefined, picked: d.id === node.changelistId }));
const pick = await vscode.window.showQuickPick(picks, { placeHolder: '将文件移至 Changelist' });
const pick = await vscode.window.showQuickPick(picks, { placeHolder: 'Move file to Changelist' });
if (pick) {
registry.move(node.item.relativePath, pick.id);
}
Expand Down Expand Up @@ -103,11 +103,11 @@ export function registerChangesCommands(
return;
}
const choice = await vscode.window.showWarningMessage(
`丢弃「${change.relativePath}」的改动?此操作不可撤销。`,
`Discard changes to "${change.relativePath}"? This action cannot be undone.`,
{ modal: true },
'丢弃',
'Discard',
);
if (choice !== '丢弃') {
if (choice !== 'Discard') {
return;
}
try {
Expand All @@ -119,7 +119,7 @@ export function registerChangesCommands(
}
tree.refresh();
} catch (e) {
void vscode.window.showErrorMessage(`丢弃失败:${e instanceof Error ? e.message : String(e)}`);
void vscode.window.showErrorMessage(`Failed to discard: ${e instanceof Error ? e.message : String(e)}`);
}
}),
);
Expand Down
12 changes: 6 additions & 6 deletions src/adapter/commit/commit-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,18 +103,18 @@ export class CommitService implements vscode.Disposable {
async executeCommit(req: CommitRequest): Promise<CommitOutcome> {
const repo = this.service.repo;
if (!repo) {
return { ok: false, error: '未找到 Git 仓库' };
return { ok: false, error: 'No Git repository found' };
}
const message = req.message.trim();
if (!message) {
return { ok: false, error: '提交信息不能为空' };
return { ok: false, error: 'Commit message cannot be empty' };
}

// CC 即时校验(pipeline 内的 hook 亦会拦截,此处给出明确原因)
if (this.conventionalEnabled()) {
const v = validateConventional(message);
if (v.severity === 'error') {
return { ok: false, error: v.reason ?? '提交信息不符合 Conventional Commits 规范' };
return { ok: false, error: v.reason ?? 'Commit message does not conform to Conventional Commits' };
}
}

Expand All @@ -123,13 +123,13 @@ export class CommitService implements vscode.Disposable {
const checkedSet = new Set(req.selectedPaths);
const absPaths = this.resolveAbsolute(req.selectedPaths, changes);
if (absPaths.length === 0) {
return { ok: false, error: '未选择任何待提交文件' };
return { ok: false, error: 'No files selected to commit' };
}

// Checkin hook 责任链(传绝对路径,供未来 AI hook 读取文件内容)
const hookResult = await this.pipeline.run({ message, filePaths: absPaths });
if (hookResult === CheckinResult.Cancel) {
return { ok: false, error: '提交被检查拦截(Checkin hook' };
return { ok: false, error: 'Commit blocked by check (Checkin hook)' };
}

try {
Expand All @@ -146,7 +146,7 @@ export class CommitService implements vscode.Disposable {
try {
await repo.push();
} catch (e) {
return { ok: true, warning: `提交已成功,但推送失败:${this.normalizeError(e)}` };
return { ok: true, warning: `Commit succeeded, but push failed: ${this.normalizeError(e)}` };
}
}
return { ok: true };
Expand Down
14 changes: 7 additions & 7 deletions src/adapter/conflict-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@ export async function handleGitConflict(service: GitRepositoryService, opName: s
const op = state.ongoingOperation;
const canAbort = op !== 'none';
const choice = await vscode.window.showWarningMessage(
`${opName} 遇到 ${state.conflictedPaths.length} 个冲突文件。`,
{ modal: true, detail: canAbort ? `正在进行:${op}。可解决冲突后继续,或中止恢复工作区。` : '请手动解决冲突后提交。' },
...(canAbort ? ['解决冲突', '中止操作'] : ['知道了']),
`${opName} encountered ${state.conflictedPaths.length} conflicted file(s).`,
{ modal: true, detail: canAbort ? `In progress: ${op}. Resolve the conflicts to continue, or abort to restore the working tree.` : 'Please resolve the conflicts manually and commit.' },
...(canAbort ? ['Resolve conflicts', 'Abort'] : ['Got it']),
);
if (choice === '中止操作' && op !== 'none') {
if (choice === 'Abort' && op !== 'none') {
try {
await service.execGit(ABORT_ARGS[op]);
void vscode.window.showInformationMessage(`已中止 ${op},工作区已恢复`);
void vscode.window.showInformationMessage(`${op} aborted, working tree restored`);
} catch {
void vscode.window.showErrorMessage('中止操作失败,请手动处理');
void vscode.window.showErrorMessage('Failed to abort, please handle manually');
}
} else if (choice === '解决冲突') {
} else if (choice === 'Resolve conflicts') {
// 打开自绘 3-way merge editor(resolveConflicts 列出冲突文件供选择)
void vscode.commands.executeCommand('hyperGit.resolveConflicts');
}
Expand Down
6 changes: 3 additions & 3 deletions src/adapter/editor/blame-annotation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class BlameAnnotationController implements vscode.Disposable {
const editor = vscode.window.activeTextEditor;
const repo = this.service.repo;
if (!editor || !repo) {
void vscode.window.showWarningMessage('请先打开一个文件');
void vscode.window.showWarningMessage('Please open a file first');
return;
}
const key = editor.document.uri.toString();
Expand All @@ -47,15 +47,15 @@ export class BlameAnnotationController implements vscode.Disposable {
}
const rel = path.relative(repo.rootUri.fsPath, editor.document.uri.fsPath).split(path.sep).join('/');
if (rel.startsWith('..') || path.isAbsolute(rel)) {
void vscode.window.showWarningMessage('该文件不在当前仓库内');
void vscode.window.showWarningMessage('This file is outside the current repository');
return;
}
let blame: BlameLineMap;
try {
const out = await this.service.execGit(['blame', '--line-porcelain', '--', rel]);
blame = new Map(parseBlamePorcelain(out).map((b) => [b.line, b]));
} catch (e) {
void vscode.window.showErrorMessage(`Blame 失败:${errMsg(e)}`);
void vscode.window.showErrorMessage(`Blame failed: ${errMsg(e)}`);
return;
}
const options: vscode.DecorationOptions[] = [];
Expand Down
14 changes: 7 additions & 7 deletions src/adapter/editor/inline-commit-codelens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class InlineCommitCodeLensProvider implements vscode.CodeLensProvider {
const line = Math.max(0, r.startLine - 1);
return new vscode.CodeLens(new vscode.Range(line, 0, line, 0), {
command: 'hyperGit.inlineCommitHunk',
title: `✓ 提交此 Hunk (+${r.addedCount} -${r.removedCount})`,
title: `✓ Commit this Hunk (+${r.addedCount} -${r.removedCount})`,
arguments: [rel, r.hunkIndex],
});
});
Expand All @@ -74,16 +74,16 @@ export function registerInlineCommitCommand(service: GitRepositoryService, provi
const otherStaged = service.getChanges().filter((c) => c.staged && c.relativePath !== rel);
if (otherStaged.length > 0) {
const ok = await vscode.window.showWarningMessage(
`当前已有其他 ${otherStaged.length} 个已暂存文件,将一并提交。继续?`,
`${otherStaged.length} other staged file(s) will be committed together. Continue?`,
{ modal: true },
'继续提交',
'Continue Commit',
);
if (ok !== '继续提交') {
if (ok !== 'Continue Commit') {
return;
}
}
const message = await vscode.window.showInputBox({
prompt: `提交 Hunk${rel} #${hunkIndex + 1})的 commit message`,
prompt: `Commit message for Hunk (${rel} #${hunkIndex + 1})`,
placeHolder: 'feat(scope): description',
});
if (!message || !message.trim()) {
Expand All @@ -109,9 +109,9 @@ export function registerInlineCommitCommand(service: GitRepositoryService, provi
}
await service.execGit(['commit', '-m', message.trim()]);
provider.refresh();
void vscode.window.showInformationMessage('已提交该 Hunk');
void vscode.window.showInformationMessage('Hunk committed');
} catch (e) {
void vscode.window.showErrorMessage(`Inline commit 失败:${errMsg(e)}`);
void vscode.window.showErrorMessage(`Inline commit failed: ${errMsg(e)}`);
}
});
}
Loading
Loading