rebase: remove the rebase.useBuiltin setting

Remove the rebase.useBuiltin setting, which was added as an escape hatch to disable the builtin version of rebase first released with Git 2.20. See [1] for the initial implementation of rebase.useBuiltin, and [2] and [3] for the documentation and corresponding GIT_TEST_REBASE_USE_BUILTIN option. Carrying the legacy version is a maintenance burden as seen in 7e097e27d3 ("legacy-rebase: backport -C<n> and --whitespace=<option> checks", 2018-11-20) and 9aea5e9286 ("rebase: fix regression in rebase.useBuiltin=false test mode", 2019-02-13). Since the built-in version has been shown to be stable enough let's remove the legacy version. As noted in [3] having use_builtin_rebase() shell out to get its config doesn't make any sense anymore, that was done for the purposes of spawning the legacy rebase without having modified any global state. Let's instead handle this case in rebase_config(). There's still a bunch of references to git-legacy-rebase in po/*.po, but those will be dealt with in time by the i18n effort. Even though this configuration variable only existed two releases let's not entirely delete the entry from the docs, but note its absence. Individual versions of git tend to be around for a while due to distro packaging timelines, so e.g. if we're "lucky" a given version like 2.21 might be installed on say OSX for half a decade. That'll mean some people probably setting this in config, and then when they later wonder if it's needed they can Google search the config option name or check it in git-config. It also allows us to refer to the docs from the warning for details. 1. 55071ea248 ("rebase: start implementing it as a builtin", 2018-08-07) 2. d8d0a546f0 ("rebase doc: document rebase.useBuiltin", 2018-11-14) 3. 62c23938fa ("tests: add a special setup where rebase.useBuiltin is off", 2018-11-14) 3. https://public-inbox.org/git/nycvar.QRO.7.76.6.1903141544110.41@tvgsbejvaqbjf.bet/ Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ævar Arnfjörð Bjarmason committed Mar 18, 2019 at 12:01 UTC d03ebd411c651641eab823f0807705f4af65c9b1
8 files changed +35 -833
.gitignore
-1
@@ -82,7 +82,6 @@
82 /git-init-db
83 /git-interpret-trailers
84 /git-instaweb
85 -/git-legacy-rebase
85 /git-log
86 /git-ls-files
87 /git-ls-remote
Documentation/config/rebase.txt
+5 -12
@@ -1,16 +1,9 @@
1 rebase.useBuiltin::
2 - Set to `false` to use the legacy shellscript implementation of
3 - linkgit:git-rebase[1]. Is `true` by default, which means use
4 - the built-in rewrite of it in C.
5 -+
6 -The C rewrite is first included with Git version 2.20. This option
7 -serves an an escape hatch to re-enable the legacy version in case any
8 -bugs are found in the rewrite. This option and the shellscript version
9 -of linkgit:git-rebase[1] will be removed in some future release.
10 -+
11 -If you find some reason to set this option to `false` other than
12 -one-off testing you should report the behavior difference as a bug in
13 -git.
2 + Unused configuration variable. Used in Git versions 2.20 and
3 + 2.21 as an escape hatch to enable the legacy shellscript
4 + implementation of rebase. Now the built-in rewrite of it in C
5 + is always used. Setting this will emit a warning, to alert any
6 + remaining users that setting this now does nothing.
7
8 rebase.stat::
9 Whether to show a diffstat of what changed upstream since the last
Makefile
-1
@@ -632,7 +632,6 @@ SCRIPT_SH += git-merge-one-file.sh
632 SCRIPT_SH += git-merge-resolve.sh
633 SCRIPT_SH += git-mergetool.sh
634 SCRIPT_SH += git-quiltimport.sh
635 -SCRIPT_SH += git-legacy-rebase.sh
635 SCRIPT_SH += git-remote-testgit.sh
636 SCRIPT_SH += git-request-pull.sh
637 SCRIPT_SH += git-stash.sh
builtin/rebase.c
+11 -39
@@ -46,29 +46,6 @@ enum rebase_type {
46 REBASE_PRESERVE_MERGES
47 };
48
49 -static int use_builtin_rebase(void)
50 -{
51 - struct child_process cp = CHILD_PROCESS_INIT;
52 - struct strbuf out = STRBUF_INIT;
53 - int ret, env = git_env_bool("GIT_TEST_REBASE_USE_BUILTIN", -1);
54 -
55 - if (env != -1)
56 - return env;
57 -
58 - argv_array_pushl(&cp.args,
59 - "config", "--bool", "rebase.usebuiltin", NULL);
60 - cp.git_cmd = 1;
61 - if (capture_command(&cp, &out, 6)) {
62 - strbuf_release(&out);
63 - return 1;
64 - }
65 -
66 - strbuf_trim(&out);
67 - ret = !strcmp("true", out.buf);
68 - strbuf_release(&out);
69 - return ret;
70 -}
71 -
49 struct rebase_options {
50 enum rebase_type type;
51 const char *state_dir;
@@ -106,6 +83,7 @@ struct rebase_options {
83 char *strategy, *strategy_opts;
84 struct strbuf git_format_patch_opt;
85 int reschedule_failed_exec;
86 + int use_legacy_rebase;
87 };
88
89 static int is_interactive(struct rebase_options *opts)
@@ -869,6 +847,11 @@ static int rebase_config(const char *var, const char *value, void *data)
847 return 0;
848 }
849
850 + if (!strcmp(var, "rebase.usebuiltin")) {
851 + opts->use_legacy_rebase = !git_config_bool(var, value);
852 + return 0;
853 + }
854 +
855 return git_default_config(var, value, data);
856 }
857
@@ -1143,22 +1126,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1126 };
1127 int i;
1128
1146 - /*
1147 - * NEEDSWORK: Once the builtin rebase has been tested enough
1148 - * and git-legacy-rebase.sh is retired to contrib/, this preamble
1149 - * can be removed.
1150 - */
1151 -
1152 - if (!use_builtin_rebase()) {
1153 - const char *path = mkpath("%s/git-legacy-rebase",
1154 - git_exec_path());
1155 -
1156 - if (sane_execvp(path, (char **)argv) < 0)
1157 - die_errno(_("could not exec %s"), path);
1158 - else
1159 - BUG("sane_execvp() returned???");
1160 - }
1161 -
1129 if (argc == 2 && !strcmp(argv[1], "-h"))
1130 usage_with_options(builtin_rebase_usage,
1131 builtin_rebase_options);
@@ -1169,6 +1136,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1136
1137 git_config(rebase_config, &options);
1138
1139 + if (options.use_legacy_rebase ||
1140 + !git_env_bool("GIT_TEST_REBASE_USE_BUILTIN", -1))
1141 + warning(_("the rebase.useBuiltin support has been removed!\n"
1142 + "See its entry in 'git help config' for details."));
1143 +
1144 strbuf_reset(&buf);
1145 strbuf_addf(&buf, "%s/applying", apply_dir());
1146 if(file_exists(buf.buf))
git-legacy-rebase.sh deleted
-770
@@ -1,770 +0,0 @@
1 -#!/bin/sh
2 -#
3 -# Copyright (c) 2005 Junio C Hamano.
4 -#
5 -
6 -SUBDIRECTORY_OK=Yes
7 -OPTIONS_KEEPDASHDASH=
8 -OPTIONS_STUCKLONG=t
9 -OPTIONS_SPEC="\
10 -git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
11 -git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
12 -git rebase --continue | --abort | --skip | --edit-todo
13 ---
14 - Available options are
15 -v,verbose! display a diffstat of what changed upstream
16 -q,quiet! be quiet. implies --no-stat
17 -autostash automatically stash/stash pop before and after
18 -fork-point use 'merge-base --fork-point' to refine upstream
19 -onto=! rebase onto given branch instead of upstream
20 -r,rebase-merges? try to rebase merges instead of skipping them
21 -p,preserve-merges! try to recreate merges instead of ignoring them
22 -s,strategy=! use the given merge strategy
23 -X,strategy-option=! pass the argument through to the merge strategy
24 -no-ff! cherry-pick all commits, even if unchanged
25 -f,force-rebase! cherry-pick all commits, even if unchanged
26 -m,merge! use merging strategies to rebase
27 -i,interactive! let the user edit the list of commits to rebase
28 -x,exec=! add exec lines after each commit of the editable list
29 -k,keep-empty preserve empty commits during rebase
30 -allow-empty-message allow rebasing commits with empty messages
31 -stat! display a diffstat of what changed upstream
32 -n,no-stat! do not show diffstat of what changed upstream
33 -verify allow pre-rebase hook to run
34 -rerere-autoupdate allow rerere to update index with resolved conflicts
35 -root! rebase all reachable commits up to the root(s)
36 -autosquash move commits that begin with squash!/fixup! under -i
37 -signoff add a Signed-off-by: line to each commit
38 -committer-date-is-author-date! passed to 'git am'
39 -ignore-date! passed to 'git am'
40 -whitespace=! passed to 'git apply'
41 -ignore-whitespace! passed to 'git apply'
42 -C=! passed to 'git apply'
43 -S,gpg-sign? GPG-sign commits
44 - Actions:
45 -continue! continue
46 -abort! abort and check out the original branch
47 -skip! skip current patch and continue
48 -edit-todo! edit the todo list during an interactive rebase
49 -quit! abort but keep HEAD where it is
50 -show-current-patch! show the patch file being applied or merged
51 -reschedule-failed-exec automatically reschedule failed exec commands
52 -"
53 -. git-sh-setup
54 -set_reflog_action rebase
55 -require_work_tree_exists
56 -cd_to_toplevel
57 -
58 -LF='
59 -'
60 -ok_to_skip_pre_rebase=
61 -
62 -squash_onto=
63 -unset onto
64 -unset restrict_revision
65 -cmd=
66 -strategy=
67 -strategy_opts=
68 -do_merge=
69 -merge_dir="$GIT_DIR"/rebase-merge
70 -apply_dir="$GIT_DIR"/rebase-apply
71 -verbose=
72 -diffstat=
73 -test "$(git config --bool rebase.stat)" = true && diffstat=t
74 -autostash="$(git config --bool rebase.autostash || echo false)"
75 -fork_point=auto
76 -git_am_opt=
77 -git_format_patch_opt=
78 -rebase_root=
79 -force_rebase=
80 -allow_rerere_autoupdate=
81 -# Non-empty if a rebase was in progress when 'git rebase' was invoked
82 -in_progress=
83 -# One of {am, merge, interactive}
84 -type=
85 -# One of {"$GIT_DIR"/rebase-apply, "$GIT_DIR"/rebase-merge}
86 -state_dir=
87 -# One of {'', continue, skip, abort}, as parsed from command line
88 -action=
89 -rebase_merges=
90 -rebase_cousins=
91 -preserve_merges=
92 -autosquash=
93 -keep_empty=
94 -allow_empty_message=--allow-empty-message
95 -signoff=
96 -reschedule_failed_exec=
97 -test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
98 -case "$(git config --bool commit.gpgsign)" in
99 -true) gpg_sign_opt=-S ;;
100 -*) gpg_sign_opt= ;;
101 -esac
102 -test "$(git config --bool rebase.reschedulefailedexec)" = "true" &&
103 -reschedule_failed_exec=--reschedule-failed-exec
104 -. git-rebase--common
105 -
106 -read_basic_state () {
107 - test -f "$state_dir/head-name" &&
108 - test -f "$state_dir/onto" &&
109 - head_name=$(cat "$state_dir"/head-name) &&
110 - onto=$(cat "$state_dir"/onto) &&
111 - # We always write to orig-head, but interactive rebase used to write to
112 - # head. Fall back to reading from head to cover for the case that the
113 - # user upgraded git with an ongoing interactive rebase.
114 - if test -f "$state_dir"/orig-head
115 - then
116 - orig_head=$(cat "$state_dir"/orig-head)
117 - else
118 - orig_head=$(cat "$state_dir"/head)
119 - fi &&
120 - test -f "$state_dir"/quiet && GIT_QUIET=t
121 - test -f "$state_dir"/verbose && verbose=t
122 - test -f "$state_dir"/strategy && strategy="$(cat "$state_dir"/strategy)"
123 - test -f "$state_dir"/strategy_opts &&
124 - strategy_opts="$(cat "$state_dir"/strategy_opts)"
125 - test -f "$state_dir"/allow_rerere_autoupdate &&
126 - allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)"
127 - test -f "$state_dir"/gpg_sign_opt &&
128 - gpg_sign_opt="$(cat "$state_dir"/gpg_sign_opt)"
129 - test -f "$state_dir"/signoff && {
130 - signoff="$(cat "$state_dir"/signoff)"
131 - force_rebase=t
132 - }
133 - test -f "$state_dir"/reschedule-failed-exec &&
134 - reschedule_failed_exec=t
135 -}
136 -
137 -finish_rebase () {
138 - rm -f "$(git rev-parse --git-path REBASE_HEAD)"
139 - apply_autostash &&
140 - { git gc --auto || true; } &&
141 - rm -rf "$state_dir"
142 -}
143 -
144 -run_interactive () {
145 - GIT_CHERRY_PICK_HELP="$resolvemsg"
146 - export GIT_CHERRY_PICK_HELP
147 -
148 - test -n "$keep_empty" && keep_empty="--keep-empty"
149 - test -n "$rebase_merges" && rebase_merges="--rebase-merges"
150 - test -n "$rebase_cousins" && rebase_cousins="--rebase-cousins"
151 - test -n "$autosquash" && autosquash="--autosquash"
152 - test -n "$verbose" && verbose="--verbose"
153 - test -n "$force_rebase" && force_rebase="--no-ff"
154 - test -n "$restrict_revision" && \
155 - restrict_revision="--restrict-revision=^$restrict_revision"
156 - test -n "$upstream" && upstream="--upstream=$upstream"
157 - test -n "$onto" && onto="--onto=$onto"
158 - test -n "$squash_onto" && squash_onto="--squash-onto=$squash_onto"
159 - test -n "$onto_name" && onto_name="--onto-name=$onto_name"
160 - test -n "$head_name" && head_name="--head-name=$head_name"
161 - test -n "$strategy" && strategy="--strategy=$strategy"
162 - test -n "$strategy_opts" && strategy_opts="--strategy-opts=$strategy_opts"
163 - test -n "$switch_to" && switch_to="--switch-to=$switch_to"
164 - test -n "$cmd" && cmd="--cmd=$cmd"
165 - test -n "$action" && action="--$action"
166 -
167 - exec git rebase--interactive "$action" "$keep_empty" "$rebase_merges" "$rebase_cousins" \
168 - "$upstream" "$onto" "$squash_onto" "$restrict_revision" \
169 - "$allow_empty_message" "$autosquash" "$verbose" \
170 - "$force_rebase" "$onto_name" "$head_name" "$strategy" \
171 - "$strategy_opts" "$cmd" "$switch_to" \
172 - "$allow_rerere_autoupdate" "$gpg_sign_opt" "$signoff" \
173 - "$reschedule_failed_exec"
174 -}
175 -
176 -run_specific_rebase () {
177 - if [ "$interactive_rebase" = implied ]; then
178 - GIT_SEQUENCE_EDITOR=:
179 - export GIT_SEQUENCE_EDITOR
180 - autosquash=
181 - fi
182 -
183 - if test -n "$interactive_rebase" -a -z "$preserve_merges"
184 - then
185 - run_interactive
186 - else
187 - . git-rebase--$type
188 -
189 - if test -z "$preserve_merges"
190 - then
191 - git_rebase__$type
192 - else
193 - git_rebase__preserve_merges
194 - fi
195 - fi
196 -
197 - ret=$?
198 - if test $ret -eq 0
199 - then
200 - finish_rebase
201 - elif test $ret -eq 2 # special exit status for rebase -p
202 - then
203 - apply_autostash &&
204 - rm -rf "$state_dir" &&
205 - die "Nothing to do"
206 - fi
207 - exit $ret
208 -}
209 -
210 -run_pre_rebase_hook () {
211 - if test -z "$ok_to_skip_pre_rebase" &&
212 - test -x "$(git rev-parse --git-path hooks/pre-rebase)"
213 - then
214 - "$(git rev-parse --git-path hooks/pre-rebase)" ${1+"$@"} ||
215 - die "$(gettext "The pre-rebase hook refused to rebase.")"
216 - fi
217 -}
218 -
219 -test -f "$apply_dir"/applying &&
220 - die "$(gettext "It looks like 'git am' is in progress. Cannot rebase.")"
221 -
222 -if test -d "$apply_dir"
223 -then
224 - type=am
225 - state_dir="$apply_dir"
226 -elif test -d "$merge_dir"
227 -then
228 - type=interactive
229 - if test -d "$merge_dir"/rewritten
230 - then
231 - type=preserve-merges
232 - interactive_rebase=explicit
233 - preserve_merges=t
234 - elif test -f "$merge_dir"/interactive
235 - then
236 - interactive_rebase=explicit
237 - fi
238 - state_dir="$merge_dir"
239 -fi
240 -test -n "$type" && in_progress=t
241 -
242 -total_argc=$#
243 -while test $# != 0
244 -do
245 - case "$1" in
246 - --no-verify)
247 - ok_to_skip_pre_rebase=yes
248 - ;;
249 - --verify)
250 - ok_to_skip_pre_rebase=
251 - ;;
252 - --continue|--skip|--abort|--quit|--edit-todo|--show-current-patch)
253 - test $total_argc -eq 2 || usage
254 - action=${1##--}
255 - ;;
256 - --onto=*)
257 - onto="${1#--onto=}"
258 - ;;
259 - --exec=*)
260 - cmd="${cmd}exec ${1#--exec=}${LF}"
261 - test -z "$interactive_rebase" && interactive_rebase=implied
262 - ;;
263 - --interactive)
264 - interactive_rebase=explicit
265 - ;;
266 - --keep-empty)
267 - keep_empty=yes
268 - ;;
269 - --allow-empty-message)
270 - allow_empty_message=--allow-empty-message
271 - ;;
272 - --no-keep-empty)
273 - keep_empty=
274 - ;;
275 - --rebase-merges)
276 - rebase_merges=t
277 - test -z "$interactive_rebase" && interactive_rebase=implied
278 - ;;
279 - --rebase-merges=*)
280 - rebase_merges=t
281 - case "${1#*=}" in
282 - rebase-cousins) rebase_cousins=t;;
283 - no-rebase-cousins) rebase_cousins=;;
284 - *) die "Unknown mode: $1";;
285 - esac
286 - test -z "$interactive_rebase" && interactive_rebase=implied
287 - ;;
288 - --preserve-merges)
289 - preserve_merges=t
290 - test -z "$interactive_rebase" && interactive_rebase=implied
291 - ;;
292 - --autosquash)
293 - autosquash=t
294 - ;;
295 - --no-autosquash)
296 - autosquash=
297 - ;;
298 - --fork-point)
299 - fork_point=t
300 - ;;
301 - --no-fork-point)
302 - fork_point=
303 - ;;
304 - --merge)
305 - do_merge=t
306 - ;;
307 - --strategy-option=*)
308 - strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--${1#--strategy-option=}" | sed -e s/^.//)"
309 - do_merge=t
310 - test -z "$strategy" && strategy=recursive
311 - ;;
312 - --strategy=*)
313 - strategy="${1#--strategy=}"
314 - do_merge=t
315 - ;;
316 - --no-stat)
317 - diffstat=
318 - ;;
319 - --stat)
320 - diffstat=t
321 - ;;
322 - --autostash)
323 - autostash=true
324 - ;;
325 - --no-autostash)
326 - autostash=false
327 - ;;
328 - --verbose)
329 - verbose=t
330 - diffstat=t
331 - GIT_QUIET=
332 - ;;
333 - --quiet)
334 - GIT_QUIET=t
335 - git_am_opt="$git_am_opt -q"
336 - verbose=
337 - diffstat=
338 - ;;
339 - --whitespace=*)
340 - git_am_opt="$git_am_opt --whitespace=${1#--whitespace=}"
341 - case "${1#--whitespace=}" in
342 - fix|strip)
343 - force_rebase=t
344 - ;;
345 - warn|nowarn|error|error-all)
346 - ;; # okay, known whitespace option
347 - *)
348 - die "fatal: Invalid whitespace option: '${1#*=}'"
349 - ;;
350 - esac
351 - ;;
352 - --ignore-whitespace)
353 - git_am_opt="$git_am_opt $1"
354 - ;;
355 - --signoff)
356 - signoff=--signoff
357 - ;;
358 - --no-signoff)
359 - signoff=
360 - ;;
361 - --committer-date-is-author-date|--ignore-date)
362 - git_am_opt="$git_am_opt $1"
363 - force_rebase=t
364 - ;;
365 - -C*[!0-9]*)
366 - die "fatal: switch \`C' expects a numerical value"
367 - ;;
368 - -C*)
369 - git_am_opt="$git_am_opt $1"
370 - ;;
371 - --root)
372 - rebase_root=t
373 - ;;
374 - --force-rebase|--no-ff)
375 - force_rebase=t
376 - ;;
377 - --rerere-autoupdate|--no-rerere-autoupdate)
378 - allow_rerere_autoupdate="$1"
379 - ;;
380 - --gpg-sign)
381 - gpg_sign_opt=-S
382 - ;;
383 - --gpg-sign=*)
384 - gpg_sign_opt="-S${1#--gpg-sign=}"
385 - ;;
386 - --reschedule-failed-exec)
387 - reschedule_failed_exec=--reschedule-failed-exec
388 - ;;
389 - --no-reschedule-failed-exec)
390 - reschedule_failed_exec=
391 - ;;
392 - --)
393 - shift
394 - break
395 - ;;
396 - *)
397 - usage
398 - ;;
399 - esac
400 - shift
401 -done
402 -test $# -gt 2 && usage
403 -
404 -if test -n "$action"
405 -then
406 - test -z "$in_progress" && die "$(gettext "No rebase in progress?")"
407 - # Only interactive rebase uses detailed reflog messages
408 - if test -n "$interactive_rebase" && test "$GIT_REFLOG_ACTION" = rebase
409 - then
410 - GIT_REFLOG_ACTION="rebase -i ($action)"
411 - export GIT_REFLOG_ACTION
412 - fi
413 -fi
414 -
415 -if test "$action" = "edit-todo" && test -z "$interactive_rebase"
416 -then
417 - die "$(gettext "The --edit-todo action can only be used during interactive rebase.")"
418 -fi
419 -
420 -case "$action" in
421 -continue)
422 - # Sanity check
423 - git rev-parse --verify HEAD >/dev/null ||
424 - die "$(gettext "Cannot read HEAD")"
425 - git update-index --ignore-submodules --refresh &&
426 - git diff-files --quiet --ignore-submodules || {
427 - echo "$(gettext "You must edit all merge conflicts and then
428 -mark them as resolved using git add")"
429 - exit 1
430 - }
431 - read_basic_state
432 - run_specific_rebase
433 - ;;
434 -skip)
435 - output git reset --hard HEAD || exit $?
436 - read_basic_state
437 - run_specific_rebase
438 - ;;
439 -abort)
440 - git rerere clear
441 - read_basic_state
442 - case "$head_name" in
443 - refs/*)
444 - git symbolic-ref -m "rebase: aborting" HEAD $head_name ||
445 - die "$(eval_gettext "Could not move back to \$head_name")"
446 - ;;
447 - esac
448 - output git reset --hard $orig_head
449 - finish_rebase
450 - exit
451 - ;;
452 -quit)
453 - exec rm -rf "$state_dir"
454 - ;;
455 -edit-todo)
456 - run_specific_rebase
457 - ;;
458 -show-current-patch)
459 - run_specific_rebase
460 - die "BUG: run_specific_rebase is not supposed to return here"
461 - ;;
462 -esac
463 -
464 -# Make sure no rebase is in progress
465 -if test -n "$in_progress"
466 -then
467 - state_dir_base=${state_dir##*/}
468 - cmd_live_rebase="git rebase (--continue | --abort | --skip)"
469 - cmd_clear_stale_rebase="rm -fr \"$state_dir\""
470 - die "
471 -$(eval_gettext 'It seems that there is already a $state_dir_base directory, and
472 -I wonder if you are in the middle of another rebase. If that is the
473 -case, please try
474 - $cmd_live_rebase
475 -If that is not the case, please
476 - $cmd_clear_stale_rebase
477 -and run me again. I am stopping in case you still have something
478 -valuable there.')"
479 -fi
480 -
481 -if test -n "$rebase_root" && test -z "$onto"
482 -then
483 - test -z "$interactive_rebase" && interactive_rebase=implied
484 -fi
485 -
486 -if test -n "$keep_empty"
487 -then
488 - test -z "$interactive_rebase" && interactive_rebase=implied
489 -fi
490 -
491 -actually_interactive=
492 -if test -n "$interactive_rebase"
493 -then
494 - if test -z "$preserve_merges"
495 - then
496 - type=interactive
497 - else
498 - type=preserve-merges
499 - fi
500 - actually_interactive=t
501 - state_dir="$merge_dir"
502 -elif test -n "$do_merge"
503 -then
504 - interactive_rebase=implied
505 - type=interactive
506 - state_dir="$merge_dir"
507 -else
508 - type=am
509 - state_dir="$apply_dir"
510 -fi
511 -
512 -if test -t 2 && test -z "$GIT_QUIET"
513 -then
514 - git_format_patch_opt="$git_format_patch_opt --progress"
515 -fi
516 -
517 -incompatible_opts=$(echo " $git_am_opt " | \
518 - sed -e 's/ -q / /g' -e 's/^ \(.*\) $/\1/')
519 -if test -n "$incompatible_opts"
520 -then
521 - if test -n "$actually_interactive" || test "$do_merge"
522 - then
523 - die "$(gettext "fatal: cannot combine am options with either interactive or merge options")"
524 - fi
525 -fi
526 -
527 -if test -n "$signoff"
528 -then
529 - test -n "$preserve_merges" &&
530 - die "$(gettext "fatal: cannot combine '--signoff' with '--preserve-merges'")"
531 - git_am_opt="$git_am_opt $signoff"
532 - force_rebase=t
533 -fi
534 -
535 -if test -n "$preserve_merges"
536 -then
537 - # Note: incompatibility with --signoff handled in signoff block above
538 - # Note: incompatibility with --interactive is just a strong warning;
539 - # git-rebase.txt caveats with "unless you know what you are doing"
540 - test -n "$rebase_merges" &&
541 - die "$(gettext "fatal: cannot combine '--preserve-merges' with '--rebase-merges'")"
542 -
543 - test -n "$reschedule_failed_exec" &&
544 - die "$(gettext "error: cannot combine '--preserve-merges' with '--reschedule-failed-exec'")"
545 -fi
546 -
547 -if test -n "$rebase_merges"
548 -then
549 - test -n "$strategy_opts" &&
550 - die "$(gettext "fatal: cannot combine '--rebase-merges' with '--strategy-option'")"
551 - test -n "$strategy" &&
552 - die "$(gettext "fatal: cannot combine '--rebase-merges' with '--strategy'")"
553 -fi
554 -
555 -if test -z "$rebase_root"
556 -then
557 - case "$#" in
558 - 0)
559 - if ! upstream_name=$(git rev-parse --symbolic-full-name \
560 - --verify -q @{upstream} 2>/dev/null)
561 - then
562 - . git-parse-remote
563 - error_on_missing_default_upstream "rebase" "rebase" \
564 - "against" "git rebase $(gettext '<branch>')"
565 - fi
566 -
567 - test "$fork_point" = auto && fork_point=t
568 - ;;
569 - *) upstream_name="$1"
570 - if test "$upstream_name" = "-"
571 - then
572 - upstream_name="@{-1}"
573 - fi
574 - shift
575 - ;;
576 - esac
577 - upstream=$(peel_committish "${upstream_name}") ||
578 - die "$(eval_gettext "invalid upstream '\$upstream_name'")"
579 - upstream_arg="$upstream_name"
580 -else
581 - if test -z "$onto"
582 - then
583 - empty_tree=$(git hash-object -t tree /dev/null)
584 - onto=$(git commit-tree $empty_tree </dev/null)
585 - squash_onto="$onto"
586 - fi
587 - unset upstream_name
588 - unset upstream
589 - test $# -gt 1 && usage
590 - upstream_arg=--root
591 -fi
592 -
593 -# Make sure the branch to rebase onto is valid.
594 -onto_name=${onto-"$upstream_name"}
595 -case "$onto_name" in
596 -*...*)
597 - if left=${onto_name%...*} right=${onto_name#*...} &&
598 - onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD})
599 - then
600 - case "$onto" in
601 - ?*"$LF"?*)
602 - die "$(eval_gettext "\$onto_name: there are more than one merge bases")"
603 - ;;
604 - '')
605 - die "$(eval_gettext "\$onto_name: there is no merge base")"
606 - ;;
607 - esac
608 - else
609 - die "$(eval_gettext "\$onto_name: there is no merge base")"
610 - fi
611 - ;;
612 -*)
613 - onto=$(peel_committish "$onto_name") ||
614 - die "$(eval_gettext "Does not point to a valid commit: \$onto_name")"
615 - ;;
616 -esac
617 -
618 -# If the branch to rebase is given, that is the branch we will rebase
619 -# $branch_name -- branch/commit being rebased, or HEAD (already detached)
620 -# $orig_head -- commit object name of tip of the branch before rebasing
621 -# $head_name -- refs/heads/<that-branch> or "detached HEAD"
622 -switch_to=
623 -case "$#" in
624 -1)
625 - # Is it "rebase other $branchname" or "rebase other $commit"?
626 - branch_name="$1"
627 - switch_to="$1"
628 -
629 - # Is it a local branch?
630 - if git show-ref --verify --quiet -- "refs/heads/$branch_name" &&
631 - orig_head=$(git rev-parse -q --verify "refs/heads/$branch_name")
632 - then
633 - head_name="refs/heads/$branch_name"
634 - # If not is it a valid ref (branch or commit)?
635 - elif orig_head=$(git rev-parse -q --verify "$branch_name")
636 - then
637 - head_name="detached HEAD"
638 -
639 - else
640 - die "$(eval_gettext "fatal: no such branch/commit '\$branch_name'")"
641 - fi
642 - ;;
643 -0)
644 - # Do not need to switch branches, we are already on it.
645 - if branch_name=$(git symbolic-ref -q HEAD)
646 - then
647 - head_name=$branch_name
648 - branch_name=$(expr "z$branch_name" : 'zrefs/heads/\(.*\)')
649 - else
650 - head_name="detached HEAD"
651 - branch_name=HEAD
652 - fi
653 - orig_head=$(git rev-parse --verify HEAD) || exit
654 - ;;
655 -*)
656 - die "BUG: unexpected number of arguments left to parse"
657 - ;;
658 -esac
659 -
660 -if test "$fork_point" = t
661 -then
662 - new_upstream=$(git merge-base --fork-point "$upstream_name" \
663 - "${switch_to:-HEAD}")
664 - if test -n "$new_upstream"
665 - then
666 - restrict_revision=$new_upstream
667 - fi
668 -fi
669 -
670 -if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null
671 -then
672 - stash_sha1=$(git stash create "autostash") ||
673 - die "$(gettext 'Cannot autostash')"
674 -
675 - mkdir -p "$state_dir" &&
676 - echo $stash_sha1 >"$state_dir/autostash" &&
677 - stash_abbrev=$(git rev-parse --short $stash_sha1) &&
678 - echo "$(eval_gettext 'Created autostash: $stash_abbrev')" &&
679 - git reset --hard
680 -fi
681 -
682 -require_clean_work_tree "rebase" "$(gettext "Please commit or stash them.")"
683 -
684 -# Now we are rebasing commits $upstream..$orig_head (or with --root,
685 -# everything leading up to $orig_head) on top of $onto
686 -
687 -# Check if we are already based on $onto with linear history,
688 -# but this should be done only when upstream and onto are the same
689 -# and if this is not an interactive rebase.
690 -mb=$(git merge-base "$onto" "$orig_head")
691 -if test -z "$actually_interactive" && test "$upstream" = "$onto" &&
692 - test "$mb" = "$onto" && test -z "$restrict_revision" &&
693 - # linear history?
694 - ! (git rev-list --parents "$onto".."$orig_head" | sane_grep " .* ") > /dev/null
695 -then
696 - if test -z "$force_rebase"
697 - then
698 - # Lazily switch to the target branch if needed...
699 - test -z "$switch_to" ||
700 - GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to" \
701 - git checkout -q "$switch_to" --
702 - if test "$branch_name" = "HEAD" &&
703 - ! git symbolic-ref -q HEAD
704 - then
705 - say "$(eval_gettext "HEAD is up to date.")"
706 - else
707 - say "$(eval_gettext "Current branch \$branch_name is up to date.")"
708 - fi
709 - finish_rebase
710 - exit 0
711 - else
712 - if test "$branch_name" = "HEAD" &&
713 - ! git symbolic-ref -q HEAD
714 - then
715 - say "$(eval_gettext "HEAD is up to date, rebase forced.")"
716 - else
717 - say "$(eval_gettext "Current branch \$branch_name is up to date, rebase forced.")"
718 - fi
719 - fi
720 -fi
721 -
722 -# If a hook exists, give it a chance to interrupt
723 -run_pre_rebase_hook "$upstream_arg" "$@"
724 -
725 -if test -n "$diffstat"
726 -then
727 - if test -n "$verbose"
728 - then
729 - if test -z "$mb"
730 - then
731 - echo "$(eval_gettext "Changes to \$onto:")"
732 - else
733 - echo "$(eval_gettext "Changes from \$mb to \$onto:")"
734 - fi
735 - fi
736 - mb_tree="${mb:-$(git hash-object -t tree /dev/null)}"
737 - # We want color (if set), but no pager
738 - GIT_PAGER='' git diff --stat --summary "$mb_tree" "$onto"
739 -fi
740 -
741 -if test -z "$actually_interactive" && test "$mb" = "$orig_head"
742 -then
743 - say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")"
744 - GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" \
745 - git checkout -q "$onto^0" || die "could not detach HEAD"
746 - # If the $onto is a proper descendant of the tip of the branch, then
747 - # we just fast-forwarded.
748 - git update-ref ORIG_HEAD $orig_head
749 - move_to_original_branch
750 - finish_rebase
751 - exit 0
752 -fi
753 -
754 -test -n "$interactive_rebase" && run_specific_rebase
755 -
756 -# Detach HEAD and reset the tree
757 -say "$(gettext "First, rewinding head to replay your work on top of it...")"
758 -
759 -GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" \
760 - git checkout -q "$onto^0" || die "could not detach HEAD"
761 -git update-ref ORIG_HEAD $orig_head
762 -
763 -if test -n "$rebase_root"
764 -then
765 - revisions="$onto..$orig_head"
766 -else
767 - revisions="${restrict_revision-$upstream}..$orig_head"
768 -fi
769 -
770 -run_specific_rebase
t/README
-4
@@ -379,10 +379,6 @@ the --no-sparse command-line argument.
379 GIT_TEST_PRELOAD_INDEX=<boolean> exercises the preload-index code path
380 by overriding the minimum number of cache entries required per thread.
381
382 -GIT_TEST_REBASE_USE_BUILTIN=<boolean>, when false, disables the
383 -builtin version of git-rebase. See 'rebase.useBuiltin' in
384 -git-config(1).
385 -
382 GIT_TEST_INDEX_THREADS=<n> enables exercising the multi-threaded loading
383 of the index for the whole test suite by bypassing the default number of
384 cache entries and thread minimums. Setting this to 1 will make the
t/t3400-rebase.sh
+16
@@ -311,4 +311,20 @@ test_expect_success 'rebase--merge.sh and --show-current-patch' '
311 )
312 '
313
314 +test_expect_success 'rebase -c rebase.useBuiltin=false warning' '
315 + expected="rebase.useBuiltin support has been removed" &&
316 +
317 + # Only warn when the legacy rebase is requested...
318 + test_must_fail git -c rebase.useBuiltin=false rebase 2>err &&
319 + test_i18ngrep "$expected" err &&
320 + test_must_fail env GIT_TEST_REBASE_USE_BUILTIN=false git rebase 2>err &&
321 + test_i18ngrep "$expected" err &&
322 +
323 + # ...not when we would have used the built-in anyway
324 + test_must_fail git -c rebase.useBuiltin=true rebase 2>err &&
325 + test_must_be_empty err &&
326 + test_must_fail env GIT_TEST_REBASE_USE_BUILTIN=true git rebase 2>err &&
327 + test_must_be_empty err
328 +'
329 +
330 test_done
t/t3404-rebase-interactive.sh
+3 -6
@@ -149,12 +149,10 @@ test_expect_success 'rebase -i with the exec command checks tree cleanness' '
149
150 test_expect_success 'rebase -x with empty command fails' '
151 test_when_finished "git rebase --abort ||:" &&
152 - test_must_fail env GIT_TEST_REBASE_USE_BUILTIN=true \
153 - git rebase -x "" @ 2>actual &&
152 + test_must_fail env git rebase -x "" @ 2>actual &&
153 test_write_lines "error: empty exec command" >expected &&
154 test_i18ncmp expected actual &&
156 - test_must_fail env GIT_TEST_REBASE_USE_BUILTIN=true \
157 - git rebase -x " " @ 2>actual &&
155 + test_must_fail env git rebase -x " " @ 2>actual &&
156 test_i18ncmp expected actual
157 '
158
@@ -162,8 +160,7 @@ LF='
160 '
161 test_expect_success 'rebase -x with newline in command fails' '
162 test_when_finished "git rebase --abort ||:" &&
165 - test_must_fail env GIT_TEST_REBASE_USE_BUILTIN=true \
166 - git rebase -x "a${LF}b" @ 2>actual &&
163 + test_must_fail env git rebase -x "a${LF}b" @ 2>actual &&
164 test_write_lines "error: exec commands cannot contain newlines" \
165 >expected &&
166 test_i18ncmp expected actual