Skip to content

Commit ba0a77b

Browse files
committed
Merge branch 'make-builtin-stash-and-rebase-opt-ins'
This branch adds back the scripted versions, then adds the option to use the builtin versions of `stash` and `rebase` by setting `stash.useBuiltin=true` and `rebase.useBuiltin=true`, respectively, (the latter already worked for the top-level `git rebase` command and the `--am` backend, and now it also works for the interactive backend). Signed-off-by: Johannes Schindelin <[email protected]>
2 parents ef0a72e + d9a5e30 commit ba0a77b

File tree

7 files changed

+314
-35
lines changed

7 files changed

+314
-35
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-legacy-rebase--interactive.sh

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
# This shell script fragment is sourced by git-rebase to implement
2+
# its interactive mode. "git rebase --interactive" makes it easy
3+
# to fix up commits in the middle of a series and rearrange commits.
4+
#
5+
# Copyright (c) 2006 Johannes E. Schindelin
6+
#
7+
# The original idea comes from Eric W. Biederman, in
8+
# https://public-inbox.org/git/[email protected]/
9+
#
10+
# The file containing rebase commands, comments, and empty lines.
11+
# This file is created by "git rebase -i" then edited by the user. As
12+
# the lines are processed, they are removed from the front of this
13+
# file and written to the tail of $done.
14+
todo="$state_dir"/git-rebase-todo
15+
16+
GIT_CHERRY_PICK_HELP="$resolvemsg"
17+
export GIT_CHERRY_PICK_HELP
18+
19+
comment_char=$(git config --get core.commentchar 2>/dev/null)
20+
case "$comment_char" in
21+
'' | auto)
22+
comment_char="#"
23+
;;
24+
?)
25+
;;
26+
*)
27+
comment_char=$(echo "$comment_char" | cut -c1)
28+
;;
29+
esac
30+
31+
orig_reflog_action="$GIT_REFLOG_ACTION"
32+
33+
comment_for_reflog () {
34+
case "$orig_reflog_action" in
35+
''|rebase*)
36+
GIT_REFLOG_ACTION="rebase -i ($1)"
37+
export GIT_REFLOG_ACTION
38+
;;
39+
esac
40+
}
41+
42+
append_todo_help () {
43+
gettext "
44+
Commands:
45+
p, pick <commit> = use commit
46+
r, reword <commit> = use commit, but edit the commit message
47+
e, edit <commit> = use commit, but stop for amending
48+
s, squash <commit> = use commit, but meld into previous commit
49+
f, fixup <commit> = like \"squash\", but discard this commit's log message
50+
x, exec <command> = run command (the rest of the line) using shell
51+
d, drop <commit> = remove commit
52+
l, label <label> = label current HEAD with a name
53+
t, reset <label> = reset HEAD to a label
54+
m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
55+
. create a merge commit using the original merge commit's
56+
. message (or the oneline, if no original merge commit was
57+
. specified). Use -c <commit> to reword the commit message.
58+
59+
These lines can be re-ordered; they are executed from top to bottom.
60+
" | git stripspace --comment-lines >>"$todo"
61+
62+
if test $(get_missing_commit_check_level) = error
63+
then
64+
gettext "
65+
Do not remove any line. Use 'drop' explicitly to remove a commit.
66+
" | git stripspace --comment-lines >>"$todo"
67+
else
68+
gettext "
69+
If you remove a line here THAT COMMIT WILL BE LOST.
70+
" | git stripspace --comment-lines >>"$todo"
71+
fi
72+
}
73+
74+
die_abort () {
75+
apply_autostash
76+
rm -rf "$state_dir"
77+
die "$1"
78+
}
79+
80+
has_action () {
81+
test -n "$(git stripspace --strip-comments <"$1")"
82+
}
83+
84+
git_sequence_editor () {
85+
if test -z "$GIT_SEQUENCE_EDITOR"
86+
then
87+
GIT_SEQUENCE_EDITOR="$(git config sequence.editor)"
88+
if [ -z "$GIT_SEQUENCE_EDITOR" ]
89+
then
90+
GIT_SEQUENCE_EDITOR="$(git var GIT_EDITOR)" || return $?
91+
fi
92+
fi
93+
94+
eval "$GIT_SEQUENCE_EDITOR" '"$@"'
95+
}
96+
97+
expand_todo_ids() {
98+
git rebase--interactive --expand-ids
99+
}
100+
101+
collapse_todo_ids() {
102+
git rebase--interactive --shorten-ids
103+
}
104+
105+
# Switch to the branch in $into and notify it in the reflog
106+
checkout_onto () {
107+
GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name"
108+
output git checkout $onto || die_abort "$(gettext "could not detach HEAD")"
109+
git update-ref ORIG_HEAD $orig_head
110+
}
111+
112+
get_missing_commit_check_level () {
113+
check_level=$(git config --get rebase.missingCommitsCheck)
114+
check_level=${check_level:-ignore}
115+
# Don't be case sensitive
116+
printf '%s' "$check_level" | tr 'A-Z' 'a-z'
117+
}
118+
119+
# Initiate an action. If the cannot be any
120+
# further action it may exec a command
121+
# or exit and not return.
122+
#
123+
# TODO: Consider a cleaner return model so it
124+
# never exits and always return 0 if process
125+
# is complete.
126+
#
127+
# Parameter 1 is the action to initiate.
128+
#
129+
# Returns 0 if the action was able to complete
130+
# and if 1 if further processing is required.
131+
initiate_action () {
132+
case "$1" in
133+
continue)
134+
exec git rebase--interactive ${force_rebase:+--no-ff} $allow_empty_message \
135+
--continue
136+
;;
137+
skip)
138+
git rerere clear
139+
exec git rebase--interactive ${force_rebase:+--no-ff} $allow_empty_message \
140+
--continue
141+
;;
142+
edit-todo)
143+
git stripspace --strip-comments <"$todo" >"$todo".new
144+
mv -f "$todo".new "$todo"
145+
collapse_todo_ids
146+
append_todo_help
147+
gettext "
148+
You are editing the todo file of an ongoing interactive rebase.
149+
To continue rebase after editing, run:
150+
git rebase --continue
151+
152+
" | git stripspace --comment-lines >>"$todo"
153+
154+
git_sequence_editor "$todo" ||
155+
die "$(gettext "Could not execute editor")"
156+
expand_todo_ids
157+
158+
exit
159+
;;
160+
show-current-patch)
161+
exec git show REBASE_HEAD --
162+
;;
163+
*)
164+
return 1 # continue
165+
;;
166+
esac
167+
}
168+
169+
setup_reflog_action () {
170+
comment_for_reflog start
171+
172+
if test ! -z "$switch_to"
173+
then
174+
GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to"
175+
output git checkout "$switch_to" -- ||
176+
die "$(eval_gettext "Could not checkout \$switch_to")"
177+
178+
comment_for_reflog start
179+
fi
180+
}
181+
182+
init_basic_state () {
183+
orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")"
184+
mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")"
185+
rm -f "$(git rev-parse --git-path REBASE_HEAD)"
186+
187+
: > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")"
188+
write_basic_state
189+
}
190+
191+
init_revisions_and_shortrevisions () {
192+
shorthead=$(git rev-parse --short $orig_head)
193+
shortonto=$(git rev-parse --short $onto)
194+
if test -z "$rebase_root"
195+
# this is now equivalent to ! -z "$upstream"
196+
then
197+
shortupstream=$(git rev-parse --short $upstream)
198+
revisions=$upstream...$orig_head
199+
shortrevisions=$shortupstream..$shorthead
200+
else
201+
revisions=$onto...$orig_head
202+
shortrevisions=$shorthead
203+
test -z "$squash_onto" ||
204+
echo "$squash_onto" >"$state_dir"/squash-onto
205+
fi
206+
}
207+
208+
complete_action() {
209+
test -s "$todo" || echo noop >> "$todo"
210+
test -z "$autosquash" || git rebase--interactive --rearrange-squash || exit
211+
test -n "$cmd" && git rebase--interactive --add-exec-commands --cmd "$cmd"
212+
213+
todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
214+
todocount=${todocount##* }
215+
216+
cat >>"$todo" <<EOF
217+
218+
$comment_char $(eval_ngettext \
219+
"Rebase \$shortrevisions onto \$shortonto (\$todocount command)" \
220+
"Rebase \$shortrevisions onto \$shortonto (\$todocount commands)" \
221+
"$todocount")
222+
EOF
223+
append_todo_help
224+
gettext "
225+
However, if you remove everything, the rebase will be aborted.
226+
227+
" | git stripspace --comment-lines >>"$todo"
228+
229+
if test -z "$keep_empty"
230+
then
231+
printf '%s\n' "$comment_char $(gettext "Note that empty commits are commented out")" >>"$todo"
232+
fi
233+
234+
235+
has_action "$todo" ||
236+
return 2
237+
238+
cp "$todo" "$todo".backup
239+
collapse_todo_ids
240+
git_sequence_editor "$todo" ||
241+
die_abort "$(gettext "Could not execute editor")"
242+
243+
has_action "$todo" ||
244+
return 2
245+
246+
git rebase--interactive --check-todo-list || {
247+
ret=$?
248+
checkout_onto
249+
exit $ret
250+
}
251+
252+
expand_todo_ids
253+
254+
test -n "$force_rebase" ||
255+
onto="$(git rebase--interactive --skip-unnecessary-picks)" ||
256+
die "Could not skip unnecessary pick commands"
257+
258+
checkout_onto
259+
require_clean_work_tree "rebase"
260+
exec git rebase--interactive ${force_rebase:+--no-ff} $allow_empty_message \
261+
--continue
262+
}
263+
264+
git_rebase__interactive () {
265+
initiate_action "$action"
266+
ret=$?
267+
if test $ret = 0; then
268+
return 0
269+
fi
270+
271+
setup_reflog_action
272+
init_basic_state
273+
274+
init_revisions_and_shortrevisions
275+
276+
git rebase--interactive --make-script ${keep_empty:+--keep-empty} \
277+
${rebase_merges:+--rebase-merges} \
278+
${rebase_cousins:+--rebase-cousins} \
279+
$revisions ${restrict_revision+^$restrict_revision} >"$todo" ||
280+
die "$(gettext "Could not generate todo list")"
281+
282+
complete_action
283+
}

0 commit comments

Comments
 (0)