diff --git a/packages/cli-kit/src/public/node/git.test.ts b/packages/cli-kit/src/public/node/git.test.ts index acff89c5765..5fef9e3f37f 100644 --- a/packages/cli-kit/src/public/node/git.test.ts +++ b/packages/cli-kit/src/public/node/git.test.ts @@ -538,3 +538,34 @@ describe('removeGitRemote()', () => { expect(mockedExeca).not.toHaveBeenCalledWith('git', ['remote', 'remove', remoteName], {cwd: directory}) }) }) + +describe('checkIfIgnoredInGitRepository()', () => { + test('returns empty array without calling git if files array is empty', async () => { + const directory = '/test/directory' + + const result = await git.checkIfIgnoredInGitRepository(directory, []) + + expect(result).toEqual([]) + expect(mockedExeca).not.toHaveBeenCalled() + }) + + test('passes -- before file paths to prevent option injection', async () => { + const directory = '/test/directory' + mockGitCommand('file1.txt\n') + + const result = await git.checkIfIgnoredInGitRepository(directory, ['file1.txt', '-v']) + + expect(mockedExeca).toHaveBeenCalledWith('git', ['check-ignore', '--', 'file1.txt', '-v'], {cwd: directory}) + expect(result).toEqual(['file1.txt']) + }) + + test('returns empty array when git check-ignore exits with code 1', async () => { + const directory = '/test/directory' + const error = Object.assign(new Error('no files ignored'), {exitCode: 1}) + mockedExeca.mockRejectedValue(error) + + const result = await git.checkIfIgnoredInGitRepository(directory, ['file1.txt']) + + expect(result).toEqual([]) + }) +}) diff --git a/packages/cli-kit/src/public/node/git.ts b/packages/cli-kit/src/public/node/git.ts index e4ed42070ca..5e66114f711 100644 --- a/packages/cli-kit/src/public/node/git.ts +++ b/packages/cli-kit/src/public/node/git.ts @@ -73,8 +73,10 @@ export async function initializeGitRepository(directory: string, initialBranch = * @returns Files ignored by the lockfile. */ export async function checkIfIgnoredInGitRepository(directory: string, files: string[]): Promise { + if (files.length === 0) return [] try { - const stdout = await gitCommand(['check-ignore', ...files], directory) + // Pass '--' to separate git check-ignore options from file paths and prevent option injection + const stdout = await gitCommand(['check-ignore', '--', ...files], directory) return stdout.split('\n').filter(Boolean) } catch (error) { // git check-ignore exits with code 1 when no files are ignored