From 9d4f912c930737fa10c0eb54792b5b3585043297 Mon Sep 17 00:00:00 2001 From: Kacper Date: Tue, 23 Dec 2025 18:26:02 +0100 Subject: [PATCH 1/2] Changes from main --- libs/git-utils/src/diff.ts | 15 ++++++++++++++- libs/git-utils/tests/diff.test.ts | 12 ++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/libs/git-utils/src/diff.ts b/libs/git-utils/src/diff.ts index 96609cfa..a5388f39 100644 --- a/libs/git-utils/src/diff.ts +++ b/libs/git-utils/src/diff.ts @@ -44,8 +44,21 @@ Binary file ${relativePath} added `; } - // Get file stats to check size + // Get file stats to check size and type const stats = await secureFs.stat(fullPath); + + // Check if it's a directory (can happen with untracked directories from git status) + if (stats.isDirectory()) { + return `diff --git a/${relativePath} b/${relativePath} +new file mode 040000 +index 0000000..0000000 +--- /dev/null ++++ b/${relativePath} +@@ -0,0 +1 @@ ++[Directory] +`; + } + if (stats.size > MAX_SYNTHETIC_DIFF_SIZE) { const sizeKB = Math.round(stats.size / 1024); return `diff --git a/${relativePath} b/${relativePath} diff --git a/libs/git-utils/tests/diff.test.ts b/libs/git-utils/tests/diff.test.ts index 6212df1a..953d2763 100644 --- a/libs/git-utils/tests/diff.test.ts +++ b/libs/git-utils/tests/diff.test.ts @@ -117,6 +117,18 @@ describe('diff.ts', () => { expect(diff).toContain(`diff --git a/${fileName} b/${fileName}`); expect(diff).toContain('[Unable to read file content]'); }); + + it('should handle directory path gracefully', async () => { + const dirName = 'some-directory'; + const dirPath = path.join(tempDir, dirName); + await fs.mkdir(dirPath); + + const diff = await generateSyntheticDiffForNewFile(tempDir, dirName); + + expect(diff).toContain(`diff --git a/${dirName} b/${dirName}`); + expect(diff).toContain('new file mode 040000'); + expect(diff).toContain('[Directory]'); + }); }); describe('appendUntrackedFileDiffs', () => { From c9e0957dfe502a451527c0cf277552b9a9f25172 Mon Sep 17 00:00:00 2001 From: Kacper Date: Tue, 23 Dec 2025 18:39:43 +0100 Subject: [PATCH 2/2] feat(diff): add helper function to create synthetic diffs for new files This update introduces a new function, createNewFileDiff, to streamline the generation of synthetic diffs for untracked files. The function reduces code duplication by handling the diff formatting for new files, including directories and large files, improving overall maintainability. --- libs/git-utils/src/diff.ts | 47 +++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/libs/git-utils/src/diff.ts b/libs/git-utils/src/diff.ts index a5388f39..f052f48d 100644 --- a/libs/git-utils/src/diff.ts +++ b/libs/git-utils/src/diff.ts @@ -24,6 +24,24 @@ function isBinaryFile(filePath: string): boolean { return BINARY_EXTENSIONS.has(ext); } +/** + * Create a synthetic diff for a new file with the given content lines + * This helper reduces duplication in diff generation logic + */ +function createNewFileDiff(relativePath: string, mode: string, contentLines: string[]): string { + const lineCount = contentLines.length; + const addedLines = contentLines.map((line) => `+${line}`).join('\n'); + + return `diff --git a/${relativePath} b/${relativePath} +new file mode ${mode} +index 0000000..0000000 +--- /dev/null ++++ b/${relativePath} +@@ -0,0 +${lineCount === 1 ? '1' : `1,${lineCount}`} @@ +${addedLines} +`; +} + /** * Generate a synthetic unified diff for an untracked (new) file * This is needed because `git diff HEAD` doesn't include untracked files @@ -49,26 +67,14 @@ Binary file ${relativePath} added // Check if it's a directory (can happen with untracked directories from git status) if (stats.isDirectory()) { - return `diff --git a/${relativePath} b/${relativePath} -new file mode 040000 -index 0000000..0000000 ---- /dev/null -+++ b/${relativePath} -@@ -0,0 +1 @@ -+[Directory] -`; + return createNewFileDiff(relativePath, '040000', ['[Directory]']); } if (stats.size > MAX_SYNTHETIC_DIFF_SIZE) { const sizeKB = Math.round(stats.size / 1024); - return `diff --git a/${relativePath} b/${relativePath} -new file mode 100644 -index 0000000..0000000 ---- /dev/null -+++ b/${relativePath} -@@ -0,0 +1 @@ -+[File too large to display: ${sizeKB}KB] -`; + return createNewFileDiff(relativePath, '100644', [ + `[File too large to display: ${sizeKB}KB]`, + ]); } // Read file content @@ -103,14 +109,7 @@ ${addedLines}`; // Log the error for debugging logger.error(`Failed to generate synthetic diff for ${fullPath}:`, error); // Return a placeholder diff - return `diff --git a/${relativePath} b/${relativePath} -new file mode 100644 -index 0000000..0000000 ---- /dev/null -+++ b/${relativePath} -@@ -0,0 +1 @@ -+[Unable to read file content] -`; + return createNewFileDiff(relativePath, '100644', ['[Unable to read file content]']); } }