@itcase/config 1.7.23 → 1.7.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/smart-commit/cli.js +46 -8
package/package.json
CHANGED
package/smart-commit/cli.js
CHANGED
|
@@ -202,28 +202,39 @@ async function main(argv) {
|
|
|
202
202
|
continue
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
const ignoredFiles = gitIgnoredFiles(cwd, planFiles)
|
|
206
|
+
const filesToStage = planFiles.filter(
|
|
207
|
+
(file) => !ignoredFiles.includes(file),
|
|
208
|
+
)
|
|
209
|
+
process.stdout.write(`\n${paint('1;36', step)} ${plan.message}\n`)
|
|
210
|
+
if (ignoredFiles.length) {
|
|
211
|
+
process.stdout.write(
|
|
212
|
+
`${dim(` skipped (gitignore): ${ignoredFiles.join(', ')}`)}\n`,
|
|
213
|
+
)
|
|
214
|
+
}
|
|
215
|
+
if (!filesToStage.length) continue
|
|
216
|
+
|
|
205
217
|
const startedAt = Date.now()
|
|
206
218
|
const fileLabel =
|
|
207
|
-
|
|
208
|
-
process.stdout.write(`\n${paint('1;36', step)} ${plan.message}\n`)
|
|
219
|
+
filesToStage.length === 1 ? '1 file' : `${filesToStage.length} files`
|
|
209
220
|
process.stdout.write(`${dim(` staging ${fileLabel}…`)}\n`)
|
|
210
221
|
|
|
211
222
|
// Drop leftover index entries so only this plan's files are committed.
|
|
212
223
|
git(cwd, ['reset', '-q', 'HEAD'])
|
|
213
|
-
stageFiles(cwd,
|
|
224
|
+
stageFiles(cwd, filesToStage)
|
|
214
225
|
const staged = lines(cwd, ['diff', '--cached', '--name-only'])
|
|
215
|
-
const stagedForPlan =
|
|
226
|
+
const stagedForPlan = filesToStage.filter((file) => staged.includes(file))
|
|
216
227
|
if (!stagedForPlan.length) {
|
|
217
228
|
throw new Error(
|
|
218
229
|
`Nothing staged for commit: ${plan.message}\n` +
|
|
219
|
-
`Files: ${
|
|
230
|
+
`Files: ${filesToStage.join(', ')}`,
|
|
220
231
|
)
|
|
221
232
|
}
|
|
222
233
|
|
|
223
234
|
const commitLabel = option.noVerify
|
|
224
235
|
? 'git commit --no-verify'
|
|
225
236
|
: 'git commit'
|
|
226
|
-
const hookLocks = siblingLocksForFiles(
|
|
237
|
+
const hookLocks = siblingLocksForFiles(filesToStage)
|
|
227
238
|
const dirtyLocksBefore = new Set(
|
|
228
239
|
hookLocks.filter((file) => fileHasChanges(cwd, file)),
|
|
229
240
|
)
|
|
@@ -233,7 +244,7 @@ async function main(argv) {
|
|
|
233
244
|
// equivalent flag — the hook simply does not run.
|
|
234
245
|
if (option.noVerify) commitArgs.push('--no-verify')
|
|
235
246
|
await gitCommitWithProgress(cwd, commitArgs, commitLabel)
|
|
236
|
-
const included = includeHookLockfiles(cwd,
|
|
247
|
+
const included = includeHookLockfiles(cwd, filesToStage, dirtyLocksBefore)
|
|
237
248
|
if (included.length) {
|
|
238
249
|
process.stdout.write(
|
|
239
250
|
`${dim(` hook updated ${included.join(', ')}, added to commit`)}\n`,
|
|
@@ -1534,6 +1545,26 @@ function isOnDisk(cwd, file) {
|
|
|
1534
1545
|
return fs.existsSync(path.join(cwd, file))
|
|
1535
1546
|
}
|
|
1536
1547
|
|
|
1548
|
+
function gitIgnoredFiles(cwd, files) {
|
|
1549
|
+
if (!files.length) return []
|
|
1550
|
+
|
|
1551
|
+
const result = spawnSync('git', ['check-ignore', '-z', '--stdin'], {
|
|
1552
|
+
cwd: cwd,
|
|
1553
|
+
encoding: 'utf8',
|
|
1554
|
+
input: `${files.join('\0')}\0`,
|
|
1555
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
1556
|
+
})
|
|
1557
|
+
// 0 — at least one path is ignored, 1 — none.
|
|
1558
|
+
if (result.status !== 0) return []
|
|
1559
|
+
|
|
1560
|
+
const ignored = new Set(
|
|
1561
|
+
String(result.stdout || '')
|
|
1562
|
+
.split('\0')
|
|
1563
|
+
.filter(Boolean),
|
|
1564
|
+
)
|
|
1565
|
+
return files.filter((file) => ignored.has(file))
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1537
1568
|
function isTracked(cwd, file) {
|
|
1538
1569
|
return gitOk(cwd, ['ls-files', '--error-unmatch', '--', file])
|
|
1539
1570
|
}
|
|
@@ -1602,9 +1633,16 @@ function includeHookLockfiles(cwd, planFiles, dirtyBefore) {
|
|
|
1602
1633
|
function stageFiles(cwd, files) {
|
|
1603
1634
|
if (!files.length) return
|
|
1604
1635
|
|
|
1636
|
+
// `git add -- ignored/path` exits 1 and abandons the rest of the batch.
|
|
1637
|
+
// Tracked files that also match gitignore still stage; check-ignore
|
|
1638
|
+
// omits them unless --no-index is passed.
|
|
1639
|
+
const ignored = new Set(gitIgnoredFiles(cwd, files))
|
|
1640
|
+
const stageableFiles = files.filter((file) => !ignored.has(file))
|
|
1641
|
+
if (!stageableFiles.length) return
|
|
1642
|
+
|
|
1605
1643
|
const existing = []
|
|
1606
1644
|
const removed = []
|
|
1607
|
-
for (const file of
|
|
1645
|
+
for (const file of stageableFiles) {
|
|
1608
1646
|
if (isOnDisk(cwd, file)) existing.push(file)
|
|
1609
1647
|
else removed.push(file)
|
|
1610
1648
|
}
|