git-stack-cli 1.0.6 → 1.1.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 CHANGED
@@ -87,14 +87,11 @@ npm run build:standalone
87
87
  >
88
88
  > **You must update the `version` in `package.json` and commit all changes first!**
89
89
 
90
- ### NPM
91
-
92
90
  ```bash
93
- npm run release:npm
94
- ```
91
+ npm run release
95
92
 
96
- ### Homebrew + Github
97
-
98
- ```bash
93
+ # release individually
94
+ npm run release:npm
95
+ npm run release:github
99
96
  npm run release:brew
100
97
  ```
@@ -26287,10 +26287,21 @@ const BaseStore = createStore()(immer((set, get) => ({
26287
26287
  if (!id) {
26288
26288
  return;
26289
26289
  }
26290
+ // set `withoutTimestamp` to skip <LogTimestamp> for all subsequent pending outputs
26291
+ // we only want to timestamp for the first part (when we initialize the [])
26292
+ // if we have many incremental outputs on the same line we do not want multiple timestamps
26293
+ //
26294
+ // await Promise.all([
26295
+ // cli(`for i in $(seq 1 5); do echo $i; sleep 1; done`),
26296
+ // cli(`for i in $(seq 5 1); do printf "$i "; sleep 1; done; echo`),
26297
+ // ]);
26298
+ //
26299
+ let withoutTimestamp = true;
26290
26300
  if (!state.pending_output[id]) {
26301
+ withoutTimestamp = false;
26291
26302
  state.pending_output[id] = [];
26292
26303
  }
26293
- const renderOutput = renderOutputArgs(args);
26304
+ const renderOutput = renderOutputArgs({ ...args, withoutTimestamp });
26294
26305
  state.pending_output[id].push(renderOutput);
26295
26306
  },
26296
26307
  end_pending_output(state, id) {
@@ -26313,7 +26324,7 @@ function renderOutputArgs(args) {
26313
26324
  }
26314
26325
  if (args.debug) {
26315
26326
  return (reactExports.createElement(reactExports.Fragment, null,
26316
- reactExports.createElement(LogTimestamp, null),
26327
+ args.withoutTimestamp ? null : reactExports.createElement(LogTimestamp, null),
26317
26328
  output));
26318
26329
  }
26319
26330
  return output;
@@ -26872,6 +26883,12 @@ const RE$4 = {
26872
26883
  };
26873
26884
 
26874
26885
  function DependencyCheck(props) {
26886
+ return (reactExports.createElement(CheckGit, null,
26887
+ reactExports.createElement(CheckGithubCli, null,
26888
+ reactExports.createElement(CheckGithubCliAuth, null,
26889
+ reactExports.createElement(CheckGitRevise, null, props.children)))));
26890
+ }
26891
+ function CheckGit(props) {
26875
26892
  const actions = Store.useActions();
26876
26893
  return (reactExports.createElement(Await, { fallback: reactExports.createElement(Text, { color: colors.yellow },
26877
26894
  "Checking ",
@@ -26888,65 +26905,84 @@ function DependencyCheck(props) {
26888
26905
  reactExports.createElement(Command, null, "git"),
26889
26906
  " must be installed."));
26890
26907
  actions.exit(2);
26891
- } },
26892
- reactExports.createElement(Await, { fallback: reactExports.createElement(Text, { color: colors.yellow },
26908
+ } }, props.children));
26909
+ }
26910
+ function CheckGithubCli(props) {
26911
+ const actions = Store.useActions();
26912
+ return (reactExports.createElement(Await, { fallback: reactExports.createElement(Text, { color: colors.yellow },
26913
+ reactExports.createElement(Text, null,
26893
26914
  "Checking ",
26894
- reactExports.createElement(Command, null, "node"),
26895
- " install..."), function: async () => {
26896
- const process_version = process.version.substring(1);
26897
- const semver_result = semver_compare(process_version, "14.0.0");
26898
- if (semver_result >= 0) {
26915
+ reactExports.createElement(Command, null, "gh"),
26916
+ " install...")), function: async () => {
26917
+ if (is_command_available("gh")) {
26918
+ return;
26919
+ }
26920
+ actions.output(reactExports.createElement(Text, { color: colors.yellow },
26921
+ reactExports.createElement(Command, null, "gh"),
26922
+ " must be installed."));
26923
+ actions.output(reactExports.createElement(Text, { color: colors.yellow },
26924
+ reactExports.createElement(Text, null, "Visit "),
26925
+ reactExports.createElement(Url, null, "https://cli.github.com"),
26926
+ reactExports.createElement(Text, null, " to install the github cli "),
26927
+ reactExports.createElement(Parens, null,
26928
+ reactExports.createElement(Command, null, "gh"))));
26929
+ actions.exit(3);
26930
+ } }, props.children));
26931
+ }
26932
+ function CheckGithubCliAuth(props) {
26933
+ const actions = Store.useActions();
26934
+ return (reactExports.createElement(Await, { fallback: reactExports.createElement(Text, { color: colors.yellow },
26935
+ reactExports.createElement(Text, null,
26936
+ "Checking ",
26937
+ reactExports.createElement(Command, null, "gh auth status"),
26938
+ "...")), function: async () => {
26939
+ const options = { ignoreExitCode: true };
26940
+ const auth_status$1 = await cli(`gh auth status`, options);
26941
+ if (auth_status$1.code === 0) {
26942
+ const username = auth_status(auth_status$1.stdout);
26943
+ if (username) {
26944
+ actions.set((state) => {
26945
+ state.username = username;
26946
+ });
26899
26947
  return;
26900
26948
  }
26901
- actions.output(reactExports.createElement(Text, { color: colors.yellow },
26902
- reactExports.createElement(Command, null, "node"),
26903
- " must be installed."));
26904
- actions.exit(2);
26905
- } },
26906
- reactExports.createElement(Await, { fallback: reactExports.createElement(Text, { color: colors.yellow },
26907
- reactExports.createElement(Text, null,
26908
- "Checking ",
26909
- reactExports.createElement(Command, null, "gh"),
26910
- " install...")), function: async () => {
26911
- if (is_command_available("gh")) {
26912
- return;
26913
- }
26914
- actions.output(reactExports.createElement(Text, { color: colors.yellow },
26915
- reactExports.createElement(Command, null, "gh"),
26916
- " must be installed."));
26917
- actions.output(reactExports.createElement(Text, { color: colors.yellow },
26918
- reactExports.createElement(Text, null, "Visit "),
26919
- reactExports.createElement(Url, null, "https://cli.github.com"),
26920
- reactExports.createElement(Text, null, " to install the github cli "),
26921
- reactExports.createElement(Parens, null,
26922
- reactExports.createElement(Command, null, "gh"))));
26923
- actions.exit(3);
26924
- } },
26925
- reactExports.createElement(Await, { fallback: reactExports.createElement(Text, { color: colors.yellow },
26926
- reactExports.createElement(Text, null,
26927
- "Checking ",
26928
- reactExports.createElement(Command, null, "gh auth status"),
26929
- "...")), function: async () => {
26930
- const options = { ignoreExitCode: true };
26931
- const auth_status$1 = await cli(`gh auth status`, options);
26932
- if (auth_status$1.code === 0) {
26933
- const username = auth_status(auth_status$1.stdout);
26934
- if (username) {
26935
- actions.set((state) => {
26936
- state.username = username;
26937
- });
26938
- return;
26939
- }
26940
- }
26941
- if (actions.isDebug()) {
26942
- actions.error("gh auth status could not find username");
26943
- }
26944
- actions.output(reactExports.createElement(Text, { color: colors.yellow },
26945
- reactExports.createElement(Command, null, "gh"),
26946
- reactExports.createElement(Text, null, " requires login, please run "),
26947
- reactExports.createElement(Command, null, "gh auth login")));
26948
- actions.exit(4);
26949
- } }, props.children)))));
26949
+ }
26950
+ if (actions.isDebug()) {
26951
+ actions.error("gh auth status could not find username");
26952
+ }
26953
+ actions.output(reactExports.createElement(Text, { color: colors.yellow },
26954
+ reactExports.createElement(Command, null, "gh"),
26955
+ reactExports.createElement(Text, null, " requires login, please run "),
26956
+ reactExports.createElement(Command, null, "gh auth login")));
26957
+ actions.exit(4);
26958
+ } }, props.children));
26959
+ }
26960
+ function CheckGitRevise(props) {
26961
+ const actions = Store.useActions();
26962
+ const argv = Store.useState((state) => state.argv);
26963
+ // skip git revise check when `--git-revise` flag is not present
26964
+ if (!argv?.["git-revise"]) {
26965
+ return props.children;
26966
+ }
26967
+ return (reactExports.createElement(Await, { fallback: reactExports.createElement(Text, { color: colors.yellow },
26968
+ reactExports.createElement(Text, null,
26969
+ "Checking ",
26970
+ reactExports.createElement(Command, null, "git-revise"),
26971
+ " install...")), function: async () => {
26972
+ if (is_command_available("git-revise")) {
26973
+ return;
26974
+ }
26975
+ actions.output(reactExports.createElement(Text, { color: colors.yellow },
26976
+ reactExports.createElement(Command, null, "git-revise"),
26977
+ " must be installed."));
26978
+ actions.output(reactExports.createElement(Text, { color: colors.yellow },
26979
+ reactExports.createElement(Text, null, "Visit "),
26980
+ reactExports.createElement(Url, null, "https://github.com/mystor/git-revise#install"),
26981
+ reactExports.createElement(Text, null, " to install the git revise cli "),
26982
+ reactExports.createElement(Parens, null,
26983
+ reactExports.createElement(Command, null, "git-revise"))));
26984
+ actions.exit(10);
26985
+ } }, props.children));
26950
26986
  }
