git-stack-cli 1.12.0 → 1.13.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/README.md +11 -1
- package/dist/cjs/index.cjs +543 -460
- package/package.json +1 -1
- package/src/app/AutoUpdate.tsx +5 -3
- package/src/app/CherryPickCheck.tsx +4 -4
- package/src/app/Debug.tsx +12 -9
- package/src/app/DependencyCheck.tsx +0 -6
- package/src/app/Main.tsx +4 -0
- package/src/app/ManualRebase.tsx +85 -357
- package/src/app/PreManualRebase.tsx +6 -5
- package/src/app/RebaseCheck.tsx +3 -3
- package/src/app/Store.tsx +8 -0
- package/src/app/SyncGithub.tsx +322 -0
- package/src/command.ts +0 -16
- package/src/commands/Rebase.tsx +31 -21
- package/src/core/GitReviseTodo.ts +3 -3
- package/src/core/github.tsx +18 -9
- package/src/core/read_json.ts +3 -3
- package/src/core/safe_exists.ts +10 -0
- package/src/core/safe_rm.ts +10 -0
- package/src/index.tsx +4 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -11,12 +11,13 @@ var node_events = require('node:events');
|
|
|
11
11
|
var fs = require('node:fs');
|
|
12
12
|
var require$$1 = require('module');
|
|
13
13
|
var node_buffer = require('node:buffer');
|
|
14
|
+
var fs$1 = require('node:fs/promises');
|
|
14
15
|
var path = require('node:path');
|
|
15
16
|
var child = require('node:child_process');
|
|
16
17
|
var https = require('node:https');
|
|
17
18
|
var crypto = require('node:crypto');
|
|
18
19
|
var path$1 = require('path');
|
|
19
|
-
var fs$
|
|
20
|
+
var fs$2 = require('fs');
|
|
20
21
|
var util = require('util');
|
|
21
22
|
var url = require('url');
|
|
22
23
|
|
|
@@ -26212,6 +26213,7 @@ const BaseStore = createStore()(immer((set, get) => ({
|
|
|
26212
26213
|
commit_map: null,
|
|
26213
26214
|
pr_templates: [],
|
|
26214
26215
|
pr_template_body: null,
|
|
26216
|
+
sync_github: null,
|
|
26215
26217
|
step: "loading",
|
|
26216
26218
|
output: [],
|
|
26217
26219
|
pending_output: {},
|
|
@@ -26520,9 +26522,9 @@ function is_finite_value(value) {
|
|
|
26520
26522
|
return typeof value === "number" && Number.isFinite(value);
|
|
26521
26523
|
}
|
|
26522
26524
|
|
|
26523
|
-
function read_json(path) {
|
|
26525
|
+
async function read_json(path) {
|
|
26524
26526
|
try {
|
|
26525
|
-
const file_buffer = fs.
|
|
26527
|
+
const file_buffer = await fs$1.readFile(path);
|
|
26526
26528
|
const json_str = String(file_buffer);
|
|
26527
26529
|
const json = JSON.parse(json_str);
|
|
26528
26530
|
return json;
|
|
@@ -26607,10 +26609,11 @@ function AutoUpdate(props) {
|
|
|
26607
26609
|
if (!latest_version) {
|
|
26608
26610
|
throw new Error("Unable to retrieve latest version from npm");
|
|
26609
26611
|
}
|
|
26610
|
-
const
|
|
26612
|
+
const script_path = await fs$1.realpath(process.argv[1]);
|
|
26613
|
+
const script_dir = path.dirname(script_path);
|
|
26611
26614
|
// dist/ts/index.js
|
|
26612
26615
|
const package_json_path = path.join(script_dir, "..", "..", "package.json");
|
|
26613
|
-
const package_json = read_json(package_json_path);
|
|
26616
|
+
const package_json = await read_json(package_json_path);
|
|
26614
26617
|
if (!package_json) {
|
|
26615
26618
|
// unable to find read package.json, skip auto update
|
|
26616
26619
|
throw new Error(`Unable to read package.json [${package_json_path}]`);
|
|
@@ -26773,6 +26776,16 @@ function Command(props) {
|
|
|
26773
26776
|
return (reactExports.createElement(Text, { bold: true, color: text_color }, props.children));
|
|
26774
26777
|
}
|
|
26775
26778
|
|
|
26779
|
+
async function safe_exists(filepath) {
|
|
26780
|
+
try {
|
|
26781
|
+
await fs$1.access(filepath);
|
|
26782
|
+
return true;
|
|
26783
|
+
}
|
|
26784
|
+
catch {
|
|
26785
|
+
return false;
|
|
26786
|
+
}
|
|
26787
|
+
}
|
|
26788
|
+
|
|
26776
26789
|
function reducer$3(state, patch) {
|
|
26777
26790
|
return { ...state, ...patch };
|
|
26778
26791
|
}
|
|
@@ -26803,7 +26816,8 @@ function CherryPickCheck(props) {
|
|
|
26803
26816
|
const actions = Store.getState().actions;
|
|
26804
26817
|
try {
|
|
26805
26818
|
const git_dir = (await cli(`git rev-parse --absolute-git-dir`)).stdout;
|
|
26806
|
-
const
|
|
26819
|
+
const cherry_pick_file = path.join(git_dir, "CHERRY_PICK_HEAD");
|
|
26820
|
+
const is_cherry_pick = await safe_exists(cherry_pick_file);
|
|
26807
26821
|
const status = is_cherry_pick ? "prompt" : "done";
|
|
26808
26822
|
patch({ status });
|
|
26809
26823
|
}
|
|
@@ -26855,6 +26869,16 @@ function deserialize(obj) {
|
|
|
26855
26869
|
return obj;
|
|
26856
26870
|
}
|
|
26857
26871
|
|
|
26872
|
+
async function safe_rm(filepath) {
|
|
26873
|
+
try {
|
|
26874
|
+
await fs$1.access(filepath);
|
|
26875
|
+
await fs$1.rm(filepath);
|
|
26876
|
+
}
|
|
26877
|
+
catch {
|
|
26878
|
+
// if access fails there is no file to remove this is safe
|
|
26879
|
+
}
|
|
26880
|
+
}
|
|
26881
|
+
|
|
26858
26882
|
function Debug() {
|
|
26859
26883
|
const actions = Store.useActions();
|
|
26860
26884
|
const state = Store.useState((state) => state);
|
|
@@ -26865,17 +26889,18 @@ function Debug() {
|
|
|
26865
26889
|
actions.output(reactExports.createElement(Text, { color: colors.yellow }, "Debug mode enabled"));
|
|
26866
26890
|
}
|
|
26867
26891
|
}, [argv]);
|
|
26868
|
-
reactExports.useEffect(function
|
|
26892
|
+
reactExports.useEffect(function sync_state_json() {
|
|
26869
26893
|
if (!argv?.["write-state-json"]) {
|
|
26870
26894
|
return;
|
|
26871
26895
|
}
|
|
26872
|
-
|
|
26873
|
-
|
|
26874
|
-
|
|
26896
|
+
sync().catch(actions.error);
|
|
26897
|
+
async function sync() {
|
|
26898
|
+
const output_file = path.join(state.cwd, "git-stack-state.json");
|
|
26899
|
+
await safe_rm(output_file);
|
|
26900
|
+
const serialized = serialize(state);
|
|
26901
|
+
const content = JSON.stringify(serialized, null, 2);
|
|
26902
|
+
await fs$1.writeFile(output_file, content);
|
|
26875
26903
|
}
|
|
26876
|
-
const serialized = serialize(state);
|
|
26877
|
-
const content = JSON.stringify(serialized, null, 2);
|
|
26878
|
-
fs.writeFileSync(output_file, content);
|
|
26879
26904
|
}, [argv, state]);
|
|
26880
26905
|
return null;
|
|
26881
26906
|
}
|
|
@@ -27005,11 +27030,6 @@ function CheckGithubCliAuth(props) {
|
|
|
27005
27030
|
}
|
|
27006
27031
|
function CheckGitRevise(props) {
|
|
27007
27032
|
const actions = Store.useActions();
|
|
27008
|
-
const argv = Store.useState((state) => state.argv);
|
|
27009
|
-
// skip git revise check when `rebase` is not git-revise
|
|
27010
|
-
if (argv?.["rebase"] !== "git-revise") {
|
|
27011
|
-
return props.children;
|
|
27012
|
-
}
|
|
27013
27033
|
return (reactExports.createElement(Await, { fallback: reactExports.createElement(Text, { color: colors.yellow },
|
|
27014
27034
|
reactExports.createElement(Text, null,
|
|
27015
27035
|
"Checking ",
|
|
@@ -29776,7 +29796,8 @@ async function pr_create(args) {
|
|
|
29776
29796
|
async function pr_edit(args) {
|
|
29777
29797
|
const command_parts = [`gh pr edit ${args.branch} --base ${args.base}`];
|
|
29778
29798
|
if (args.body) {
|
|
29779
|
-
|
|
29799
|
+
const body_file = await write_body_file(args);
|
|
29800
|
+
command_parts.push(`--body-file="${body_file}"`);
|
|
29780
29801
|
}
|
|
29781
29802
|
const command = command_parts.join(" ");
|
|
29782
29803
|
const cli_result = await cli(command);
|
|
@@ -29785,6 +29806,9 @@ async function pr_edit(args) {
|
|
|
29785
29806
|
}
|
|
29786
29807
|
}
|
|
29787
29808
|
async function pr_draft(args) {
|
|
29809
|
+
// https://cli.github.com/manual/gh_api
|
|
29810
|
+
// https://docs.github.com/en/graphql/reference/mutations#convertpullrequesttodraft
|
|
29811
|
+
// https://docs.github.com/en/graphql/reference/mutations#markpullrequestreadyforreview
|
|
29788
29812
|
const mutation_name = args.draft
|
|
29789
29813
|
? "convertPullRequestToDraft"
|
|
29790
29814
|
: "markPullRequestReadyForReview";
|
|
@@ -29827,7 +29851,7 @@ async function gh_json(command) {
|
|
|
29827
29851
|
return new Error(cli_result.output);
|
|
29828
29852
|
}
|
|
29829
29853
|
// read from file
|
|
29830
|
-
const json_str = fs.
|
|
29854
|
+
const json_str = await fs$1.readFile(tmp_pr_json, "utf-8");
|
|
29831
29855
|
const json = JSON.parse(json_str);
|
|
29832
29856
|
return json;
|
|
29833
29857
|
}
|
|
@@ -29840,13 +29864,12 @@ function handle_error(output) {
|
|
|
29840
29864
|
throw new Error(output);
|
|
29841
29865
|
}
|
|
29842
29866
|
// convert a string to a file for use via github cli `--body-file`
|
|
29843
|
-
function
|
|
29867
|
+
async function write_body_file(args) {
|
|
29868
|
+
invariant(args.body, "args.body must exist");
|
|
29844
29869
|
const temp_dir = os.tmpdir();
|
|
29845
|
-
const temp_path = path.join(temp_dir,
|
|
29846
|
-
|
|
29847
|
-
|
|
29848
|
-
}
|
|
29849
|
-
fs.writeFileSync(temp_path, body);
|
|
29870
|
+
const temp_path = path.join(temp_dir, `git-stack-body-${args.base}`);
|
|
29871
|
+
await safe_rm(temp_path);
|
|
29872
|
+
await fs$1.writeFile(temp_path, args.body);
|
|
29850
29873
|
return temp_path;
|
|
29851
29874
|
}
|
|
29852
29875
|
|
|
@@ -30128,9 +30151,9 @@ echo "------ END ------"
|
|
|
30128
30151
|
echo "$GIT_REVISE_TODO" > "$git_revise_todo_path"
|
|
30129
30152
|
`;
|
|
30130
30153
|
// write script to temporary path
|
|
30131
|
-
fs.
|
|
30154
|
+
await fs$1.writeFile(tmp_git_sequence_editor_path, GIT_SEQUENCE_EDITOR_SCRIPT);
|
|
30132
30155
|
// ensure script is executable
|
|
30133
|
-
fs.
|
|
30156
|
+
await fs$1.chmod(tmp_git_sequence_editor_path, "755");
|
|
30134
30157
|
const git_revise_todo = GitReviseTodo(args);
|
|
30135
30158
|
// execute cli with temporary git sequence editor script
|
|
30136
30159
|
// revise from merge base to pick correct commits
|
|
@@ -30300,9 +30323,9 @@ function DirtyCheck(props) {
|
|
|
30300
30323
|
|
|
30301
30324
|
function GatherMetadata(props) {
|
|
30302
30325
|
const fallback = (reactExports.createElement(Text, { color: colors.yellow }, "Gathering local git information\u2026"));
|
|
30303
|
-
return (reactExports.createElement(Await, { fallback: fallback, function: run$
|
|
30326
|
+
return (reactExports.createElement(Await, { fallback: fallback, function: run$a }, props.children));
|
|
30304
30327
|
}
|
|
30305
|
-
async function run$
|
|
30328
|
+
async function run$a() {
|
|
30306
30329
|
const actions = Store.getState().actions;
|
|
30307
30330
|
const argv = Store.getState().argv;
|
|
30308
30331
|
try {
|
|
@@ -30396,9 +30419,9 @@ function format_time(date) {
|
|
|
30396
30419
|
}
|
|
30397
30420
|
|
|
30398
30421
|
function GithubApiError() {
|
|
30399
|
-
return reactExports.createElement(Await, { fallback: null, function: run$
|
|
30422
|
+
return reactExports.createElement(Await, { fallback: null, function: run$9 });
|
|
30400
30423
|
}
|
|
30401
|
-
async function run$
|
|
30424
|
+
async function run$9() {
|
|
30402
30425
|
const actions = Store.getState().actions;
|
|
30403
30426
|
const res = await cli(`gh api https://api.github.com/rate_limit`);
|
|
30404
30427
|
const res_json = JSON.parse(res.stdout);
|
|
@@ -30440,7 +30463,7 @@ function LocalCommitStatus(props) {
|
|
|
30440
30463
|
if (argv["mock-metadata"]) {
|
|
30441
30464
|
return (reactExports.createElement(Await, { fallback: fallback, function: mock_metadata }, props.children));
|
|
30442
30465
|
}
|
|
30443
|
-
return (reactExports.createElement(Await, { fallback: fallback, function: run$
|
|
30466
|
+
return (reactExports.createElement(Await, { fallback: fallback, function: run$8 }, props.children));
|
|
30444
30467
|
}
|
|
30445
30468
|
async function mock_metadata() {
|
|
30446
30469
|
const module = await Promise.resolve().then(function () { return metadata; });
|
|
@@ -30450,7 +30473,7 @@ async function mock_metadata() {
|
|
|
30450
30473
|
state.step = "status";
|
|
30451
30474
|
});
|
|
30452
30475
|
}
|
|
30453
|
-
async function run$
|
|
30476
|
+
async function run$8() {
|
|
30454
30477
|
const actions = Store.getState().actions;
|
|
30455
30478
|
try {
|
|
30456
30479
|
const commit_range = await range();
|
|
@@ -30529,10 +30552,22 @@ function encode(value) {
|
|
|
30529
30552
|
return result.padStart(max_char_size, "=");
|
|
30530
30553
|
}
|
|
30531
30554
|
|
|
30532
|
-
function Rebase
|
|
30533
|
-
|
|
30555
|
+
function Rebase() {
|
|
30556
|
+
const abort_handler = reactExports.useRef(() => { });
|
|
30557
|
+
reactExports.useEffect(function listen_sigint() {
|
|
30558
|
+
process.once("SIGINT", sigint_handler);
|
|
30559
|
+
return function cleanup() {
|
|
30560
|
+
process.removeListener("SIGINT", sigint_handler);
|
|
30561
|
+
};
|
|
30562
|
+
function sigint_handler() {
|
|
30563
|
+
abort_handler.current();
|
|
30564
|
+
}
|
|
30565
|
+
}, []);
|
|
30566
|
+
return (reactExports.createElement(Await, { fallback: reactExports.createElement(Text, { color: colors.yellow }, "Rebasing commits\u2026"), function: async function () {
|
|
30567
|
+
await Rebase.run({ abort_handler });
|
|
30568
|
+
} }));
|
|
30534
30569
|
}
|
|
30535
|
-
Rebase
|
|
30570
|
+
Rebase.run = async function run(args) {
|
|
30536
30571
|
const state = Store.getState();
|
|
30537
30572
|
const actions = state.actions;
|
|
30538
30573
|
const branch_name = state.branch_name;
|
|
@@ -30544,7 +30579,10 @@ Rebase$1.run = async function run() {
|
|
|
30544
30579
|
invariant(commit_range, "commit_range must exist");
|
|
30545
30580
|
invariant(repo_root, "repo_root must exist");
|
|
30546
30581
|
// always listen for SIGINT event and restore git state
|
|
30547
|
-
|
|
30582
|
+
args.abort_handler.current = async function sigint_handler() {
|
|
30583
|
+
actions.output(reactExports.createElement(Text, { color: colors.red }, "\uD83D\uDEA8 Abort"));
|
|
30584
|
+
handle_exit(19);
|
|
30585
|
+
};
|
|
30548
30586
|
const temp_branch_name = `${branch_name}_${short_id()}`;
|
|
30549
30587
|
try {
|
|
30550
30588
|
// actions.debug(`commit_range=${JSON.stringify(commit_range, null, 2)}`);
|
|
@@ -30586,9 +30624,8 @@ Rebase$1.run = async function run() {
|
|
|
30586
30624
|
const sha_list = picked_commit_list.map((commit) => commit.sha).join(" ");
|
|
30587
30625
|
await cli(`git cherry-pick --keep-redundant-commits ${sha_list}`);
|
|
30588
30626
|
}
|
|
30589
|
-
// after all commits have been cherry-picked
|
|
30590
|
-
//
|
|
30591
|
-
// now we are locally in sync with github and on the original branch
|
|
30627
|
+
// after all commits have been cherry-picked move the pointer
|
|
30628
|
+
// of original branch to the newly created temporary branch
|
|
30592
30629
|
await cli(`git branch -f ${branch_name} ${temp_branch_name}`);
|
|
30593
30630
|
restore_git();
|
|
30594
30631
|
const next_commit_range = await range();
|
|
@@ -30608,7 +30645,7 @@ Rebase$1.run = async function run() {
|
|
|
30608
30645
|
actions.error(err.message);
|
|
30609
30646
|
}
|
|
30610
30647
|
}
|
|
30611
|
-
handle_exit();
|
|
30648
|
+
handle_exit(20);
|
|
30612
30649
|
}
|
|
30613
30650
|
// cleanup git operations if cancelled during manual rebase
|
|
30614
30651
|
function restore_git() {
|
|
@@ -30616,8 +30653,6 @@ Rebase$1.run = async function run() {
|
|
|
30616
30653
|
// trying to use `await cli(...)` here will silently fail since
|
|
30617
30654
|
// all children processes receive the SIGINT signal
|
|
30618
30655
|
const spawn_options = { ignoreExitCode: true };
|
|
30619
|
-
// always clean up any patch files
|
|
30620
|
-
cli.sync(`rm ${PATCH_FILE$1}`, spawn_options);
|
|
30621
30656
|
// always hard reset and clean to allow subsequent checkout
|
|
30622
30657
|
// if there are files checkout will fail and cascade fail subsequent commands
|
|
30623
30658
|
cli.sync(`git reset --hard`, spawn_options);
|
|
@@ -30626,19 +30661,13 @@ Rebase$1.run = async function run() {
|
|
|
30626
30661
|
cli.sync(`git checkout ${branch_name}`, spawn_options);
|
|
30627
30662
|
// ...and cleanup temporary branch
|
|
30628
30663
|
cli.sync(`git branch -D ${temp_branch_name}`, spawn_options);
|
|
30629
|
-
if (commit_range) {
|
|
30630
|
-
// ...and cleanup pr group branches
|
|
30631
|
-
for (const group of commit_range.group_list) {
|
|
30632
|
-
cli.sync(`git branch -D ${group.id}`, spawn_options);
|
|
30633
|
-
}
|
|
30634
|
-
}
|
|
30635
30664
|
// restore back to original dir
|
|
30636
30665
|
if (fs.existsSync(cwd)) {
|
|
30637
30666
|
process.chdir(cwd);
|
|
30638
30667
|
}
|
|
30639
30668
|
cli.sync(`pwd`, spawn_options);
|
|
30640
30669
|
}
|
|
30641
|
-
function handle_exit() {
|
|
30670
|
+
function handle_exit(code) {
|
|
30642
30671
|
actions.output(reactExports.createElement(Text, { color: colors.yellow },
|
|
30643
30672
|
"Restoring ",
|
|
30644
30673
|
reactExports.createElement(Brackets, null, branch_name),
|
|
@@ -30648,126 +30677,30 @@ Rebase$1.run = async function run() {
|
|
|
30648
30677
|
"Restored ",
|
|
30649
30678
|
reactExports.createElement(Brackets, null, branch_name),
|
|
30650
30679
|
"."));
|
|
30651
|
-
actions.exit(
|
|
30680
|
+
actions.exit(code);
|
|
30652
30681
|
}
|
|
30653
30682
|
};
|
|
30654
|
-
const PATCH_FILE$1 = "git-stack-cli-patch.patch";
|
|
30655
30683
|
|
|
30656
30684
|
function LocalMergeRebase() {
|
|
30657
|
-
return reactExports.createElement(Rebase
|
|
30685
|
+
return reactExports.createElement(Rebase, null);
|
|
30658
30686
|
}
|
|
30659
30687
|
|
|
30660
|
-
function write(args) {
|
|
30661
|
-
const stack_table = table(args);
|
|
30662
|
-
let result = args.body;
|
|
30663
|
-
if (RE.stack_table_link.test(result)) {
|
|
30664
|
-
// replace stack table
|
|
30665
|
-
result = result.replace(RE.stack_table_link, stack_table);
|
|
30666
|
-
}
|
|
30667
|
-
else if (RE.stack_table_legacy.test(result)) {
|
|
30668
|
-
// replace stack table
|
|
30669
|
-
result = result.replace(RE.stack_table_legacy, stack_table);
|
|
30670
|
-
}
|
|
30671
|
-
else {
|
|
30672
|
-
// append stack table
|
|
30673
|
-
result = `${result}\n\n${stack_table}`;
|
|
30674
|
-
}
|
|
30675
|
-
result = result.trimEnd();
|
|
30676
|
-
return result;
|
|
30677
|
-
}
|
|
30678
|
-
function table(args) {
|
|
30679
|
-
const stack_pr_url_list = [...args.pr_url_list];
|
|
30680
|
-
const old_stack = parse(args.body);
|
|
30681
|
-
// remove existing stack pr urls from the old stack pr urls
|
|
30682
|
-
for (const pr_url of stack_pr_url_list) {
|
|
30683
|
-
old_stack.delete(pr_url);
|
|
30684
|
-
}
|
|
30685
|
-
// add remaining old stack pr urls to the front of stack pr url list
|
|
30686
|
-
const old_pr_list = Array.from(old_stack.keys());
|
|
30687
|
-
old_pr_list.reverse();
|
|
30688
|
-
for (const pr_url of old_pr_list) {
|
|
30689
|
-
stack_pr_url_list.unshift(pr_url);
|
|
30690
|
-
}
|
|
30691
|
-
const stack_list = [];
|
|
30692
|
-
const num_digits = String(stack_pr_url_list.length).length;
|
|
30693
|
-
for (let i = 0; i < stack_pr_url_list.length; i++) {
|
|
30694
|
-
const pr_url = stack_pr_url_list[i];
|
|
30695
|
-
const selected = args.selected_url === pr_url;
|
|
30696
|
-
let icon;
|
|
30697
|
-
if (old_stack.has(pr_url)) {
|
|
30698
|
-
icon = "✅";
|
|
30699
|
-
}
|
|
30700
|
-
else if (selected) {
|
|
30701
|
-
icon = "👉";
|
|
30702
|
-
}
|
|
30703
|
-
else {
|
|
30704
|
-
icon = "⏳";
|
|
30705
|
-
}
|
|
30706
|
-
const num = String(i + 1).padStart(num_digits, "0");
|
|
30707
|
-
stack_list.push(TEMPLATE.row({ icon, num, pr_url }));
|
|
30708
|
-
}
|
|
30709
|
-
if (!stack_list.length) {
|
|
30710
|
-
return "";
|
|
30711
|
-
}
|
|
30712
|
-
return TEMPLATE.stack_table_link(["", ...stack_list, "", ""].join("\n"));
|
|
30713
|
-
}
|
|
30714
|
-
function parse(body) {
|
|
30715
|
-
let stack_table_match = body.match(RE.stack_table_link);
|
|
30716
|
-
if (!stack_table_match?.groups) {
|
|
30717
|
-
stack_table_match = body.match(RE.stack_table_legacy);
|
|
30718
|
-
}
|
|
30719
|
-
if (!stack_table_match?.groups) {
|
|
30720
|
-
return new Map();
|
|
30721
|
-
}
|
|
30722
|
-
const rows_string = stack_table_match.groups["rows"];
|
|
30723
|
-
const row_list = rows_string.split("\n");
|
|
30724
|
-
const result = new Map();
|
|
30725
|
-
for (const row of row_list) {
|
|
30726
|
-
const row_match = row.match(RE.row);
|
|
30727
|
-
const parsed_row = row_match?.groups;
|
|
30728
|
-
if (!parsed_row) {
|
|
30729
|
-
// skip invalid row
|
|
30730
|
-
continue;
|
|
30731
|
-
}
|
|
30732
|
-
if (!RE.pr_url.test(parsed_row.pr_url)) {
|
|
30733
|
-
continue;
|
|
30734
|
-
}
|
|
30735
|
-
result.set(parsed_row.pr_url, parsed_row);
|
|
30736
|
-
}
|
|
30737
|
-
return result;
|
|
30738
|
-
}
|
|
30739
|
-
const TEMPLATE = {
|
|
30740
|
-
stack_table_legacy(rows) {
|
|
30741
|
-
return `#### git stack${rows}`;
|
|
30742
|
-
},
|
|
30743
|
-
stack_table_link(rows) {
|
|
30744
|
-
return `#### [git stack](https://github.com/magus/git-stack-cli)${rows}`;
|
|
30745
|
-
},
|
|
30746
|
-
row(args) {
|
|
30747
|
-
return `- ${args.icon} \`${args.num}\` ${args.pr_url}`;
|
|
30748
|
-
},
|
|
30749
|
-
};
|
|
30750
|
-
const RE = {
|
|
30751
|
-
// https://regex101.com/r/kqB9Ft/1
|
|
30752
|
-
stack_table_legacy: new RegExp(TEMPLATE.stack_table_legacy("\\s+(?<rows>(?:- [^\r^\n]*(?:[\r\n]+)?)+)")),
|
|
30753
|
-
stack_table_link: new RegExp(TEMPLATE.stack_table_link("ROWS")
|
|
30754
|
-
.replace("[", "\\[")
|
|
30755
|
-
.replace("]", "\\]")
|
|
30756
|
-
.replace("(", "\\(")
|
|
30757
|
-
.replace(")", "\\)")
|
|
30758
|
-
.replace("ROWS", "\\s+(?<rows>(?:- [^\r^\n]*(?:[\r\n]+)?)+)")),
|
|
30759
|
-
row: new RegExp(TEMPLATE.row({
|
|
30760
|
-
icon: "(?<icon>.+)",
|
|
30761
|
-
num: "(?<num>\\d+)",
|
|
30762
|
-
pr_url: "(?<pr_url>.+)",
|
|
30763
|
-
})),
|
|
30764
|
-
pr_url: /^https:\/\/.*$/,
|
|
30765
|
-
};
|
|
30766
|
-
|
|
30767
30688
|
function ManualRebase() {
|
|
30768
|
-
|
|
30689
|
+
const abort_handler = reactExports.useRef(() => { });
|
|
30690
|
+
reactExports.useEffect(function listen_sigint() {
|
|
30691
|
+
process.once("SIGINT", sigint_handler);
|
|
30692
|
+
return function cleanup() {
|
|
30693
|
+
process.removeListener("SIGINT", sigint_handler);
|
|
30694
|
+
};
|
|
30695
|
+
async function sigint_handler() {
|
|
30696
|
+
abort_handler.current();
|
|
30697
|
+
}
|
|
30698
|
+
}, []);
|
|
30699
|
+
return (reactExports.createElement(Await, { fallback: reactExports.createElement(Text, { color: colors.yellow }, "Rebasing commits\u2026"), function: async function () {
|
|
30700
|
+
await run$7({ abort_handler });
|
|
30701
|
+
} }));
|
|
30769
30702
|
}
|
|
30770
|
-
async function run$
|
|
30703
|
+
async function run$7(args) {
|
|
30771
30704
|
const state = Store.getState();
|
|
30772
30705
|
const actions = state.actions;
|
|
30773
30706
|
const argv = state.argv;
|
|
@@ -30780,80 +30713,53 @@ async function run$6() {
|
|
|
30780
30713
|
invariant(commit_map, "commit_map must exist");
|
|
30781
30714
|
invariant(repo_root, "repo_root must exist");
|
|
30782
30715
|
// always listen for SIGINT event and restore git state
|
|
30783
|
-
|
|
30784
|
-
|
|
30785
|
-
|
|
30786
|
-
|
|
30787
|
-
let commit_range = await range(commit_map);
|
|
30788
|
-
// reverse group list to ensure we create git revise in correct order
|
|
30789
|
-
commit_range.group_list.reverse();
|
|
30790
|
-
for (const commit of commit_range.commit_list) {
|
|
30791
|
-
const group_from_map = commit_map[commit.sha];
|
|
30792
|
-
commit.branch_id = group_from_map.id;
|
|
30793
|
-
commit.title = group_from_map.title;
|
|
30794
|
-
}
|
|
30795
|
-
await GitReviseTodo.execute({
|
|
30796
|
-
rebase_group_index: 0,
|
|
30797
|
-
rebase_merge_base: merge_base,
|
|
30798
|
-
commit_range,
|
|
30799
|
-
});
|
|
30800
|
-
let DEFAULT_PR_BODY = "";
|
|
30801
|
-
if (state.pr_template_body) {
|
|
30802
|
-
DEFAULT_PR_BODY = state.pr_template_body;
|
|
30803
|
-
}
|
|
30716
|
+
args.abort_handler.current = function sigint_handler() {
|
|
30717
|
+
actions.output(reactExports.createElement(Text, { color: colors.red }, "\uD83D\uDEA8 Abort"));
|
|
30718
|
+
handle_exit(15);
|
|
30719
|
+
};
|
|
30804
30720
|
const temp_branch_name = `${branch_name}_${short_id()}`;
|
|
30805
|
-
commit_range = await range(commit_map);
|
|
30806
|
-
// reverse commit list so that we can cherry-pick in order
|
|
30807
|
-
commit_range.group_list.reverse();
|
|
30808
|
-
let rebase_merge_base = merge_base;
|
|
30809
|
-
let rebase_group_index = 0;
|
|
30810
|
-
for (let i = 0; i < commit_range.group_list.length; i++) {
|
|
30811
|
-
const group = commit_range.group_list[i];
|
|
30812
|
-
if (!group.dirty) {
|
|
30813
|
-
continue;
|
|
30814
|
-
}
|
|
30815
|
-
if (i > 0) {
|
|
30816
|
-
const prev_group = commit_range.group_list[i - 1];
|
|
30817
|
-
const prev_commit = prev_group.commits[prev_group.commits.length - 1];
|
|
30818
|
-
rebase_merge_base = prev_commit.sha;
|
|
30819
|
-
rebase_group_index = i;
|
|
30820
|
-
}
|
|
30821
|
-
break;
|
|
30822
|
-
}
|
|
30823
|
-
actions.debug(`rebase_merge_base = ${rebase_merge_base}`);
|
|
30824
|
-
actions.debug(`rebase_group_index = ${rebase_group_index}`);
|
|
30825
|
-
// actions.debug(`commit_range=${JSON.stringify(commit_range, null, 2)}`);
|
|
30826
30721
|
try {
|
|
30827
|
-
//
|
|
30828
|
-
|
|
30829
|
-
|
|
30830
|
-
|
|
30831
|
-
|
|
30832
|
-
|
|
30833
|
-
|
|
30834
|
-
|
|
30722
|
+
// get latest merge_base relative to local master
|
|
30723
|
+
const merge_base = (await cli(`git merge-base HEAD ${master_branch}`))
|
|
30724
|
+
.stdout;
|
|
30725
|
+
// immediately paint all commit to preserve selected commit ranges
|
|
30726
|
+
let commit_range = await range(commit_map);
|
|
30727
|
+
// reverse group list to ensure we create git revise in correct order
|
|
30728
|
+
commit_range.group_list.reverse();
|
|
30729
|
+
for (const commit of commit_range.commit_list) {
|
|
30730
|
+
const group_from_map = commit_map[commit.sha];
|
|
30731
|
+
commit.branch_id = group_from_map.id;
|
|
30732
|
+
commit.title = group_from_map.title;
|
|
30835
30733
|
}
|
|
30836
|
-
|
|
30837
|
-
|
|
30838
|
-
|
|
30839
|
-
|
|
30840
|
-
restore_git();
|
|
30841
|
-
actions.set((state) => {
|
|
30842
|
-
state.step = "post-rebase-status";
|
|
30734
|
+
await GitReviseTodo.execute({
|
|
30735
|
+
rebase_group_index: 0,
|
|
30736
|
+
rebase_merge_base: merge_base,
|
|
30737
|
+
commit_range,
|
|
30843
30738
|
});
|
|
30844
|
-
|
|
30845
|
-
|
|
30846
|
-
|
|
30847
|
-
|
|
30848
|
-
|
|
30849
|
-
|
|
30739
|
+
commit_range = await range(commit_map);
|
|
30740
|
+
// reverse commit list so that we can cherry-pick in order
|
|
30741
|
+
commit_range.group_list.reverse();
|
|
30742
|
+
let rebase_merge_base = merge_base;
|
|
30743
|
+
let rebase_group_index = 0;
|
|
30744
|
+
for (let i = 0; i < commit_range.group_list.length; i++) {
|
|
30745
|
+
const group = commit_range.group_list[i];
|
|
30746
|
+
if (!group.dirty) {
|
|
30747
|
+
continue;
|
|
30748
|
+
}
|
|
30749
|
+
if (i > 0) {
|
|
30750
|
+
const prev_group = commit_range.group_list[i - 1];
|
|
30751
|
+
const prev_commit = prev_group.commits[prev_group.commits.length - 1];
|
|
30752
|
+
rebase_merge_base = prev_commit.sha;
|
|
30753
|
+
rebase_group_index = i;
|
|
30850
30754
|
}
|
|
30755
|
+
break;
|
|
30851
30756
|
}
|
|
30852
|
-
|
|
30853
|
-
|
|
30854
|
-
|
|
30855
|
-
|
|
30856
|
-
|
|
30757
|
+
actions.debug(`rebase_merge_base = ${rebase_merge_base}`);
|
|
30758
|
+
actions.debug(`rebase_group_index = ${rebase_group_index}`);
|
|
30759
|
+
// actions.debug(`commit_range=${JSON.stringify(commit_range, null, 2)}`);
|
|
30760
|
+
// must perform rebase from repo root for applying git patch
|
|
30761
|
+
process.chdir(repo_root);
|
|
30762
|
+
await cli(`pwd`);
|
|
30857
30763
|
// create temporary branch
|
|
30858
30764
|
await cli(`git checkout -b ${temp_branch_name}`);
|
|
30859
30765
|
await GitReviseTodo.execute({
|
|
@@ -30861,195 +30767,31 @@ async function run$6() {
|
|
|
30861
30767
|
rebase_merge_base,
|
|
30862
30768
|
commit_range,
|
|
30863
30769
|
});
|
|
30864
|
-
//
|
|
30865
|
-
|
|
30866
|
-
|
|
30867
|
-
|
|
30868
|
-
|
|
30869
|
-
|
|
30870
|
-
|
|
30871
|
-
|
|
30872
|
-
let lookback_index = 0;
|
|
30873
|
-
for (let i = 0; i < commit_range.group_list.length; i++) {
|
|
30874
|
-
const index = commit_range.group_list.length - 1 - i;
|
|
30875
|
-
// do not go past rebase_group_index
|
|
30876
|
-
if (index < rebase_group_index) {
|
|
30877
|
-
break;
|
|
30878
|
-
}
|
|
30879
|
-
const group = commit_range.group_list[index];
|
|
30880
|
-
// console.debug({ i, index, group });
|
|
30881
|
-
if (i > 0) {
|
|
30882
|
-
const prev_group = commit_range.group_list[index + 1];
|
|
30883
|
-
lookback_index += prev_group.commits.length;
|
|
30884
|
-
}
|
|
30885
|
-
// console.debug(`git show head~${lookback_index}`);
|
|
30886
|
-
// push group and lookback_index onto front of push_group_list
|
|
30887
|
-
push_group_list.unshift({ group, lookback_index });
|
|
30888
|
-
}
|
|
30889
|
-
const pr_url_list = commit_range.group_list.map(get_group_url);
|
|
30890
|
-
// use push_group_list to sync each group HEAD to github
|
|
30891
|
-
for (const push_group of push_group_list) {
|
|
30892
|
-
const { group } = push_group;
|
|
30893
|
-
// move to temporary branch for resetting to lookback_index to create PR
|
|
30894
|
-
await cli(`git checkout -b ${group.id}`);
|
|
30895
|
-
// prepare branch for sync, reset to commit at lookback index
|
|
30896
|
-
await cli(`git reset --hard HEAD~${push_group.lookback_index}`);
|
|
30897
|
-
await sync_group_github({ group, pr_url_list, skip_checkout: true });
|
|
30898
|
-
// done, remove temp push branch and move back to temp branch
|
|
30899
|
-
await cli(`git checkout ${temp_branch_name}`);
|
|
30900
|
-
await cli(`git branch -D ${group.id}`);
|
|
30901
|
-
}
|
|
30902
|
-
// finally, ensure all prs have the updated stack table from updated pr_url_list
|
|
30903
|
-
await update_pr_tables(pr_url_list);
|
|
30904
|
-
}
|
|
30905
|
-
async function rebase_cherry_pick() {
|
|
30906
|
-
actions.debug("rebase_cherry_pick");
|
|
30907
|
-
// create temporary branch based on merge base
|
|
30908
|
-
await cli(`git checkout -b ${temp_branch_name} ${rebase_merge_base}`);
|
|
30909
|
-
const pr_url_list = commit_range.group_list.map(get_group_url);
|
|
30910
|
-
for (let i = rebase_group_index; i < commit_range.group_list.length; i++) {
|
|
30911
|
-
const group = commit_range.group_list[i];
|
|
30912
|
-
invariant(group.base, "group.base must exist");
|
|
30913
|
-
actions.output(reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { color: colors.yellow, wrap: "truncate-end" }), message: "Rebasing {group}\u2026", values: {
|
|
30914
|
-
group: (reactExports.createElement(Brackets, null, group.pr?.title || group.title || group.id)),
|
|
30915
|
-
} }));
|
|
30916
|
-
// cherry-pick and amend commits one by one
|
|
30917
|
-
for (const commit of group.commits) {
|
|
30918
|
-
// ensure clean base to avoid conflicts when applying patch
|
|
30919
|
-
await cli(`git clean -fd`);
|
|
30920
|
-
// create, apply and cleanup patch
|
|
30921
|
-
await cli(`git format-patch -1 ${commit.sha} --stdout > ${PATCH_FILE}`);
|
|
30922
|
-
await cli(`git apply ${PATCH_FILE}`);
|
|
30923
|
-
await cli(`rm ${PATCH_FILE}`);
|
|
30924
|
-
// add all changes to stage
|
|
30925
|
-
await cli(`git add --all`);
|
|
30926
|
-
const metadata = { id: group.id, title: group.title };
|
|
30927
|
-
const new_message = write$1(commit.full_message, metadata);
|
|
30928
|
-
const git_commit_comand = [`git commit -m "${new_message}"`];
|
|
30929
|
-
if (argv.verify === false) {
|
|
30930
|
-
git_commit_comand.push("--no-verify");
|
|
30931
|
-
}
|
|
30932
|
-
await cli(git_commit_comand);
|
|
30933
|
-
}
|
|
30934
|
-
await sync_group_github({ group, pr_url_list, skip_checkout: false });
|
|
30935
|
-
}
|
|
30936
|
-
// finally, ensure all prs have the updated stack table from updated pr_url_list
|
|
30937
|
-
await update_pr_tables(pr_url_list);
|
|
30938
|
-
}
|
|
30939
|
-
async function sync_group_github(args) {
|
|
30940
|
-
if (!argv.sync) {
|
|
30941
|
-
return;
|
|
30942
|
-
}
|
|
30943
|
-
const { group, pr_url_list } = args;
|
|
30944
|
-
invariant(group.base, "group.base must exist");
|
|
30945
|
-
actions.output(reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { color: colors.yellow, wrap: "truncate-end" }), message: "Syncing {group}\u2026", values: {
|
|
30946
|
-
group: (reactExports.createElement(Brackets, null, group.pr?.title || group.title || group.id)),
|
|
30947
|
-
} }));
|
|
30948
|
-
// we may temporarily mark PR as a draft before editing it
|
|
30949
|
-
// if it is not already a draft PR, to avoid notification spam
|
|
30950
|
-
let is_temp_draft = false;
|
|
30951
|
-
// before pushing reset base to master temporarily
|
|
30952
|
-
// avoid accidentally pointing to orphaned parent commit
|
|
30953
|
-
// should hopefully fix issues where a PR includes a bunch of commits after pushing
|
|
30954
|
-
if (group.pr) {
|
|
30955
|
-
if (!group.pr.isDraft) {
|
|
30956
|
-
is_temp_draft = true;
|
|
30957
|
-
}
|
|
30958
|
-
if (is_temp_draft) {
|
|
30959
|
-
await pr_draft({
|
|
30960
|
-
branch: group.id,
|
|
30961
|
-
draft: true,
|
|
30962
|
-
});
|
|
30963
|
-
}
|
|
30964
|
-
await pr_edit({
|
|
30965
|
-
branch: group.id,
|
|
30966
|
-
base: master_branch,
|
|
30967
|
-
});
|
|
30968
|
-
}
|
|
30969
|
-
// push to origin since github requires commit shas to line up perfectly
|
|
30970
|
-
const git_push_command = [`git push -f origin HEAD:${group.id}`];
|
|
30971
|
-
if (argv.verify === false) {
|
|
30972
|
-
git_push_command.push("--no-verify");
|
|
30973
|
-
}
|
|
30974
|
-
await cli(git_push_command);
|
|
30975
|
-
const selected_url = get_group_url(group);
|
|
30976
|
-
if (group.pr) {
|
|
30977
|
-
// ensure base matches pr in github
|
|
30978
|
-
await pr_edit({
|
|
30979
|
-
branch: group.id,
|
|
30980
|
-
base: group.base,
|
|
30981
|
-
body: write({
|
|
30982
|
-
body: group.pr.body,
|
|
30983
|
-
pr_url_list,
|
|
30984
|
-
selected_url,
|
|
30985
|
-
}),
|
|
30770
|
+
// after all commits have been modified move the pointer
|
|
30771
|
+
// of original branch to the newly created temporary branch
|
|
30772
|
+
await cli(`git branch -f ${branch_name} ${temp_branch_name}`);
|
|
30773
|
+
restore_git();
|
|
30774
|
+
if (argv.sync) {
|
|
30775
|
+
actions.set((state) => {
|
|
30776
|
+
state.step = "sync-github";
|
|
30777
|
+
state.sync_github = { commit_range, rebase_group_index };
|
|
30986
30778
|
});
|
|
30987
|
-
if (is_temp_draft) {
|
|
30988
|
-
// mark pr as ready for review again
|
|
30989
|
-
await pr_draft({
|
|
30990
|
-
branch: group.id,
|
|
30991
|
-
draft: false,
|
|
30992
|
-
});
|
|
30993
|
-
}
|
|
30994
30779
|
}
|
|
30995
30780
|
else {
|
|
30996
|
-
|
|
30997
|
-
|
|
30998
|
-
await cli(`git branch -D ${group.id}`, { ignoreExitCode: true });
|
|
30999
|
-
// move to temporary branch for creating pr
|
|
31000
|
-
await cli(`git checkout -b ${group.id}`);
|
|
31001
|
-
}
|
|
31002
|
-
// create pr in github
|
|
31003
|
-
const pr_url = await pr_create({
|
|
31004
|
-
branch: group.id,
|
|
31005
|
-
base: group.base,
|
|
31006
|
-
title: group.title,
|
|
31007
|
-
body: DEFAULT_PR_BODY,
|
|
31008
|
-
draft: argv.draft,
|
|
30781
|
+
actions.set((state) => {
|
|
30782
|
+
state.step = "post-rebase-status";
|
|
31009
30783
|
});
|
|
31010
|
-
if (!pr_url) {
|
|
31011
|
-
throw new Error("unable to create pr");
|
|
31012
|
-
}
|
|
31013
|
-
// update pr_url_list with created pr_url
|
|
31014
|
-
for (let i = 0; i < pr_url_list.length; i++) {
|
|
31015
|
-
const url = pr_url_list[i];
|
|
31016
|
-
if (url === selected_url) {
|
|
31017
|
-
pr_url_list[i] = pr_url;
|
|
31018
|
-
}
|
|
31019
|
-
}
|
|
31020
|
-
// move back to temp branch
|
|
31021
|
-
if (!args.skip_checkout) {
|
|
31022
|
-
await cli(`git checkout ${temp_branch_name}`);
|
|
31023
|
-
}
|
|
31024
30784
|
}
|
|
31025
30785
|
}
|
|
31026
|
-
|
|
31027
|
-
if (
|
|
31028
|
-
|
|
30786
|
+
catch (err) {
|
|
30787
|
+
if (err instanceof Error) {
|
|
30788
|
+
actions.error(err.message);
|
|
31029
30789
|
}
|
|
31030
|
-
|
|
31031
|
-
|
|
31032
|
-
|
|
31033
|
-
const selected_url = pr_url_list[i];
|
|
31034
|
-
invariant(group.base, "group.base must exist");
|
|
31035
|
-
const body = group.pr?.body || DEFAULT_PR_BODY;
|
|
31036
|
-
const update_body = write({
|
|
31037
|
-
body,
|
|
31038
|
-
pr_url_list,
|
|
31039
|
-
selected_url,
|
|
31040
|
-
});
|
|
31041
|
-
if (update_body === body) {
|
|
31042
|
-
actions.debug(`Skipping body update for ${selected_url}`);
|
|
31043
|
-
}
|
|
31044
|
-
else {
|
|
31045
|
-
actions.debug(`Update body for ${selected_url}`);
|
|
31046
|
-
await pr_edit({
|
|
31047
|
-
branch: group.id,
|
|
31048
|
-
base: group.base,
|
|
31049
|
-
body: update_body,
|
|
31050
|
-
});
|
|
31051
|
-
}
|
|
30790
|
+
actions.error("Unable to rebase.");
|
|
30791
|
+
if (!argv.verbose) {
|
|
30792
|
+
actions.error("Try again with `--verbose` to see more information.");
|
|
31052
30793
|
}
|
|
30794
|
+
handle_exit(16);
|
|
31053
30795
|
}
|
|
31054
30796
|
// cleanup git operations if cancelled during manual rebase
|
|
31055
30797
|
function restore_git() {
|
|
@@ -31057,8 +30799,6 @@ async function run$6() {
|
|
|
31057
30799
|
// trying to use `await cli(...)` here will silently fail since
|
|
31058
30800
|
// all children processes receive the SIGINT signal
|
|
31059
30801
|
const spawn_options = { ignoreExitCode: true };
|
|
31060
|
-
// always clean up any patch files
|
|
31061
|
-
cli.sync(`rm ${PATCH_FILE}`, spawn_options);
|
|
31062
30802
|
// always hard reset and clean to allow subsequent checkout
|
|
31063
30803
|
// if there are files checkout will fail and cascade fail subsequent commands
|
|
31064
30804
|
cli.sync(`git reset --hard`, spawn_options);
|
|
@@ -31067,19 +30807,13 @@ async function run$6() {
|
|
|
31067
30807
|
cli.sync(`git checkout ${branch_name}`, spawn_options);
|
|
31068
30808
|
// ...and cleanup temporary branch
|
|
31069
30809
|
cli.sync(`git branch -D ${temp_branch_name}`, spawn_options);
|
|
31070
|
-
if (commit_range) {
|
|
31071
|
-
// ...and cleanup pr group branches
|
|
31072
|
-
for (const group of commit_range.group_list) {
|
|
31073
|
-
cli.sync(`git branch -D ${group.id}`, spawn_options);
|
|
31074
|
-
}
|
|
31075
|
-
}
|
|
31076
30810
|
// restore back to original dir
|
|
31077
30811
|
if (fs.existsSync(cwd)) {
|
|
31078
30812
|
process.chdir(cwd);
|
|
31079
30813
|
}
|
|
31080
30814
|
cli.sync(`pwd`, spawn_options);
|
|
31081
30815
|
}
|
|
31082
|
-
function handle_exit() {
|
|
30816
|
+
function handle_exit(code) {
|
|
31083
30817
|
actions.output(reactExports.createElement(Text, { color: colors.yellow },
|
|
31084
30818
|
"Restoring ",
|
|
31085
30819
|
reactExports.createElement(Brackets, null, branch_name),
|
|
@@ -31089,11 +30823,9 @@ async function run$6() {
|
|
|
31089
30823
|
"Restored ",
|
|
31090
30824
|
reactExports.createElement(Brackets, null, branch_name),
|
|
31091
30825
|
"."));
|
|
31092
|
-
actions.exit(
|
|
30826
|
+
actions.exit(code);
|
|
31093
30827
|
}
|
|
31094
30828
|
}
|
|
31095
|
-
const get_group_url = (group) => group.pr?.url || group.id;
|
|
31096
|
-
const PATCH_FILE = "git-stack-cli-patch.patch";
|
|
31097
30829
|
|
|
31098
30830
|
function Table(props) {
|
|
31099
30831
|
if (!props.data.length) {
|
|
@@ -31272,9 +31004,9 @@ function get_status_bold(row) {
|
|
|
31272
31004
|
}
|
|
31273
31005
|
|
|
31274
31006
|
function PostRebaseStatus() {
|
|
31275
|
-
return reactExports.createElement(Await, { fallback: null, function: run$
|
|
31007
|
+
return reactExports.createElement(Await, { fallback: null, function: run$6 });
|
|
31276
31008
|
}
|
|
31277
|
-
async function run$
|
|
31009
|
+
async function run$6() {
|
|
31278
31010
|
const actions = Store.getState().actions;
|
|
31279
31011
|
// reset github pr cache before refreshing via commit range below
|
|
31280
31012
|
actions.reset_pr();
|
|
@@ -31304,9 +31036,9 @@ function PreLocalMergeRebase() {
|
|
|
31304
31036
|
}
|
|
31305
31037
|
|
|
31306
31038
|
function PreManualRebase() {
|
|
31307
|
-
return reactExports.createElement(Await, { fallback: null, function: run$
|
|
31039
|
+
return reactExports.createElement(Await, { fallback: null, function: run$5 });
|
|
31308
31040
|
}
|
|
31309
|
-
async function run$
|
|
31041
|
+
async function run$5() {
|
|
31310
31042
|
const state = Store.getState();
|
|
31311
31043
|
const actions = state.actions;
|
|
31312
31044
|
const repo_root = state.repo_root;
|
|
@@ -31325,8 +31057,8 @@ async function run$4() {
|
|
|
31325
31057
|
// ./docs/pull_request_template.md
|
|
31326
31058
|
for (const key of PR_TEMPLATE_KEY_LIST) {
|
|
31327
31059
|
const pr_template_fn = PR_TEMPLATE[key];
|
|
31328
|
-
if (
|
|
31329
|
-
pr_template_body = fs.
|
|
31060
|
+
if (await safe_exists(pr_template_fn(repo_root))) {
|
|
31061
|
+
pr_template_body = await fs$1.readFile(pr_template_fn(repo_root), "utf-8");
|
|
31330
31062
|
actions.output(reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { color: colors.yellow }), message: "Using PR template {pr_filepath}", values: {
|
|
31331
31063
|
pr_filepath: reactExports.createElement(Brackets, null, pr_template_fn("")),
|
|
31332
31064
|
} }));
|
|
@@ -31335,8 +31067,8 @@ async function run$4() {
|
|
|
31335
31067
|
}
|
|
31336
31068
|
// ./.github/PULL_REQUEST_TEMPLATE/*.md
|
|
31337
31069
|
let pr_templates = [];
|
|
31338
|
-
if (
|
|
31339
|
-
pr_templates = fs.
|
|
31070
|
+
if (await safe_exists(PR_TEMPLATE.TemplateDir(repo_root))) {
|
|
31071
|
+
pr_templates = await fs$1.readdir(PR_TEMPLATE.TemplateDir(repo_root));
|
|
31340
31072
|
}
|
|
31341
31073
|
// check if repo has multiple pr templates
|
|
31342
31074
|
actions.set((state) => {
|
|
@@ -31815,9 +31547,9 @@ const SYMBOL = {
|
|
|
31815
31547
|
};
|
|
31816
31548
|
|
|
31817
31549
|
function Status() {
|
|
31818
|
-
return reactExports.createElement(Await, { fallback: null, function: run$
|
|
31550
|
+
return reactExports.createElement(Await, { fallback: null, function: run$4 });
|
|
31819
31551
|
}
|
|
31820
|
-
async function run$
|
|
31552
|
+
async function run$4() {
|
|
31821
31553
|
const state = Store.getState();
|
|
31822
31554
|
const actions = state.actions;
|
|
31823
31555
|
const argv = state.argv;
|
|
@@ -31862,6 +31594,366 @@ async function run$3() {
|
|
|
31862
31594
|
}
|
|
31863
31595
|
}
|
|
31864
31596
|
|
|
31597
|
+
/**
|
|
31598
|
+
* Gets the last element of `array`.
|
|
31599
|
+
*
|
|
31600
|
+
* @static
|
|
31601
|
+
* @memberOf _
|
|
31602
|
+
* @since 0.1.0
|
|
31603
|
+
* @category Array
|
|
31604
|
+
* @param {Array} array The array to query.
|
|
31605
|
+
* @returns {*} Returns the last element of `array`.
|
|
31606
|
+
* @example
|
|
31607
|
+
*
|
|
31608
|
+
* _.last([1, 2, 3]);
|
|
31609
|
+
* // => 3
|
|
31610
|
+
*/
|
|
31611
|
+
|
|
31612
|
+
function last(array) {
|
|
31613
|
+
var length = array == null ? 0 : array.length;
|
|
31614
|
+
return length ? array[length - 1] : undefined;
|
|
31615
|
+
}
|
|
31616
|
+
|
|
31617
|
+
var last_1 = last;
|
|
31618
|
+
|
|
31619
|
+
var last$1 = /*@__PURE__*/getDefaultExportFromCjs(last_1);
|
|
31620
|
+
|
|
31621
|
+
function write(args) {
|
|
31622
|
+
const stack_table = table(args);
|
|
31623
|
+
let result = args.body;
|
|
31624
|
+
if (RE.stack_table_link.test(result)) {
|
|
31625
|
+
// replace stack table
|
|
31626
|
+
result = result.replace(RE.stack_table_link, stack_table);
|
|
31627
|
+
}
|
|
31628
|
+
else if (RE.stack_table_legacy.test(result)) {
|
|
31629
|
+
// replace stack table
|
|
31630
|
+
result = result.replace(RE.stack_table_legacy, stack_table);
|
|
31631
|
+
}
|
|
31632
|
+
else {
|
|
31633
|
+
// append stack table
|
|
31634
|
+
result = `${result}\n\n${stack_table}`;
|
|
31635
|
+
}
|
|
31636
|
+
result = result.trimEnd();
|
|
31637
|
+
return result;
|
|
31638
|
+
}
|
|
31639
|
+
function table(args) {
|
|
31640
|
+
const stack_pr_url_list = [...args.pr_url_list];
|
|
31641
|
+
const old_stack = parse(args.body);
|
|
31642
|
+
// remove existing stack pr urls from the old stack pr urls
|
|
31643
|
+
for (const pr_url of stack_pr_url_list) {
|
|
31644
|
+
old_stack.delete(pr_url);
|
|
31645
|
+
}
|
|
31646
|
+
// add remaining old stack pr urls to the front of stack pr url list
|
|
31647
|
+
const old_pr_list = Array.from(old_stack.keys());
|
|
31648
|
+
old_pr_list.reverse();
|
|
31649
|
+
for (const pr_url of old_pr_list) {
|
|
31650
|
+
stack_pr_url_list.unshift(pr_url);
|
|
31651
|
+
}
|
|
31652
|
+
const stack_list = [];
|
|
31653
|
+
const num_digits = String(stack_pr_url_list.length).length;
|
|
31654
|
+
for (let i = 0; i < stack_pr_url_list.length; i++) {
|
|
31655
|
+
const pr_url = stack_pr_url_list[i];
|
|
31656
|
+
const selected = args.selected_url === pr_url;
|
|
31657
|
+
let icon;
|
|
31658
|
+
if (old_stack.has(pr_url)) {
|
|
31659
|
+
icon = "✅";
|
|
31660
|
+
}
|
|
31661
|
+
else if (selected) {
|
|
31662
|
+
icon = "👉";
|
|
31663
|
+
}
|
|
31664
|
+
else {
|
|
31665
|
+
icon = "⏳";
|
|
31666
|
+
}
|
|
31667
|
+
const num = String(i + 1).padStart(num_digits, "0");
|
|
31668
|
+
stack_list.push(TEMPLATE.row({ icon, num, pr_url }));
|
|
31669
|
+
}
|
|
31670
|
+
if (!stack_list.length) {
|
|
31671
|
+
return "";
|
|
31672
|
+
}
|
|
31673
|
+
return TEMPLATE.stack_table_link(["", ...stack_list, "", ""].join("\n"));
|
|
31674
|
+
}
|
|
31675
|
+
function parse(body) {
|
|
31676
|
+
let stack_table_match = body.match(RE.stack_table_link);
|
|
31677
|
+
if (!stack_table_match?.groups) {
|
|
31678
|
+
stack_table_match = body.match(RE.stack_table_legacy);
|
|
31679
|
+
}
|
|
31680
|
+
if (!stack_table_match?.groups) {
|
|
31681
|
+
return new Map();
|
|
31682
|
+
}
|
|
31683
|
+
const rows_string = stack_table_match.groups["rows"];
|
|
31684
|
+
const row_list = rows_string.split("\n");
|
|
31685
|
+
const result = new Map();
|
|
31686
|
+
for (const row of row_list) {
|
|
31687
|
+
const row_match = row.match(RE.row);
|
|
31688
|
+
const parsed_row = row_match?.groups;
|
|
31689
|
+
if (!parsed_row) {
|
|
31690
|
+
// skip invalid row
|
|
31691
|
+
continue;
|
|
31692
|
+
}
|
|
31693
|
+
if (!RE.pr_url.test(parsed_row.pr_url)) {
|
|
31694
|
+
continue;
|
|
31695
|
+
}
|
|
31696
|
+
result.set(parsed_row.pr_url, parsed_row);
|
|
31697
|
+
}
|
|
31698
|
+
return result;
|
|
31699
|
+
}
|
|
31700
|
+
const TEMPLATE = {
|
|
31701
|
+
stack_table_legacy(rows) {
|
|
31702
|
+
return `#### git stack${rows}`;
|
|
31703
|
+
},
|
|
31704
|
+
stack_table_link(rows) {
|
|
31705
|
+
return `#### [git stack](https://github.com/magus/git-stack-cli)${rows}`;
|
|
31706
|
+
},
|
|
31707
|
+
row(args) {
|
|
31708
|
+
return `- ${args.icon} \`${args.num}\` ${args.pr_url}`;
|
|
31709
|
+
},
|
|
31710
|
+
};
|
|
31711
|
+
const RE = {
|
|
31712
|
+
// https://regex101.com/r/kqB9Ft/1
|
|
31713
|
+
stack_table_legacy: new RegExp(TEMPLATE.stack_table_legacy("\\s+(?<rows>(?:- [^\r^\n]*(?:[\r\n]+)?)+)")),
|
|
31714
|
+
stack_table_link: new RegExp(TEMPLATE.stack_table_link("ROWS")
|
|
31715
|
+
.replace("[", "\\[")
|
|
31716
|
+
.replace("]", "\\]")
|
|
31717
|
+
.replace("(", "\\(")
|
|
31718
|
+
.replace(")", "\\)")
|
|
31719
|
+
.replace("ROWS", "\\s+(?<rows>(?:- [^\r^\n]*(?:[\r\n]+)?)+)")),
|
|
31720
|
+
row: new RegExp(TEMPLATE.row({
|
|
31721
|
+
icon: "(?<icon>.+)",
|
|
31722
|
+
num: "(?<num>\\d+)",
|
|
31723
|
+
pr_url: "(?<pr_url>.+)",
|
|
31724
|
+
})),
|
|
31725
|
+
pr_url: /^https:\/\/.*$/,
|
|
31726
|
+
};
|
|
31727
|
+
|
|
31728
|
+
function SyncGithub() {
|
|
31729
|
+
const abort_handler = reactExports.useRef(() => { });
|
|
31730
|
+
reactExports.useEffect(function listen_sigint() {
|
|
31731
|
+
process.once("SIGINT", sigint_handler);
|
|
31732
|
+
return function cleanup() {
|
|
31733
|
+
process.removeListener("SIGINT", sigint_handler);
|
|
31734
|
+
};
|
|
31735
|
+
function sigint_handler() {
|
|
31736
|
+
abort_handler.current();
|
|
31737
|
+
}
|
|
31738
|
+
}, []);
|
|
31739
|
+
return (reactExports.createElement(Await, { fallback: reactExports.createElement(Text, { color: colors.yellow }, "Syncing\u2026"), function: async function () {
|
|
31740
|
+
await run$3({ abort_handler });
|
|
31741
|
+
} }));
|
|
31742
|
+
}
|
|
31743
|
+
async function run$3(args) {
|
|
31744
|
+
const state = Store.getState();
|
|
31745
|
+
const actions = state.actions;
|
|
31746
|
+
const argv = state.argv;
|
|
31747
|
+
const branch_name = state.branch_name;
|
|
31748
|
+
const commit_map = state.commit_map;
|
|
31749
|
+
const master_branch = state.master_branch;
|
|
31750
|
+
const repo_root = state.repo_root;
|
|
31751
|
+
const sync_github = state.sync_github;
|
|
31752
|
+
invariant(branch_name, "branch_name must exist");
|
|
31753
|
+
invariant(commit_map, "commit_map must exist");
|
|
31754
|
+
invariant(repo_root, "repo_root must exist");
|
|
31755
|
+
invariant(sync_github, "sync_github must exist");
|
|
31756
|
+
const commit_range = sync_github.commit_range;
|
|
31757
|
+
const rebase_group_index = sync_github.rebase_group_index;
|
|
31758
|
+
// always listen for SIGINT event and restore pr state
|
|
31759
|
+
args.abort_handler.current = function sigint_handler() {
|
|
31760
|
+
actions.output(reactExports.createElement(Text, { color: colors.red }, "\uD83D\uDEA8 Abort"));
|
|
31761
|
+
handle_exit(17);
|
|
31762
|
+
};
|
|
31763
|
+
let DEFAULT_PR_BODY = "";
|
|
31764
|
+
if (state.pr_template_body) {
|
|
31765
|
+
DEFAULT_PR_BODY = state.pr_template_body;
|
|
31766
|
+
}
|
|
31767
|
+
const push_group_list = get_push_group_list();
|
|
31768
|
+
// for all push targets in push_group_list
|
|
31769
|
+
// things that can be done in parallel are grouped by numbers
|
|
31770
|
+
//
|
|
31771
|
+
// -----------------------------------
|
|
31772
|
+
// 1 (before_push) temp mark draft
|
|
31773
|
+
// --------------------------------------
|
|
31774
|
+
// 2 push simultaneously to github
|
|
31775
|
+
// --------------------------------------
|
|
31776
|
+
// 2 create PR / edit PR
|
|
31777
|
+
// 2 (after_push) undo temp mark draft
|
|
31778
|
+
// --------------------------------------
|
|
31779
|
+
try {
|
|
31780
|
+
const before_push_tasks = [];
|
|
31781
|
+
for (const group of push_group_list) {
|
|
31782
|
+
before_push_tasks.push(before_push({ group }));
|
|
31783
|
+
}
|
|
31784
|
+
await Promise.all(before_push_tasks);
|
|
31785
|
+
// git push -f origin HEAD~6:OtVX7Qvrw HEAD~3:E63ytp5dj HEAD~2:gs-NBabNSjXA HEAD~1:gs-UGVJdKNoD HEAD~0:gs-6LAx-On4
|
|
31786
|
+
const git_push_command = [`git push -f origin`];
|
|
31787
|
+
if (argv.verify === false) {
|
|
31788
|
+
git_push_command.push("--no-verify");
|
|
31789
|
+
}
|
|
31790
|
+
for (const group of push_group_list) {
|
|
31791
|
+
const last_commit = last$1(group.commits);
|
|
31792
|
+
invariant(last_commit, "last_commit must exist");
|
|
31793
|
+
const target = `${last_commit.sha}:${group.id}`;
|
|
31794
|
+
git_push_command.push(target);
|
|
31795
|
+
}
|
|
31796
|
+
await cli(git_push_command);
|
|
31797
|
+
const pr_url_list = commit_range.group_list.map(get_group_url);
|
|
31798
|
+
const after_push_tasks = [];
|
|
31799
|
+
for (const group of push_group_list) {
|
|
31800
|
+
after_push_tasks.push(after_push({ group, pr_url_list }));
|
|
31801
|
+
}
|
|
31802
|
+
await Promise.all(after_push_tasks);
|
|
31803
|
+
// finally, ensure all prs have the updated stack table from updated pr_url_list
|
|
31804
|
+
// this step must come after the after_push since that step may create new PRs
|
|
31805
|
+
// we need the urls for all prs at this step so we run it after the after_push
|
|
31806
|
+
const update_pr_body_tasks = [];
|
|
31807
|
+
for (let i = 0; i < commit_range.group_list.length; i++) {
|
|
31808
|
+
const group = commit_range.group_list[i];
|
|
31809
|
+
// use the updated pr_url_list to get the actual selected_url
|
|
31810
|
+
const selected_url = pr_url_list[i];
|
|
31811
|
+
const task = update_pr_body({ group, selected_url, pr_url_list });
|
|
31812
|
+
update_pr_body_tasks.push(task);
|
|
31813
|
+
}
|
|
31814
|
+
await Promise.all(update_pr_body_tasks);
|
|
31815
|
+
actions.set((state) => {
|
|
31816
|
+
state.step = "post-rebase-status";
|
|
31817
|
+
});
|
|
31818
|
+
}
|
|
31819
|
+
catch (err) {
|
|
31820
|
+
if (err instanceof Error) {
|
|
31821
|
+
actions.error(err.message);
|
|
31822
|
+
}
|
|
31823
|
+
actions.error("Unable to sync.");
|
|
31824
|
+
if (!argv.verbose) {
|
|
31825
|
+
actions.error("Try again with `--verbose` to see more information.");
|
|
31826
|
+
}
|
|
31827
|
+
await handle_exit(18);
|
|
31828
|
+
}
|
|
31829
|
+
function get_push_group_list() {
|
|
31830
|
+
// start from HEAD and work backward to rebase_group_index
|
|
31831
|
+
const push_group_list = [];
|
|
31832
|
+
for (let i = 0; i < commit_range.group_list.length; i++) {
|
|
31833
|
+
const index = commit_range.group_list.length - 1 - i;
|
|
31834
|
+
// do not go past rebase_group_index
|
|
31835
|
+
if (index < rebase_group_index) {
|
|
31836
|
+
break;
|
|
31837
|
+
}
|
|
31838
|
+
const group = commit_range.group_list[index];
|
|
31839
|
+
push_group_list.unshift(group);
|
|
31840
|
+
}
|
|
31841
|
+
return push_group_list;
|
|
31842
|
+
}
|
|
31843
|
+
async function before_push(args) {
|
|
31844
|
+
const { group } = args;
|
|
31845
|
+
invariant(group.base, "group.base must exist");
|
|
31846
|
+
// we may temporarily mark PR as a draft before editing it
|
|
31847
|
+
// if it is not already a draft PR, to avoid notification spam
|
|
31848
|
+
let is_temp_draft = !group.pr?.isDraft;
|
|
31849
|
+
// before pushing reset base to master temporarily
|
|
31850
|
+
// avoid accidentally pointing to orphaned parent commit
|
|
31851
|
+
// should hopefully fix issues where a PR includes a bunch of commits after pushing
|
|
31852
|
+
if (group.pr) {
|
|
31853
|
+
if (!group.pr.isDraft) {
|
|
31854
|
+
is_temp_draft = true;
|
|
31855
|
+
}
|
|
31856
|
+
if (is_temp_draft) {
|
|
31857
|
+
await pr_draft({
|
|
31858
|
+
branch: group.id,
|
|
31859
|
+
draft: true,
|
|
31860
|
+
});
|
|
31861
|
+
}
|
|
31862
|
+
await pr_edit({
|
|
31863
|
+
branch: group.id,
|
|
31864
|
+
base: master_branch,
|
|
31865
|
+
});
|
|
31866
|
+
}
|
|
31867
|
+
}
|
|
31868
|
+
async function after_push(args) {
|
|
31869
|
+
const { group, pr_url_list } = args;
|
|
31870
|
+
invariant(group.base, "group.base must exist");
|
|
31871
|
+
const selected_url = get_group_url(group);
|
|
31872
|
+
if (group.pr) {
|
|
31873
|
+
// ensure base matches pr in github
|
|
31874
|
+
await pr_edit({
|
|
31875
|
+
branch: group.id,
|
|
31876
|
+
base: group.base,
|
|
31877
|
+
body: write({
|
|
31878
|
+
body: group.pr.body,
|
|
31879
|
+
pr_url_list,
|
|
31880
|
+
selected_url,
|
|
31881
|
+
}),
|
|
31882
|
+
});
|
|
31883
|
+
// we may temporarily mark PR as a draft before editing it
|
|
31884
|
+
// if it is not already a draft PR, to avoid notification spam
|
|
31885
|
+
let is_temp_draft = !group.pr?.isDraft;
|
|
31886
|
+
if (is_temp_draft) {
|
|
31887
|
+
// mark pr as ready for review again
|
|
31888
|
+
await pr_draft({
|
|
31889
|
+
branch: group.id,
|
|
31890
|
+
draft: false,
|
|
31891
|
+
});
|
|
31892
|
+
}
|
|
31893
|
+
}
|
|
31894
|
+
else {
|
|
31895
|
+
// create pr in github
|
|
31896
|
+
const pr_url = await pr_create({
|
|
31897
|
+
branch: group.id,
|
|
31898
|
+
base: group.base,
|
|
31899
|
+
title: group.title,
|
|
31900
|
+
body: DEFAULT_PR_BODY,
|
|
31901
|
+
draft: argv.draft,
|
|
31902
|
+
});
|
|
31903
|
+
if (!pr_url) {
|
|
31904
|
+
throw new Error("unable to create pr");
|
|
31905
|
+
}
|
|
31906
|
+
// update pr_url_list with created pr_url
|
|
31907
|
+
for (let i = 0; i < pr_url_list.length; i++) {
|
|
31908
|
+
const url = pr_url_list[i];
|
|
31909
|
+
if (url === selected_url) {
|
|
31910
|
+
pr_url_list[i] = pr_url;
|
|
31911
|
+
}
|
|
31912
|
+
}
|
|
31913
|
+
}
|
|
31914
|
+
}
|
|
31915
|
+
async function update_pr_body(args) {
|
|
31916
|
+
const { group, selected_url, pr_url_list } = args;
|
|
31917
|
+
invariant(group.base, "group.base must exist");
|
|
31918
|
+
const body = group.pr?.body || DEFAULT_PR_BODY;
|
|
31919
|
+
const update_body = write({
|
|
31920
|
+
body,
|
|
31921
|
+
pr_url_list,
|
|
31922
|
+
selected_url,
|
|
31923
|
+
});
|
|
31924
|
+
if (update_body === body) {
|
|
31925
|
+
actions.debug(`Skipping body update for ${selected_url}`);
|
|
31926
|
+
}
|
|
31927
|
+
else {
|
|
31928
|
+
actions.debug(`Update body for ${selected_url}`);
|
|
31929
|
+
await pr_edit({
|
|
31930
|
+
branch: group.id,
|
|
31931
|
+
base: group.base,
|
|
31932
|
+
body: update_body,
|
|
31933
|
+
});
|
|
31934
|
+
}
|
|
31935
|
+
}
|
|
31936
|
+
function handle_exit(code) {
|
|
31937
|
+
actions.output(reactExports.createElement(Text, { color: colors.yellow }, "Restoring PR state\u2026"));
|
|
31938
|
+
for (const group of push_group_list) {
|
|
31939
|
+
// we may temporarily mark PR as a draft before editing it
|
|
31940
|
+
// if it is not already a draft PR, to avoid notification spam
|
|
31941
|
+
let is_temp_draft = !group.pr?.isDraft;
|
|
31942
|
+
// restore PR to non-draft state
|
|
31943
|
+
if (is_temp_draft) {
|
|
31944
|
+
pr_draft({
|
|
31945
|
+
branch: group.id,
|
|
31946
|
+
draft: false,
|
|
31947
|
+
})
|
|
31948
|
+
.catch(actions.error);
|
|
31949
|
+
}
|
|
31950
|
+
}
|
|
31951
|
+
actions.output(reactExports.createElement(Text, { color: colors.yellow }, "Restored PR state."));
|
|
31952
|
+
actions.exit(code);
|
|
31953
|
+
}
|
|
31954
|
+
}
|
|
31955
|
+
const get_group_url = (group) => group.pr?.url || group.id;
|
|
31956
|
+
|
|
31865
31957
|
function Main() {
|
|
31866
31958
|
const step = Store.useState((state) => state.step);
|
|
31867
31959
|
switch (step) {
|
|
@@ -31883,6 +31975,8 @@ function Main() {
|
|
|
31883
31975
|
return reactExports.createElement(PreManualRebase, null);
|
|
31884
31976
|
case "manual-rebase":
|
|
31885
31977
|
return reactExports.createElement(ManualRebase, null);
|
|
31978
|
+
case "sync-github":
|
|
31979
|
+
return reactExports.createElement(SyncGithub, null);
|
|
31886
31980
|
case "post-rebase-status":
|
|
31887
31981
|
return reactExports.createElement(PostRebaseStatus, null);
|
|
31888
31982
|
default:
|
|
@@ -31943,8 +32037,8 @@ function RebaseCheck(props) {
|
|
|
31943
32037
|
try {
|
|
31944
32038
|
const git_dir = (await cli(`git rev-parse --absolute-git-dir`)).stdout;
|
|
31945
32039
|
let is_rebase = false;
|
|
31946
|
-
is_rebase ||=
|
|
31947
|
-
is_rebase ||=
|
|
32040
|
+
is_rebase ||= await safe_exists(path.join(git_dir, "rebase-apply"));
|
|
32041
|
+
is_rebase ||= await safe_exists(path.join(git_dir, "rebase-merge"));
|
|
31948
32042
|
const status = is_rebase ? "prompt" : "done";
|
|
31949
32043
|
patch({ status });
|
|
31950
32044
|
}
|
|
@@ -32151,7 +32245,7 @@ function MaybeMain() {
|
|
|
32151
32245
|
else if (positional_list.has("rebase")) {
|
|
32152
32246
|
return (reactExports.createElement(GatherMetadata, null,
|
|
32153
32247
|
reactExports.createElement(LocalCommitStatus, null,
|
|
32154
|
-
reactExports.createElement(Rebase
|
|
32248
|
+
reactExports.createElement(Rebase, null))));
|
|
32155
32249
|
}
|
|
32156
32250
|
return (reactExports.createElement(DirtyCheck, null,
|
|
32157
32251
|
!argv.verbose ? null : reactExports.createElement(GithubApiError, null),
|
|
@@ -32490,14 +32584,14 @@ function ui (opts) {
|
|
|
32490
32584
|
|
|
32491
32585
|
function escalade (start, callback) {
|
|
32492
32586
|
let dir = path$1.resolve('.', start);
|
|
32493
|
-
let tmp, stats = fs$
|
|
32587
|
+
let tmp, stats = fs$2.statSync(dir);
|
|
32494
32588
|
|
|
32495
32589
|
if (!stats.isDirectory()) {
|
|
32496
32590
|
dir = path$1.dirname(dir);
|
|
32497
32591
|
}
|
|
32498
32592
|
|
|
32499
32593
|
while (true) {
|
|
32500
|
-
tmp = callback(dir, fs$
|
|
32594
|
+
tmp = callback(dir, fs$2.readdirSync(dir));
|
|
32501
32595
|
if (tmp) return path$1.resolve(dir, tmp);
|
|
32502
32596
|
dir = path$1.dirname(tmp = dir);
|
|
32503
32597
|
if (tmp === dir) break;
|
|
@@ -33703,7 +33797,7 @@ const parser = new YargsParser({
|
|
|
33703
33797
|
}
|
|
33704
33798
|
else if (path.match(/\.json$/)) {
|
|
33705
33799
|
// Addresses: https://github.com/yargs/yargs/issues/2040
|
|
33706
|
-
return JSON.parse(fs$
|
|
33800
|
+
return JSON.parse(fs$2.readFileSync(path, 'utf8'));
|
|
33707
33801
|
}
|
|
33708
33802
|
else {
|
|
33709
33803
|
throw Error('only .json config files are supported in ESM');
|
|
@@ -33751,14 +33845,14 @@ class YError extends Error {
|
|
|
33751
33845
|
|
|
33752
33846
|
var shim$3 = {
|
|
33753
33847
|
fs: {
|
|
33754
|
-
readFileSync: fs$
|
|
33755
|
-
writeFile: fs$
|
|
33848
|
+
readFileSync: fs$2.readFileSync,
|
|
33849
|
+
writeFile: fs$2.writeFile
|
|
33756
33850
|
},
|
|
33757
33851
|
format: util.format,
|
|
33758
33852
|
resolve: path$1.resolve,
|
|
33759
33853
|
exists: (file) => {
|
|
33760
33854
|
try {
|
|
33761
|
-
return fs$
|
|
33855
|
+
return fs$2.statSync(file).isFile();
|
|
33762
33856
|
}
|
|
33763
33857
|
catch (err) {
|
|
33764
33858
|
return false;
|
|
@@ -33989,7 +34083,7 @@ var shim$1 = {
|
|
|
33989
34083
|
nextTick: process.nextTick,
|
|
33990
34084
|
stdColumns: typeof process.stdout.columns !== 'undefined' ? process.stdout.columns : null
|
|
33991
34085
|
},
|
|
33992
|
-
readFileSync: fs$
|
|
34086
|
+
readFileSync: fs$2.readFileSync,
|
|
33993
34087
|
require: () => {
|
|
33994
34088
|
throw new YError(REQUIRE_ERROR)
|
|
33995
34089
|
},
|
|
@@ -37479,15 +37573,11 @@ async function command() {
|
|
|
37479
37573
|
.wrap(123)
|
|
37480
37574
|
// disallow unknown options
|
|
37481
37575
|
.strict()
|
|
37482
|
-
.version("1.
|
|
37576
|
+
.version("1.13.1" )
|
|
37483
37577
|
.showHidden("show-hidden", "Show hidden options via `git stack help --show-hidden`")
|
|
37484
37578
|
.help("help", "Show usage via `git stack help`")
|
|
37485
37579
|
.argv;
|
|
37486
37580
|
}
|
|
37487
|
-
const Rebase = Object.freeze({
|
|
37488
|
-
"git-revise": "git-revise",
|
|
37489
|
-
"cherry-pick": "cherry-pick",
|
|
37490
|
-
});
|
|
37491
37581
|
const GlobalOptions = {
|
|
37492
37582
|
verbose: {
|
|
37493
37583
|
type: "boolean",
|
|
@@ -37520,16 +37610,6 @@ const DefaultOptions = {
|
|
|
37520
37610
|
default: true,
|
|
37521
37611
|
description: "Run git hooks such as pre-commit and pre-push, disable with --no-verify",
|
|
37522
37612
|
},
|
|
37523
|
-
"rebase": {
|
|
37524
|
-
type: "string",
|
|
37525
|
-
choices: [Rebase["git-revise"], Rebase["cherry-pick"]],
|
|
37526
|
-
default: Rebase["git-revise"],
|
|
37527
|
-
description: [
|
|
37528
|
-
"Strategy used for syncing branches",
|
|
37529
|
-
`${Rebase["git-revise"]}: perform faster in-memory rebase`,
|
|
37530
|
-
`${Rebase["cherry-pick"]}: use disk and incrementally rebase each commit`,
|
|
37531
|
-
].join(" | "),
|
|
37532
|
-
},
|
|
37533
37613
|
"update": {
|
|
37534
37614
|
type: "boolean",
|
|
37535
37615
|
alias: ["u", "upgrade"],
|
|
@@ -37578,7 +37658,10 @@ const FixupOptions = {
|
|
|
37578
37658
|
|
|
37579
37659
|
command()
|
|
37580
37660
|
.then((argv) => {
|
|
37581
|
-
const ink = render(reactExports.createElement(App, null)
|
|
37661
|
+
const ink = render(reactExports.createElement(App, null), {
|
|
37662
|
+
// If true, each update will be rendered as a separate output, without replacing the previous one.
|
|
37663
|
+
// debug: true,
|
|
37664
|
+
});
|
|
37582
37665
|
Store.setState((state) => {
|
|
37583
37666
|
state.ink = ink;
|
|
37584
37667
|
state.process_argv = process.argv;
|