git-stack-cli 1.12.0 → 1.13.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 +11 -1
- package/dist/cjs/index.cjs +154 -203
- 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/ManualRebase.tsx +114 -183
- package/src/app/PreManualRebase.tsx +6 -5
- package/src/app/RebaseCheck.tsx +3 -3
- package/src/command.ts +0 -16
- package/src/commands/Rebase.tsx +2 -15
- 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/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
|
|
|
@@ -26520,9 +26521,9 @@ function is_finite_value(value) {
|
|
|
26520
26521
|
return typeof value === "number" && Number.isFinite(value);
|
|
26521
26522
|
}
|
|
26522
26523
|
|
|
26523
|
-
function read_json(path) {
|
|
26524
|
+
async function read_json(path) {
|
|
26524
26525
|
try {
|
|
26525
|
-
const file_buffer = fs.
|
|
26526
|
+
const file_buffer = await fs$1.readFile(path);
|
|
26526
26527
|
const json_str = String(file_buffer);
|
|
26527
26528
|
const json = JSON.parse(json_str);
|
|
26528
26529
|
return json;
|
|
@@ -26607,10 +26608,11 @@ function AutoUpdate(props) {
|
|
|
26607
26608
|
if (!latest_version) {
|
|
26608
26609
|
throw new Error("Unable to retrieve latest version from npm");
|
|
26609
26610
|
}
|
|
26610
|
-
const
|
|
26611
|
+
const script_path = await fs$1.realpath(process.argv[1]);
|
|
26612
|
+
const script_dir = path.dirname(script_path);
|
|
26611
26613
|
// dist/ts/index.js
|
|
26612
26614
|
const package_json_path = path.join(script_dir, "..", "..", "package.json");
|
|
26613
|
-
const package_json = read_json(package_json_path);
|
|
26615
|
+
const package_json = await read_json(package_json_path);
|
|
26614
26616
|
if (!package_json) {
|
|
26615
26617
|
// unable to find read package.json, skip auto update
|
|
26616
26618
|
throw new Error(`Unable to read package.json [${package_json_path}]`);
|
|
@@ -26773,6 +26775,16 @@ function Command(props) {
|
|
|
26773
26775
|
return (reactExports.createElement(Text, { bold: true, color: text_color }, props.children));
|
|
26774
26776
|
}
|
|
26775
26777
|
|
|
26778
|
+
async function safe_exists(filepath) {
|
|
26779
|
+
try {
|
|
26780
|
+
await fs$1.access(filepath);
|
|
26781
|
+
return true;
|
|
26782
|
+
}
|
|
26783
|
+
catch {
|
|
26784
|
+
return false;
|
|
26785
|
+
}
|
|
26786
|
+
}
|
|
26787
|
+
|
|
26776
26788
|
function reducer$3(state, patch) {
|
|
26777
26789
|
return { ...state, ...patch };
|
|
26778
26790
|
}
|
|
@@ -26803,7 +26815,8 @@ function CherryPickCheck(props) {
|
|
|
26803
26815
|
const actions = Store.getState().actions;
|
|
26804
26816
|
try {
|
|
26805
26817
|
const git_dir = (await cli(`git rev-parse --absolute-git-dir`)).stdout;
|
|
26806
|
-
const
|
|
26818
|
+
const cherry_pick_file = path.join(git_dir, "CHERRY_PICK_HEAD");
|
|
26819
|
+
const is_cherry_pick = await safe_exists(cherry_pick_file);
|
|
26807
26820
|
const status = is_cherry_pick ? "prompt" : "done";
|
|
26808
26821
|
patch({ status });
|
|
26809
26822
|
}
|
|
@@ -26855,6 +26868,16 @@ function deserialize(obj) {
|
|
|
26855
26868
|
return obj;
|
|
26856
26869
|
}
|
|
26857
26870
|
|
|
26871
|
+
async function safe_rm(filepath) {
|
|
26872
|
+
try {
|
|
26873
|
+
await fs$1.access(filepath);
|
|
26874
|
+
await fs$1.rm(filepath);
|
|
26875
|
+
}
|
|
26876
|
+
catch {
|
|
26877
|
+
// if access fails there is no file to remove this is safe
|
|
26878
|
+
}
|
|
26879
|
+
}
|
|
26880
|
+
|
|
26858
26881
|
function Debug() {
|
|
26859
26882
|
const actions = Store.useActions();
|
|
26860
26883
|
const state = Store.useState((state) => state);
|
|
@@ -26865,17 +26888,18 @@ function Debug() {
|
|
|
26865
26888
|
actions.output(reactExports.createElement(Text, { color: colors.yellow }, "Debug mode enabled"));
|
|
26866
26889
|
}
|
|
26867
26890
|
}, [argv]);
|
|
26868
|
-
reactExports.useEffect(function
|
|
26891
|
+
reactExports.useEffect(function sync_state_json() {
|
|
26869
26892
|
if (!argv?.["write-state-json"]) {
|
|
26870
26893
|
return;
|
|
26871
26894
|
}
|
|
26872
|
-
|
|
26873
|
-
|
|
26874
|
-
|
|
26895
|
+
sync().catch(actions.error);
|
|
26896
|
+
async function sync() {
|
|
26897
|
+
const output_file = path.join(state.cwd, "git-stack-state.json");
|
|
26898
|
+
await safe_rm(output_file);
|
|
26899
|
+
const serialized = serialize(state);
|
|
26900
|
+
const content = JSON.stringify(serialized, null, 2);
|
|
26901
|
+
await fs$1.writeFile(output_file, content);
|
|
26875
26902
|
}
|
|
26876
|
-
const serialized = serialize(state);
|
|
26877
|
-
const content = JSON.stringify(serialized, null, 2);
|
|
26878
|
-
fs.writeFileSync(output_file, content);
|
|
26879
26903
|
}, [argv, state]);
|
|
26880
26904
|
return null;
|
|
26881
26905
|
}
|
|
@@ -27005,11 +27029,6 @@ function CheckGithubCliAuth(props) {
|
|
|
27005
27029
|
}
|
|
27006
27030
|
function CheckGitRevise(props) {
|
|
27007
27031
|
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
27032
|
return (reactExports.createElement(Await, { fallback: reactExports.createElement(Text, { color: colors.yellow },
|
|
27014
27033
|
reactExports.createElement(Text, null,
|
|
27015
27034
|
"Checking ",
|
|
@@ -29776,7 +29795,8 @@ async function pr_create(args) {
|
|
|
29776
29795
|
async function pr_edit(args) {
|
|
29777
29796
|
const command_parts = [`gh pr edit ${args.branch} --base ${args.base}`];
|
|
29778
29797
|
if (args.body) {
|
|
29779
|
-
|
|
29798
|
+
const body_file = await write_body_file(args);
|
|
29799
|
+
command_parts.push(`--body-file="${body_file}"`);
|
|
29780
29800
|
}
|
|
29781
29801
|
const command = command_parts.join(" ");
|
|
29782
29802
|
const cli_result = await cli(command);
|
|
@@ -29785,6 +29805,9 @@ async function pr_edit(args) {
|
|
|
29785
29805
|
}
|
|
29786
29806
|
}
|
|
29787
29807
|
async function pr_draft(args) {
|
|
29808
|
+
// https://cli.github.com/manual/gh_api
|
|
29809
|
+
// https://docs.github.com/en/graphql/reference/mutations#convertpullrequesttodraft
|
|
29810
|
+
// https://docs.github.com/en/graphql/reference/mutations#markpullrequestreadyforreview
|
|
29788
29811
|
const mutation_name = args.draft
|
|
29789
29812
|
? "convertPullRequestToDraft"
|
|
29790
29813
|
: "markPullRequestReadyForReview";
|
|
@@ -29827,7 +29850,7 @@ async function gh_json(command) {
|
|
|
29827
29850
|
return new Error(cli_result.output);
|
|
29828
29851
|
}
|
|
29829
29852
|
// read from file
|
|
29830
|
-
const json_str = fs.
|
|
29853
|
+
const json_str = await fs$1.readFile(tmp_pr_json, "utf-8");
|
|
29831
29854
|
const json = JSON.parse(json_str);
|
|
29832
29855
|
return json;
|
|
29833
29856
|
}
|
|
@@ -29840,13 +29863,12 @@ function handle_error(output) {
|
|
|
29840
29863
|
throw new Error(output);
|
|
29841
29864
|
}
|
|
29842
29865
|
// convert a string to a file for use via github cli `--body-file`
|
|
29843
|
-
function
|
|
29866
|
+
async function write_body_file(args) {
|
|
29867
|
+
invariant(args.body, "args.body must exist");
|
|
29844
29868
|
const temp_dir = os.tmpdir();
|
|
29845
|
-
const temp_path = path.join(temp_dir,
|
|
29846
|
-
|
|
29847
|
-
|
|
29848
|
-
}
|
|
29849
|
-
fs.writeFileSync(temp_path, body);
|
|
29869
|
+
const temp_path = path.join(temp_dir, `git-stack-body-${args.base}`);
|
|
29870
|
+
await safe_rm(temp_path);
|
|
29871
|
+
await fs$1.writeFile(temp_path, args.body);
|
|
29850
29872
|
return temp_path;
|
|
29851
29873
|
}
|
|
29852
29874
|
|
|
@@ -30128,9 +30150,9 @@ echo "------ END ------"
|
|
|
30128
30150
|
echo "$GIT_REVISE_TODO" > "$git_revise_todo_path"
|
|
30129
30151
|
`;
|
|
30130
30152
|
// write script to temporary path
|
|
30131
|
-
fs.
|
|
30153
|
+
await fs$1.writeFile(tmp_git_sequence_editor_path, GIT_SEQUENCE_EDITOR_SCRIPT);
|
|
30132
30154
|
// ensure script is executable
|
|
30133
|
-
fs.
|
|
30155
|
+
await fs$1.chmod(tmp_git_sequence_editor_path, "755");
|
|
30134
30156
|
const git_revise_todo = GitReviseTodo(args);
|
|
30135
30157
|
// execute cli with temporary git sequence editor script
|
|
30136
30158
|
// revise from merge base to pick correct commits
|
|
@@ -30529,10 +30551,10 @@ function encode(value) {
|
|
|
30529
30551
|
return result.padStart(max_char_size, "=");
|
|
30530
30552
|
}
|
|
30531
30553
|
|
|
30532
|
-
function Rebase
|
|
30533
|
-
return (reactExports.createElement(Await, { function: Rebase
|
|
30554
|
+
function Rebase() {
|
|
30555
|
+
return (reactExports.createElement(Await, { function: Rebase.run, fallback: reactExports.createElement(Text, { color: colors.yellow }, "Rebasing commits\u2026") }));
|
|
30534
30556
|
}
|
|
30535
|
-
Rebase
|
|
30557
|
+
Rebase.run = async function run() {
|
|
30536
30558
|
const state = Store.getState();
|
|
30537
30559
|
const actions = state.actions;
|
|
30538
30560
|
const branch_name = state.branch_name;
|
|
@@ -30586,9 +30608,8 @@ Rebase$1.run = async function run() {
|
|
|
30586
30608
|
const sha_list = picked_commit_list.map((commit) => commit.sha).join(" ");
|
|
30587
30609
|
await cli(`git cherry-pick --keep-redundant-commits ${sha_list}`);
|
|
30588
30610
|
}
|
|
30589
|
-
// after all commits have been cherry-picked
|
|
30590
|
-
//
|
|
30591
|
-
// now we are locally in sync with github and on the original branch
|
|
30611
|
+
// after all commits have been cherry-picked move the pointer
|
|
30612
|
+
// of original branch to the newly created temporary branch
|
|
30592
30613
|
await cli(`git branch -f ${branch_name} ${temp_branch_name}`);
|
|
30593
30614
|
restore_git();
|
|
30594
30615
|
const next_commit_range = await range();
|
|
@@ -30616,8 +30637,6 @@ Rebase$1.run = async function run() {
|
|
|
30616
30637
|
// trying to use `await cli(...)` here will silently fail since
|
|
30617
30638
|
// all children processes receive the SIGINT signal
|
|
30618
30639
|
const spawn_options = { ignoreExitCode: true };
|
|
30619
|
-
// always clean up any patch files
|
|
30620
|
-
cli.sync(`rm ${PATCH_FILE$1}`, spawn_options);
|
|
30621
30640
|
// always hard reset and clean to allow subsequent checkout
|
|
30622
30641
|
// if there are files checkout will fail and cascade fail subsequent commands
|
|
30623
30642
|
cli.sync(`git reset --hard`, spawn_options);
|
|
@@ -30626,12 +30645,6 @@ Rebase$1.run = async function run() {
|
|
|
30626
30645
|
cli.sync(`git checkout ${branch_name}`, spawn_options);
|
|
30627
30646
|
// ...and cleanup temporary branch
|
|
30628
30647
|
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
30648
|
// restore back to original dir
|
|
30636
30649
|
if (fs.existsSync(cwd)) {
|
|
30637
30650
|
process.chdir(cwd);
|
|
@@ -30651,10 +30664,9 @@ Rebase$1.run = async function run() {
|
|
|
30651
30664
|
actions.exit(6);
|
|
30652
30665
|
}
|
|
30653
30666
|
};
|
|
30654
|
-
const PATCH_FILE$1 = "git-stack-cli-patch.patch";
|
|
30655
30667
|
|
|
30656
30668
|
function LocalMergeRebase() {
|
|
30657
|
-
return reactExports.createElement(Rebase
|
|
30669
|
+
return reactExports.createElement(Rebase, null);
|
|
30658
30670
|
}
|
|
30659
30671
|
|
|
30660
30672
|
function write(args) {
|
|
@@ -30827,44 +30839,36 @@ async function run$6() {
|
|
|
30827
30839
|
// must perform rebase from repo root for applying git patch
|
|
30828
30840
|
process.chdir(repo_root);
|
|
30829
30841
|
await cli(`pwd`);
|
|
30830
|
-
|
|
30831
|
-
|
|
30832
|
-
}
|
|
30833
|
-
|
|
30834
|
-
|
|
30835
|
-
|
|
30836
|
-
|
|
30837
|
-
|
|
30838
|
-
//
|
|
30842
|
+
actions.output(reactExports.createElement(Text, { color: colors.yellow, wrap: "truncate-end" }, "Rebasing\u2026"));
|
|
30843
|
+
// create temporary branch
|
|
30844
|
+
await cli(`git checkout -b ${temp_branch_name}`);
|
|
30845
|
+
await GitReviseTodo.execute({
|
|
30846
|
+
rebase_group_index,
|
|
30847
|
+
rebase_merge_base,
|
|
30848
|
+
commit_range,
|
|
30849
|
+
});
|
|
30850
|
+
// after all commits have been modified move the pointer
|
|
30851
|
+
// of original branch to the newly created temporary branch
|
|
30839
30852
|
await cli(`git branch -f ${branch_name} ${temp_branch_name}`);
|
|
30853
|
+
if (argv.sync) {
|
|
30854
|
+
await sync_github();
|
|
30855
|
+
}
|
|
30840
30856
|
restore_git();
|
|
30841
30857
|
actions.set((state) => {
|
|
30842
30858
|
state.step = "post-rebase-status";
|
|
30843
30859
|
});
|
|
30844
30860
|
}
|
|
30845
30861
|
catch (err) {
|
|
30846
|
-
actions.error("Unable to rebase.");
|
|
30847
30862
|
if (err instanceof Error) {
|
|
30848
|
-
|
|
30849
|
-
|
|
30850
|
-
|
|
30863
|
+
actions.error(err.message);
|
|
30864
|
+
}
|
|
30865
|
+
actions.error("Unable to rebase.");
|
|
30866
|
+
if (!argv.verbose) {
|
|
30867
|
+
actions.error("Try again with `--verbose` to see more information.");
|
|
30851
30868
|
}
|
|
30852
30869
|
handle_exit();
|
|
30853
30870
|
}
|
|
30854
|
-
async function
|
|
30855
|
-
actions.debug(`rebase_git_revise`);
|
|
30856
|
-
actions.output(reactExports.createElement(Text, { color: colors.yellow, wrap: "truncate-end" }, "Rebasing\u2026"));
|
|
30857
|
-
// create temporary branch
|
|
30858
|
-
await cli(`git checkout -b ${temp_branch_name}`);
|
|
30859
|
-
await GitReviseTodo.execute({
|
|
30860
|
-
rebase_group_index,
|
|
30861
|
-
rebase_merge_base,
|
|
30862
|
-
commit_range,
|
|
30863
|
-
});
|
|
30864
|
-
// early return since we do not need to sync
|
|
30865
|
-
if (!argv.sync) {
|
|
30866
|
-
return;
|
|
30867
|
-
}
|
|
30871
|
+
async function sync_github() {
|
|
30868
30872
|
// in order to sync we walk from rebase_group_index to HEAD
|
|
30869
30873
|
// checking out each group and syncing to github
|
|
30870
30874
|
// start from HEAD and work backward to rebase_group_index
|
|
@@ -30886,68 +30890,75 @@ async function run$6() {
|
|
|
30886
30890
|
// push group and lookback_index onto front of push_group_list
|
|
30887
30891
|
push_group_list.unshift({ group, lookback_index });
|
|
30888
30892
|
}
|
|
30893
|
+
actions.output(reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { color: colors.yellow, wrap: "truncate-end" }), message: "Syncing {group_list}\u2026", values: {
|
|
30894
|
+
group_list: (reactExports.createElement(reactExports.Fragment, null, push_group_list.map((push_group) => {
|
|
30895
|
+
const group = push_group.group;
|
|
30896
|
+
return (reactExports.createElement(Brackets, { key: group.id }, group.pr?.title || group.title || group.id));
|
|
30897
|
+
}))),
|
|
30898
|
+
} }));
|
|
30899
|
+
// for all push targets in push_group_list
|
|
30900
|
+
// things that can be done in parallel are grouped by numbers
|
|
30901
|
+
//
|
|
30902
|
+
// -----------------------------------
|
|
30903
|
+
// 1 (before_push) temp mark draft
|
|
30904
|
+
// --------------------------------------
|
|
30905
|
+
// 2 push simultaneously to github
|
|
30906
|
+
// --------------------------------------
|
|
30907
|
+
// 2 create PR / edit PR
|
|
30908
|
+
// 2 (after_push) undo temp mark draft
|
|
30909
|
+
// --------------------------------------
|
|
30910
|
+
const before_push_tasks = [];
|
|
30911
|
+
for (const push_group of push_group_list) {
|
|
30912
|
+
before_push_tasks.push(before_push(push_group));
|
|
30913
|
+
}
|
|
30914
|
+
await Promise.all(before_push_tasks);
|
|
30915
|
+
const push_target_list = push_group_list.map((push_group) => {
|
|
30916
|
+
return `HEAD~${push_group.lookback_index}:${push_group.group.id}`;
|
|
30917
|
+
});
|
|
30918
|
+
const push_target_args = push_target_list.join(" ");
|
|
30919
|
+
const git_push_command = [`git push -f origin ${push_target_args}`];
|
|
30920
|
+
if (argv.verify === false) {
|
|
30921
|
+
git_push_command.push("--no-verify");
|
|
30922
|
+
}
|
|
30923
|
+
await cli(git_push_command);
|
|
30889
30924
|
const pr_url_list = commit_range.group_list.map(get_group_url);
|
|
30890
|
-
|
|
30925
|
+
const after_push_tasks = [];
|
|
30891
30926
|
for (const push_group of push_group_list) {
|
|
30892
|
-
const
|
|
30893
|
-
|
|
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}`);
|
|
30927
|
+
const group = push_group.group;
|
|
30928
|
+
after_push_tasks.push(after_push({ group, pr_url_list }));
|
|
30901
30929
|
}
|
|
30930
|
+
await Promise.all(after_push_tasks);
|
|
30902
30931
|
// finally, ensure all prs have the updated stack table from updated pr_url_list
|
|
30903
|
-
|
|
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++) {
|
|
30932
|
+
for (let i = 0; i < commit_range.group_list.length; i++) {
|
|
30911
30933
|
const group = commit_range.group_list[i];
|
|
30934
|
+
// use the updated pr_url_list to get the actual selected_url
|
|
30935
|
+
const selected_url = pr_url_list[i];
|
|
30912
30936
|
invariant(group.base, "group.base must exist");
|
|
30913
|
-
|
|
30914
|
-
|
|
30915
|
-
|
|
30916
|
-
|
|
30917
|
-
|
|
30918
|
-
|
|
30919
|
-
|
|
30920
|
-
|
|
30921
|
-
|
|
30922
|
-
|
|
30923
|
-
|
|
30924
|
-
|
|
30925
|
-
|
|
30926
|
-
|
|
30927
|
-
|
|
30928
|
-
|
|
30929
|
-
if (argv.verify === false) {
|
|
30930
|
-
git_commit_comand.push("--no-verify");
|
|
30931
|
-
}
|
|
30932
|
-
await cli(git_commit_comand);
|
|
30937
|
+
const body = group.pr?.body || DEFAULT_PR_BODY;
|
|
30938
|
+
const update_body = write({
|
|
30939
|
+
body,
|
|
30940
|
+
pr_url_list,
|
|
30941
|
+
selected_url,
|
|
30942
|
+
});
|
|
30943
|
+
if (update_body === body) {
|
|
30944
|
+
actions.debug(`Skipping body update for ${selected_url}`);
|
|
30945
|
+
}
|
|
30946
|
+
else {
|
|
30947
|
+
actions.debug(`Update body for ${selected_url}`);
|
|
30948
|
+
await pr_edit({
|
|
30949
|
+
branch: group.id,
|
|
30950
|
+
base: group.base,
|
|
30951
|
+
body: update_body,
|
|
30952
|
+
});
|
|
30933
30953
|
}
|
|
30934
|
-
await sync_group_github({ group, pr_url_list, skip_checkout: false });
|
|
30935
30954
|
}
|
|
30936
|
-
// finally, ensure all prs have the updated stack table from updated pr_url_list
|
|
30937
|
-
await update_pr_tables(pr_url_list);
|
|
30938
30955
|
}
|
|
30939
|
-
async function
|
|
30940
|
-
|
|
30941
|
-
return;
|
|
30942
|
-
}
|
|
30943
|
-
const { group, pr_url_list } = args;
|
|
30956
|
+
async function before_push(args) {
|
|
30957
|
+
const { group } = args;
|
|
30944
30958
|
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
30959
|
// we may temporarily mark PR as a draft before editing it
|
|
30949
30960
|
// if it is not already a draft PR, to avoid notification spam
|
|
30950
|
-
let is_temp_draft =
|
|
30961
|
+
let is_temp_draft = !group.pr?.isDraft;
|
|
30951
30962
|
// before pushing reset base to master temporarily
|
|
30952
30963
|
// avoid accidentally pointing to orphaned parent commit
|
|
30953
30964
|
// should hopefully fix issues where a PR includes a bunch of commits after pushing
|
|
@@ -30966,12 +30977,10 @@ async function run$6() {
|
|
|
30966
30977
|
base: master_branch,
|
|
30967
30978
|
});
|
|
30968
30979
|
}
|
|
30969
|
-
|
|
30970
|
-
|
|
30971
|
-
|
|
30972
|
-
|
|
30973
|
-
}
|
|
30974
|
-
await cli(git_push_command);
|
|
30980
|
+
}
|
|
30981
|
+
async function after_push(args) {
|
|
30982
|
+
const { group, pr_url_list } = args;
|
|
30983
|
+
invariant(group.base, "group.base must exist");
|
|
30975
30984
|
const selected_url = get_group_url(group);
|
|
30976
30985
|
if (group.pr) {
|
|
30977
30986
|
// ensure base matches pr in github
|
|
@@ -30984,6 +30993,9 @@ async function run$6() {
|
|
|
30984
30993
|
selected_url,
|
|
30985
30994
|
}),
|
|
30986
30995
|
});
|
|
30996
|
+
// we may temporarily mark PR as a draft before editing it
|
|
30997
|
+
// if it is not already a draft PR, to avoid notification spam
|
|
30998
|
+
let is_temp_draft = !group.pr?.isDraft;
|
|
30987
30999
|
if (is_temp_draft) {
|
|
30988
31000
|
// mark pr as ready for review again
|
|
30989
31001
|
await pr_draft({
|
|
@@ -30993,12 +31005,6 @@ async function run$6() {
|
|
|
30993
31005
|
}
|
|
30994
31006
|
}
|
|
30995
31007
|
else {
|
|
30996
|
-
if (!args.skip_checkout) {
|
|
30997
|
-
// delete local group branch if leftover
|
|
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
31008
|
// create pr in github
|
|
31003
31009
|
const pr_url = await pr_create({
|
|
31004
31010
|
branch: group.id,
|
|
@@ -31017,38 +31023,6 @@ async function run$6() {
|
|
|
31017
31023
|
pr_url_list[i] = pr_url;
|
|
31018
31024
|
}
|
|
31019
31025
|
}
|
|
31020
|
-
// move back to temp branch
|
|
31021
|
-
if (!args.skip_checkout) {
|
|
31022
|
-
await cli(`git checkout ${temp_branch_name}`);
|
|
31023
|
-
}
|
|
31024
|
-
}
|
|
31025
|
-
}
|
|
31026
|
-
async function update_pr_tables(pr_url_list) {
|
|
31027
|
-
if (!argv.sync) {
|
|
31028
|
-
return;
|
|
31029
|
-
}
|
|
31030
|
-
for (let i = 0; i < commit_range.group_list.length; i++) {
|
|
31031
|
-
const group = commit_range.group_list[i];
|
|
31032
|
-
// use the updated pr_url_list to get the actual selected_url
|
|
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
|
-
}
|
|
31052
31026
|
}
|
|
31053
31027
|
}
|
|
31054
31028
|
// cleanup git operations if cancelled during manual rebase
|
|
@@ -31057,8 +31031,6 @@ async function run$6() {
|
|
|
31057
31031
|
// trying to use `await cli(...)` here will silently fail since
|
|
31058
31032
|
// all children processes receive the SIGINT signal
|
|
31059
31033
|
const spawn_options = { ignoreExitCode: true };
|
|
31060
|
-
// always clean up any patch files
|
|
31061
|
-
cli.sync(`rm ${PATCH_FILE}`, spawn_options);
|
|
31062
31034
|
// always hard reset and clean to allow subsequent checkout
|
|
31063
31035
|
// if there are files checkout will fail and cascade fail subsequent commands
|
|
31064
31036
|
cli.sync(`git reset --hard`, spawn_options);
|
|
@@ -31067,12 +31039,6 @@ async function run$6() {
|
|
|
31067
31039
|
cli.sync(`git checkout ${branch_name}`, spawn_options);
|
|
31068
31040
|
// ...and cleanup temporary branch
|
|
31069
31041
|
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
31042
|
// restore back to original dir
|
|
31077
31043
|
if (fs.existsSync(cwd)) {
|
|
31078
31044
|
process.chdir(cwd);
|
|
@@ -31093,7 +31059,6 @@ async function run$6() {
|
|
|
31093
31059
|
}
|
|
31094
31060
|
}
|
|
31095
31061
|
const get_group_url = (group) => group.pr?.url || group.id;
|
|
31096
|
-
const PATCH_FILE = "git-stack-cli-patch.patch";
|
|
31097
31062
|
|
|
31098
31063
|
function Table(props) {
|
|
31099
31064
|
if (!props.data.length) {
|
|
@@ -31325,8 +31290,8 @@ async function run$4() {
|
|
|
31325
31290
|
// ./docs/pull_request_template.md
|
|
31326
31291
|
for (const key of PR_TEMPLATE_KEY_LIST) {
|
|
31327
31292
|
const pr_template_fn = PR_TEMPLATE[key];
|
|
31328
|
-
if (
|
|
31329
|
-
pr_template_body = fs.
|
|
31293
|
+
if (await safe_exists(pr_template_fn(repo_root))) {
|
|
31294
|
+
pr_template_body = await fs$1.readFile(pr_template_fn(repo_root), "utf-8");
|
|
31330
31295
|
actions.output(reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { color: colors.yellow }), message: "Using PR template {pr_filepath}", values: {
|
|
31331
31296
|
pr_filepath: reactExports.createElement(Brackets, null, pr_template_fn("")),
|
|
31332
31297
|
} }));
|
|
@@ -31335,8 +31300,8 @@ async function run$4() {
|
|
|
31335
31300
|
}
|
|
31336
31301
|
// ./.github/PULL_REQUEST_TEMPLATE/*.md
|
|
31337
31302
|
let pr_templates = [];
|
|
31338
|
-
if (
|
|
31339
|
-
pr_templates = fs.
|
|
31303
|
+
if (await safe_exists(PR_TEMPLATE.TemplateDir(repo_root))) {
|
|
31304
|
+
pr_templates = await fs$1.readdir(PR_TEMPLATE.TemplateDir(repo_root));
|
|
31340
31305
|
}
|
|
31341
31306
|
// check if repo has multiple pr templates
|
|
31342
31307
|
actions.set((state) => {
|
|
@@ -31943,8 +31908,8 @@ function RebaseCheck(props) {
|
|
|
31943
31908
|
try {
|
|
31944
31909
|
const git_dir = (await cli(`git rev-parse --absolute-git-dir`)).stdout;
|
|
31945
31910
|
let is_rebase = false;
|
|
31946
|
-
is_rebase ||=
|
|
31947
|
-
is_rebase ||=
|
|
31911
|
+
is_rebase ||= await safe_exists(path.join(git_dir, "rebase-apply"));
|
|
31912
|
+
is_rebase ||= await safe_exists(path.join(git_dir, "rebase-merge"));
|
|
31948
31913
|
const status = is_rebase ? "prompt" : "done";
|
|
31949
31914
|
patch({ status });
|
|
31950
31915
|
}
|
|
@@ -32151,7 +32116,7 @@ function MaybeMain() {
|
|
|
32151
32116
|
else if (positional_list.has("rebase")) {
|
|
32152
32117
|
return (reactExports.createElement(GatherMetadata, null,
|
|
32153
32118
|
reactExports.createElement(LocalCommitStatus, null,
|
|
32154
|
-
reactExports.createElement(Rebase
|
|
32119
|
+
reactExports.createElement(Rebase, null))));
|
|
32155
32120
|
}
|
|
32156
32121
|
return (reactExports.createElement(DirtyCheck, null,
|
|
32157
32122
|
!argv.verbose ? null : reactExports.createElement(GithubApiError, null),
|
|
@@ -32490,14 +32455,14 @@ function ui (opts) {
|
|
|
32490
32455
|
|
|
32491
32456
|
function escalade (start, callback) {
|
|
32492
32457
|
let dir = path$1.resolve('.', start);
|
|
32493
|
-
let tmp, stats = fs$
|
|
32458
|
+
let tmp, stats = fs$2.statSync(dir);
|
|
32494
32459
|
|
|
32495
32460
|
if (!stats.isDirectory()) {
|
|
32496
32461
|
dir = path$1.dirname(dir);
|
|
32497
32462
|
}
|
|
32498
32463
|
|
|
32499
32464
|
while (true) {
|
|
32500
|
-
tmp = callback(dir, fs$
|
|
32465
|
+
tmp = callback(dir, fs$2.readdirSync(dir));
|
|
32501
32466
|
if (tmp) return path$1.resolve(dir, tmp);
|
|
32502
32467
|
dir = path$1.dirname(tmp = dir);
|
|
32503
32468
|
if (tmp === dir) break;
|
|
@@ -33703,7 +33668,7 @@ const parser = new YargsParser({
|
|
|
33703
33668
|
}
|
|
33704
33669
|
else if (path.match(/\.json$/)) {
|
|
33705
33670
|
// Addresses: https://github.com/yargs/yargs/issues/2040
|
|
33706
|
-
return JSON.parse(fs$
|
|
33671
|
+
return JSON.parse(fs$2.readFileSync(path, 'utf8'));
|
|
33707
33672
|
}
|
|
33708
33673
|
else {
|
|
33709
33674
|
throw Error('only .json config files are supported in ESM');
|
|
@@ -33751,14 +33716,14 @@ class YError extends Error {
|
|
|
33751
33716
|
|
|
33752
33717
|
var shim$3 = {
|
|
33753
33718
|
fs: {
|
|
33754
|
-
readFileSync: fs$
|
|
33755
|
-
writeFile: fs$
|
|
33719
|
+
readFileSync: fs$2.readFileSync,
|
|
33720
|
+
writeFile: fs$2.writeFile
|
|
33756
33721
|
},
|
|
33757
33722
|
format: util.format,
|
|
33758
33723
|
resolve: path$1.resolve,
|
|
33759
33724
|
exists: (file) => {
|
|
33760
33725
|
try {
|
|
33761
|
-
return fs$
|
|
33726
|
+
return fs$2.statSync(file).isFile();
|
|
33762
33727
|
}
|
|
33763
33728
|
catch (err) {
|
|
33764
33729
|
return false;
|
|
@@ -33989,7 +33954,7 @@ var shim$1 = {
|
|
|
33989
33954
|
nextTick: process.nextTick,
|
|
33990
33955
|
stdColumns: typeof process.stdout.columns !== 'undefined' ? process.stdout.columns : null
|
|
33991
33956
|
},
|
|
33992
|
-
readFileSync: fs$
|
|
33957
|
+
readFileSync: fs$2.readFileSync,
|
|
33993
33958
|
require: () => {
|
|
33994
33959
|
throw new YError(REQUIRE_ERROR)
|
|
33995
33960
|
},
|
|
@@ -37479,15 +37444,11 @@ async function command() {
|
|
|
37479
37444
|
.wrap(123)
|
|
37480
37445
|
// disallow unknown options
|
|
37481
37446
|
.strict()
|
|
37482
|
-
.version("1.
|
|
37447
|
+
.version("1.13.0" )
|
|
37483
37448
|
.showHidden("show-hidden", "Show hidden options via `git stack help --show-hidden`")
|
|
37484
37449
|
.help("help", "Show usage via `git stack help`")
|
|
37485
37450
|
.argv;
|
|
37486
37451
|
}
|
|
37487
|
-
const Rebase = Object.freeze({
|
|
37488
|
-
"git-revise": "git-revise",
|
|
37489
|
-
"cherry-pick": "cherry-pick",
|
|
37490
|
-
});
|
|
37491
37452
|
const GlobalOptions = {
|
|
37492
37453
|
verbose: {
|
|
37493
37454
|
type: "boolean",
|
|
@@ -37520,16 +37481,6 @@ const DefaultOptions = {
|
|
|
37520
37481
|
default: true,
|
|
37521
37482
|
description: "Run git hooks such as pre-commit and pre-push, disable with --no-verify",
|
|
37522
37483
|
},
|
|
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
37484
|
"update": {
|
|
37534
37485
|
type: "boolean",
|
|
37535
37486
|
alias: ["u", "upgrade"],
|