git-stack-cli 1.9.0 → 1.10.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/README.md +17 -17
- package/dist/cjs/index.cjs +3220 -486
- package/package.json +3 -1
- package/src/app/App.tsx +4 -1
- package/src/app/CherryPickCheck.tsx +3 -3
- package/src/app/DetectInitialPR.tsx +189 -0
- package/src/app/DirtyCheck.tsx +3 -3
- package/src/app/FormatText.tsx +1 -1
- package/src/app/GatherMetadata.tsx +2 -2
- package/src/app/LocalCommitStatus.tsx +2 -3
- package/src/app/ManualRebase.tsx +25 -16
- package/src/app/RebaseCheck.tsx +3 -3
- package/src/app/SelectCommitRanges.tsx +2 -2
- package/src/core/CommitMetadata.ts +1 -24
- package/src/core/GitReviseTodo.test.ts +29 -29
- package/src/core/GitReviseTodo.ts +75 -17
- package/src/core/gs_short_id.ts +5 -0
|
@@ -67,7 +67,7 @@ test("git-revise-todo handles double quotes in commit message", () => {
|
|
|
67
67
|
[
|
|
68
68
|
//force line break
|
|
69
69
|
"++ pick f143d03c723c",
|
|
70
|
-
'[new] invalid
|
|
70
|
+
'[new] invalid \\"by me\\" quotes',
|
|
71
71
|
"",
|
|
72
72
|
"git-stack-id: 6Ak-qn+5Z",
|
|
73
73
|
'git-stack-title: [new] invalid \\"by me\\" quotes',
|
|
@@ -115,7 +115,7 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
115
115
|
full_message: "banana color\n\ngit-stack-id: AAWsYx1UU",
|
|
116
116
|
subject_line: "banana color",
|
|
117
117
|
branch_id: "AAWsYx1UU",
|
|
118
|
-
title:
|
|
118
|
+
title: "banana",
|
|
119
119
|
},
|
|
120
120
|
],
|
|
121
121
|
},
|
|
@@ -186,28 +186,28 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
186
186
|
full_message: "lemon color\n\ngit-stack-id: E63ytp5dj",
|
|
187
187
|
subject_line: "lemon color",
|
|
188
188
|
branch_id: "E63ytp5dj",
|
|
189
|
-
title:
|
|
189
|
+
title: "lemon color",
|
|
190
190
|
},
|
|
191
191
|
{
|
|
192
192
|
sha: "d36d63499425bb46a1e62c2c9df1a4332b13004f",
|
|
193
193
|
full_message: "cantaloupe color\n\ngit-stack-id: E63ytp5dj",
|
|
194
194
|
subject_line: "cantaloupe color",
|
|
195
195
|
branch_id: "E63ytp5dj",
|
|
196
|
-
title:
|
|
196
|
+
title: "lemon color",
|
|
197
197
|
},
|
|
198
198
|
{
|
|
199
199
|
sha: "4f98dd3e67d03b79d7a12480c7d1c2fcbd186ac5",
|
|
200
200
|
full_message: "banana sweet\n\ngit-stack-id: E63ytp5dj",
|
|
201
201
|
subject_line: "banana sweet",
|
|
202
202
|
branch_id: "E63ytp5dj",
|
|
203
|
-
title:
|
|
203
|
+
title: "lemon color",
|
|
204
204
|
},
|
|
205
205
|
{
|
|
206
206
|
sha: "f143d03c723c9f5231a81c1e12098511611898cb",
|
|
207
207
|
full_message: "apple sweet",
|
|
208
208
|
subject_line: "apple sweet",
|
|
209
|
-
branch_id:
|
|
210
|
-
title:
|
|
209
|
+
branch_id: "E63ytp5dj",
|
|
210
|
+
title: "lemon color",
|
|
211
211
|
},
|
|
212
212
|
],
|
|
213
213
|
},
|
|
@@ -218,35 +218,35 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
218
218
|
full_message: "banana color\n\ngit-stack-id: AAWsYx1UU",
|
|
219
219
|
subject_line: "banana color",
|
|
220
220
|
branch_id: "AAWsYx1UU",
|
|
221
|
-
title:
|
|
221
|
+
title: "banana",
|
|
222
222
|
},
|
|
223
223
|
{
|
|
224
224
|
sha: "3cb22661ecff6c872e96ce9c40b31c824938cab7",
|
|
225
225
|
full_message: "lemon color\n\ngit-stack-id: E63ytp5dj",
|
|
226
226
|
subject_line: "lemon color",
|
|
227
227
|
branch_id: "E63ytp5dj",
|
|
228
|
-
title:
|
|
228
|
+
title: "lemon color",
|
|
229
229
|
},
|
|
230
230
|
{
|
|
231
231
|
sha: "d36d63499425bb46a1e62c2c9df1a4332b13004f",
|
|
232
232
|
full_message: "cantaloupe color\n\ngit-stack-id: E63ytp5dj",
|
|
233
233
|
subject_line: "cantaloupe color",
|
|
234
234
|
branch_id: "E63ytp5dj",
|
|
235
|
-
title:
|
|
235
|
+
title: "lemon color",
|
|
236
236
|
},
|
|
237
237
|
{
|
|
238
238
|
sha: "4f98dd3e67d03b79d7a12480c7d1c2fcbd186ac5",
|
|
239
239
|
full_message: "banana sweet\n\ngit-stack-id: E63ytp5dj",
|
|
240
240
|
subject_line: "banana sweet",
|
|
241
241
|
branch_id: "E63ytp5dj",
|
|
242
|
-
title:
|
|
242
|
+
title: "lemon color",
|
|
243
243
|
},
|
|
244
244
|
{
|
|
245
245
|
sha: "f143d03c723c9f5231a81c1e12098511611898cb",
|
|
246
246
|
full_message: "apple sweet",
|
|
247
247
|
subject_line: "apple sweet",
|
|
248
|
-
branch_id:
|
|
249
|
-
title:
|
|
248
|
+
branch_id: "6Ak-qn+5Z",
|
|
249
|
+
title: "new group",
|
|
250
250
|
},
|
|
251
251
|
],
|
|
252
252
|
pr_lookup: {
|
|
@@ -376,7 +376,7 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
376
376
|
full_message: "banana color\n\ngit-stack-id: AAWsYx1UU",
|
|
377
377
|
subject_line: "banana color",
|
|
378
378
|
branch_id: "AAWsYx1UU",
|
|
379
|
-
title:
|
|
379
|
+
title: "banana",
|
|
380
380
|
},
|
|
381
381
|
],
|
|
382
382
|
},
|
|
@@ -447,21 +447,21 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
447
447
|
full_message: "lemon color\n\ngit-stack-id: E63ytp5dj",
|
|
448
448
|
subject_line: "lemon color",
|
|
449
449
|
branch_id: "E63ytp5dj",
|
|
450
|
-
title:
|
|
450
|
+
title: "lemon color",
|
|
451
451
|
},
|
|
452
452
|
{
|
|
453
453
|
sha: "d36d63499425bb46a1e62c2c9df1a4332b13004f",
|
|
454
454
|
full_message: "cantaloupe color\n\ngit-stack-id: E63ytp5dj",
|
|
455
455
|
subject_line: "cantaloupe color",
|
|
456
456
|
branch_id: "E63ytp5dj",
|
|
457
|
-
title:
|
|
457
|
+
title: "lemon color",
|
|
458
458
|
},
|
|
459
459
|
{
|
|
460
460
|
sha: "4f98dd3e67d03b79d7a12480c7d1c2fcbd186ac5",
|
|
461
461
|
full_message: "banana sweet\n\ngit-stack-id: E63ytp5dj",
|
|
462
462
|
subject_line: "banana sweet",
|
|
463
463
|
branch_id: "E63ytp5dj",
|
|
464
|
-
title:
|
|
464
|
+
title: "lemon color",
|
|
465
465
|
},
|
|
466
466
|
],
|
|
467
467
|
},
|
|
@@ -476,8 +476,8 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
476
476
|
sha: "f143d03c723c9f5231a81c1e12098511611898cb",
|
|
477
477
|
full_message: "apple sweet",
|
|
478
478
|
subject_line: "apple sweet",
|
|
479
|
-
branch_id:
|
|
480
|
-
title:
|
|
479
|
+
branch_id: "6Ak-qn+5Z",
|
|
480
|
+
title: "new group",
|
|
481
481
|
},
|
|
482
482
|
],
|
|
483
483
|
},
|
|
@@ -488,35 +488,35 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
488
488
|
full_message: "banana color\n\ngit-stack-id: AAWsYx1UU",
|
|
489
489
|
subject_line: "banana color",
|
|
490
490
|
branch_id: "AAWsYx1UU",
|
|
491
|
-
title:
|
|
491
|
+
title: "banana",
|
|
492
492
|
},
|
|
493
493
|
{
|
|
494
494
|
sha: "3cb22661ecff6c872e96ce9c40b31c824938cab7",
|
|
495
495
|
full_message: "lemon color\n\ngit-stack-id: E63ytp5dj",
|
|
496
496
|
subject_line: "lemon color",
|
|
497
497
|
branch_id: "E63ytp5dj",
|
|
498
|
-
title:
|
|
498
|
+
title: "lemon color",
|
|
499
499
|
},
|
|
500
500
|
{
|
|
501
501
|
sha: "d36d63499425bb46a1e62c2c9df1a4332b13004f",
|
|
502
502
|
full_message: "cantaloupe color\n\ngit-stack-id: E63ytp5dj",
|
|
503
503
|
subject_line: "cantaloupe color",
|
|
504
504
|
branch_id: "E63ytp5dj",
|
|
505
|
-
title:
|
|
505
|
+
title: "lemon color",
|
|
506
506
|
},
|
|
507
507
|
{
|
|
508
508
|
sha: "4f98dd3e67d03b79d7a12480c7d1c2fcbd186ac5",
|
|
509
509
|
full_message: "banana sweet\n\ngit-stack-id: E63ytp5dj",
|
|
510
510
|
subject_line: "banana sweet",
|
|
511
511
|
branch_id: "E63ytp5dj",
|
|
512
|
-
title:
|
|
512
|
+
title: "lemon color",
|
|
513
513
|
},
|
|
514
514
|
{
|
|
515
515
|
sha: "f143d03c723c9f5231a81c1e12098511611898cb",
|
|
516
516
|
full_message: "apple sweet",
|
|
517
517
|
subject_line: "apple sweet",
|
|
518
|
-
branch_id:
|
|
519
|
-
title:
|
|
518
|
+
branch_id: "6Ak-qn+5Z",
|
|
519
|
+
title: "new group",
|
|
520
520
|
},
|
|
521
521
|
],
|
|
522
522
|
pr_lookup: {
|
|
@@ -620,8 +620,8 @@ const COMMIT_MESSAGE_WITH_QUOTES: CommitMetadata.CommitRange = {
|
|
|
620
620
|
sha: "f143d03c723c9f5231a81c1e12098511611898cb",
|
|
621
621
|
full_message: '[new] invalid "by me" quotes',
|
|
622
622
|
subject_line: '[new] invalid "by me" quotes',
|
|
623
|
-
branch_id:
|
|
624
|
-
title:
|
|
623
|
+
branch_id: "6Ak-qn+5Z",
|
|
624
|
+
title: '[new] invalid "by me" quotes',
|
|
625
625
|
},
|
|
626
626
|
],
|
|
627
627
|
},
|
|
@@ -631,8 +631,8 @@ const COMMIT_MESSAGE_WITH_QUOTES: CommitMetadata.CommitRange = {
|
|
|
631
631
|
sha: "f143d03c723c9f5231a81c1e12098511611898cb",
|
|
632
632
|
full_message: '[new] invalid "by me" quotes',
|
|
633
633
|
subject_line: '[new] invalid "by me" quotes',
|
|
634
|
-
branch_id:
|
|
635
|
-
title:
|
|
634
|
+
branch_id: "6Ak-qn+5Z",
|
|
635
|
+
title: '[new] invalid "by me" quotes',
|
|
636
636
|
},
|
|
637
637
|
],
|
|
638
638
|
pr_lookup: {},
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
1
5
|
import * as Metadata from "~/core/Metadata";
|
|
6
|
+
import { cli } from "~/core/cli";
|
|
7
|
+
import { invariant } from "~/core/invariant";
|
|
2
8
|
|
|
3
9
|
import type * as CommitMetadata from "~/core/CommitMetadata";
|
|
4
10
|
|
|
@@ -47,7 +53,7 @@ import type * as CommitMetadata from "~/core/CommitMetadata";
|
|
|
47
53
|
// apple sweet
|
|
48
54
|
//
|
|
49
55
|
export function GitReviseTodo(args: Args): string {
|
|
50
|
-
const
|
|
56
|
+
const commit_list = [];
|
|
51
57
|
|
|
52
58
|
const group_list = args.commit_range.group_list;
|
|
53
59
|
|
|
@@ -55,31 +61,83 @@ export function GitReviseTodo(args: Args): string {
|
|
|
55
61
|
const group = group_list[i];
|
|
56
62
|
|
|
57
63
|
for (const commit of group.commits) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
commit_list.push(commit);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const todo = GitReviseTodo.todo({ commit_list });
|
|
69
|
+
return todo;
|
|
70
|
+
}
|
|
64
71
|
|
|
65
|
-
|
|
72
|
+
type CommitListArgs = {
|
|
73
|
+
commit_list: CommitMetadata.CommitRange["commit_list"];
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
GitReviseTodo.todo = function todo(args: CommitListArgs) {
|
|
77
|
+
const entry_list = [];
|
|
66
78
|
|
|
67
|
-
|
|
79
|
+
for (const commit of args.commit_list) {
|
|
80
|
+
// update git commit message with stack id
|
|
81
|
+
const id = commit.branch_id;
|
|
82
|
+
const title = commit.title;
|
|
68
83
|
|
|
69
|
-
|
|
70
|
-
|
|
84
|
+
invariant(id, "commit.branch_id must exist");
|
|
85
|
+
invariant(title, "commit.title must exist");
|
|
71
86
|
|
|
72
|
-
|
|
73
|
-
const entry_lines = [`++ pick ${sha}`, message_with_id];
|
|
74
|
-
const entry = entry_lines.join("\n");
|
|
87
|
+
const metadata = { id, title };
|
|
75
88
|
|
|
76
|
-
|
|
77
|
-
|
|
89
|
+
const unsafe_message_with_id = Metadata.write(
|
|
90
|
+
commit.full_message,
|
|
91
|
+
metadata
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
let message_with_id = unsafe_message_with_id;
|
|
95
|
+
|
|
96
|
+
message_with_id = message_with_id.replace(/[^\\]"/g, '\\"');
|
|
97
|
+
|
|
98
|
+
// get first 12 characters of commit sha
|
|
99
|
+
const sha = commit.sha.slice(0, 12);
|
|
100
|
+
|
|
101
|
+
// generate git revise entry
|
|
102
|
+
const entry_lines = [`++ pick ${sha}`, message_with_id];
|
|
103
|
+
const entry = entry_lines.join("\n");
|
|
104
|
+
|
|
105
|
+
entry_list.push(entry);
|
|
78
106
|
}
|
|
79
107
|
|
|
80
108
|
const todo = entry_list.join("\n\n");
|
|
81
109
|
return todo;
|
|
82
|
-
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
GitReviseTodo.execute = async function grt_execute(args: ExecuteArgs) {
|
|
113
|
+
// generate temporary directory and drop sequence editor script
|
|
114
|
+
const tmp_git_sequence_editor_path = path.join(
|
|
115
|
+
os.tmpdir(),
|
|
116
|
+
"git-sequence-editor.sh"
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
// ensure script is executable
|
|
120
|
+
fs.chmodSync(tmp_git_sequence_editor_path, "755");
|
|
121
|
+
|
|
122
|
+
const git_revise_todo = GitReviseTodo(args);
|
|
123
|
+
|
|
124
|
+
// execute cli with temporary git sequence editor script
|
|
125
|
+
// revise from merge base to pick correct commits
|
|
126
|
+
const command = [
|
|
127
|
+
`GIT_EDITOR="${tmp_git_sequence_editor_path}"`,
|
|
128
|
+
`GIT_REVISE_TODO="${git_revise_todo}"`,
|
|
129
|
+
`git`,
|
|
130
|
+
`revise --edit -i ${args.rebase_merge_base}`,
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
await cli(command, { stdio: ["ignore", "ignore", "ignore"] });
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
type ExecuteArgs = {
|
|
137
|
+
rebase_group_index: number;
|
|
138
|
+
rebase_merge_base: string;
|
|
139
|
+
commit_range: CommitMetadata.CommitRange;
|
|
140
|
+
};
|
|
83
141
|
|
|
84
142
|
type Args = {
|
|
85
143
|
rebase_group_index: number;
|