26951
26987
 
26952
26988
  function GatherMetadata(props) {
@@ -27555,7 +27591,7 @@ async function run$3() {
27555
27591
  await cli(`git add --all`);
27556
27592
  let new_message;
27557
27593
  if (commit.branch_id) {
27558
- new_message = await write$1(commit.full_message, commit.branch_id);
27594
+ new_message = write$1(commit.full_message, commit.branch_id);
27559
27595
  }
27560
27596
  else {
27561
27597
  new_message = commit.full_message;
@@ -27640,6 +27676,69 @@ async function run$3() {
27640
27676
  }
27641
27677
  const PATCH_FILE$1 = "git-stack-cli-patch.patch";
27642
27678
 
27679
+ // https://git-revise.readthedocs.io/en/latest/man.html#interactive-mode
27680
+ //
27681
+ // # Interactive Revise Todos(4 commands)
27682
+ // #
27683
+ // # Commands:
27684
+ // # p, pick <commit> = use commit
27685
+ // # r, reword <commit> = use commit, but edit the commit message
27686
+ // # s, squash <commit> = use commit, but meld into previous commit
27687
+ // # f, fixup <commit> = like squash, but discard this commit's message
27688
+ // # c, cut <commit> = interactively split commit into two smaller commits
27689
+ // # i, index <commit> = leave commit changes staged, but uncommitted
27690
+ // #
27691
+ // # Each command block is prefixed by a '++' marker, followed by the command to
27692
+ // # run, the commit hash and after a newline the complete commit message until
27693
+ // # the next '++' marker or the end of the file.
27694
+ // #
27695
+ // # Commit messages will be reworded to match the provided message before the
27696
+ // # command is performed.
27697
+ // #
27698
+ // # These blocks are executed from top to bottom. They can be re-ordered and
27699
+ // # their commands can be changed, however the number of blocks must remain
27700
+ // # identical. If present, index blocks must be at the bottom of the list,
27701
+ // # i.e. they can not be followed by non-index blocks.
27702
+ // #
27703
+ // #
27704
+ // # If you remove everything, the revising process will be aborted.
27705
+ // calculate git-revise-todo from commit_range and rebase_group_index
27706
+ //
27707
+ // Example
27708
+ // ----------------------------
27709
+ // ++ pick d36d63499425
27710
+ // cantaloupe color
27711
+ //
27712
+ // git-stack-id: E63ytp5dj
27713
+ //
27714
+ // ++ pick 4f98dd3e67d0
27715
+ // banana sweet
27716
+ //
27717
+ // git-stack-id: E63ytp5dj
27718
+ //
27719
+ // ++ pick f143d03c723c
27720
+ // apple sweet
27721
+ //
27722
+ function GitReviseTodo(args) {
27723
+ const entry_list = [];
27724
+ const group_list = args.commit_range.group_list;
27725
+ for (let i = args.rebase_group_index; i < group_list.length; i++) {
27726
+ const group = group_list[i];
27727
+ for (const commit of group.commits) {
27728
+ // update git commit message with stack id
27729
+ const message_with_id = write$1(commit.full_message, group.id);
27730
+ // get first 12 characters of commit sha
27731
+ const sha = commit.sha.slice(0, 12);
27732
+ // generate git revise entry
27733
+ const entry_lines = [`++ pick ${sha}`, message_with_id];
27734
+ const entry = entry_lines.join("\n");
27735
+ entry_list.push(entry);
27736
+ }
27737
+ }
27738
+ const todo = entry_list.join("\n\n");
27739
+ return todo;
27740
+ }
27741
+
27643
27742
  function write(args) {
27644
27743
  const stack_table = table(args);
27645
27744
  let result = args.body;
@@ -27759,17 +27858,141 @@ async function run$2(props) {
27759
27858
  continue;
27760
27859
  }
27761
27860
  if (i > 0) {
27762
- const last_group = commit_range.group_list[i - 1];
27763
- const last_commit = last_group.commits[last_group.commits.length - 1];
27764
- rebase_merge_base = last_commit.sha;
27861
+ const prev_group = commit_range.group_list[i - 1];
27862
+ const prev_commit = prev_group.commits[prev_group.commits.length - 1];
27863
+ rebase_merge_base = prev_commit.sha;
27765
27864
  rebase_group_index = i;
27766
27865
  }
27767
27866
  break;
27768
27867
  }
27868
+ actions.debug(`rebase_merge_base=${rebase_merge_base}`);
27869
+ actions.debug(`rebase_group_index=${rebase_group_index}`);
27870
+ actions.debug(`commit_range=${JSON.stringify(commit_range, null, 2)}`);
27769
27871
  try {
27770
27872
  // must perform rebase from repo root for applying git patch
27771
27873
  process.chdir(repo_root);
27772
27874
  await cli(`pwd`);
27875
+ if (argv["git-revise"]) {
27876
+ await rebase_git_revise();
27877
+ }
27878
+ else {
27879
+ await rebase_cherry_pick();
27880
+ }
27881
+ // after all commits have been cherry-picked and amended
27882
+ // move the branch pointer to the newly created temporary branch
27883
+ // now we are in locally in sync with github and on the original branch
27884
+ await cli(`git branch -f ${branch_name} ${temp_branch_name}`);
27885
+ restore_git();
27886
+ actions.set((state) => {
27887
+ state.step = "post-rebase-status";
27888
+ });
27889
+ }
27890
+ catch (err) {
27891
+ actions.error("Unable to rebase.");
27892
+ if (err instanceof Error) {
27893
+ if (actions.isDebug()) {
27894
+ actions.error(err.message);
27895
+ }
27896
+ }
27897
+ handle_exit();
27898
+ }
27899
+ async function rebase_git_revise() {
27900
+ invariant(argv, "argv must exist");
27901
+ actions.debug(`rebase_git_revise`);
27902
+ actions.output(reactExports.createElement(Text, { color: colors.yellow, wrap: "truncate-end" }, "Rebasing\u2026"));
27903
+ // generate temporary directory and drop sequence editor script
27904
+ const tmp_git_sequence_editor_path = path.join(os.tmpdir(), "git-sequence-editor.sh");
27905
+ actions.debug(`tmp_git_sequence_editor_path=${tmp_git_sequence_editor_path}`);
27906
+ // replaced at build time with literal contents of `scripts/git-sequence-editor.sh`
27907
+ const GIT_SEQUENCE_EDITOR_SCRIPT = `#!/bin/sh
27908
+
27909
+ # Example
27910
+ #
27911
+ # GIT_REVISE_TODO="abc" GIT_EDITOR="$(pwd)/scripts/git-sequence-editor.sh" git revise --edit -i head~4
27912
+ #
27913
+ # Note
27914
+ # ----------------
27915
+ # Use \`GIT_EDITOR\` above instead of \`GIT_SEQUENCE_EDITOR\` because \`git revise\` does not use
27916
+ # \`GIT_SEQUENCE_EDITOR\` when passing the \`--edit\` flag, but does work without the \`--edit\` flag
27917
+ #
27918
+ #
27919
+
27920
+ # debug print env variables
27921
+ echo "GIT_REVISE_TODO=$GIT_REVISE_TODO"
27922
+ echo "CLI=$0 $*"
27923
+ echo "PWD=$(pwd)"
27924
+
27925
+ # ensure \`GIT_REVISE_TODO\` is not empty
27926
+ if [ -z "$GIT_REVISE_TODO" ]; then
27927
+ echo "🚨 GIT_REVISE_TODO environment variable is empty" >&2
27928
+ exit 1
27929
+ fi
27930
+
27931
+ # first argument into git sequence editor is git-revise-todo file
27932
+ git_revise_todo_path="$1"
27933
+
27934
+ # debug print git-revise-todo file passed into command
27935
+ echo "$git_revise_todo_path"
27936
+ echo "----- START -----"
27937
+ cat "$git_revise_todo_path"
27938
+ echo "------ END ------"
27939
+
27940
+ # write content of \`GIT_REVISE_TODO\` env variable to \`git_revise_todo_path\`
27941
+ echo "$GIT_REVISE_TODO" > "$git_revise_todo_path"
27942
+ `;
27943
+ // write script to temporary path
27944
+ fs.writeFileSync(tmp_git_sequence_editor_path, GIT_SEQUENCE_EDITOR_SCRIPT);
27945
+ // ensure script is executable
27946
+ fs.chmodSync(tmp_git_sequence_editor_path, "755");
27947
+ // create temporary branch
27948
+ await cli(`git checkout -b ${temp_branch_name}`);
27949
+ const git_revise_todo = GitReviseTodo({ rebase_group_index, commit_range });
27950
+ // execute cli with temporary git sequence editor script
27951
+ // revise from merge base to pick correct commits
27952
+ await cli([
27953
+ `GIT_EDITOR="${tmp_git_sequence_editor_path}"`,
27954
+ `GIT_REVISE_TODO="${git_revise_todo}"`,
27955
+ `git`,
27956
+ `revise --edit -i ${rebase_merge_base}`,
27957
+ ]);
27958
+ // start from HEAD and work backward to rebase_group_index
27959
+ const push_group_list = [];
27960
+ let lookback_index = 0;
27961
+ for (let i = 0; i < commit_range.group_list.length; i++) {
27962
+ const index = commit_range.group_list.length - 1 - i;
27963
+ // do not go past rebase_group_index
27964
+ if (index < rebase_group_index) {
27965
+ break;
27966
+ }
27967
+ const group = commit_range.group_list[index];
27968
+ // console.debug({ i, index, group });
27969
+ if (i > 0) {
27970
+ const prev_group = commit_range.group_list[index + 1];
27971
+ lookback_index += prev_group.commits.length;
27972
+ }
27973
+ // console.debug(`git show head~${lookback_index}`);
27974
+ // push group and lookback_index onto front of push_group_list
27975
+ push_group_list.unshift({ group, lookback_index });
27976
+ }
27977
+ const pr_url_list = commit_range.group_list.map(get_group_url);
27978
+ // use push_group_list to sync each group HEAD to github
27979
+ for (const push_group of push_group_list) {
27980
+ const { group } = push_group;
27981
+ // move to temporary branch for resetting to lookback_index to create PR
27982
+ await cli(`git checkout -b ${group.id}`);
27983
+ // prepare branch for sync, reset to commit at lookback index
27984
+ await cli(`git reset --hard HEAD~${push_group.lookback_index}`);
27985
+ await sync_group_github({ group, pr_url_list, skip_checkout: true });
27986
+ // done, remove temp push branch and move back to temp branch
27987
+ await cli(`git checkout ${temp_branch_name}`);
27988
+ await cli(`git branch -D ${group.id}`);
27989
+ }
27990
+ // finally, ensure all prs have the updated stack table from updated pr_url_list
27991
+ await update_pr_tables(pr_url_list);
27992
+ }
27993
+ async function rebase_cherry_pick() {
27994
+ invariant(argv, "argv must exist");
27995
+ actions.debug("rebase_cherry_pick");
27773
27996
  // create temporary branch based on merge base
27774
27997
  await cli(`git checkout -b ${temp_branch_name} ${rebase_merge_base}`);
27775
27998
  const pr_url_list = commit_range.group_list.map(get_group_url);
@@ -27779,7 +28002,6 @@ async function run$2(props) {
27779
28002
  actions.output(reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { color: colors.yellow, wrap: "truncate-end" }), message: "Rebasing {group}\u2026", values: {
27780
28003
  group: (reactExports.createElement(Brackets, null, group.pr?.title || group.title || group.id)),
27781
28004
  } }));
27782
- const selected_url = get_group_url(group);
27783
28005
  // cherry-pick and amend commits one by one
27784
28006
  for (const commit of group.commits) {
27785
28007
  // ensure clean base to avoid conflicts when applying patch
@@ -27790,63 +28012,78 @@ async function run$2(props) {
27790
28012
  await cli(`rm ${PATCH_FILE}`);
27791
28013
  // add all changes to stage
27792
28014
  await cli(`git add --all`);
27793
- const new_message = await write$1(commit.full_message, group.id);
28015
+ const new_message = write$1(commit.full_message, group.id);
27794
28016
  const git_commit_comand = [`git commit -m "${new_message}"`];
27795
28017
  if (argv.verify === false) {
27796
28018
  git_commit_comand.push("--no-verify");
27797
28019
  }
27798
28020
  await cli(git_commit_comand);
27799
28021
  }
27800
- actions.output(reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { color: colors.yellow, wrap: "truncate-end" }), message: "Syncing {group}\u2026", values: {
27801
- group: (reactExports.createElement(Brackets, null, group.pr?.title || group.title || group.id)),
27802
- } }));
27803
- if (!props.skipSync) {
27804
- // push to origin since github requires commit shas to line up perfectly
27805
- const git_push_command = [`git push -f origin HEAD:${group.id}`];
27806
- if (argv.verify === false) {
27807
- git_push_command.push("--no-verify");
27808
- }
27809
- await cli(git_push_command);
27810
- if (group.pr) {
27811
- // ensure base matches pr in github
27812
- await pr_edit({
27813
- branch: group.id,
27814
- base: group.base,
27815
- body: write({
27816
- body: group.pr.body,
27817
- pr_url_list,
27818
- selected_url,
27819
- }),
27820
- });
27821
- }
27822
- else {
27823
- // delete local group branch if leftover
27824
- await cli(`git branch -D ${group.id}`, { ignoreExitCode: true });
27825
- // move to temporary branch for creating pr
27826
- await cli(`git checkout -b ${group.id}`);
27827
- // create pr in github
27828
- const pr_url = await pr_create({
27829
- branch: group.id,
27830
- base: group.base,
27831
- title: group.title,
27832
- body: "",
27833
- });
27834
- if (!pr_url) {
27835
- throw new Error("unable to create pr");
27836
- }
27837
- // update pr_url_list with created pr_url
27838
- for (let i = 0; i < pr_url_list.length; i++) {
27839
- const url = pr_url_list[i];
27840
- if (url === selected_url) {
27841
- pr_url_list[i] = pr_url;
27842
- }
27843
- }
27844
- // move back to temp branch
27845
- await cli(`git checkout ${temp_branch_name}`);
28022
+ await sync_group_github({ group, pr_url_list, skip_checkout: false });
28023
+ }
28024
+ // finally, ensure all prs have the updated stack table from updated pr_url_list
28025
+ await update_pr_tables(pr_url_list);
28026
+ }
28027
+ async function sync_group_github(args) {
28028
+ if (props.skipSync) {
28029
+ return;
28030
+ }
28031
+ const { group, pr_url_list } = args;
28032
+ invariant(argv, "argv must exist");
28033
+ invariant(group.base, "group.base must exist");
28034
+ actions.output(reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { color: colors.yellow, wrap: "truncate-end" }), message: "Syncing {group}\u2026", values: {
28035
+ group: (reactExports.createElement(Brackets, null, group.pr?.title || group.title || group.id)),
28036
+ } }));
28037
+ // push to origin since github requires commit shas to line up perfectly
28038
+ const git_push_command = [`git push -f origin HEAD:${group.id}`];
28039
+ if (argv.verify === false) {
28040
+ git_push_command.push("--no-verify");
28041
+ }
28042
+ await cli(git_push_command);
28043
+ const selected_url = get_group_url(group);
28044
+ if (group.pr) {
28045
+ // ensure base matches pr in github
28046
+ await pr_edit({
28047
+ branch: group.id,
28048
+ base: group.base,
28049
+ body: write({
28050
+ body: group.pr.body,
28051
+ pr_url_list,
28052
+ selected_url,
28053
+ }),
28054
+ });
28055
+ }
28056
+ else {
28057
+ if (!args.skip_checkout) {
28058
+ // delete local group branch if leftover
28059
+ await cli(`git branch -D ${group.id}`, { ignoreExitCode: true });
28060
+ // move to temporary branch for creating pr
28061
+ await cli(`git checkout -b ${group.id}`);
28062
+ }
28063
+ // create pr in github
28064
+ const pr_url = await pr_create({
28065
+ branch: group.id,
28066
+ base: group.base,
28067
+ title: group.title,
28068
+ body: "",
28069
+ });
28070
+ if (!pr_url) {
28071
+ throw new Error("unable to create pr");
28072
+ }
28073
+ // update pr_url_list with created pr_url
28074
+ for (let i = 0; i < pr_url_list.length; i++) {
28075
+ const url = pr_url_list[i];
28076
+ if (url === selected_url) {
28077
+ pr_url_list[i] = pr_url;
27846
28078
  }
27847
28079
  }
28080
+ // move back to temp branch
28081
+ if (!args.skip_checkout) {
28082
+ await cli(`git checkout ${temp_branch_name}`);
28083
+ }
27848
28084
  }
