git-stack-cli 2.7.8 → 2.8.1
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/dist/js/index.js +76 -76
- package/package.json +1 -1
- package/scripts/bun-build.ts +3 -2
- package/scripts/release-npm.ts +6 -4
- package/src/app/ManualRebase.tsx +69 -14
- package/src/app/MultiSelect.tsx +19 -0
- package/src/app/SelectCommitRanges.tsx +63 -8
- package/src/app/SyncGithub.tsx +100 -48
- package/src/core/CommitMetadata.ts +71 -13
- package/src/core/GitReviseTodo.test.ts +46 -0
- package/src/core/GitReviseTodo.ts +6 -1
- package/src/core/Metadata.test.ts +51 -0
- package/src/core/Metadata.ts +24 -1
- package/src/core/__snapshots__/git.test.ts.snap +4 -0
- package/src/core/git.ts +15 -1
- package/src/core/github.tsx +21 -4
|
@@ -14,10 +14,16 @@ type CommitGroup = {
|
|
|
14
14
|
base: null | string;
|
|
15
15
|
dirty: boolean;
|
|
16
16
|
commits: Array<git.Commit>;
|
|
17
|
+
master_base: boolean;
|
|
17
18
|
};
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
type CommitRangeGroup = {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
master_base: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type CommitGroupMap = { [sha: string]: CommitRangeGroup };
|
|
21
27
|
|
|
22
28
|
export async function range(commit_group_map?: CommitGroupMap) {
|
|
23
29
|
// gather all open prs in repo first
|
|
@@ -25,6 +31,7 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
25
31
|
await github.pr_list();
|
|
26
32
|
|
|
27
33
|
const master_branch = Store.getState().master_branch;
|
|
34
|
+
const master_branch_name = master_branch.replace(/^origin\//, "");
|
|
28
35
|
const commit_list = await git.get_commits(`${master_branch}..HEAD`);
|
|
29
36
|
|
|
30
37
|
const pr_lookup: Record<string, void | PullRequest> = {};
|
|
@@ -37,6 +44,7 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
37
44
|
for (const commit of commit_list) {
|
|
38
45
|
let id = commit.branch_id;
|
|
39
46
|
let title = commit.title || id;
|
|
47
|
+
let master_base = commit.master_base;
|
|
40
48
|
|
|
41
49
|
// console.debug({ commit, id });
|
|
42
50
|
|
|
@@ -47,6 +55,7 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
47
55
|
if (group) {
|
|
48
56
|
id = group.id;
|
|
49
57
|
title = group.title;
|
|
58
|
+
master_base = group.master_base;
|
|
50
59
|
}
|
|
51
60
|
}
|
|
52
61
|
|
|
@@ -75,6 +84,7 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
75
84
|
const group = group_map.get(id) || {
|
|
76
85
|
id,
|
|
77
86
|
title,
|
|
87
|
+
master_base,
|
|
78
88
|
pr: null,
|
|
79
89
|
base: null,
|
|
80
90
|
dirty: false,
|
|
@@ -111,6 +121,7 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
111
121
|
|
|
112
122
|
for (let i = 0; i < group_value_list.length; i++) {
|
|
113
123
|
const group = group_value_list[i];
|
|
124
|
+
const previous_group: undefined | CommitGroup = group_value_list[i - 1];
|
|
114
125
|
|
|
115
126
|
if (group.id !== UNASSIGNED) {
|
|
116
127
|
let pr_result = pr_lookup[group.id];
|
|
@@ -130,17 +141,20 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
130
141
|
}
|
|
131
142
|
|
|
132
143
|
if (i === 0) {
|
|
133
|
-
const master_branch_name = master_branch.replace(/^origin\//, "");
|
|
134
144
|
group.base = master_branch_name;
|
|
135
145
|
} else {
|
|
136
146
|
const last_group = group_value_list[i - 1];
|
|
137
147
|
// console.debug(" ", "last_group", last_group.pr?.title.substring(0, 40));
|
|
138
148
|
// console.debug(" ", "last_group.id", last_group.id);
|
|
139
149
|
|
|
140
|
-
|
|
141
|
-
|
|
150
|
+
if (group.master_base) {
|
|
151
|
+
// explicitly set base to master when master_base is true
|
|
152
|
+
group.base = master_branch_name;
|
|
153
|
+
} else if (group.id === UNASSIGNED) {
|
|
154
|
+
// null out base when unassigned and after unassigned
|
|
142
155
|
group.base = null;
|
|
143
156
|
} else if (last_group.base === null) {
|
|
157
|
+
// null out base when last group base is null
|
|
144
158
|
group.base = null;
|
|
145
159
|
} else {
|
|
146
160
|
group.base = last_group.id;
|
|
@@ -151,17 +165,61 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
151
165
|
|
|
152
166
|
if (!group.pr) {
|
|
153
167
|
group.dirty = true;
|
|
154
|
-
} else if (group.pr.commits.length !== group.commits.length) {
|
|
155
|
-
group.dirty = true;
|
|
156
|
-
} else if (group.pr.baseRefName !== group.base) {
|
|
157
|
-
group.dirty = true;
|
|
158
168
|
} else {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
169
|
+
if (group.pr.baseRefName !== group.base) {
|
|
170
|
+
group.dirty = true;
|
|
171
|
+
} else if (group.master_base && i > 0) {
|
|
172
|
+
// special case
|
|
173
|
+
// master_base groups cannot be compared by commit sha
|
|
174
|
+
// instead compare the literal diff local against origin
|
|
175
|
+
// gh pr diff --color=never 110
|
|
176
|
+
// git --no-pager diff --color=never 00c8fe0~1..00c8fe0
|
|
177
|
+
const diff_github = await github.pr_diff(group.pr.number);
|
|
178
|
+
const diff_local = await git.get_diff(group.commits);
|
|
179
|
+
if (diff_github !== diff_local) {
|
|
180
|
+
group.dirty = true;
|
|
181
|
+
}
|
|
182
|
+
} else if (!group.master_base && previous_group && previous_group.master_base) {
|
|
183
|
+
// special case
|
|
184
|
+
// boundary between normal commits and master commits
|
|
185
|
+
|
|
186
|
+
// collect all previous groups for sha comparison
|
|
187
|
+
const all_commits: Array<git.Commit> = [];
|
|
188
|
+
const previous_groups = group_value_list.slice(0, i);
|
|
189
|
+
for (const g of previous_groups) {
|
|
190
|
+
for (const c of g.commits) {
|
|
191
|
+
all_commits.push(c);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
for (const c of group.commits) {
|
|
195
|
+
all_commits.push(c);
|
|
196
|
+
}
|
|
162
197
|
|
|
163
|
-
|
|
198
|
+
// compare all commits against pr commits
|
|
199
|
+
if (group.pr.commits.length !== all_commits.length) {
|
|
164
200
|
group.dirty = true;
|
|
201
|
+
} else {
|
|
202
|
+
for (let i = 0; i < group.pr.commits.length; i++) {
|
|
203
|
+
const pr_commit = group.pr.commits[i];
|
|
204
|
+
const local_commit = all_commits[i];
|
|
205
|
+
|
|
206
|
+
if (pr_commit.oid !== local_commit.sha) {
|
|
207
|
+
group.dirty = true;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
} else if (group.pr.commits.length !== group.commits.length) {
|
|
212
|
+
group.dirty = true;
|
|
213
|
+
} else {
|
|
214
|
+
// if we still haven't marked this dirty, check each commit
|
|
215
|
+
// comapre literal commit shas in group
|
|
216
|
+
for (let i = 0; i < group.pr.commits.length; i++) {
|
|
217
|
+
const pr_commit = group.pr.commits[i];
|
|
218
|
+
const local_commit = group.commits[i];
|
|
219
|
+
|
|
220
|
+
if (pr_commit.oid !== local_commit.sha) {
|
|
221
|
+
group.dirty = true;
|
|
222
|
+
}
|
|
165
223
|
}
|
|
166
224
|
}
|
|
167
225
|
}
|
|
@@ -171,8 +171,10 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
171
171
|
subject_line: "banana color",
|
|
172
172
|
branch_id: "AAWsYx1UU",
|
|
173
173
|
title: "banana",
|
|
174
|
+
master_base: false,
|
|
174
175
|
},
|
|
175
176
|
],
|
|
177
|
+
master_base: false,
|
|
176
178
|
},
|
|
177
179
|
{
|
|
178
180
|
id: "E63ytp5dj",
|
|
@@ -244,6 +246,7 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
244
246
|
subject_line: "lemon color",
|
|
245
247
|
branch_id: "E63ytp5dj",
|
|
246
248
|
title: "lemon color",
|
|
249
|
+
master_base: false,
|
|
247
250
|
},
|
|
248
251
|
{
|
|
249
252
|
sha: "d36d63499425bb46a1e62c2c9df1a4332b13004f",
|
|
@@ -251,6 +254,7 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
251
254
|
subject_line: "cantaloupe color",
|
|
252
255
|
branch_id: "E63ytp5dj",
|
|
253
256
|
title: "lemon color",
|
|
257
|
+
master_base: false,
|
|
254
258
|
},
|
|
255
259
|
{
|
|
256
260
|
sha: "4f98dd3e67d03b79d7a12480c7d1c2fcbd186ac5",
|
|
@@ -258,6 +262,7 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
258
262
|
subject_line: "banana sweet",
|
|
259
263
|
branch_id: "E63ytp5dj",
|
|
260
264
|
title: "lemon color",
|
|
265
|
+
master_base: false,
|
|
261
266
|
},
|
|
262
267
|
{
|
|
263
268
|
sha: "f143d03c723c9f5231a81c1e12098511611898cb",
|
|
@@ -265,8 +270,10 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
265
270
|
subject_line: "apple sweet",
|
|
266
271
|
branch_id: "E63ytp5dj",
|
|
267
272
|
title: "lemon color",
|
|
273
|
+
master_base: false,
|
|
268
274
|
},
|
|
269
275
|
],
|
|
276
|
+
master_base: false,
|
|
270
277
|
},
|
|
271
278
|
],
|
|
272
279
|
commit_list: [
|
|
@@ -276,6 +283,7 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
276
283
|
subject_line: "banana color",
|
|
277
284
|
branch_id: "AAWsYx1UU",
|
|
278
285
|
title: "banana",
|
|
286
|
+
master_base: false,
|
|
279
287
|
},
|
|
280
288
|
{
|
|
281
289
|
sha: "3cb22661ecff6c872e96ce9c40b31c824938cab7",
|
|
@@ -283,6 +291,7 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
283
291
|
subject_line: "lemon color",
|
|
284
292
|
branch_id: "E63ytp5dj",
|
|
285
293
|
title: "lemon color",
|
|
294
|
+
master_base: false,
|
|
286
295
|
},
|
|
287
296
|
{
|
|
288
297
|
sha: "d36d63499425bb46a1e62c2c9df1a4332b13004f",
|
|
@@ -290,6 +299,7 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
290
299
|
subject_line: "cantaloupe color",
|
|
291
300
|
branch_id: "E63ytp5dj",
|
|
292
301
|
title: "lemon color",
|
|
302
|
+
master_base: false,
|
|
293
303
|
},
|
|
294
304
|
{
|
|
295
305
|
sha: "4f98dd3e67d03b79d7a12480c7d1c2fcbd186ac5",
|
|
@@ -297,6 +307,7 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
297
307
|
subject_line: "banana sweet",
|
|
298
308
|
branch_id: "E63ytp5dj",
|
|
299
309
|
title: "lemon color",
|
|
310
|
+
master_base: false,
|
|
300
311
|
},
|
|
301
312
|
{
|
|
302
313
|
sha: "f143d03c723c9f5231a81c1e12098511611898cb",
|
|
@@ -304,6 +315,7 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
304
315
|
subject_line: "apple sweet",
|
|
305
316
|
branch_id: "6Ak-qn+5Z",
|
|
306
317
|
title: "new group",
|
|
318
|
+
master_base: false,
|
|
307
319
|
},
|
|
308
320
|
],
|
|
309
321
|
pr_lookup: {
|
|
@@ -440,8 +452,10 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
440
452
|
subject_line: "banana color",
|
|
441
453
|
branch_id: "AAWsYx1UU",
|
|
442
454
|
title: "banana",
|
|
455
|
+
master_base: false,
|
|
443
456
|
},
|
|
444
457
|
],
|
|
458
|
+
master_base: false,
|
|
445
459
|
},
|
|
446
460
|
{
|
|
447
461
|
id: "E63ytp5dj",
|
|
@@ -513,6 +527,7 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
513
527
|
subject_line: "lemon color",
|
|
514
528
|
branch_id: "E63ytp5dj",
|
|
515
529
|
title: "lemon color",
|
|
530
|
+
master_base: false,
|
|
516
531
|
},
|
|
517
532
|
{
|
|
518
533
|
sha: "d36d63499425bb46a1e62c2c9df1a4332b13004f",
|
|
@@ -520,6 +535,7 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
520
535
|
subject_line: "cantaloupe color",
|
|
521
536
|
branch_id: "E63ytp5dj",
|
|
522
537
|
title: "lemon color",
|
|
538
|
+
master_base: false,
|
|
523
539
|
},
|
|
524
540
|
{
|
|
525
541
|
sha: "4f98dd3e67d03b79d7a12480c7d1c2fcbd186ac5",
|
|
@@ -527,8 +543,10 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
527
543
|
subject_line: "banana sweet",
|
|
528
544
|
branch_id: "E63ytp5dj",
|
|
529
545
|
title: "lemon color",
|
|
546
|
+
master_base: false,
|
|
530
547
|
},
|
|
531
548
|
],
|
|
549
|
+
master_base: false,
|
|
532
550
|
},
|
|
533
551
|
{
|
|
534
552
|
id: "6Ak-qn+5Z",
|
|
@@ -543,8 +561,10 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
543
561
|
subject_line: "apple sweet",
|
|
544
562
|
branch_id: "6Ak-qn+5Z",
|
|
545
563
|
title: "new group",
|
|
564
|
+
master_base: false,
|
|
546
565
|
},
|
|
547
566
|
],
|
|
567
|
+
master_base: false,
|
|
548
568
|
},
|
|
549
569
|
],
|
|
550
570
|
commit_list: [
|
|
@@ -554,6 +574,7 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
554
574
|
subject_line: "banana color",
|
|
555
575
|
branch_id: "AAWsYx1UU",
|
|
556
576
|
title: "banana",
|
|
577
|
+
master_base: false,
|
|
557
578
|
},
|
|
558
579
|
{
|
|
559
580
|
sha: "3cb22661ecff6c872e96ce9c40b31c824938cab7",
|
|
@@ -561,6 +582,7 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
561
582
|
subject_line: "lemon color",
|
|
562
583
|
branch_id: "E63ytp5dj",
|
|
563
584
|
title: "lemon color",
|
|
585
|
+
master_base: false,
|
|
564
586
|
},
|
|
565
587
|
{
|
|
566
588
|
sha: "d36d63499425bb46a1e62c2c9df1a4332b13004f",
|
|
@@ -568,6 +590,7 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
568
590
|
subject_line: "cantaloupe color",
|
|
569
591
|
branch_id: "E63ytp5dj",
|
|
570
592
|
title: "lemon color",
|
|
593
|
+
master_base: false,
|
|
571
594
|
},
|
|
572
595
|
{
|
|
573
596
|
sha: "4f98dd3e67d03b79d7a12480c7d1c2fcbd186ac5",
|
|
@@ -575,6 +598,7 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
575
598
|
subject_line: "banana sweet",
|
|
576
599
|
branch_id: "E63ytp5dj",
|
|
577
600
|
title: "lemon color",
|
|
601
|
+
master_base: false,
|
|
578
602
|
},
|
|
579
603
|
{
|
|
580
604
|
sha: "f143d03c723c9f5231a81c1e12098511611898cb",
|
|
@@ -582,6 +606,7 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
582
606
|
subject_line: "apple sweet",
|
|
583
607
|
branch_id: "6Ak-qn+5Z",
|
|
584
608
|
title: "new group",
|
|
609
|
+
master_base: false,
|
|
585
610
|
},
|
|
586
611
|
],
|
|
587
612
|
pr_lookup: {
|
|
@@ -691,8 +716,10 @@ const COMMIT_MESSAGE_WITH_QUOTES: CommitMetadata.CommitRange = {
|
|
|
691
716
|
subject_line: '[new] invalid "by me" quotes',
|
|
692
717
|
branch_id: "6Ak-qn+5Z",
|
|
693
718
|
title: '[new] invalid "by me" quotes',
|
|
719
|
+
master_base: false,
|
|
694
720
|
},
|
|
695
721
|
],
|
|
722
|
+
master_base: false,
|
|
696
723
|
},
|
|
697
724
|
],
|
|
698
725
|
commit_list: [
|
|
@@ -702,6 +729,7 @@ const COMMIT_MESSAGE_WITH_QUOTES: CommitMetadata.CommitRange = {
|
|
|
702
729
|
subject_line: '[new] invalid "by me" quotes',
|
|
703
730
|
branch_id: "6Ak-qn+5Z",
|
|
704
731
|
title: '[new] invalid "by me" quotes',
|
|
732
|
+
master_base: false,
|
|
705
733
|
},
|
|
706
734
|
],
|
|
707
735
|
pr_lookup: {},
|
|
@@ -726,6 +754,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
726
754
|
subject_line: "head~7",
|
|
727
755
|
branch_id: "gs---4gvxa-5v-2mx26",
|
|
728
756
|
title: "pr-title",
|
|
757
|
+
master_base: false,
|
|
729
758
|
},
|
|
730
759
|
{
|
|
731
760
|
sha: "391476bbfc6b77b60a3ef7fa97155496a9f8f27f",
|
|
@@ -733,6 +762,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
733
762
|
subject_line: "head~6",
|
|
734
763
|
branch_id: "gs---4gvxa-5v-2mx26",
|
|
735
764
|
title: "pr-title",
|
|
765
|
+
master_base: false,
|
|
736
766
|
},
|
|
737
767
|
{
|
|
738
768
|
sha: "5a98cf8f0406712405d41af07c3a012f72ad36fa",
|
|
@@ -740,6 +770,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
740
770
|
subject_line: "head~5",
|
|
741
771
|
branch_id: "gs---4gvxa-5v-2mx26",
|
|
742
772
|
title: "pr-title",
|
|
773
|
+
master_base: false,
|
|
743
774
|
},
|
|
744
775
|
{
|
|
745
776
|
sha: "e820018cb370bb6cda118dc649e841c75d797188",
|
|
@@ -747,6 +778,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
747
778
|
subject_line: "head~4",
|
|
748
779
|
branch_id: "gs---4gvxa-5v-2mx26",
|
|
749
780
|
title: "pr-title",
|
|
781
|
+
master_base: false,
|
|
750
782
|
},
|
|
751
783
|
{
|
|
752
784
|
sha: "e6d1dfc7ec007468712bfc015884cc22bfa79e1d",
|
|
@@ -754,6 +786,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
754
786
|
subject_line: "head~3",
|
|
755
787
|
branch_id: "gs---4gvxa-5v-2mx26",
|
|
756
788
|
title: "pr-title",
|
|
789
|
+
master_base: false,
|
|
757
790
|
},
|
|
758
791
|
{
|
|
759
792
|
sha: "a26f21025a558968554c439ab9b942d5fe84bccb",
|
|
@@ -761,8 +794,10 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
761
794
|
subject_line: "head~2",
|
|
762
795
|
branch_id: "gs---4gvxa-5v-2mx26",
|
|
763
796
|
title: "pr-title",
|
|
797
|
+
master_base: false,
|
|
764
798
|
},
|
|
765
799
|
],
|
|
800
|
+
master_base: false,
|
|
766
801
|
},
|
|
767
802
|
{
|
|
768
803
|
id: "unassigned",
|
|
@@ -777,6 +812,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
777
812
|
subject_line: "head~1",
|
|
778
813
|
branch_id: "unassigned",
|
|
779
814
|
title: "allow_unassigned",
|
|
815
|
+
master_base: false,
|
|
780
816
|
},
|
|
781
817
|
{
|
|
782
818
|
sha: "b61c5b09a4b7c9dcff9a9071386b134997569a01",
|
|
@@ -784,8 +820,10 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
784
820
|
subject_line: "head",
|
|
785
821
|
branch_id: "unassigned",
|
|
786
822
|
title: "allow_unassigned",
|
|
823
|
+
master_base: false,
|
|
787
824
|
},
|
|
788
825
|
],
|
|
826
|
+
master_base: false,
|
|
789
827
|
},
|
|
790
828
|
],
|
|
791
829
|
commit_list: [
|
|
@@ -795,6 +833,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
795
833
|
subject_line: "head~7",
|
|
796
834
|
branch_id: "gs---4gvxa-5v-2mx26",
|
|
797
835
|
title: "pr-title",
|
|
836
|
+
master_base: false,
|
|
798
837
|
},
|
|
799
838
|
{
|
|
800
839
|
sha: "391476bbfc6b77b60a3ef7fa97155496a9f8f27f",
|
|
@@ -802,6 +841,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
802
841
|
subject_line: "head~6",
|
|
803
842
|
branch_id: "gs---4gvxa-5v-2mx26",
|
|
804
843
|
title: "pr-title",
|
|
844
|
+
master_base: false,
|
|
805
845
|
},
|
|
806
846
|
{
|
|
807
847
|
sha: "5a98cf8f0406712405d41af07c3a012f72ad36fa",
|
|
@@ -809,6 +849,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
809
849
|
subject_line: "head~5",
|
|
810
850
|
branch_id: "gs---4gvxa-5v-2mx26",
|
|
811
851
|
title: "pr-title",
|
|
852
|
+
master_base: false,
|
|
812
853
|
},
|
|
813
854
|
{
|
|
814
855
|
sha: "e820018cb370bb6cda118dc649e841c75d797188",
|
|
@@ -816,6 +857,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
816
857
|
subject_line: "head~4",
|
|
817
858
|
branch_id: "gs---4gvxa-5v-2mx26",
|
|
818
859
|
title: "pr-title",
|
|
860
|
+
master_base: false,
|
|
819
861
|
},
|
|
820
862
|
{
|
|
821
863
|
sha: "e6d1dfc7ec007468712bfc015884cc22bfa79e1d",
|
|
@@ -823,6 +865,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
823
865
|
subject_line: "head~3",
|
|
824
866
|
branch_id: "gs---4gvxa-5v-2mx26",
|
|
825
867
|
title: "pr-title",
|
|
868
|
+
master_base: false,
|
|
826
869
|
},
|
|
827
870
|
{
|
|
828
871
|
sha: "a26f21025a558968554c439ab9b942d5fe84bccb",
|
|
@@ -830,6 +873,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
830
873
|
subject_line: "head~2",
|
|
831
874
|
branch_id: "gs---4gvxa-5v-2mx26",
|
|
832
875
|
title: "pr-title",
|
|
876
|
+
master_base: false,
|
|
833
877
|
},
|
|
834
878
|
{
|
|
835
879
|
sha: "90667fe97e059e8285e070d6268f2b4035b2ebd4",
|
|
@@ -837,6 +881,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
837
881
|
subject_line: "head~1",
|
|
838
882
|
branch_id: "unassigned",
|
|
839
883
|
title: "allow_unassigned",
|
|
884
|
+
master_base: false,
|
|
840
885
|
},
|
|
841
886
|
{
|
|
842
887
|
sha: "b61c5b09a4b7c9dcff9a9071386b134997569a01",
|
|
@@ -844,6 +889,7 @@ const SYNC_WITH_UNASSIGNED: CommitMetadata.CommitRange = {
|
|
|
844
889
|
subject_line: "head",
|
|
845
890
|
branch_id: "unassigned",
|
|
846
891
|
title: "allow_unassigned",
|
|
892
|
+
master_base: false,
|
|
847
893
|
},
|
|
848
894
|
],
|
|
849
895
|
pr_lookup: {},
|
|
@@ -76,6 +76,8 @@ type CommitListArgs = {
|
|
|
76
76
|
commit_list: CommitMetadata.CommitRange["commit_list"];
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
+
type MetadataWriteValues = Parameters<typeof Metadata.write>[1];
|
|
80
|
+
|
|
79
81
|
GitReviseTodo.todo = function todo(args: CommitListArgs) {
|
|
80
82
|
const entry_list = [];
|
|
81
83
|
|
|
@@ -95,7 +97,10 @@ GitReviseTodo.todo = function todo(args: CommitListArgs) {
|
|
|
95
97
|
const title = commit.title;
|
|
96
98
|
invariant(title, "commit.title must exist");
|
|
97
99
|
|
|
98
|
-
const metadata = { id, title };
|
|
100
|
+
const metadata: MetadataWriteValues = { id, title };
|
|
101
|
+
if (commit.master_base) {
|
|
102
|
+
metadata.base = "master";
|
|
103
|
+
}
|
|
99
104
|
const unsafe_message_with_id = Metadata.write(commit.full_message, metadata);
|
|
100
105
|
const message_with_id = unsafe_message_with_id;
|
|
101
106
|
entry_lines.push(message_with_id);
|
|
@@ -2,6 +2,54 @@ import { test, expect } from "bun:test";
|
|
|
2
2
|
|
|
3
3
|
import * as Metadata from "~/core/Metadata";
|
|
4
4
|
|
|
5
|
+
test("read all metadata", () => {
|
|
6
|
+
const body = [
|
|
7
|
+
"[test] read all metadata",
|
|
8
|
+
"",
|
|
9
|
+
"git-stack-id: noah/test---4h783e3zbtavw4",
|
|
10
|
+
"git-stack-title: read all metadata",
|
|
11
|
+
"git-stack-base: master",
|
|
12
|
+
].join("\n");
|
|
13
|
+
|
|
14
|
+
const metadata = Metadata.read(body);
|
|
15
|
+
|
|
16
|
+
expect(metadata).toEqual({
|
|
17
|
+
subject: "[test] read all metadata",
|
|
18
|
+
id: "noah/test---4h783e3zbtavw4",
|
|
19
|
+
title: "read all metadata",
|
|
20
|
+
base: "master",
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("write all metadata", () => {
|
|
25
|
+
const body = [
|
|
26
|
+
"[test] write all metadata",
|
|
27
|
+
"",
|
|
28
|
+
"- details about this commit",
|
|
29
|
+
"",
|
|
30
|
+
"git-stack-id: DdKIFyufW",
|
|
31
|
+
"git-stack-title: old title",
|
|
32
|
+
].join("\n");
|
|
33
|
+
|
|
34
|
+
const metadata = {
|
|
35
|
+
id: "noah/test---4h783e3zbtavw4",
|
|
36
|
+
title: "read all metadata",
|
|
37
|
+
base: "master",
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
expect(Metadata.write(body, metadata)).toEqual(
|
|
41
|
+
[
|
|
42
|
+
"[test] write all metadata",
|
|
43
|
+
"",
|
|
44
|
+
"- details about this commit",
|
|
45
|
+
"",
|
|
46
|
+
"git-stack-id: noah/test---4h783e3zbtavw4",
|
|
47
|
+
"git-stack-title: read all metadata",
|
|
48
|
+
"git-stack-base: master",
|
|
49
|
+
].join("\n"),
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
|
|
5
53
|
test("read handles bulleted lists", () => {
|
|
6
54
|
const body = [
|
|
7
55
|
"[feat] implement various features",
|
|
@@ -20,6 +68,7 @@ test("read handles bulleted lists", () => {
|
|
|
20
68
|
subject: "[feat] implement various features",
|
|
21
69
|
id: "DdKIFyufW",
|
|
22
70
|
title: "saved group title",
|
|
71
|
+
base: null,
|
|
23
72
|
});
|
|
24
73
|
});
|
|
25
74
|
|
|
@@ -67,6 +116,7 @@ test("read handles slashes in branch name", () => {
|
|
|
67
116
|
subject: "[fix] slash in branch name",
|
|
68
117
|
id: "dev/noah/fix-slash-branch",
|
|
69
118
|
title: "fix slash branch",
|
|
119
|
+
base: null,
|
|
70
120
|
});
|
|
71
121
|
});
|
|
72
122
|
|
|
@@ -114,6 +164,7 @@ test("read handles double quotes", () => {
|
|
|
114
164
|
subject: 'Revert "[abc / 123] subject (#1234)"',
|
|
115
165
|
id: "dev/noah/fix-slash-branch",
|
|
116
166
|
title: 'Revert \\"[abc / 123] subject (#1234)\\"',
|
|
167
|
+
base: null,
|
|
117
168
|
});
|
|
118
169
|
});
|
|
119
170
|
|
package/src/core/Metadata.ts
CHANGED
|
@@ -3,12 +3,14 @@ import { invariant } from "~/core/invariant";
|
|
|
3
3
|
type InputMetadataValues = {
|
|
4
4
|
id: string;
|
|
5
5
|
title?: string;
|
|
6
|
+
base?: string;
|
|
6
7
|
};
|
|
7
8
|
|
|
8
9
|
type OutputMetadataValues = {
|
|
9
10
|
subject: null | string;
|
|
10
11
|
id: null | string;
|
|
11
12
|
title: null | string;
|
|
13
|
+
base: null | string;
|
|
12
14
|
};
|
|
13
15
|
|
|
14
16
|
export function write(message: string, values: InputMetadataValues) {
|
|
@@ -23,13 +25,22 @@ export function write(message: string, values: InputMetadataValues) {
|
|
|
23
25
|
line_list.push(TEMPLATE.group_title(values.title));
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
if (values.base) {
|
|
29
|
+
line_list.push(TEMPLATE.base(values.base));
|
|
30
|
+
}
|
|
31
|
+
|
|
26
32
|
let new_message = line_list.join("\n");
|
|
27
33
|
|
|
28
34
|
return new_message;
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
export function read(message: string): OutputMetadataValues {
|
|
32
|
-
const values: OutputMetadataValues = {
|
|
38
|
+
const values: OutputMetadataValues = {
|
|
39
|
+
subject: null,
|
|
40
|
+
id: null,
|
|
41
|
+
title: null,
|
|
42
|
+
base: null,
|
|
43
|
+
};
|
|
33
44
|
|
|
34
45
|
const match_subject = message.match(RE.subject_line);
|
|
35
46
|
|
|
@@ -51,6 +62,12 @@ export function read(message: string): OutputMetadataValues {
|
|
|
51
62
|
values.title = match_title.groups["title"];
|
|
52
63
|
}
|
|
53
64
|
|
|
65
|
+
const match_base = message.match(RE.base);
|
|
66
|
+
|
|
67
|
+
if (match_base?.groups) {
|
|
68
|
+
values.base = match_base.groups["ref"];
|
|
69
|
+
}
|
|
70
|
+
|
|
54
71
|
return values;
|
|
55
72
|
}
|
|
56
73
|
|
|
@@ -60,6 +77,7 @@ export function remove(message: string) {
|
|
|
60
77
|
// remove metadata
|
|
61
78
|
result = result.replace(new RegExp(RE.stack_id, "gmi"), "");
|
|
62
79
|
result = result.replace(new RegExp(RE.group_title, "gmi"), "");
|
|
80
|
+
result = result.replace(new RegExp(RE.base, "gmi"), "");
|
|
63
81
|
|
|
64
82
|
result = result.trimEnd();
|
|
65
83
|
|
|
@@ -74,6 +92,10 @@ const TEMPLATE = {
|
|
|
74
92
|
group_title(title: string) {
|
|
75
93
|
return `git-stack-title: ${title}`;
|
|
76
94
|
},
|
|
95
|
+
|
|
96
|
+
base(ref: string) {
|
|
97
|
+
return `git-stack-base: ${ref}`;
|
|
98
|
+
},
|
|
77
99
|
};
|
|
78
100
|
|
|
79
101
|
const RE = {
|
|
@@ -82,4 +104,5 @@ const RE = {
|
|
|
82
104
|
// https://regex101.com/r/wLmGVq/1
|
|
83
105
|
stack_id: new RegExp(`${TEMPLATE.stack_id("(?<id>[^\\s]+)")}`, "i"),
|
|
84
106
|
group_title: new RegExp(TEMPLATE.group_title("(?<title>[^\\n^\\r]+)"), "i"),
|
|
107
|
+
base: new RegExp(`${TEMPLATE.base("(?<ref>[^\\s]+)")}`, "i"),
|
|
85
108
|
};
|
|
@@ -51,6 +51,7 @@ git-stack-title: Github: pr_list duration timer"
|
|
|
51
51
|
{
|
|
52
52
|
"branch_id": null,
|
|
53
53
|
"full_message": "homebrew-git-stack 2.7.1",
|
|
54
|
+
"master_base": false,
|
|
54
55
|
"sha": "ba067f8ad641dda7e65e3c2acb2421c955843829",
|
|
55
56
|
"subject_line": "homebrew-git-stack 2.7.1",
|
|
56
57
|
"title": null,
|
|
@@ -63,6 +64,7 @@ git-stack-title: Github: pr_list duration timer"
|
|
|
63
64
|
git-stack-id: noah/paint-test---4gwpqhd033n6y5
|
|
64
65
|
git-stack-title: Rebase: debug logs"
|
|
65
66
|
,
|
|
67
|
+
"master_base": false,
|
|
66
68
|
"sha": "7c8da9f5fe681fc7459a0e737241df631983cd3c",
|
|
67
69
|
"subject_line": "Rebase: debug logs",
|
|
68
70
|
"title": "Rebase: debug logs",
|
|
@@ -75,6 +77,7 @@ git-stack-title: Rebase: debug logs"
|
|
|
75
77
|
git-stack-id: noah/paint-test---4gwpqirewoudxa
|
|
76
78
|
git-stack-title: CommitMetadata: track last group id"
|
|
77
79
|
,
|
|
80
|
+
"master_base": false,
|
|
78
81
|
"sha": "47a69d37f8c5cc796884a91fa9e93fc1db5297dd",
|
|
79
82
|
"subject_line": "CommitMetadata: track last group id",
|
|
80
83
|
"title": "CommitMetadata: track last group id",
|
|
@@ -87,6 +90,7 @@ git-stack-title: CommitMetadata: track last group id"
|
|
|
87
90
|
git-stack-id: noah/paint-test---4gwpqjcpu7-isv
|
|
88
91
|
git-stack-title: Github: pr_list duration timer"
|
|
89
92
|
,
|
|
93
|
+
"master_base": false,
|
|
90
94
|
"sha": "8ccf42a7c72aa194fafc7c326f5874f5a0a009c6",
|
|
91
95
|
"subject_line": "Github: pr_list duration timer",
|
|
92
96
|
"title": "Github: pr_list duration timer",
|