Skip to content

Commit 0510d8f

Browse files
committed
non-builtin rebase: use non-builtin interactive backend
We recently converted both the `git rebase` and the `git rebase -i` command from Unix shell scripts to builtins. The former has a safety valve allowing to fall back to the scripted `rebase`, just in case that there is a bug in the builtin `rebase`: setting the config variable `rebase.useBuiltin` to `false` will fall back to using the scripted version. The latter did not have such a safety hatch. Let's reinstate the scripted interactive rebase backend so that `rebase.useBuiltin=false` will not use the builtin interactive rebase, just in case that an end user runs into a bug with the builtin version and needs to get out of the fix really quickly. This is necessary because Git for Windows wants to ship the builtin rebase/interactive rebase earlier than core Git: Git for Windows v2.19.0 will come with the option of a drastically faster (if a lot less battle-tested) `git rebase`/`git rebase -i`. As the file name `git-rebase--interactive` is already in use, let's rename the scripted backend to `git-legacy-rebase--interactive`. A couple of additional touch-ups are needed (such as teaching the builtin `rebase--interactive`, which assumed the role of the `rebase--helper`, to perform the two tricks to skip the unnecessary picks and to generate a new todo list) to make things work again. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 9f2d833 commit 0510d8f

File tree

7 files changed

+41
-45
lines changed

7 files changed

+41
-45
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
/git-interpret-trailers
8383
/git-instaweb
8484
/git-legacy-rebase
85+
/git-legacy-rebase--interactive
8586
/git-legacy-stash
8687
/git-log
8788
/git-ls-files

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,7 @@ SCRIPT_SH += git-request-pull.sh
623623
SCRIPT_SH += git-submodule.sh
624624
SCRIPT_SH += git-web--browse.sh
625625

626+
SCRIPT_LIB += git-legacy-rebase--interactive
626627
SCRIPT_LIB += git-mergetool--lib
627628
SCRIPT_LIB += git-parse-remote
628629
SCRIPT_LIB += git-rebase--am

builtin/rebase--interactive.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
141141
char *raw_strategies = NULL;
142142
enum {
143143
NONE = 0, CONTINUE, SKIP, EDIT_TODO, SHOW_CURRENT_PATCH,
144-
SHORTEN_OIDS, EXPAND_OIDS, CHECK_TODO_LIST, REARRANGE_SQUASH, ADD_EXEC
144+
SHORTEN_OIDS, EXPAND_OIDS, CHECK_TODO_LIST, REARRANGE_SQUASH, ADD_EXEC,
145+
MAKE_SCRIPT, SKIP_UNNECESSARY_PICKS,
145146
} command = 0;
146147
struct option options[] = {
147148
OPT_BOOL(0, "ff", &opts.allow_ff, N_("allow fast-forward")),
@@ -192,6 +193,10 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
192193
OPT_STRING(0, "onto-name", &onto_name, N_("onto-name"), N_("onto name")),
193194
OPT_STRING(0, "cmd", &cmd, N_("cmd"), N_("the command to run")),
194195
OPT_RERERE_AUTOUPDATE(&opts.allow_rerere_auto),
196+
OPT_CMDMODE(0, "make-script", &command,
197+
N_("make rebase script"), MAKE_SCRIPT),
198+
OPT_CMDMODE(0, "skip-unnecessary-picks", &command,
199+
N_("skip unnecessary picks"), SKIP_UNNECESSARY_PICKS),
195200
OPT_END()
196201
};
197202

@@ -263,6 +268,17 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
263268
case ADD_EXEC:
264269
ret = sequencer_add_exec_commands(cmd);
265270
break;
271+
case MAKE_SCRIPT:
272+
ret = sequencer_make_script(stdout, argc, argv, flags);
273+
break;
274+
case SKIP_UNNECESSARY_PICKS: {
275+
struct object_id oid;
276+
277+
ret = skip_unnecessary_picks(&oid);
278+
if (!ret)
279+
printf("%s\n", oid_to_hex(&oid));
280+
break;
281+
}
266282
default:
267283
BUG("invalid command '%d'", command);
268284
}

git-rebase--interactive.sh renamed to git-legacy-rebase--interactive.sh

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,11 @@ git_sequence_editor () {
9595
}
9696

9797
expand_todo_ids() {
98-
git rebase--helper --expand-ids
98+
git rebase--interactive --expand-ids
9999
}
100100

101101
collapse_todo_ids() {
102-
git rebase--helper --shorten-ids
102+
git rebase--interactive --shorten-ids
103103
}
104104