27849
- // finally, ensure all prs have the updated stack table from updated pr_url_list
28085
+ }
28086
+ async function update_pr_tables(pr_url_list) {
27850
28087
  for (let i = 0; i < commit_range.group_list.length; i++) {
27851
28088
  const group = commit_range.group_list[i];
27852
28089
  // use the updated pr_url_list to get the actual selected_url
@@ -27870,23 +28107,6 @@ async function run$2(props) {
27870
28107
  });
27871
28108
  }
27872
28109
  }
27873
- // after all commits have been cherry-picked and amended
27874
- // move the branch pointer to the newly created temporary branch
27875
- // now we are in locally in sync with github and on the original branch
27876
- await cli(`git branch -f ${branch_name} ${temp_branch_name}`);
27877
- restore_git();
27878
- actions.set((state) => {
27879
- state.step = "post-rebase-status";
27880
- });
27881
- }
27882
- catch (err) {
27883
- actions.error("Unable to rebase.");
27884
- if (err instanceof Error) {
27885
- if (actions.isDebug()) {
27886
- actions.error(err.message);
27887
- }
27888
- }
27889
- handle_exit();
27890
28110
  }
27891
28111
  // cleanup git operations if cancelled during manual rebase
27892
28112
  function restore_git() {
@@ -28440,6 +28660,7 @@ function SelectCommitRangesInternal(props) {
28440
28660
  switch (inputLower) {
28441
28661
  case "s":
28442
28662
  state.step = "manual-rebase";
28663
+ // state.step = "manual-rebase-no-sync";
28443
28664
  break;
28444
28665
  }
28445
28666
  });
