|
3 | 3 | const debug = require('debug')('lint-staged:git') |
4 | 4 | const path = require('path') |
5 | 5 |
|
| 6 | +const chunkFiles = require('./chunkFiles') |
6 | 7 | const execGit = require('./execGit') |
7 | 8 | const { readFile, unlink, writeFile } = require('./file') |
8 | 9 |
|
@@ -52,14 +53,15 @@ const handleError = (error, ctx) => { |
52 | 53 | } |
53 | 54 |
|
54 | 55 | class GitWorkflow { |
55 | | - constructor({ allowEmpty, gitConfigDir, gitDir, stagedFileChunks }) { |
| 56 | + constructor({ allowEmpty, gitConfigDir, gitDir, matchedFiles, maxArgLength }) { |
56 | 57 | this.execGit = (args, options = {}) => execGit(args, { ...options, cwd: gitDir }) |
57 | 58 | this.deletedFiles = [] |
58 | 59 | this.gitConfigDir = gitConfigDir |
59 | 60 | this.gitDir = gitDir |
60 | 61 | this.unstagedDiff = null |
61 | 62 | this.allowEmpty = allowEmpty |
62 | | - this.stagedFileChunks = stagedFileChunks |
| 63 | + this.matchedFiles = matchedFiles |
| 64 | + this.maxArgLength = maxArgLength |
63 | 65 |
|
64 | 66 | /** |
65 | 67 | * These three files hold state about an ongoing git merge |
@@ -235,12 +237,22 @@ class GitWorkflow { |
235 | 237 | */ |
236 | 238 | async applyModifications(ctx) { |
237 | 239 | debug('Adding task modifications to index...') |
238 | | - // stagedFileChunks includes staged files that lint-staged originally detected. |
| 240 | + // `matchedFiles` includes staged files that lint-staged originally detected and matched against a task. |
239 | 241 | // Add only these files so any 3rd-party edits to other files won't be included in the commit. |
240 | | - // This is run "serially" to prevent race conditions because `git add` is a locking operation. |
241 | | - for (const stagedFiles of this.stagedFileChunks) { |
242 | | - await this.execGit(['add', '--', ...stagedFiles]) |
| 242 | + const files = Array.from(this.matchedFiles) |
| 243 | + // Chunk files for better Windows compatibility |
| 244 | + const matchedFileChunks = chunkFiles({ |
| 245 | + baseDir: this.gitDir, |
| 246 | + files, |
| 247 | + maxArgLength: this.maxArgLength |
| 248 | + }) |
| 249 | + |
| 250 | + // These additions per chunk are run "serially" to prevent race conditions. |
| 251 | + // Git add creates a lockfile in the repo causing concurrent operations to fail. |
| 252 | + for (const files of matchedFileChunks) { |
| 253 | + await this.execGit(['add', '--', ...files]) |
243 | 254 | } |
| 255 | + |
244 | 256 | debug('Done adding task modifications to index!') |
245 | 257 |
|
246 | 258 | const stagedFilesAfterAdd = await this.execGit(['diff', '--name-only', '--cached']) |
|
0 commit comments