105105
# Switch to the branch in $into and notify it in the reflog
@@ -131,12 +131,12 @@ get_missing_commit_check_level () {
131131
initiate_action () {
132132
case "$1" in
133133
continue)
134-
exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
134+
exec git rebase--interactive ${force_rebase:+--no-ff} $allow_empty_message \
135135
--continue
136136
;;
137137
skip)
138138
git rerere clear
139-
exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
139+
exec git rebase--interactive ${force_rebase:+--no-ff} $allow_empty_message \
140140
--continue
141141
;;
142142
edit-todo)
@@ -207,8 +207,8 @@ init_revisions_and_shortrevisions () {
207207

208208
complete_action() {
209209
test -s "$todo" || echo noop >> "$todo"
210-
test -z "$autosquash" || git rebase--helper --rearrange-squash || exit
211-
test -n "$cmd" && git rebase--helper --add-exec-commands "$cmd"
210+
test -z "$autosquash" || git rebase--interactive --rearrange-squash || exit
211+
test -n "$cmd" && git rebase--interactive --add-exec-commands --cmd "$cmd"
212212

213213
todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
214214
todocount=${todocount##* }
@@ -243,7 +243,7 @@ EOF
243243
has_action "$todo" ||
244244
return 2
245245

246-
git rebase--helper --check-todo-list || {
246+
git rebase--interactive --check-todo-list || {
247247
ret=$?
248248
checkout_onto
249249
exit $ret
@@ -252,12 +252,12 @@ EOF
252252
expand_todo_ids
253253

254254
test -n "$force_rebase" ||
255-
onto="$(git rebase--helper --skip-unnecessary-picks)" ||
255+
onto="$(git rebase--interactive --skip-unnecessary-picks)" ||
256256
die "Could not skip unnecessary pick commands"
257257

258258
checkout_onto
259259
require_clean_work_tree "rebase"
260-
exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
260+
exec git rebase--interactive ${force_rebase:+--no-ff} $allow_empty_message \
261261
--continue
262262
}
263263

@@ -273,7 +273,7 @@ git_rebase__interactive () {
273273

274274
init_revisions_and_shortrevisions
275275

276-
git rebase--helper --make-script ${keep_empty:+--keep-empty} \
276+
git rebase--interactive --make-script ${keep_empty:+--keep-empty} \
277277
${rebase_merges:+--rebase-merges} \
278278
${rebase_cousins:+--rebase-cousins} \
279279
$revisions ${restrict_revision+^$restrict_revision} >"$todo" ||

git-legacy-rebase.sh

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -135,37 +135,6 @@ finish_rebase () {
135135
rm -rf "$state_dir"
136136
}
137137

138-
run_interactive () {
139-
GIT_CHERRY_PICK_HELP="$resolvemsg"
140-
export GIT_CHERRY_PICK_HELP
141-
142-
test -n "$keep_empty" && keep_empty="--keep-empty"
143-
test -n "$rebase_merges" && rebase_merges="--rebase-merges"
144-
test -n "$rebase_cousins" && rebase_cousins="--rebase-cousins"
145-
test -n "$autosquash" && autosquash="--autosquash"
146-
test -n "$verbose" && verbose="--verbose"
147-
test -n "$force_rebase" && force_rebase="--no-ff"
148-
test -n "$restrict_revision" && \
149-
restrict_revision="--restrict-revision=^$restrict_revision"
150-
test -n "$upstream" && upstream="--upstream=$upstream"
151-
test -n "$onto" && onto="--onto=$onto"
152-
test -n "$squash_onto" && squash_onto="--squash-onto=$squash_onto"
153-
test -n "$onto_name" && onto_name="--onto-name=$onto_name"
154-
test -n "$head_name" && head_name="--head-name=$head_name"
155-
test -n "$strategy" && strategy="--strategy=$strategy"
156-
test -n "$strategy_opts" && strategy_opts="--strategy-opts=$strategy_opts"
157-
test -n "$switch_to" && switch_to="--switch-to=$switch_to"
158-
test -n "$cmd" && cmd="--cmd=$cmd"
159-
test -n "$action" && action="--$action"
160-
161-
exec git rebase--interactive "$action" "$keep_empty" "$rebase_merges" "$rebase_cousins" \
162-
"$upstream" "$onto" "$squash_onto" "$restrict_revision" \
163-
"$allow_empty_message" "$autosquash" "$verbose" \
164-
"$force_rebase" "$onto_name" "$head_name" "$strategy" \
165-
"$strategy_opts" "$cmd" "$switch_to" \
166-
"$allow_rerere_autoupdate" "$gpg_sign_opt" "$signoff"
167-
}
168-
169138
run_specific_rebase () {
170139
if [ "$interactive_rebase" = implied ]; then
171140
GIT_EDITOR=:
@@ -175,7 +144,9 @@ run_specific_rebase () {
175144

176145
if test -n "$interactive_rebase" -a -z "$preserve_merges"
177146
then
178-
run_interactive
147+
. git-legacy-rebase--$type
148+
149+
git_rebase__$type
179150
else
180151
. git-rebase--$type
181152

@@ -195,7 +166,12 @@ run_specific_rebase () {
195166
then
196167
apply_autostash &&
197168
rm -rf "$state_dir" &&
198-
die "Nothing to do"
169+
if test -n "$interactive_rebase" -a -z "$preserve_merges"
170+
then
171+
die "error: nothing to do"
172+
else
173+
die "Nothing to do"
174+
fi
199175
fi
200176
exit $ret
201177
}

sequencer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4729,7 +4729,7 @@ static int rewrite_file(const char *path, const char *buf, size_t len)
47294729
}
47304730

47314731
/* skip picking commits whose parents are unchanged */
4732-
static int skip_unnecessary_picks(struct object_id *output_oid)
4732+
int skip_unnecessary_picks(struct object_id *output_oid)
47334733
{
47344734
const char *todo_file = rebase_path_todo();
47354735
struct strbuf buf = STRBUF_INIT;

sequencer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,5 @@ int read_author_script(const char *path, char **name, char **email, char **date,
138138
void parse_strategy_opts(struct replay_opts *opts, char *raw_opts);
139139
int write_basic_state(struct replay_opts *opts, const char *head_name,
140140
const char *onto, const char *orig_head);
141+
142+
int skip_unnecessary_picks(struct object_id *output_oid);

0 commit comments

Comments
 (0)