diff --git a/out/cli.cjs b/out/cli.cjs index 8a79a122..e37c4195 100755 --- a/out/cli.cjs +++ b/out/cli.cjs @@ -67303,6 +67303,7 @@ var getMainCommitPrompt = async (fullGitMojiSpec, context) => { // src/utils/mergeDiffs.ts function mergeDiffs(arr, maxStringLength) { + if (arr.length === 0) return []; const mergedArr = []; let currentItem = arr[0]; for (const item of arr.slice(1)) { @@ -67355,7 +67356,8 @@ var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false, context const commitMessagePromises = await getCommitMsgsPromisesFromFileDiffs( diff, MAX_REQUEST_TOKENS, - fullGitMojiSpec + fullGitMojiSpec, + context ); const commitMessages = []; for (const promise of commitMessagePromises) { @@ -67378,7 +67380,7 @@ var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false, context throw error; } }; -function getMessagesPromisesByChangesInFile(fileDiff, separator, maxChangeLength, fullGitMojiSpec) { +function getMessagesPromisesByChangesInFile(fileDiff, separator, maxChangeLength, fullGitMojiSpec, context) { const hunkHeaderSeparator = "@@ "; const [fileHeader, ...fileDiffByLines] = fileDiff.split(hunkHeaderSeparator); const mergedChanges = mergeDiffs( @@ -67400,7 +67402,8 @@ function getMessagesPromisesByChangesInFile(fileDiff, separator, maxChangeLength async (lineDiff) => { const messages = await generateCommitMessageChatCompletionPrompt( separator + lineDiff, - fullGitMojiSpec + fullGitMojiSpec, + context ); return engine.generateCommitMessage(messages); } @@ -67432,9 +67435,21 @@ function splitDiff(diff, maxChangeLength) { } return splitDiffs; } -var getCommitMsgsPromisesFromFileDiffs = async (diff, maxDiffLength, fullGitMojiSpec) => { +var getCommitMsgsPromisesFromFileDiffs = async (diff, maxDiffLength, fullGitMojiSpec, context = "") => { const separator = "diff --git "; const diffByFiles = diff.split(separator).slice(1); + if (diffByFiles.length === 0) { + const engine = getEngine(); + const chunks = splitDiff(diff, maxDiffLength); + return chunks.map(async (chunk) => { + const messages = await generateCommitMessageChatCompletionPrompt( + chunk, + fullGitMojiSpec, + context + ); + return engine.generateCommitMessage(messages); + }); + } const mergedFilesDiffs = mergeDiffs(diffByFiles, maxDiffLength); const commitMessagePromises = []; for (const fileDiff of mergedFilesDiffs) { @@ -67443,13 +67458,15 @@ var getCommitMsgsPromisesFromFileDiffs = async (diff, maxDiffLength, fullGitMoji fileDiff, separator, maxDiffLength, - fullGitMojiSpec + fullGitMojiSpec, + context ); commitMessagePromises.push(...messagesPromises); } else { const messages = await generateCommitMessageChatCompletionPrompt( separator + fileDiff, - fullGitMojiSpec + fullGitMojiSpec, + context ); const engine = getEngine(); commitMessagePromises.push(engine.generateCommitMessage(messages)); @@ -67544,7 +67561,7 @@ ${lockFiles.join( ); const { stdout: diff } = await execa( "git", - ["diff", "--staged", "--", ...filesWithoutLocks], + ["diff", "--staged", "--no-ext-diff", "--no-color", "--", ...filesWithoutLocks], { cwd: gitDir } ); return diff; diff --git a/out/github-action.cjs b/out/github-action.cjs index 39b526bb..16a52ddf 100644 --- a/out/github-action.cjs +++ b/out/github-action.cjs @@ -87874,6 +87874,7 @@ var getMainCommitPrompt = async (fullGitMojiSpec, context2) => { // src/utils/mergeDiffs.ts function mergeDiffs(arr, maxStringLength) { + if (arr.length === 0) return []; const mergedArr = []; let currentItem = arr[0]; for (const item of arr.slice(1)) { @@ -87926,7 +87927,8 @@ var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false, context2 const commitMessagePromises = await getCommitMsgsPromisesFromFileDiffs( diff, MAX_REQUEST_TOKENS, - fullGitMojiSpec + fullGitMojiSpec, + context2 ); const commitMessages = []; for (const promise of commitMessagePromises) { @@ -87949,7 +87951,7 @@ var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false, context2 throw error; } }; -function getMessagesPromisesByChangesInFile(fileDiff, separator, maxChangeLength, fullGitMojiSpec) { +function getMessagesPromisesByChangesInFile(fileDiff, separator, maxChangeLength, fullGitMojiSpec, context2) { const hunkHeaderSeparator = "@@ "; const [fileHeader, ...fileDiffByLines] = fileDiff.split(hunkHeaderSeparator); const mergedChanges = mergeDiffs( @@ -87971,7 +87973,8 @@ function getMessagesPromisesByChangesInFile(fileDiff, separator, maxChangeLength async (lineDiff) => { const messages = await generateCommitMessageChatCompletionPrompt( separator + lineDiff, - fullGitMojiSpec + fullGitMojiSpec, + context2 ); return engine.generateCommitMessage(messages); } @@ -88003,9 +88006,21 @@ function splitDiff(diff, maxChangeLength) { } return splitDiffs; } -var getCommitMsgsPromisesFromFileDiffs = async (diff, maxDiffLength, fullGitMojiSpec) => { +var getCommitMsgsPromisesFromFileDiffs = async (diff, maxDiffLength, fullGitMojiSpec, context2 = "") => { const separator = "diff --git "; const diffByFiles = diff.split(separator).slice(1); + if (diffByFiles.length === 0) { + const engine = getEngine(); + const chunks = splitDiff(diff, maxDiffLength); + return chunks.map(async (chunk) => { + const messages = await generateCommitMessageChatCompletionPrompt( + chunk, + fullGitMojiSpec, + context2 + ); + return engine.generateCommitMessage(messages); + }); + } const mergedFilesDiffs = mergeDiffs(diffByFiles, maxDiffLength); const commitMessagePromises = []; for (const fileDiff of mergedFilesDiffs) { @@ -88014,13 +88029,15 @@ var getCommitMsgsPromisesFromFileDiffs = async (diff, maxDiffLength, fullGitMoji fileDiff, separator, maxDiffLength, - fullGitMojiSpec + fullGitMojiSpec, + context2 ); commitMessagePromises.push(...messagesPromises); } else { const messages = await generateCommitMessageChatCompletionPrompt( separator + fileDiff, - fullGitMojiSpec + fullGitMojiSpec, + context2 ); const engine = getEngine(); commitMessagePromises.push(engine.generateCommitMessage(messages)); diff --git a/src/generateCommitMessageFromGitDiff.ts b/src/generateCommitMessageFromGitDiff.ts index 4c4d038f..ee65028a 100644 --- a/src/generateCommitMessageFromGitDiff.ts +++ b/src/generateCommitMessageFromGitDiff.ts @@ -63,7 +63,8 @@ export const generateCommitMessageByDiff = async ( const commitMessagePromises = await getCommitMsgsPromisesFromFileDiffs( diff, MAX_REQUEST_TOKENS, - fullGitMojiSpec + fullGitMojiSpec, + context ); const commitMessages = [] as string[]; @@ -97,7 +98,8 @@ function getMessagesPromisesByChangesInFile( fileDiff: string, separator: string, maxChangeLength: number, - fullGitMojiSpec: boolean + fullGitMojiSpec: boolean, + context: string ) { const hunkHeaderSeparator = '@@ '; const [fileHeader, ...fileDiffByLines] = fileDiff.split(hunkHeaderSeparator); @@ -125,7 +127,8 @@ function getMessagesPromisesByChangesInFile( async (lineDiff) => { const messages = await generateCommitMessageChatCompletionPrompt( separator + lineDiff, - fullGitMojiSpec + fullGitMojiSpec, + context ); return engine.generateCommitMessage(messages); @@ -174,12 +177,28 @@ function splitDiff(diff: string, maxChangeLength: number) { export const getCommitMsgsPromisesFromFileDiffs = async ( diff: string, maxDiffLength: number, - fullGitMojiSpec: boolean + fullGitMojiSpec: boolean, + context: string = '' ) => { const separator = 'diff --git '; const diffByFiles = diff.split(separator).slice(1); + // If `git diff` output doesn't include file markers (e.g. external diff tools), + // fall back to splitting the full diff into chunks. + if (diffByFiles.length === 0) { + const engine = getEngine(); + const chunks = splitDiff(diff, maxDiffLength); + return chunks.map(async (chunk) => { + const messages = await generateCommitMessageChatCompletionPrompt( + chunk, + fullGitMojiSpec, + context + ); + return engine.generateCommitMessage(messages); + }); + } + // merge multiple files-diffs into 1 prompt to save tokens const mergedFilesDiffs = mergeDiffs(diffByFiles, maxDiffLength); @@ -192,14 +211,16 @@ export const getCommitMsgsPromisesFromFileDiffs = async ( fileDiff, separator, maxDiffLength, - fullGitMojiSpec + fullGitMojiSpec, + context ); commitMessagePromises.push(...messagesPromises); } else { const messages = await generateCommitMessageChatCompletionPrompt( separator + fileDiff, - fullGitMojiSpec + fullGitMojiSpec, + context ); const engine = getEngine(); diff --git a/src/utils/git.ts b/src/utils/git.ts index 902d61a8..08ef9056 100644 --- a/src/utils/git.ts +++ b/src/utils/git.ts @@ -122,7 +122,7 @@ export const getDiff = async ({ files }: { files: string[] }) => { const { stdout: diff } = await execa( 'git', - ['diff', '--staged', '--', ...filesWithoutLocks], + ['diff', '--staged', '--no-ext-diff', '--no-color', '--', ...filesWithoutLocks], { cwd: gitDir } ); diff --git a/src/utils/mergeDiffs.ts b/src/utils/mergeDiffs.ts index 75b71d2c..67d2d505 100644 --- a/src/utils/mergeDiffs.ts +++ b/src/utils/mergeDiffs.ts @@ -1,6 +1,8 @@ import { tokenCount } from './tokenCount'; export function mergeDiffs(arr: string[], maxStringLength: number): string[] { + if (arr.length === 0) return []; + const mergedArr: string[] = []; let currentItem: string = arr[0]; for (const item of arr.slice(1)) { diff --git a/test/unit/mergeDiffs.test.ts b/test/unit/mergeDiffs.test.ts new file mode 100644 index 00000000..f35cfb10 --- /dev/null +++ b/test/unit/mergeDiffs.test.ts @@ -0,0 +1,8 @@ +import { mergeDiffs } from '../../src/utils/mergeDiffs'; + +describe('mergeDiffs', () => { + it('returns an empty array when given no diffs', () => { + expect(mergeDiffs([], 100)).toEqual([]); + }); +}); +