Skip to content

Commit

Permalink
fix: support non-ASCII filenames when git is configured with `core.qu…
Browse files Browse the repository at this point in the history
…otepath on`
  • Loading branch information
kachkaev committed Mar 29, 2020
1 parent 1ad263a commit 2cb26a6
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
11 changes: 9 additions & 2 deletions lib/getStagedFiles.js
Expand Up @@ -4,8 +4,15 @@ const execGit = require('./execGit')

module.exports = async function getStagedFiles(options) {
try {
const lines = await execGit(['diff', '--staged', '--diff-filter=ACMR', '--name-only'], options)
return lines ? lines.split('\n') : []
// Docs for --diff-filter option: https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203
// Docs for -z option: https://git-scm.com/docs/git-diff#Documentation/git-diff.txt--z
const lines = await execGit(
['diff', '--staged', '--diff-filter=ACMR', '--name-only', '-z'],
options
)
// With `-z`, git prints `fileA\u0000fileB\u0000fileC\u0000` so we need to remove the last occurrence of `\u0000` before splitting
// eslint-disable-next-line no-control-regex
return lines ? lines.replace(/\u0000$/, '').split('\u0000') : []
} catch {
return null
}
Expand Down
2 changes: 1 addition & 1 deletion test/getStagedFiles.spec.js
Expand Up @@ -5,7 +5,7 @@ jest.mock('../lib/execGit')

describe('getStagedFiles', () => {
it('should return array of file names', async () => {
execGit.mockImplementationOnce(async () => 'foo.js\nbar.js')
execGit.mockImplementationOnce(async () => 'foo.js\u0000bar.js\u0000')
const staged = await getStagedFiles()
expect(staged).toEqual(['foo.js', 'bar.js'])
})
Expand Down
27 changes: 27 additions & 0 deletions test/runAll.unmocked.spec.js
Expand Up @@ -843,6 +843,33 @@ describe('runAll', () => {
expect(await execGit(['log', '-1', '--pretty=%B'], { cwd: workTreeDir })).toMatch('test')
expect(await readFile('test.js', workTreeDir)).toEqual(testJsFilePretty)
})

test.each([['on'], ['off']])(
'should handle files with non-ascii characters when core.quotepath is %s',
async quotePath => {
await execGit(['config', 'core.quotepath', quotePath])

// Stage multiple ugly files
await appendFile('привет.js', testJsFileUgly)
await execGit(['add', 'привет.js'])

await appendFile('你好.js', testJsFileUgly)
await execGit(['add', '你好.js'])

await appendFile('👋.js', testJsFileUgly)
await execGit(['add', '👋.js'])

// Run lint-staged with `prettier --write` and commit pretty files
await gitCommit(fixJsConfig)

// Nothing is wrong, so a new commit is created and files are pretty
expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2')
expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test')
expect(await readFile('привет.js')).toEqual(testJsFilePretty)
expect(await readFile('你好.js')).toEqual(testJsFilePretty)
expect(await readFile('👋.js')).toEqual(testJsFilePretty)
}
)
})

describe('runAll', () => {
Expand Down

0 comments on commit 2cb26a6

Please sign in to comment.