mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-01 08:13:37 +00:00
feat: enhance git diff functionality for untracked files
- Implemented synthetic diff generation for untracked files in both git and non-git directories. - Added fallback UI in the GitDiffPanel for files without diff content, ensuring better user experience. - Improved error handling and logging for git operations, enhancing reliability in file diff retrieval. This update allows users to see diffs for new files that are not yet tracked by git, improving the overall functionality of the diff panel.
This commit is contained in:
@@ -6,9 +6,22 @@ import type { Request, Response } from "express";
|
||||
import { exec } from "child_process";
|
||||
import { promisify } from "util";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
import { appendUntrackedFileDiffs, generateDiffsForNonGitDirectory } from "../../common.js";
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
/**
|
||||
* Check if a path is a git repository
|
||||
*/
|
||||
async function isGitRepo(repoPath: string): Promise<boolean> {
|
||||
try {
|
||||
await execAsync("git rev-parse --is-inside-work-tree", { cwd: repoPath });
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function createDiffsHandler() {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
@@ -19,6 +32,26 @@ export function createDiffsHandler() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if it's a git repository
|
||||
const isRepo = await isGitRepo(projectPath);
|
||||
|
||||
if (!isRepo) {
|
||||
// Not a git repo - list all files and treat them as new
|
||||
try {
|
||||
const result = await generateDiffsForNonGitDirectory(projectPath);
|
||||
res.json({
|
||||
success: true,
|
||||
diff: result.diff,
|
||||
files: result.files,
|
||||
hasChanges: result.files.length > 0,
|
||||
});
|
||||
} catch (error) {
|
||||
logError(error, "Failed to list files in non-git directory");
|
||||
res.json({ success: true, diff: "", files: [], hasChanges: false });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { stdout: diff } = await execAsync("git diff HEAD", {
|
||||
cwd: projectPath,
|
||||
@@ -50,13 +83,19 @@ export function createDiffsHandler() {
|
||||
};
|
||||
});
|
||||
|
||||
// Generate synthetic diffs for untracked (new) files
|
||||
// git diff HEAD doesn't include untracked files, so we need to generate them
|
||||
const combinedDiff = await appendUntrackedFileDiffs(projectPath, diff, files);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
diff,
|
||||
diff: combinedDiff,
|
||||
files,
|
||||
hasChanges: files.length > 0,
|
||||
});
|
||||
} catch {
|
||||
} catch (innerError) {
|
||||
// Log the error for debugging instead of silently swallowing it
|
||||
logError(innerError, "Git command failed");
|
||||
res.json({ success: true, diff: "", files: [], hasChanges: false });
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { Request, Response } from "express";
|
||||
import { exec } from "child_process";
|
||||
import { promisify } from "util";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
import { generateSyntheticDiffForNewFile } from "../../common.js";
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
@@ -25,16 +26,33 @@ export function createFileDiffHandler() {
|
||||
}
|
||||
|
||||
try {
|
||||
const { stdout: diff } = await execAsync(
|
||||
`git diff HEAD -- "${filePath}"`,
|
||||
{
|
||||
cwd: projectPath,
|
||||
maxBuffer: 10 * 1024 * 1024,
|
||||
}
|
||||
// First check if the file is untracked
|
||||
const { stdout: status } = await execAsync(
|
||||
`git status --porcelain -- "${filePath}"`,
|
||||
{ cwd: projectPath }
|
||||
);
|
||||
|
||||
const isUntracked = status.trim().startsWith("??");
|
||||
|
||||
let diff: string;
|
||||
if (isUntracked) {
|
||||
// Generate synthetic diff for untracked file
|
||||
diff = await generateSyntheticDiffForNewFile(projectPath, filePath);
|
||||
} else {
|
||||
// Use regular git diff for tracked files
|
||||
const result = await execAsync(
|
||||
`git diff HEAD -- "${filePath}"`,
|
||||
{
|
||||
cwd: projectPath,
|
||||
maxBuffer: 10 * 1024 * 1024,
|
||||
}
|
||||
);
|
||||
diff = result.stdout;
|
||||
}
|
||||
|
||||
res.json({ success: true, diff, filePath });
|
||||
} catch {
|
||||
} catch (innerError) {
|
||||
logError(innerError, "Git file diff failed");
|
||||
res.json({ success: true, diff: "", filePath });
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user