Skip to content

Commit 3967105

Browse files
feat: Add lazycommit command for auto commits
1 parent eea1f72 commit 3967105

File tree

2 files changed

+77
-5
lines changed

2 files changed

+77
-5
lines changed

src/commands/lazycommit.ts

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
select,
88
confirm,
99
isCancel,
10+
text,
1011
} from '@clack/prompts';
1112
import {
1213
assertGitRepo,
@@ -344,10 +345,36 @@ export default async (
344345
commitSpinner.start(`Creating commit ${i + 1}/${groups.length}: ${group.message}`);
345346

346347
try {
348+
// Optionally edit this group's commit message before committing
349+
let finalMessage = group.message!;
350+
const wantsEdit = await confirm({ message: `Edit commit ${i + 1} message before committing?` });
351+
if (wantsEdit && !isCancel(wantsEdit)) {
352+
const edited = await text({
353+
message: 'Edit commit message:',
354+
initialValue: finalMessage,
355+
validate: (value) => (value && value.trim().length > 0 ? undefined : 'Message cannot be empty'),
356+
});
357+
if (isCancel(edited)) {
358+
outro('Commits cancelled');
359+
return;
360+
}
361+
finalMessage = String(edited).trim();
362+
group.message = finalMessage;
363+
}
364+
365+
// Confirm proceed with the (possibly edited) message for this commit
366+
const proceedGroup = await confirm({
367+
message: `Proceed with commit ${i + 1}/${groups.length} message?\n\n ${finalMessage}\n`,
368+
});
369+
if (!proceedGroup || isCancel(proceedGroup)) {
370+
outro('Commits cancelled');
371+
return;
372+
}
373+
347374
// Reset and stage only files for this group
348375
await execa('git', ['reset', 'HEAD', '--']);
349376
await execa('git', ['add', ...group.files]);
350-
await execa('git', ['commit', '-m', group.message!, ...rawArgv]);
377+
await execa('git', ['commit', '-m', finalMessage, ...rawArgv]);
351378
} finally {
352379
commitSpinner.stop(`Commit ${i + 1} created`);
353380
}
@@ -401,16 +428,36 @@ export default async (
401428
}
402429

403430
let message: string;
431+
let editedAlready = false;
404432
if (messages.length === 1) {
405433
[message] = messages;
406-
const confirmed = await confirm({
407-
message: `Use this commit message?\n\n ${message}\n`,
434+
const choice = await select({
435+
message: `Review generated commit message:\n\n ${message}\n`,
436+
options: [
437+
{ label: 'Use as-is', value: 'use' },
438+
{ label: 'Edit', value: 'edit' },
439+
{ label: 'Cancel', value: 'cancel' },
440+
],
408441
});
409442

410-
if (!confirmed || isCancel(confirmed)) {
443+
if (isCancel(choice) || choice === 'cancel') {
411444
outro('Commit cancelled');
412445
return;
413446
}
447+
448+
if (choice === 'edit') {
449+
const edited = await text({
450+
message: 'Edit commit message:',
451+
initialValue: message,
452+
validate: (value) => (value && value.trim().length > 0 ? undefined : 'Message cannot be empty'),
453+
});
454+
if (isCancel(edited)) {
455+
outro('Commit cancelled');
456+
return;
457+
}
458+
message = String(edited).trim();
459+
editedAlready = true;
460+
}
414461
} else {
415462
const selected = await select({
416463
message: `Pick a commit message to use: ${dim('(Ctrl+c to exit)')}`,
@@ -425,6 +472,32 @@ export default async (
425472
message = selected as string;
426473
}
427474

475+
// Offer editing of the final commit message (skip if already edited)
476+
if (!editedAlready) {
477+
const wantsEdit = await confirm({ message: 'Edit the commit message before committing?' });
478+
if (wantsEdit && !isCancel(wantsEdit)) {
479+
const edited = await text({
480+
message: 'Edit commit message:',
481+
initialValue: message,
482+
validate: (value) => (value && value.trim().length > 0 ? undefined : 'Message cannot be empty'),
483+
});
484+
if (isCancel(edited)) {
485+
outro('Commit cancelled');
486+
return;
487+
}
488+
message = String(edited).trim();
489+
}
490+
}
491+
492+
// Final proceed confirmation displaying the message
493+
const proceed = await confirm({
494+
message: `Proceed with this commit message?\n\n ${message}\n`,
495+
});
496+
if (!proceed || isCancel(proceed)) {
497+
outro('Commit cancelled');
498+
return;
499+
}
500+
428501
await execa('git', ['commit', '-m', message, ...rawArgv]);
429502

430503
outro(`${green('✔')} Successfully committed!`);

src/utils/git.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ const excludeFromDiff = (path: string) => `:(exclude)${path}`;
1919

2020
const filesToExclude = [
2121
'package-lock.json',
22-
'pnpm-lock.yaml',
2322
'node_modules/**',
2423
'dist/**',
2524
'build/**',

0 commit comments

Comments
 (0)