Skip to content

Commit

Permalink
🐛 fix(scm): 修复 GitProvider 和 SvnProvider 中的错误处理逻辑
Browse files Browse the repository at this point in the history
- 修复 GitProvider 中的错误处理逻辑,当没有找到工作区文件夹时抛出错误
- 修复 SvnProvider 中的错误处理逻辑,当没有找到工作区文件夹时抛出错误
  • Loading branch information
littleCareless committed Dec 9, 2024
1 parent 2e3c5b4 commit b2854e2
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 26 deletions.
126 changes: 106 additions & 20 deletions src/scm/GitProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import * as vscode from "vscode";
import { ISCMProvider } from "./SCMProvider";
import { promisify } from "util";
import * as childProcess from "child_process";
import { DiffSimplifier } from "../utils/DiffSimplifier";
import { LocalizationManager } from "../utils/LocalizationManager";

const exec = promisify(childProcess.exec);

Expand All @@ -12,7 +14,9 @@ export class GitProvider implements ISCMProvider {
constructor(private readonly gitExtension: any) {
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
if (!workspaceRoot) {
throw new Error("No workspace folder found");
throw new Error(
LocalizationManager.getInstance().getMessage("workspace.not.found")
);
}
this.workspaceRoot = workspaceRoot;
}
Expand All @@ -23,36 +27,114 @@ export class GitProvider implements ISCMProvider {
return repositories.length > 0;
}

private async getFileStatus(file: string): Promise<string> {
try {
// 检查文件是否是新文件
const { stdout: lsFiles } = await exec(`git ls-files "${file}"`, {
cwd: this.workspaceRoot,
});

if (!lsFiles) {
const { stdout: status } = await exec(
`git status --porcelain "${file}"`,
{
cwd: this.workspaceRoot,
}
);
if (status.startsWith("??")) {
return "New File";
}
}

// 检查文件是否被删除
const { stdout: status } = await exec(
`git status --porcelain "${file}"`,
{
cwd: this.workspaceRoot,
}
);
if (status.startsWith(" D") || status.startsWith("D ")) {
return "Deleted File";
}

return "Modified File";
} catch (error) {
console.error(`Error getting file status: ${error}`);
return "Unknown";
}
}

async getDiff(files?: string[]): Promise<string | undefined> {
try {
let command: string;
let diffOutput = "";

if (files && files.length > 0) {
// 对特定文件执行 diff
const filesPaths = files.map((file) => `"${file}"`).join(" ");
command = `git diff HEAD ${filesPaths}`;
// 处理多个文件的情况
for (const file of files) {
const fileStatus = await this.getFileStatus(file);
const escapedFile = file.replace(/"/g, '\\"');

const { stdout } = await exec(`git diff HEAD -- "${escapedFile}"`, {
cwd: this.workspaceRoot,
maxBuffer: 1024 * 1024 * 10,
});

if (stdout.trim()) {
diffOutput += `\n=== ${fileStatus}: ${file} ===\n${stdout}`;
}
}
} else {
// 对所有暂存文件执行 diff
command = "git diff HEAD";
// 处理所有改动文件的情况
const { stdout } = await exec("git diff HEAD", {
cwd: this.workspaceRoot,
maxBuffer: 1024 * 1024 * 10,
});
diffOutput = stdout;
}

const { stdout, stderr } = await exec(command, {
cwd: this.workspaceRoot,
});

if (stderr) {
throw new Error(stderr);
if (!diffOutput.trim()) {
throw new Error(
LocalizationManager.getInstance().getMessage("diff.noChanges")
);
}

if (!stdout.trim()) {
throw new Error("No changes found");
// 获取配置
const config = vscode.workspace.getConfiguration("dish-ai-commit");
const enableSimplification = config.get<boolean>(
"enableDiffSimplification"
);

// 根据配置决定是否显示警告和简化diff
if (enableSimplification) {
const result = await vscode.window.showWarningMessage(
LocalizationManager.getInstance().getMessage(
"diff.simplification.warning"
),
LocalizationManager.getInstance().getMessage("button.yes"),
LocalizationManager.getInstance().getMessage("button.no")
);
if (
result === LocalizationManager.getInstance().getMessage("button.yes")
) {
return DiffSimplifier.simplify(diffOutput);
}
}

return stdout;
// 如果未启用简化,直接返回原始diff
return diffOutput;
} catch (error) {
if (error instanceof Error) {
vscode.window.showErrorMessage(`Git diff failed: ${error.message}`);
console.error("Git diff error:", error); // 添加调试日志
vscode.window.showErrorMessage(
LocalizationManager.getInstance().format(
"git.diff.failed",
error.message
)
);
}
throw error;
throw new Error(
LocalizationManager.getInstance().getMessage("diff.failed")
);
}
}

Expand All @@ -61,7 +143,9 @@ export class GitProvider implements ISCMProvider {
const repository = api.repositories[0];

if (!repository) {
throw new Error("No Git repository found");
throw new Error(
LocalizationManager.getInstance().getMessage("git.repository.not.found")
);
}

await repository.commit(message, { all: files ? false : true, files });
Expand All @@ -72,7 +156,9 @@ export class GitProvider implements ISCMProvider {
const repository = api.repositories[0];

if (!repository) {
throw new Error("No Git repository found");
throw new Error(
LocalizationManager.getInstance().getMessage("git.repository.not.found")
);
}

repository.inputBox.value = message;
Expand Down
46 changes: 40 additions & 6 deletions src/scm/SvnProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import * as vscode from "vscode";
import { ISCMProvider } from "./SCMProvider";
import { promisify } from "util";
import * as childProcess from "child_process";
import { DiffSimplifier } from "../utils/DiffSimplifier";
import { LocalizationManager } from "../utils/LocalizationManager";

const exec = promisify(childProcess.exec);

Expand All @@ -15,7 +17,9 @@ export class SvnProvider implements ISCMProvider {
this.api = svnExtension;
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
if (!workspaceRoot) {
throw new Error("No workspace folder found");
throw new Error(
LocalizationManager.getInstance().getMessage("workspace.not.found")
);
}
this.workspaceRoot = workspaceRoot;
}
Expand Down Expand Up @@ -69,13 +73,37 @@ export class SvnProvider implements ISCMProvider {
}

if (!stdout.trim()) {
throw new Error("No changes found");
throw new Error(
LocalizationManager.getInstance().getMessage("diff.noChanges")
);
}

// 获取配置
const config = vscode.workspace.getConfiguration("dish-ai-commit");
const enableSimplification = config.get<boolean>(
"enableDiffSimplification"
);

// 根据配置决定是否显示警告和简化diff
if (enableSimplification) {
vscode.window.showWarningMessage(
LocalizationManager.getInstance().getMessage(
"diff.simplification.warning"
)
);
return DiffSimplifier.simplify(stdout);
}

// 如果未启用简化,直接返回原始diff
return stdout;
} catch (error) {
if (error instanceof Error) {
vscode.window.showErrorMessage(`SVN diff failed: ${error.message}`);
vscode.window.showErrorMessage(
LocalizationManager.getInstance().format(
"git.diff.failed",
error.message
)
);
}
throw error;
}
Expand All @@ -84,21 +112,27 @@ export class SvnProvider implements ISCMProvider {
async commit(message: string, files?: string[]): Promise<void> {
const repository = this.api?.repositories?.[0];
if (!repository) {
throw new Error("No SVN repository found");
throw new Error(
LocalizationManager.getInstance().getMessage("git.repository.not.found")
);
}

try {
await repository.commitFiles(files || [], message);
} catch (error) {
console.error("Failed to commit to SVN:", error);
throw new Error(`SVN commit failed: ${error}`);
throw new Error(
LocalizationManager.getInstance().format("svn.commit.failed", error)
);
}
}

async setCommitInput(message: string): Promise<void> {
const repository = this.api?.repositories?.[0];
if (!repository) {
throw new Error("No SVN repository found");
throw new Error(
LocalizationManager.getInstance().getMessage("git.repository.not.found")
);
}

repository.inputBox.value = message;
Expand Down

0 comments on commit b2854e2

Please sign in to comment.