git-stack-cli 2.10.0 → 2.11.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/dist/js/index.js +53 -53
- package/package.json +1 -1
- package/src/commands/Rebase.tsx +40 -6
- package/src/core/cli.ts +40 -3
package/package.json
CHANGED
package/src/commands/Rebase.tsx
CHANGED
|
@@ -6,6 +6,7 @@ import * as Ink from "ink-cjs";
|
|
|
6
6
|
|
|
7
7
|
import { Await } from "~/app/Await";
|
|
8
8
|
import { Brackets } from "~/app/Brackets";
|
|
9
|
+
import { Command } from "~/app/Command";
|
|
9
10
|
import { FormatText } from "~/app/FormatText";
|
|
10
11
|
import { Status } from "~/app/Status";
|
|
11
12
|
import { Store } from "~/app/Store";
|
|
@@ -41,8 +42,12 @@ Rebase.run = async function run(props: Props) {
|
|
|
41
42
|
invariant(commit_range, "commit_range must exist");
|
|
42
43
|
invariant(repo_root, "repo_root must exist");
|
|
43
44
|
|
|
45
|
+
const abort_controller = new AbortController();
|
|
46
|
+
const signal = abort_controller.signal;
|
|
47
|
+
|
|
44
48
|
// immediately register abort_handler in case of ctrl+c exit
|
|
45
49
|
actions.register_abort_handler(async function abort_rebase() {
|
|
50
|
+
abort_controller.abort();
|
|
46
51
|
actions.output(<Ink.Text color={colors.red}>🚨 Abort</Ink.Text>);
|
|
47
52
|
handle_exit();
|
|
48
53
|
return 19;
|
|
@@ -59,7 +64,7 @@ Rebase.run = async function run(props: Props) {
|
|
|
59
64
|
await cli(`pwd`);
|
|
60
65
|
|
|
61
66
|
// fetch origin master branch for latest sha
|
|
62
|
-
await cli(`git fetch --no-tags -v origin ${master_branch_name}
|
|
67
|
+
await cli(`git fetch --no-tags -v origin ${master_branch_name}`, { signal });
|
|
63
68
|
|
|
64
69
|
if (branch_name === master_branch_name) {
|
|
65
70
|
await rebase_master();
|
|
@@ -69,12 +74,41 @@ Rebase.run = async function run(props: Props) {
|
|
|
69
74
|
|
|
70
75
|
actions.unregister_abort_handler();
|
|
71
76
|
} catch (err) {
|
|
77
|
+
actions.unregister_abort_handler();
|
|
72
78
|
actions.error("Unable to rebase.");
|
|
73
79
|
|
|
74
80
|
if (err instanceof Error) {
|
|
75
81
|
actions.error(err.message);
|
|
76
82
|
}
|
|
77
83
|
|
|
84
|
+
actions.output(
|
|
85
|
+
<Ink.Box flexDirection="column">
|
|
86
|
+
<Ink.Box height={1} />
|
|
87
|
+
<Ink.Text>⚠️ WARNING</Ink.Text>
|
|
88
|
+
<FormatText
|
|
89
|
+
message="You are in a temporary branch {branch_name} based on {original_branch}"
|
|
90
|
+
values={{
|
|
91
|
+
branch_name: <Brackets>{temp_branch_name}</Brackets>,
|
|
92
|
+
original_branch: <Brackets>{branch_name}</Brackets>,
|
|
93
|
+
}}
|
|
94
|
+
/>
|
|
95
|
+
<FormatText
|
|
96
|
+
message="Fix merge conflicts then run {cp_continue} to proceed"
|
|
97
|
+
values={{
|
|
98
|
+
cp_continue: <Command>git cherry-pick --continue</Command>,
|
|
99
|
+
}}
|
|
100
|
+
/>
|
|
101
|
+
<FormatText
|
|
102
|
+
message="To go back to the original branch run {checkout_original}"
|
|
103
|
+
values={{
|
|
104
|
+
checkout_original: (
|
|
105
|
+
<Command>git cherry-pick --abort && git checkout -f {branch_name}</Command>
|
|
106
|
+
),
|
|
107
|
+
}}
|
|
108
|
+
/>
|
|
109
|
+
</Ink.Box>,
|
|
110
|
+
);
|
|
111
|
+
|
|
78
112
|
actions.exit(8);
|
|
79
113
|
}
|
|
80
114
|
|
|
@@ -105,7 +139,7 @@ Rebase.run = async function run(props: Props) {
|
|
|
105
139
|
}
|
|
106
140
|
|
|
107
141
|
async function rebase_master() {
|
|
108
|
-
await cli(`git switch -C "${master_branch_name}" "${master_branch}"
|
|
142
|
+
await cli(`git switch -C "${master_branch_name}" "${master_branch}"`, { signal });
|
|
109
143
|
}
|
|
110
144
|
|
|
111
145
|
async function rebase_branch() {
|
|
@@ -115,7 +149,7 @@ Rebase.run = async function run(props: Props) {
|
|
|
115
149
|
const rebase_merge_base = master_sha;
|
|
116
150
|
|
|
117
151
|
// create temporary branch based on merge base
|
|
118
|
-
await cli(`git checkout -b ${temp_branch_name} ${rebase_merge_base}
|
|
152
|
+
await cli(`git checkout -b ${temp_branch_name} ${rebase_merge_base}`, { signal });
|
|
119
153
|
|
|
120
154
|
const picked_commit_list = [];
|
|
121
155
|
|
|
@@ -157,17 +191,17 @@ Rebase.run = async function run(props: Props) {
|
|
|
157
191
|
|
|
158
192
|
if (picked_commit_list.length > 0) {
|
|
159
193
|
// ensure clean base to avoid conflicts when applying patch
|
|
160
|
-
await cli(`git clean -fd
|
|
194
|
+
await cli(`git clean -fd`, { signal });
|
|
161
195
|
|
|
162
196
|
// create list of sha for cherry-pick
|
|
163
197
|
const sha_list = picked_commit_list.map((commit) => commit.sha).join(" ");
|
|
164
198
|
|
|
165
|
-
await cli(`git cherry-pick --keep-redundant-commits ${sha_list}
|
|
199
|
+
await cli(`git cherry-pick --keep-redundant-commits ${sha_list}`, { signal });
|
|
166
200
|
}
|
|
167
201
|
|
|
168
202
|
// after all commits have been cherry-picked move the pointer
|
|
169
203
|
// of original branch to the newly created temporary branch
|
|
170
|
-
await cli(`git branch -f ${branch_name} ${temp_branch_name}
|
|
204
|
+
await cli(`git branch -f ${branch_name} ${temp_branch_name}`, { signal });
|
|
171
205
|
|
|
172
206
|
actions.debug("start restore_git()");
|
|
173
207
|
restore_git();
|
package/src/core/cli.ts
CHANGED
|
@@ -38,7 +38,15 @@ export async function cli(
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
return new Promise((resolve, reject) => {
|
|
41
|
-
|
|
41
|
+
let childProcess: child.ChildProcess;
|
|
42
|
+
try {
|
|
43
|
+
childProcess = child.spawn("sh", ["-c", command], options);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
reject(err);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let settled = false;
|
|
42
50
|
|
|
43
51
|
let stdout = "";
|
|
44
52
|
let stderr = "";
|
|
@@ -71,7 +79,11 @@ export async function cli(
|
|
|
71
79
|
});
|
|
72
80
|
|
|
73
81
|
childProcess.on("close", (unsafe_code) => {
|
|
74
|
-
|
|
82
|
+
if (settled) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
settled = true;
|
|
75
87
|
|
|
76
88
|
const result = {
|
|
77
89
|
command,
|
|
@@ -79,11 +91,12 @@ export async function cli(
|
|
|
79
91
|
stdout: stdout.trimEnd(),
|
|
80
92
|
stderr: stderr.trimEnd(),
|
|
81
93
|
output: output.trimEnd(),
|
|
82
|
-
duration,
|
|
94
|
+
duration: timer.duration(),
|
|
83
95
|
};
|
|
84
96
|
|
|
85
97
|
state.actions.debug_pending_end(id);
|
|
86
98
|
state.actions.debug(log.end(result));
|
|
99
|
+
|
|
87
100
|
if (!options.quiet) {
|
|
88
101
|
state.actions.debug(log.output(result));
|
|
89
102
|
}
|
|
@@ -97,6 +110,24 @@ export async function cli(
|
|
|
97
110
|
});
|
|
98
111
|
|
|
99
112
|
childProcess.on("error", (err) => {
|
|
113
|
+
if (settled) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
settled = true;
|
|
118
|
+
|
|
119
|
+
const result = {
|
|
120
|
+
command,
|
|
121
|
+
code: -1,
|
|
122
|
+
stdout: stdout.trimEnd(),
|
|
123
|
+
stderr: stderr.trimEnd(),
|
|
124
|
+
output: output.trimEnd(),
|
|
125
|
+
duration: timer.duration(),
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
state.actions.debug_pending_end(id);
|
|
129
|
+
state.actions.debug(log.abort({ result, err }));
|
|
130
|
+
|
|
100
131
|
reject(err);
|
|
101
132
|
});
|
|
102
133
|
});
|
|
@@ -173,6 +204,12 @@ const log = {
|
|
|
173
204
|
return `${command} (exit_code=${code} duration=${duration})`;
|
|
174
205
|
},
|
|
175
206
|
|
|
207
|
+
abort({ result, err }: { result: Return; err?: unknown }) {
|
|
208
|
+
const { command, duration } = result;
|
|
209
|
+
const err_message = err instanceof Error ? err.message : String(err);
|
|
210
|
+
return `[error] ${command} err=${err_message} (duration=${duration})`;
|
|
211
|
+
},
|
|
212
|
+
|
|
176
213
|
error(result: Return) {
|
|
177
214
|
const lines = [result.output, this.non_zero_exit(result)];
|
|
178
215
|
return lines.join("\n");
|