@@ -34069,6 +34290,11 @@ async function command() {
34069
34290
  type: "boolean",
34070
34291
  default: true,
34071
34292
  description: "Skip git hooks such as pre-commit and pre-push",
34293
+ })
34294
+ .option("git-revise", {
34295
+ type: "boolean",
34296
+ default: false,
34297
+ description: `Use git-revise to perform in-memory rebase, (macOS + Linux only)`,
34072
34298
  })
34073
34299
  .option("verbose", {
34074
34300
  type: "boolean",
@@ -34104,7 +34330,7 @@ async function command() {
34104
34330
  .wrap(null)
34105
34331
  // disallow unknown options
34106
34332
  .strict()
34107
- .version("1.0.6" )
34333
+ .version("1.1.0" )
34108
34334
  .showHidden("show-hidden", "Show hidden options via `git stack help --show-hidden`")
34109
34335
  .help("help", "Show usage via `git stack help`").argv);
34110
34336
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-stack-cli",
3
- "version": "1.0.6",
3
+ "version": "1.1.0",
4
4
  "description": "",
5
5
  "author": "magus",
6
6
  "license": "MIT",
@@ -17,13 +17,13 @@
17
17
  "scripts",
18
18
  "src",
19
19
  "package-lock.json",
20
- "rollup.config.mjs",
20
+ "rollup.config.js",
21
21
  "tsconfig.json"
22
22
  ],
23
23
  "scripts": {
24
24
  "dev": "npm run build -- --watch",
25
- "build": "rollup -c rollup.config.mjs",
26
- "build:standalone": "bun run scripts/build-standalone.ts",
25
+ "build": "rollup -c rollup.config.js",
26
+ "build:standalone": "GIT_STACK_STANDALONE=true bun run scripts/build-standalone.ts",
27
27
  "release:npm": "bun run scripts/release-npm.ts",
28
28
  "release:github": "bun run scripts/release-github.ts",
29
29
  "release:brew": "bun run scripts/release-brew.ts",