Skip to content

Commit 0d627a5

Browse files
author
Piotr Bosak
authored
fix: correctly handle git stash when using MSYS2 (#1178)
1 parent 1a5a66a commit 0d627a5

File tree

2 files changed

+104
-1
lines changed

2 files changed

+104
-1
lines changed

lib/gitWorkflow.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const processRenames = (files, includeRenameFrom = true) =>
4343
return flattened
4444
}, [])
4545

46-
const STASH = 'lint-staged automatic backup'
46+
export const STASH = 'lint-staged automatic backup'
4747

4848
const PATCH_UNSTAGED = 'lint-staged_unstaged.patch'
4949

@@ -103,6 +103,16 @@ export class GitWorkflow {
103103
ctx.errors.add(GetBackupStashError)
104104
throw new Error('lint-staged automatic backup is missing!')
105105
}
106+
107+
/**
108+
* https://github.com/okonet/lint-staged/issues/1121
109+
* Detect MSYS in login shell mode and escape braces
110+
* to prevent interpolation
111+
*/
112+
if (!!process.env.MSYSTEM && !!process.env.LOGINSHELL) {
113+
return `refs/stash@\\{${index}\\}`
114+
}
115+
106116
return `refs/stash@{${index}}`
107117
}
108118

test/unit/getBackupStash.spec.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { execGit } from '../../lib/execGit.js'
2+
import { GitWorkflow, STASH } from '../../lib/gitWorkflow.js'
3+
import { getInitialState } from '../../lib/state.js'
4+
import { GetBackupStashError } from '../../lib/symbols'
5+
6+
jest.mock('../../lib/execGit.js', () => ({
7+
execGit: jest.fn(async () => ''),
8+
}))
9+
10+
describe('gitWorkflow', () => {
11+
const options = { gitConfigDir: '.' }
12+
13+
describe('getBackupStash', () => {
14+
it('should throw when stash not found', async () => {
15+
const gitWorkflow = new GitWorkflow(options)
16+
const ctx = getInitialState()
17+
18+
await expect(gitWorkflow.getBackupStash(ctx)).rejects.toThrowError(
19+
'lint-staged automatic backup is missing!'
20+
)
21+
22+
expect(ctx.errors.has(GetBackupStashError)).toEqual(true)
23+
})
24+
25+
it('should throw when stash not found even when other stashes are', async () => {
26+
const gitWorkflow = new GitWorkflow(options)
27+
const ctx = getInitialState()
28+
29+
execGit.mockResolvedValueOnce('stash@{0}: some random stuff')
30+
31+
await expect(gitWorkflow.getBackupStash(ctx)).rejects.toThrowError(
32+
'lint-staged automatic backup is missing!'
33+
)
34+
35+
expect(ctx.errors.has(GetBackupStashError)).toEqual(true)
36+
})
37+
38+
it('should return ref to the backup stash', async () => {
39+
const gitWorkflow = new GitWorkflow(options)
40+
const ctx = getInitialState()
41+
42+
execGit.mockResolvedValueOnce(
43+
[
44+
'stash@{0}: some random stuff',
45+
`stash@{1}: ${STASH}`,
46+
'stash@{2}: other random stuff',
47+
].join('\n')
48+
)
49+
50+
await expect(gitWorkflow.getBackupStash(ctx)).resolves.toEqual('refs/stash@{1}')
51+
})
52+
53+
it('should return unescaped ref to the backup stash when using MSYS2 without login shell', async () => {
54+
const gitWorkflow = new GitWorkflow(options)
55+
const ctx = getInitialState()
56+
57+
process.env.MSYSTEM = 'MSYS'
58+
59+
execGit.mockResolvedValueOnce(
60+
[
61+
'stash@{0}: some random stuff',
62+
`stash@{1}: ${STASH}`,
63+
'stash@{2}: other random stuff',
64+
].join('\n')
65+
)
66+
67+
await expect(gitWorkflow.getBackupStash(ctx)).resolves.toEqual('refs/stash@{1}')
68+
69+
delete process.env.MSYSTEM
70+
})
71+
72+
it('should return escaped ref to the backup stash when using MSYS2 with login shell', async () => {
73+
const gitWorkflow = new GitWorkflow(options)
74+
const ctx = getInitialState()
75+
76+
process.env.MSYSTEM = 'MSYS'
77+
process.env.LOGINSHELL = 'bash'
78+
79+
execGit.mockResolvedValueOnce(
80+
[
81+
'stash@{0}: some random stuff',
82+
`stash@{1}: ${STASH}`,
83+
'stash@{2}: other random stuff',
84+
].join('\n')
85+
)
86+
87+
await expect(gitWorkflow.getBackupStash(ctx)).resolves.toEqual('refs/stash@\\{1\\}')
88+
89+
delete process.env.MSYSTEM
90+
delete process.env.LOGINSHELL
91+
})
92+
})
93+
})

0 commit comments

Comments
 (0)