git-stack-cli 1.13.2 → 1.14.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 +13 -0
- package/dist/cjs/index.cjs +56 -26
- package/package.json +1 -1
- package/src/app/SelectCommitRanges.tsx +14 -1
- package/src/command.ts +11 -5
- package/src/core/github.tsx +22 -7
- package/src/types/global.d.ts +1 -0
package/README.md
CHANGED
|
@@ -83,6 +83,19 @@ To update your local branch with the latest changes in the remote branch (e.g. `
|
|
|
83
83
|
git stack rebase
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
+
### Customizing branch name
|
|
87
|
+
|
|
88
|
+
By default `git stack` generates a unique branch name such as `gs-3cmrMBSUj`.
|
|
89
|
+
|
|
90
|
+
You can specify a prefix for the generated branch name by using either the environment variable or the command line option.
|
|
91
|
+
In the example below branches would be generated such as `dev/magus/gs-3cmrMBSUj`.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
GIT_STACK_BRANCH_PREFIX="dev/magus/" git stack
|
|
95
|
+
|
|
96
|
+
git stack --branch-prefix="dev/magus/"
|
|
97
|
+
```
|
|
98
|
+
|
|
86
99
|
## Why?
|
|
87
100
|
|
|
88
101
|
The goal of `git stack` is to combine the **simplicity of developing in a single branch** in order to **preserve your commit history** while also **grouping commits into pull requests for code review**.
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -14912,7 +14912,7 @@ var isSafeInteger = hasNativeIsSafeInteger
|
|
|
14912
14912
|
// IE11 does not support y and u.
|
|
14913
14913
|
var REGEX_SUPPORTS_U_AND_Y = true;
|
|
14914
14914
|
try {
|
|
14915
|
-
var re = RE$
|
|
14915
|
+
var re = RE$6('([^\\p{White_Space}\\p{Pattern_Syntax}]*)', 'yu');
|
|
14916
14916
|
/**
|
|
14917
14917
|
* legacy Edge or Xbox One browser
|
|
14918
14918
|
* Unicode flag support: supported
|
|
@@ -15009,14 +15009,14 @@ var trimEnd = hasTrimEnd
|
|
|
15009
15009
|
return s.replace(SPACE_SEPARATOR_END_REGEX, '');
|
|
15010
15010
|
};
|
|
15011
15011
|
// Prevent minifier to translate new RegExp to literal form that might cause syntax error on IE11.
|
|
15012
|
-
function RE$
|
|
15012
|
+
function RE$6(s, flag) {
|
|
15013
15013
|
return new RegExp(s, flag);
|
|
15014
15014
|
}
|
|
15015
15015
|
// #endregion
|
|
15016
15016
|
var matchIdentifierAtIndex;
|
|
15017
15017
|
if (REGEX_SUPPORTS_U_AND_Y) {
|
|
15018
15018
|
// Native
|
|
15019
|
-
var IDENTIFIER_PREFIX_RE_1 = RE$
|
|
15019
|
+
var IDENTIFIER_PREFIX_RE_1 = RE$6('([^\\p{White_Space}\\p{Pattern_Syntax}]*)', 'yu');
|
|
15020
15020
|
matchIdentifierAtIndex = function matchIdentifierAtIndex(s, index) {
|
|
15021
15021
|
var _a;
|
|
15022
15022
|
IDENTIFIER_PREFIX_RE_1.lastIndex = index;
|
|
@@ -26941,15 +26941,15 @@ match_group.safe = (value, re, group) => {
|
|
|
26941
26941
|
|
|
26942
26942
|
function auth_status(output) {
|
|
26943
26943
|
let username;
|
|
26944
|
-
username = match_group.safe(output, RE$
|
|
26944
|
+
username = match_group.safe(output, RE$5.logged_in_as, "username");
|
|
26945
26945
|
if (username)
|
|
26946
26946
|
return username;
|
|
26947
|
-
username = match_group.safe(output, RE$
|
|
26947
|
+
username = match_group.safe(output, RE$5.logged_in_account, "username");
|
|
26948
26948
|
if (username)
|
|
26949
26949
|
return username;
|
|
26950
26950
|
return null;
|
|
26951
26951
|
}
|
|
26952
|
-
const RE$
|
|
26952
|
+
const RE$5 = {
|
|
26953
26953
|
// Logged in to github.com as magus
|
|
26954
26954
|
logged_in_as: /Logged in to github.com as (?<username>[^\s]+)/,
|
|
26955
26955
|
logged_in_account: /Logged in to github.com account (?<username>[^\s]+)/,
|
|
@@ -29663,10 +29663,10 @@ var cloneDeep$1 = /*@__PURE__*/getDefaultExportFromCjs(cloneDeep_1);
|
|
|
29663
29663
|
// escape double-quote for cli
|
|
29664
29664
|
function safe_quote(value) {
|
|
29665
29665
|
let result = value;
|
|
29666
|
-
result = result.replace(RE$
|
|
29666
|
+
result = result.replace(RE$4.all_double_quote, '\\"');
|
|
29667
29667
|
return result;
|
|
29668
29668
|
}
|
|
29669
|
-
const RE$
|
|
29669
|
+
const RE$4 = {
|
|
29670
29670
|
all_double_quote: /"/g,
|
|
29671
29671
|
};
|
|
29672
29672
|
|
|
@@ -29684,12 +29684,12 @@ function write$1(message, values) {
|
|
|
29684
29684
|
}
|
|
29685
29685
|
function read(message) {
|
|
29686
29686
|
const values = { id: null, title: null };
|
|
29687
|
-
const match_id = message.match(RE$
|
|
29687
|
+
const match_id = message.match(RE$3.stack_id);
|
|
29688
29688
|
if (match_id?.groups) {
|
|
29689
29689
|
values.id = match_id.groups["id"];
|
|
29690
29690
|
invariant(values.id, "id must exist");
|
|
29691
29691
|
}
|
|
29692
|
-
const match_title = message.match(RE$
|
|
29692
|
+
const match_title = message.match(RE$3.group_title);
|
|
29693
29693
|
if (match_title?.groups) {
|
|
29694
29694
|
values.title = match_title.groups["title"];
|
|
29695
29695
|
}
|
|
@@ -29698,8 +29698,8 @@ function read(message) {
|
|
|
29698
29698
|
function remove(message) {
|
|
29699
29699
|
let result = message;
|
|
29700
29700
|
// remove metadata
|
|
29701
|
-
result = result.replace(new RegExp(RE$
|
|
29702
|
-
result = result.replace(new RegExp(RE$
|
|
29701
|
+
result = result.replace(new RegExp(RE$3.stack_id, "gmi"), "");
|
|
29702
|
+
result = result.replace(new RegExp(RE$3.group_title, "gmi"), "");
|
|
29703
29703
|
result = result.trimEnd();
|
|
29704
29704
|
return result;
|
|
29705
29705
|
}
|
|
@@ -29711,7 +29711,7 @@ const TEMPLATE$1 = {
|
|
|
29711
29711
|
return `git-stack-title: ${title}`;
|
|
29712
29712
|
},
|
|
29713
29713
|
};
|
|
29714
|
-
const RE$
|
|
29714
|
+
const RE$3 = {
|
|
29715
29715
|
// https://regex101.com/r/wLmGVq/1
|
|
29716
29716
|
stack_id: new RegExp(`${TEMPLATE$1.stack_id("(?<id>[^\\s]+)")}`, "i"),
|
|
29717
29717
|
group_title: new RegExp(TEMPLATE$1.group_title("(?<title>[^\\n^\\r]+)"), "i"),
|
|
@@ -29788,11 +29788,17 @@ async function pr_create(args) {
|
|
|
29788
29788
|
// pull request create failed: GraphQL: Head sha can't be blank, Base sha can't be blank, No commits between gs-6LAx-On45 and origin/gs-ED2etrzv2, Head ref must be a branch (createPullRequest)
|
|
29789
29789
|
//
|
|
29790
29790
|
// https://github.com/cli/cli/issues/5465
|
|
29791
|
-
let
|
|
29791
|
+
let command_parts = [
|
|
29792
|
+
"gh pr create",
|
|
29793
|
+
`--head refs/heads/${args.branch}`,
|
|
29794
|
+
`--base ${args.base}`,
|
|
29795
|
+
`--title="${title}"`,
|
|
29796
|
+
`--body="${args.body}"`,
|
|
29797
|
+
];
|
|
29792
29798
|
if (args.draft) {
|
|
29793
|
-
|
|
29799
|
+
command_parts.push("--draft");
|
|
29794
29800
|
}
|
|
29795
|
-
const cli_result = await cli(
|
|
29801
|
+
const cli_result = await cli(command_parts);
|
|
29796
29802
|
if (cli_result.code !== 0) {
|
|
29797
29803
|
handle_error(cli_result.output);
|
|
29798
29804
|
return null;
|
|
@@ -29805,8 +29811,7 @@ async function pr_edit(args) {
|
|
|
29805
29811
|
const body_file = await write_body_file(args);
|
|
29806
29812
|
command_parts.push(`--body-file="${body_file}"`);
|
|
29807
29813
|
}
|
|
29808
|
-
const
|
|
29809
|
-
const cli_result = await cli(command);
|
|
29814
|
+
const cli_result = await cli(command_parts);
|
|
29810
29815
|
if (cli_result.code !== 0) {
|
|
29811
29816
|
handle_error(cli_result.output);
|
|
29812
29817
|
}
|
|
@@ -29873,11 +29878,19 @@ function handle_error(output) {
|
|
|
29873
29878
|
async function write_body_file(args) {
|
|
29874
29879
|
invariant(args.body, "args.body must exist");
|
|
29875
29880
|
const temp_dir = os.tmpdir();
|
|
29876
|
-
|
|
29881
|
+
// ensure unique filename is safe for filesystem
|
|
29882
|
+
// base (group id) might contain slashes, e.g. dev/magus/gs-3cmrMBSUj
|
|
29883
|
+
// the flashes would mess up the filesystem path to this file
|
|
29884
|
+
let temp_filename = `git-stack-body-${args.base}`;
|
|
29885
|
+
temp_filename = temp_filename.replace(RE$2.non_alphanumeric_dash, "-");
|
|
29886
|
+
const temp_path = path.join(temp_dir, temp_filename);
|
|
29877
29887
|
await safe_rm(temp_path);
|
|
29878
29888
|
await fs$1.writeFile(temp_path, args.body);
|
|
29879
29889
|
return temp_path;
|
|
29880
29890
|
}
|
|
29891
|
+
const RE$2 = {
|
|
29892
|
+
non_alphanumeric_dash: /[^a-zA-Z0-9_-]+/g,
|
|
29893
|
+
};
|
|
29881
29894
|
|
|
29882
29895
|
async function range(commit_group_map) {
|
|
29883
29896
|
const master_branch = Store.getState().master_branch;
|
|
@@ -31534,8 +31547,20 @@ function SelectCommitRangesInternal(props) {
|
|
|
31534
31547
|
reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { color: colors.gray }), message: "Press {enter} to toggle commit selection", values: {
|
|
31535
31548
|
enter: (reactExports.createElement(Text, { bold: true, color: colors.green }, SYMBOL.enter)),
|
|
31536
31549
|
} }))));
|
|
31550
|
+
function get_group_id() {
|
|
31551
|
+
let branch_prefix = "";
|
|
31552
|
+
// branch prefix via cli flag or env var
|
|
31553
|
+
// cli flag takes precedence since it is more explicit
|
|
31554
|
+
if (argv["branch-prefix"]) {
|
|
31555
|
+
branch_prefix = argv["branch-prefix"];
|
|
31556
|
+
}
|
|
31557
|
+
else if (process.env.GIT_STACK_BRANCH_PREFIX) {
|
|
31558
|
+
branch_prefix = process.env.GIT_STACK_BRANCH_PREFIX;
|
|
31559
|
+
}
|
|
31560
|
+
return `${branch_prefix}${gs_short_id()}`;
|
|
31561
|
+
}
|
|
31537
31562
|
function submit_group_input(title) {
|
|
31538
|
-
const id =
|
|
31563
|
+
const id = get_group_id();
|
|
31539
31564
|
actions.output(reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { dimColor: true }), message: "Created new group {group} {note}", values: {
|
|
31540
31565
|
group: reactExports.createElement(Brackets, null, title),
|
|
31541
31566
|
note: reactExports.createElement(Parens, null, id),
|
|
@@ -37595,7 +37620,7 @@ async function command() {
|
|
|
37595
37620
|
.wrap(123)
|
|
37596
37621
|
// disallow unknown options
|
|
37597
37622
|
.strict()
|
|
37598
|
-
.version("1.
|
|
37623
|
+
.version("1.14.0" )
|
|
37599
37624
|
.showHidden("show-hidden", "Show hidden options via `git stack help --show-hidden`")
|
|
37600
37625
|
.help("help", "Show usage via `git stack help`")
|
|
37601
37626
|
.argv;
|
|
@@ -37649,17 +37674,22 @@ const DefaultOptions = {
|
|
|
37649
37674
|
default: false,
|
|
37650
37675
|
description: "Open all PRs as drafts",
|
|
37651
37676
|
},
|
|
37652
|
-
"
|
|
37653
|
-
|
|
37654
|
-
|
|
37655
|
-
|
|
37656
|
-
description: "Write state to local json file for debugging",
|
|
37677
|
+
"branch-prefix": {
|
|
37678
|
+
type: "string",
|
|
37679
|
+
default: "",
|
|
37680
|
+
description: "Prefix for generated branch names, e.g. dev/magus/",
|
|
37657
37681
|
},
|
|
37658
37682
|
"template": {
|
|
37659
37683
|
type: "boolean",
|
|
37660
37684
|
default: true,
|
|
37661
37685
|
description: "Use automatic Github PR template, e.g. .github/pull_request_template.md, disable with --no-template",
|
|
37662
37686
|
},
|
|
37687
|
+
"write-state-json": {
|
|
37688
|
+
hidden: true,
|
|
37689
|
+
type: "boolean",
|
|
37690
|
+
default: false,
|
|
37691
|
+
description: "Write state to local json file for debugging",
|
|
37692
|
+
},
|
|
37663
37693
|
"mock-metadata": {
|
|
37664
37694
|
hidden: true,
|
|
37665
37695
|
type: "boolean",
|
package/package.json
CHANGED
|
@@ -387,8 +387,21 @@ function SelectCommitRangesInternal(props: Props) {
|
|
|
387
387
|
</Ink.Box>
|
|
388
388
|
);
|
|
389
389
|
|
|
390
|
+
function get_group_id() {
|
|
391
|
+
let branch_prefix = "";
|
|
392
|
+
|
|
393
|
+
// branch prefix via cli flag or env var
|
|
394
|
+
// cli flag takes precedence since it is more explicit
|
|
395
|
+
if (argv["branch-prefix"]) {
|
|
396
|
+
branch_prefix = argv["branch-prefix"];
|
|
397
|
+
} else if (process.env.GIT_STACK_BRANCH_PREFIX) {
|
|
398
|
+
branch_prefix = process.env.GIT_STACK_BRANCH_PREFIX;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
return `${branch_prefix}${gs_short_id()}`;
|
|
402
|
+
}
|
|
390
403
|
function submit_group_input(title: string) {
|
|
391
|
-
const id =
|
|
404
|
+
const id = get_group_id();
|
|
392
405
|
|
|
393
406
|
actions.output(
|
|
394
407
|
<FormatText
|
package/src/command.ts
CHANGED
|
@@ -111,11 +111,10 @@ const DefaultOptions = {
|
|
|
111
111
|
description: "Open all PRs as drafts",
|
|
112
112
|
},
|
|
113
113
|
|
|
114
|
-
"
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
description: "Write state to local json file for debugging",
|
|
114
|
+
"branch-prefix": {
|
|
115
|
+
type: "string",
|
|
116
|
+
default: "",
|
|
117
|
+
description: "Prefix for generated branch names, e.g. dev/magus/",
|
|
119
118
|
},
|
|
120
119
|
|
|
121
120
|
"template": {
|
|
@@ -125,6 +124,13 @@ const DefaultOptions = {
|
|
|
125
124
|
"Use automatic Github PR template, e.g. .github/pull_request_template.md, disable with --no-template",
|
|
126
125
|
},
|
|
127
126
|
|
|
127
|
+
"write-state-json": {
|
|
128
|
+
hidden: true,
|
|
129
|
+
type: "boolean",
|
|
130
|
+
default: false,
|
|
131
|
+
description: "Write state to local json file for debugging",
|
|
132
|
+
},
|
|
133
|
+
|
|
128
134
|
"mock-metadata": {
|
|
129
135
|
hidden: true,
|
|
130
136
|
type: "boolean",
|
package/src/core/github.tsx
CHANGED
|
@@ -130,13 +130,19 @@ export async function pr_create(args: CreatePullRequestArgs) {
|
|
|
130
130
|
// pull request create failed: GraphQL: Head sha can't be blank, Base sha can't be blank, No commits between gs-6LAx-On45 and origin/gs-ED2etrzv2, Head ref must be a branch (createPullRequest)
|
|
131
131
|
//
|
|
132
132
|
// https://github.com/cli/cli/issues/5465
|
|
133
|
-
let
|
|
133
|
+
let command_parts = [
|
|
134
|
+
"gh pr create",
|
|
135
|
+
`--head refs/heads/${args.branch}`,
|
|
136
|
+
`--base ${args.base}`,
|
|
137
|
+
`--title="${title}"`,
|
|
138
|
+
`--body="${args.body}"`,
|
|
139
|
+
];
|
|
134
140
|
|
|
135
141
|
if (args.draft) {
|
|
136
|
-
|
|
142
|
+
command_parts.push("--draft");
|
|
137
143
|
}
|
|
138
144
|
|
|
139
|
-
const cli_result = await cli(
|
|
145
|
+
const cli_result = await cli(command_parts);
|
|
140
146
|
|
|
141
147
|
if (cli_result.code !== 0) {
|
|
142
148
|
handle_error(cli_result.output);
|
|
@@ -160,9 +166,7 @@ export async function pr_edit(args: EditPullRequestArgs) {
|
|
|
160
166
|
command_parts.push(`--body-file="${body_file}"`);
|
|
161
167
|
}
|
|
162
168
|
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
const cli_result = await cli(command);
|
|
169
|
+
const cli_result = await cli(command_parts);
|
|
166
170
|
|
|
167
171
|
if (cli_result.code !== 0) {
|
|
168
172
|
handle_error(cli_result.output);
|
|
@@ -254,7 +258,14 @@ async function write_body_file(args: EditPullRequestArgs) {
|
|
|
254
258
|
invariant(args.body, "args.body must exist");
|
|
255
259
|
|
|
256
260
|
const temp_dir = os.tmpdir();
|
|
257
|
-
|
|
261
|
+
|
|
262
|
+
// ensure unique filename is safe for filesystem
|
|
263
|
+
// base (group id) might contain slashes, e.g. dev/magus/gs-3cmrMBSUj
|
|
264
|
+
// the flashes would mess up the filesystem path to this file
|
|
265
|
+
let temp_filename = `git-stack-body-${args.base}`;
|
|
266
|
+
temp_filename = temp_filename.replace(RE.non_alphanumeric_dash, "-");
|
|
267
|
+
|
|
268
|
+
const temp_path = path.join(temp_dir, temp_filename);
|
|
258
269
|
|
|
259
270
|
await safe_rm(temp_path);
|
|
260
271
|
|
|
@@ -291,3 +302,7 @@ export type PullRequest = {
|
|
|
291
302
|
url: string;
|
|
292
303
|
isDraft: boolean;
|
|
293
304
|
};
|
|
305
|
+
|
|
306
|
+
const RE = {
|
|
307
|
+
non_alphanumeric_dash: /[^a-zA-Z0-9_-]+/g,
|
|
308
|
+
};
|