git-it-done 1.0.1 → 1.1.0
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/LICENSE +21 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +26 -29
- package/dist/index.js.map +1 -1
- package/dist/utils/checkGitStatus.d.ts +1 -1
- package/dist/utils/checkGitStatus.js +40 -26
- package/dist/utils/checkGitStatus.js.map +1 -1
- package/dist/utils/commitMessage.d.ts +1 -1
- package/dist/utils/commitMessage.js +17 -23
- package/dist/utils/commitMessage.js.map +1 -1
- package/dist/utils/diffSignals.d.ts +22 -0
- package/dist/utils/diffSignals.js +75 -0
- package/dist/utils/diffSignals.js.map +1 -0
- package/dist/utils/displayStatus.d.ts +1 -1
- package/dist/utils/displayStatus.js +10 -16
- package/dist/utils/displayStatus.js.map +1 -1
- package/dist/utils/fileStaging.d.ts +1 -1
- package/dist/utils/fileStaging.js +84 -44
- package/dist/utils/fileStaging.js.map +1 -1
- package/dist/utils/formatFileStatus.js +14 -14
- package/dist/utils/formatFileStatus.js.map +1 -1
- package/dist/utils/generateCommitMessage.d.ts +13 -1
- package/dist/utils/generateCommitMessage.js +179 -90
- package/dist/utils/generateCommitMessage.js.map +1 -1
- package/dist/utils/getFileChanges.d.ts +15 -1
- package/dist/utils/getFileChanges.js +60 -22
- package/dist/utils/getFileChanges.js.map +1 -1
- package/dist/utils/gitCommand.d.ts +27 -1
- package/dist/utils/gitCommand.js +53 -13
- package/dist/utils/gitCommand.js.map +1 -1
- package/dist/utils/performCommit.js +39 -50
- package/dist/utils/performCommit.js.map +1 -1
- package/dist/utils/process_interruption.js +23 -17
- package/dist/utils/process_interruption.js.map +1 -1
- package/dist/utils/push_to_remote.js +56 -46
- package/dist/utils/push_to_remote.js.map +1 -1
- package/dist/utils/repoRoot.d.ts +6 -0
- package/dist/utils/repoRoot.js +10 -0
- package/dist/utils/repoRoot.js.map +1 -0
- package/dist/utils/types/types.d.ts +11 -1
- package/dist/utils/types/types.js +1 -2
- package/package.json +39 -8
- package/readme.md +298 -9
- package/dist/utils/isGitrepo.d.ts +0 -1
- package/dist/utils/isGitrepo.js +0 -9
- package/dist/utils/isGitrepo.js.map +0 -1
|
@@ -1,28 +1,66 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import { gitCommand } from './gitCommand.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse `git diff --name-status -z` output.
|
|
4
|
+
*
|
|
5
|
+
* With `-z` every field is its own NUL-terminated record:
|
|
6
|
+
* `M\0path\0` for ordinary changes
|
|
7
|
+
* `R100\0oldPath\0newPath\0` for renames (and `C###` for copies)
|
|
8
|
+
*
|
|
9
|
+
* The similarity score is stripped from the status and the destination path is
|
|
10
|
+
* used for renames/copies, so downstream code never sees `R100` or a bogus
|
|
11
|
+
* `old\tnew` path.
|
|
12
|
+
*/
|
|
13
|
+
export function parseNameStatusZ(output) {
|
|
14
|
+
const tokens = output.split('\0').filter(token => token.length > 0);
|
|
15
|
+
const changes = [];
|
|
16
|
+
for (let i = 0; i < tokens.length;) {
|
|
17
|
+
const raw = tokens[i++];
|
|
18
|
+
const status = raw.charAt(0).toUpperCase();
|
|
19
|
+
if (status === 'R' || status === 'C') {
|
|
20
|
+
const from = tokens[i++];
|
|
21
|
+
const to = tokens[i++];
|
|
22
|
+
if (from === undefined || to === undefined)
|
|
23
|
+
break;
|
|
24
|
+
changes.push({ status, file: to, from });
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const file = tokens[i++];
|
|
28
|
+
if (file === undefined)
|
|
29
|
+
break;
|
|
30
|
+
changes.push({ status, file });
|
|
13
31
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
32
|
+
}
|
|
33
|
+
return changes;
|
|
34
|
+
}
|
|
35
|
+
/** Parse a NUL-separated list of paths (e.g. `git ls-files -z`). */
|
|
36
|
+
export function parseNulList(output, status) {
|
|
37
|
+
return output
|
|
38
|
+
.split('\0')
|
|
39
|
+
.filter(file => file.length > 0)
|
|
40
|
+
.map(file => ({ status, file }));
|
|
41
|
+
}
|
|
42
|
+
function nameStatus(args) {
|
|
43
|
+
const result = gitCommand(args);
|
|
44
|
+
return result.ok ? parseNameStatusZ(result.stdout) : [];
|
|
17
45
|
}
|
|
18
|
-
function getChanges() {
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
46
|
+
export function getChanges() {
|
|
47
|
+
const staged = nameStatus(['diff', '--cached', '--name-status', '--find-renames', '-z']);
|
|
48
|
+
const unstaged = nameStatus(['diff', '--name-status', '--find-renames', '-z']);
|
|
49
|
+
// `--full-name` + `:/` keep untracked paths repo-root-relative like the diff
|
|
50
|
+
// output above, even when the tool is invoked from a subdirectory.
|
|
51
|
+
const untrackedResult = gitCommand([
|
|
52
|
+
'ls-files',
|
|
53
|
+
'--others',
|
|
54
|
+
'--exclude-standard',
|
|
55
|
+
'--full-name',
|
|
56
|
+
'-z',
|
|
57
|
+
'--',
|
|
58
|
+
':/'
|
|
59
|
+
]);
|
|
22
60
|
return {
|
|
23
|
-
staged
|
|
24
|
-
unstaged
|
|
25
|
-
untracked:
|
|
61
|
+
staged,
|
|
62
|
+
unstaged,
|
|
63
|
+
untracked: untrackedResult.ok ? parseNulList(untrackedResult.stdout, '??') : []
|
|
26
64
|
};
|
|
27
65
|
}
|
|
28
66
|
//# sourceMappingURL=getFileChanges.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileChanges.js","sourceRoot":"","sources":["../../src/utils/getFileChanges.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getFileChanges.js","sourceRoot":"","sources":["../../src/utils/getFileChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACpE,MAAM,OAAO,GAAiB,EAAE,CAAC;IAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,GAAI,CAAC;QACpC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;QACxB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAE3C,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;YACzB,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;YACvB,IAAI,IAAI,KAAK,SAAS,IAAI,EAAE,KAAK,SAAS;gBAAE,MAAM;YAClD,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;YACzB,IAAI,IAAI,KAAK,SAAS;gBAAE,MAAM;YAC9B,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,MAAc;IACzD,OAAO,MAAM;SACV,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,UAAU,CAAC,IAAc;IAChC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC;IACzF,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC;IAE/E,6EAA6E;IAC7E,mEAAmE;IACnE,MAAM,eAAe,GAAG,UAAU,CAAC;QACjC,UAAU;QACV,UAAU;QACV,oBAAoB;QACpB,aAAa;QACb,IAAI;QACJ,IAAI;QACJ,IAAI;KACL,CAAC,CAAC;IAEH,OAAO;QACL,MAAM;QACN,QAAQ;QACR,SAAS,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;KAChF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1,27 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface GitResult {
|
|
2
|
+
/** True when git exited with status 0. */
|
|
3
|
+
ok: boolean;
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
status: number | null;
|
|
7
|
+
/** True when the output exceeded `maxBuffer` and was therefore truncated. */
|
|
8
|
+
oversized: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface GitOptions {
|
|
11
|
+
/** Defaults to 64 MiB (Node's default of 1 MiB truncates large diffs). */
|
|
12
|
+
maxBuffer?: number;
|
|
13
|
+
cwd?: string;
|
|
14
|
+
input?: string;
|
|
15
|
+
}
|
|
16
|
+
/** 64 MiB — big enough for realistic diffs, small enough to stay a guard rail. */
|
|
17
|
+
export declare const DEFAULT_MAX_BUFFER: number;
|
|
18
|
+
/**
|
|
19
|
+
* Run git with an argv array. Never goes through a shell, so file names and
|
|
20
|
+
* commit messages containing `$`, backticks, `!`, quotes or newlines are passed
|
|
21
|
+
* through verbatim instead of being interpreted by /bin/sh.
|
|
22
|
+
*/
|
|
23
|
+
export declare function gitCommand(args: string[], options?: GitOptions): GitResult;
|
|
24
|
+
/** Convenience wrapper for the common "give me the trimmed stdout" case. */
|
|
25
|
+
export declare function gitOutput(args: string[], options?: GitOptions): string | null;
|
|
26
|
+
/** Best-effort explanation of a failed git invocation, for display to the user. */
|
|
27
|
+
export declare function gitErrorText(result: GitResult): string;
|
package/dist/utils/gitCommand.js
CHANGED
|
@@ -1,17 +1,57 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
/** 64 MiB — big enough for realistic diffs, small enough to stay a guard rail. */
|
|
3
|
+
export const DEFAULT_MAX_BUFFER = 64 * 1024 * 1024;
|
|
4
|
+
/**
|
|
5
|
+
* Run git with an argv array. Never goes through a shell, so file names and
|
|
6
|
+
* commit messages containing `$`, backticks, `!`, quotes or newlines are passed
|
|
7
|
+
* through verbatim instead of being interpreted by /bin/sh.
|
|
8
|
+
*/
|
|
9
|
+
export function gitCommand(args, options = {}) {
|
|
10
|
+
var _a, _b, _c;
|
|
11
|
+
const result = spawnSync('git', args, {
|
|
12
|
+
encoding: 'utf-8',
|
|
13
|
+
maxBuffer: (_a = options.maxBuffer) !== null && _a !== void 0 ? _a : DEFAULT_MAX_BUFFER,
|
|
14
|
+
cwd: options.cwd,
|
|
15
|
+
input: options.input
|
|
16
|
+
});
|
|
17
|
+
const stdout = (_b = result.stdout) !== null && _b !== void 0 ? _b : '';
|
|
18
|
+
const stderr = (_c = result.stderr) !== null && _c !== void 0 ? _c : '';
|
|
19
|
+
if (result.error) {
|
|
20
|
+
const code = result.error.code;
|
|
21
|
+
return {
|
|
22
|
+
ok: false,
|
|
23
|
+
stdout,
|
|
24
|
+
stderr: stderr || result.error.message,
|
|
25
|
+
status: result.status,
|
|
26
|
+
oversized: code === 'ENOBUFS'
|
|
27
|
+
};
|
|
12
28
|
}
|
|
13
|
-
|
|
14
|
-
|
|
29
|
+
return {
|
|
30
|
+
ok: result.status === 0,
|
|
31
|
+
stdout,
|
|
32
|
+
stderr,
|
|
33
|
+
status: result.status,
|
|
34
|
+
oversized: false
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** Convenience wrapper for the common "give me the trimmed stdout" case. */
|
|
38
|
+
export function gitOutput(args, options = {}) {
|
|
39
|
+
const result = gitCommand(args, options);
|
|
40
|
+
return result.ok ? result.stdout.trim() : null;
|
|
41
|
+
}
|
|
42
|
+
/** Best-effort explanation of a failed git invocation, for display to the user. */
|
|
43
|
+
export function gitErrorText(result) {
|
|
44
|
+
var _a;
|
|
45
|
+
const text = [result.stderr, result.stdout]
|
|
46
|
+
.map(part => part.trim())
|
|
47
|
+
.filter(Boolean)
|
|
48
|
+
.join('\n');
|
|
49
|
+
if (text) {
|
|
50
|
+
return text;
|
|
51
|
+
}
|
|
52
|
+
if (result.oversized) {
|
|
53
|
+
return 'git produced more output than could be buffered';
|
|
15
54
|
}
|
|
55
|
+
return `git exited with status ${(_a = result.status) !== null && _a !== void 0 ? _a : 'unknown'}`;
|
|
16
56
|
}
|
|
17
57
|
//# sourceMappingURL=gitCommand.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitCommand.js","sourceRoot":"","sources":["../../src/utils/gitCommand.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gitCommand.js","sourceRoot":"","sources":["../../src/utils/gitCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAmB1C,kFAAkF;AAClF,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnD;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,IAAc,EAAE,UAAsB,EAAE;;IACjE,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE;QACpC,QAAQ,EAAE,OAAO;QACjB,SAAS,EAAE,MAAA,OAAO,CAAC,SAAS,mCAAI,kBAAkB;QAClD,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAA,MAAM,CAAC,MAAM,mCAAI,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,MAAA,MAAM,CAAC,MAAM,mCAAI,EAAE,CAAC;IAEnC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,IAAI,GAAI,MAAM,CAAC,KAA+B,CAAC,IAAI,CAAC;QAC1D,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM;YACN,MAAM,EAAE,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO;YACtC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,IAAI,KAAK,SAAS;SAC9B,CAAC;IACJ,CAAC;IAED,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QACvB,MAAM;QACN,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,SAAS,CAAC,IAAc,EAAE,UAAsB,EAAE;IAChE,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzC,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,YAAY,CAAC,MAAiB;;IAC5C,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;SACxC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SACxB,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,OAAO,iDAAiD,CAAC;IAC3D,CAAC;IACD,OAAO,0BAA0B,MAAA,MAAM,CAAC,MAAM,mCAAI,SAAS,EAAE,CAAC;AAChE,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
2
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
3
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -8,72 +7,62 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
8
|
});
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
exports.performCommit = performCommit;
|
|
16
|
-
const prompts_1 = require("@clack/prompts");
|
|
17
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
18
|
-
const gitCommand_1 = require("./gitCommand");
|
|
19
|
-
function performCommit(commitMessage) {
|
|
10
|
+
import { confirm, spinner, cancel, isCancel } from '@clack/prompts';
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
import { gitCommand, gitErrorText, gitOutput } from './gitCommand.js';
|
|
13
|
+
export function performCommit(commitMessage) {
|
|
20
14
|
return __awaiter(this, void 0, void 0, function* () {
|
|
21
15
|
// Confirm commit
|
|
22
|
-
const shouldCommit = yield
|
|
16
|
+
const shouldCommit = yield confirm({
|
|
23
17
|
message: `Commit with message: "${commitMessage}"?`
|
|
24
18
|
});
|
|
25
|
-
if (
|
|
26
|
-
|
|
19
|
+
if (isCancel(shouldCommit) || !shouldCommit) {
|
|
20
|
+
cancel('Commit cancelled');
|
|
27
21
|
return false;
|
|
28
22
|
}
|
|
29
23
|
// Execute commit
|
|
30
|
-
const s =
|
|
24
|
+
const s = spinner();
|
|
31
25
|
s.start('Committing changes...');
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
(0, prompts_1.cancel)('Failed to commit changes. Please check your git status.');
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
// Verify commit was created
|
|
40
|
-
const lastCommit = (0, gitCommand_1.gitCommand)('log -1 --oneline');
|
|
41
|
-
if (!lastCommit) {
|
|
42
|
-
s.stop('⚠️ Commit status unclear');
|
|
43
|
-
console.log(chalk_1.default.yellow('Commit may not have been created. Please check git status manually.'));
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
s.stop('✅ Changes committed successfully!');
|
|
48
|
-
console.log(chalk_1.default.dim(`Last commit: ${lastCommit}`));
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
26
|
+
// The message is passed as a single argv entry — no shell, so `$(id)`,
|
|
27
|
+
// backticks and `!` reach git verbatim.
|
|
28
|
+
const result = gitCommand(['commit', '-m', commitMessage]);
|
|
29
|
+
if (!result.ok) {
|
|
53
30
|
s.stop('❌ Commit failed');
|
|
54
|
-
handleCommitError(
|
|
31
|
+
handleCommitError(result);
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
// Verify commit was created
|
|
35
|
+
const lastCommit = gitOutput(['log', '-1', '--oneline']);
|
|
36
|
+
if (!lastCommit) {
|
|
37
|
+
s.stop('⚠️ Commit status unclear');
|
|
38
|
+
console.log(chalk.yellow('Commit may not have been created. Please check git status manually.'));
|
|
55
39
|
return false;
|
|
56
40
|
}
|
|
41
|
+
s.stop('✅ Changes committed successfully!');
|
|
42
|
+
console.log(chalk.dim(`Last commit: ${lastCommit}`));
|
|
43
|
+
return true;
|
|
57
44
|
});
|
|
58
45
|
}
|
|
59
|
-
function
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
46
|
+
function handleCommitError(result) {
|
|
47
|
+
const details = gitErrorText(result);
|
|
48
|
+
// Always surface git's own output — pre-commit hook rejections and commitlint
|
|
49
|
+
// failures only ever explain themselves there.
|
|
50
|
+
console.log(chalk.red('\nGit reported:'));
|
|
51
|
+
console.log(chalk.dim(details));
|
|
52
|
+
if (/nothing to commit|no changes added to commit/i.test(details)) {
|
|
53
|
+
cancel('Nothing to commit - working tree clean');
|
|
54
|
+
}
|
|
55
|
+
else if (/Please tell me who you are/i.test(details)) {
|
|
56
|
+
cancel('Git user not configured. Run: git config --global user.email "you@example.com"');
|
|
68
57
|
}
|
|
69
|
-
else if (
|
|
70
|
-
|
|
58
|
+
else if (/not a git repository/i.test(details)) {
|
|
59
|
+
cancel('Not in a git repository');
|
|
71
60
|
}
|
|
72
|
-
else if (
|
|
73
|
-
|
|
61
|
+
else if (result.status === 1 && /hook|husky|commitlint/i.test(details)) {
|
|
62
|
+
cancel('A git hook rejected the commit (see output above)');
|
|
74
63
|
}
|
|
75
64
|
else {
|
|
76
|
-
|
|
65
|
+
cancel('Failed to commit changes (see output above)');
|
|
77
66
|
}
|
|
78
67
|
}
|
|
79
68
|
//# sourceMappingURL=performCommit.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performCommit.js","sourceRoot":"","sources":["../../src/utils/performCommit.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"performCommit.js","sourceRoot":"","sources":["../../src/utils/performCommit.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAa,MAAM,iBAAiB,CAAC;AAEjF,MAAM,UAAgB,aAAa,CAAC,aAAqB;;QACvD,iBAAiB;QACjB,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC;YACjC,OAAO,EAAE,yBAAyB,aAAa,IAAI;SACpD,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5C,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAC3B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,iBAAiB;QACjB,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QACpB,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAEjC,uEAAuE;QACvE,wCAAwC;QACxC,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;QAE3D,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC1B,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC1B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,4BAA4B;QAC5B,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,qEAAqE,CAAC,CAAC,CAAC;YACjG,OAAO,KAAK,CAAC;QACf,CAAC;QAED,CAAC,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,UAAU,EAAE,CAAC,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;CAAA;AAED,SAAS,iBAAiB,CAAC,MAAiB;IAC1C,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAErC,8EAA8E;IAC9E,+CAA+C;IAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAEhC,IAAI,+CAA+C,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAClE,MAAM,CAAC,wCAAwC,CAAC,CAAC;IACnD,CAAC;SAAM,IAAI,6BAA6B,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,MAAM,CAAC,gFAAgF,CAAC,CAAC;IAC3F,CAAC;SAAM,IAAI,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,MAAM,CAAC,yBAAyB,CAAC,CAAC;IACpC,CAAC;SAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACzE,MAAM,CAAC,mDAAmD,CAAC,CAAC;IAC9D,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,6CAA6C,CAAC,CAAC;IACxD,CAAC;AACH,CAAC"}
|
|
@@ -1,20 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
});
|
|
14
|
-
main().catch((error) => {
|
|
15
|
-
(0, prompts_1.cancel)('An unexpected error occurred');
|
|
1
|
+
import { cancel } from '@clack/prompts';
|
|
2
|
+
const SHOW_CURSOR = '\u001B[?25h';
|
|
3
|
+
/** clack hides the cursor while a prompt/spinner is active; bring it back. */
|
|
4
|
+
function restoreCursor() {
|
|
5
|
+
if (process.stdout.isTTY) {
|
|
6
|
+
process.stdout.write(SHOW_CURSOR);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
function exitWith(code, message, error) {
|
|
10
|
+
restoreCursor();
|
|
11
|
+
cancel(message);
|
|
12
|
+
if (error !== undefined) {
|
|
16
13
|
console.error(error instanceof Error ? error.stack || error.message : error);
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
}
|
|
15
|
+
process.exit(code);
|
|
16
|
+
}
|
|
17
|
+
export default function start(main) {
|
|
18
|
+
// 128 + signal number, so CI wrappers do not read Ctrl+C as success.
|
|
19
|
+
process.on('SIGINT', () => exitWith(130, 'Operation cancelled by user'));
|
|
20
|
+
process.on('SIGTERM', () => exitWith(143, 'Operation terminated'));
|
|
21
|
+
process.on('unhandledRejection', (reason) => exitWith(1, 'An unexpected error occurred (unhandled rejection)', reason));
|
|
22
|
+
process.on('uncaughtException', (error) => exitWith(1, 'An unexpected error occurred (uncaught exception)', error));
|
|
23
|
+
process.on('exit', restoreCursor);
|
|
24
|
+
main().catch((error) => exitWith(1, 'An unexpected error occurred', error));
|
|
19
25
|
}
|
|
20
26
|
//# sourceMappingURL=process_interruption.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process_interruption.js","sourceRoot":"","sources":["../../src/utils/process_interruption.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"process_interruption.js","sourceRoot":"","sources":["../../src/utils/process_interruption.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,MAAM,WAAW,GAAG,aAAa,CAAC;AAElC,8EAA8E;AAC9E,SAAS,aAAa;IACpB,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpC,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,OAAe,EAAE,KAAe;IAC9D,aAAa,EAAE,CAAC;IAChB,MAAM,CAAC,OAAO,CAAC,CAAC;IAChB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,IAAyB;IACrD,qEAAqE;IACrE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,6BAA6B,CAAC,CAAC,CAAC;IACzE,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAEnE,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAe,EAAE,EAAE,CACnD,QAAQ,CAAC,CAAC,EAAE,oDAAoD,EAAE,MAAM,CAAC,CAC1E,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAc,EAAE,EAAE,CACjD,QAAQ,CAAC,CAAC,EAAE,mDAAmD,EAAE,KAAK,CAAC,CACxE,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAElC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,8BAA8B,EAAE,KAAK,CAAC,CAAC,CAAC;AACvF,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
2
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
3
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -8,61 +7,72 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
8
|
});
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const prompts_1 = require("@clack/prompts");
|
|
17
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
18
|
-
const gitCommand_1 = require("./gitCommand");
|
|
19
|
-
function handlePushToRemote() {
|
|
10
|
+
import { confirm, spinner, isCancel } from '@clack/prompts';
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
import { gitCommand, gitErrorText, gitOutput } from './gitCommand.js';
|
|
13
|
+
const PROTECTED_BRANCHES = new Set(['main', 'master', 'production', 'release']);
|
|
14
|
+
export function handlePushToRemote() {
|
|
20
15
|
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
var _a;
|
|
17
|
+
const remotes = ((_a = gitOutput(['remote'])) !== null && _a !== void 0 ? _a : '').split('\n').filter(Boolean);
|
|
18
|
+
if (remotes.length === 0) {
|
|
19
|
+
console.log(chalk.yellow('⚠️ No remote repository configured. Skipping push.'));
|
|
25
20
|
return;
|
|
26
21
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
function executePush() {
|
|
31
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
-
const pushSpinner = (0, prompts_1.spinner)();
|
|
33
|
-
pushSpinner.start('Pushing to remote...');
|
|
34
|
-
// Check if remote exists
|
|
35
|
-
const remotes = (0, gitCommand_1.gitCommand)('remote');
|
|
36
|
-
if (!remotes) {
|
|
37
|
-
pushSpinner.stop('⚠️ No remote repository configured');
|
|
38
|
-
console.log(chalk_1.default.yellow('No remote repository found. Skipping push.'));
|
|
22
|
+
const branch = gitOutput(['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
23
|
+
if (!branch || branch === 'HEAD') {
|
|
24
|
+
console.log(chalk.yellow('⚠️ HEAD is detached — not pushing. Create a branch first.'));
|
|
39
25
|
return;
|
|
40
26
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
27
|
+
const upstream = gitOutput(['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}']);
|
|
28
|
+
const remote = upstream ? upstream.split('/')[0] : remotes.includes('origin') ? 'origin' : remotes[0];
|
|
29
|
+
const target = { branch, remote, upstream };
|
|
30
|
+
if (PROTECTED_BRANCHES.has(branch.toLowerCase())) {
|
|
31
|
+
console.log(chalk.yellow.bold(`\n⚠️ You are about to push directly to "${branch}".`));
|
|
32
|
+
}
|
|
33
|
+
if (!upstream) {
|
|
34
|
+
console.log(chalk.yellow(`ℹ️ "${branch}" has no upstream; it will be created as ${remote}/${branch}.`));
|
|
50
35
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
36
|
+
const shouldPush = yield confirm({
|
|
37
|
+
message: upstream
|
|
38
|
+
? `Push to ${upstream}?`
|
|
39
|
+
: `Push to ${remote}/${branch} and set it as upstream?`
|
|
40
|
+
});
|
|
41
|
+
if (isCancel(shouldPush) || !shouldPush) {
|
|
42
|
+
return;
|
|
55
43
|
}
|
|
44
|
+
executePush(target);
|
|
56
45
|
});
|
|
57
46
|
}
|
|
58
|
-
function
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
function executePush(target) {
|
|
48
|
+
const pushSpinner = spinner();
|
|
49
|
+
pushSpinner.start(`Pushing to ${target.remote}/${target.branch}...`);
|
|
50
|
+
const args = target.upstream
|
|
51
|
+
? ['push']
|
|
52
|
+
: ['push', '--set-upstream', target.remote, target.branch];
|
|
53
|
+
const result = gitCommand(args);
|
|
54
|
+
if (result.ok) {
|
|
55
|
+
pushSpinner.stop('🚀 Changes pushed successfully!');
|
|
56
|
+
const summary = gitErrorText(result);
|
|
57
|
+
if (summary) {
|
|
58
|
+
console.log(chalk.dim(summary));
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
pushSpinner.stop('❌ Push failed');
|
|
63
|
+
handlePushFailure(target, gitErrorText(result));
|
|
64
|
+
}
|
|
65
|
+
function handlePushFailure(target, details) {
|
|
66
|
+
console.log(chalk.red('\nGit reported:'));
|
|
67
|
+
console.log(chalk.dim(details));
|
|
68
|
+
if (/non-fast-forward|fetch first|behind its remote/i.test(details)) {
|
|
69
|
+
console.log(chalk.yellow(`Remote has commits you don't. Try: git pull --rebase ${target.remote} ${target.branch}`));
|
|
70
|
+
}
|
|
71
|
+
else if (/Authentication failed|could not read Username|Permission denied|403/i.test(details)) {
|
|
72
|
+
console.log(chalk.yellow('Authentication failed — check your credentials or SSH key.'));
|
|
63
73
|
}
|
|
64
|
-
else {
|
|
65
|
-
console.log(
|
|
74
|
+
else if (/protected branch|pre-receive hook declined/i.test(details)) {
|
|
75
|
+
console.log(chalk.yellow('The remote rejected the push (protected branch or server-side hook).'));
|
|
66
76
|
}
|
|
67
77
|
}
|
|
68
78
|
//# sourceMappingURL=push_to_remote.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push_to_remote.js","sourceRoot":"","sources":["../../src/utils/push_to_remote.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"push_to_remote.js","sourceRoot":"","sources":["../../src/utils/push_to_remote.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Absolute path of the repository root, or null when it cannot be resolved.
|
|
3
|
+
* Used so staging operates on the same (repo-root-relative) set of paths that
|
|
4
|
+
* the status display shows, no matter which subdirectory the tool was run from.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getRepoRoot(): string | null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { gitOutput } from './gitCommand.js';
|
|
2
|
+
/**
|
|
3
|
+
* Absolute path of the repository root, or null when it cannot be resolved.
|
|
4
|
+
* Used so staging operates on the same (repo-root-relative) set of paths that
|
|
5
|
+
* the status display shows, no matter which subdirectory the tool was run from.
|
|
6
|
+
*/
|
|
7
|
+
export function getRepoRoot() {
|
|
8
|
+
return gitOutput(['rev-parse', '--show-toplevel']);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=repoRoot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repoRoot.js","sourceRoot":"","sources":["../../src/utils/repoRoot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,SAAS,CAAC,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export interface FileChange {
|
|
2
|
+
/** Single-letter git status: A, M, D, R, C, T, U or `??` for untracked. */
|
|
2
3
|
status: string;
|
|
4
|
+
/** Repo-root-relative path. For renames/copies this is the destination. */
|
|
3
5
|
file: string;
|
|
6
|
+
/** Source path, present only for renames and copies. */
|
|
7
|
+
from?: string;
|
|
4
8
|
}
|
|
5
9
|
export interface GitChanges {
|
|
6
10
|
staged: FileChange[];
|
|
@@ -10,8 +14,14 @@ export interface GitChanges {
|
|
|
10
14
|
export interface GitStatus {
|
|
11
15
|
valid: boolean;
|
|
12
16
|
reason?: string;
|
|
17
|
+
/** Non-fatal problems worth shouting about (e.g. detached HEAD). */
|
|
18
|
+
warnings?: string[];
|
|
13
19
|
}
|
|
14
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Conventional Commits types only — anything outside this list is rejected by a
|
|
22
|
+
* standard commitlint `commit-msg` hook.
|
|
23
|
+
*/
|
|
24
|
+
export type CommitType = 'feat' | 'fix' | 'docs' | 'style' | 'refactor' | 'perf' | 'test' | 'build' | 'ci' | 'chore' | 'revert';
|
|
15
25
|
export interface CommitInfo {
|
|
16
26
|
type: CommitType;
|
|
17
27
|
scope?: string;
|