rebase: drop support for `--preserve-merges`

This option was deprecated in favor of `--rebase-merges` some time ago, and now we retire it. To assist users to transition away, we do not _actually_ remove the option, but now we no longer implement the functionality. Instead, we offer a helpful error message suggesting which option to use. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Reviewed-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Sep 7, 2021 at 21:05 UTC a74b35081c51adbde3ef01870ba03e859db33be6
5 files changed +11 -1238
.gitignore
-1
@@ -125,7 +125,6 @@
125 /git-range-diff
126 /git-read-tree
127 /git-rebase
128 -/git-rebase--preserve-merges
128 /git-receive-pack
129 /git-reflog
130 /git-remote
Documentation/git-rebase.txt
-51
@@ -525,29 +525,12 @@ i.e. commits that would be excluded by linkgit:git-log[1]'s
525 the `rebase-cousins` mode is turned on, such commits are instead rebased
526 onto `<upstream>` (or `<onto>`, if specified).
527 +
528 -The `--rebase-merges` mode is similar in spirit to the deprecated
529 -`--preserve-merges` but works with interactive rebases,
530 -where commits can be reordered, inserted and dropped at will.
531 -+
528 It is currently only possible to recreate the merge commits using the
529 `recursive` merge strategy; Different merge strategies can be used only via
530 explicit `exec git merge -s <strategy> [...]` commands.
531 +
532 See also REBASING MERGES and INCOMPATIBLE OPTIONS below.
533
538 --p::
539 ---preserve-merges::
540 - [DEPRECATED: use `--rebase-merges` instead] Recreate merge commits
541 - instead of flattening the history by replaying commits a merge commit
542 - introduces. Merge conflict resolutions or manual amendments to merge
543 - commits are not preserved.
544 -+
545 -This uses the `--interactive` machinery internally, but combining it
546 -with the `--interactive` option explicitly is generally not a good
547 -idea unless you know what you are doing (see BUGS below).
548 -+
549 -See also INCOMPATIBLE OPTIONS below.
550 -
534 -x <cmd>::
535 --exec <cmd>::
536 Append "exec <cmd>" after each line creating a commit in the
@@ -579,9 +562,6 @@ See also INCOMPATIBLE OPTIONS below.
562 the root commit(s) on a branch. When used with --onto, it
563 will skip changes already contained in <newbase> (instead of
564 <upstream>) whereas without --onto it will operate on every change.
582 - When used together with both --onto and --preserve-merges,
583 - 'all' root commits will be rewritten to have <newbase> as parent
584 - instead.
565 +
566 See also INCOMPATIBLE OPTIONS below.
567
@@ -643,7 +623,6 @@ are incompatible with the following options:
623 * --allow-empty-message
624 * --[no-]autosquash
625 * --rebase-merges
646 - * --preserve-merges
626 * --interactive
627 * --exec
628 * --no-keep-empty
@@ -654,13 +633,6 @@ are incompatible with the following options:
633
634 In addition, the following pairs of options are incompatible:
635
657 - * --preserve-merges and --interactive
658 - * --preserve-merges and --signoff
659 - * --preserve-merges and --rebase-merges
660 - * --preserve-merges and --empty=
661 - * --preserve-merges and --ignore-whitespace
662 - * --preserve-merges and --committer-date-is-author-date
663 - * --preserve-merges and --ignore-date
636 * --keep-base and --onto
637 * --keep-base and --root
638 * --fork-point and --root
@@ -1274,29 +1246,6 @@ CONFIGURATION
1246 include::config/rebase.txt[]
1247 include::config/sequencer.txt[]
1248
1277 -BUGS
1278 -----
1279 -The todo list presented by the deprecated `--preserve-merges --interactive`
1280 -does not represent the topology of the revision graph (use `--rebase-merges`
1281 -instead). Editing commits and rewording their commit messages should work
1282 -fine, but attempts to reorder commits tend to produce counterintuitive results.
1283 -Use `--rebase-merges` in such scenarios instead.
1284 -
1285 -For example, an attempt to rearrange
1286 -------------
1287 -1 --- 2 --- 3 --- 4 --- 5
1288 -------------
1289 -to
1290 -------------
1291 -1 --- 2 --- 4 --- 3 --- 5
1292 -------------
1293 -by moving the "pick 4" line will result in the following history:
1294 -------------
1295 - 3
1296 - /
1297 -1 --- 2 --- 4 --- 5
1298 -------------
1299 -
1249 GIT
1250 ---
1251 Part of the linkgit:git[1] suite
Makefile
-2
@@ -616,7 +616,6 @@ SCRIPT_SH += git-submodule.sh
616 SCRIPT_SH += git-web--browse.sh
617
618 SCRIPT_LIB += git-mergetool--lib
619 -SCRIPT_LIB += git-rebase--preserve-merges
619 SCRIPT_LIB += git-sh-i18n
620 SCRIPT_LIB += git-sh-setup
621
@@ -2649,7 +2648,6 @@ XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \
2648 --keyword=__ --keyword=N__ --keyword="__n:1,2"
2649 LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H)
2650 LOCALIZED_SH = $(SCRIPT_SH)
2652 -LOCALIZED_SH += git-rebase--preserve-merges.sh
2651 LOCALIZED_SH += git-sh-setup.sh
2652 LOCALIZED_PERL = $(SCRIPT_PERL)
2653
builtin/rebase.c
+11 -127
@@ -48,8 +48,7 @@ static GIT_PATH_FUNC(merge_dir, "rebase-merge")
48 enum rebase_type {
49 REBASE_UNSPECIFIED = -1,
50 REBASE_APPLY,
51 - REBASE_MERGE,
52 - REBASE_PRESERVE_MERGES
51 + REBASE_MERGE
52 };
53
54 enum empty_type {
@@ -571,8 +570,7 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
570
571 static int is_merge(struct rebase_options *opts)
572 {
574 - return opts->type == REBASE_MERGE ||
575 - opts->type == REBASE_PRESERVE_MERGES;
573 + return opts->type == REBASE_MERGE;
574 }
575
576 static void imply_merge(struct rebase_options *opts, const char *option)
@@ -582,7 +580,6 @@ static void imply_merge(struct rebase_options *opts, const char *option)
580 die(_("%s requires the merge backend"), option);
581 break;
582 case REBASE_MERGE:
585 - case REBASE_PRESERVE_MERGES:
583 break;
584 default:
585 opts->type = REBASE_MERGE; /* implied */
@@ -773,17 +770,6 @@ static struct commit *peel_committish(const char *name)
770 return (struct commit *)peel_to_type(name, 0, obj, OBJ_COMMIT);
771 }
772
776 -static void add_var(struct strbuf *buf, const char *name, const char *value)
777 -{
778 - if (!value)
779 - strbuf_addf(buf, "unset %s; ", name);
780 - else {
781 - strbuf_addf(buf, "%s=", name);
782 - sq_quote_buf(buf, value);
783 - strbuf_addstr(buf, "; ");
784 - }
785 -}
786 -
773 static int move_to_original_branch(struct rebase_options *opts)
774 {
775 struct strbuf orig_head_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;
@@ -940,10 +926,7 @@ static int run_am(struct rebase_options *opts)
926
927 static int run_specific_rebase(struct rebase_options *opts, enum action action)
928 {
943 - const char *argv[] = { NULL, NULL };
944 - struct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;
929 int status;
946 - const char *backend, *backend_func;
930
931 if (opts->type == REBASE_MERGE) {
932 /* Run sequencer-based rebase */
@@ -960,87 +943,11 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)
943 }
944
945 status = run_sequencer_rebase(opts, action);
963 - goto finished_rebase;
964 - }
965 -
966 - if (opts->type == REBASE_APPLY) {
946 + } else if (opts->type == REBASE_APPLY)
947 status = run_am(opts);
968 - goto finished_rebase;
969 - }
970 -
971 - add_var(&script_snippet, "GIT_DIR", absolute_path(get_git_dir()));
972 - add_var(&script_snippet, "state_dir", opts->state_dir);
973 -
974 - add_var(&script_snippet, "upstream_name", opts->upstream_name);
975 - add_var(&script_snippet, "upstream", opts->upstream ?
976 - oid_to_hex(&opts->upstream->object.oid) : NULL);
977 - add_var(&script_snippet, "head_name",
978 - opts->head_name ? opts->head_name : "detached HEAD");
979 - add_var(&script_snippet, "orig_head", oid_to_hex(&opts->orig_head));
980 - add_var(&script_snippet, "onto", opts->onto ?
981 - oid_to_hex(&opts->onto->object.oid) : NULL);
982 - add_var(&script_snippet, "onto_name", opts->onto_name);
983 - add_var(&script_snippet, "revisions", opts->revisions);
984 - add_var(&script_snippet, "restrict_revision", opts->restrict_revision ?
985 - oid_to_hex(&opts->restrict_revision->object.oid) : NULL);
986 - sq_quote_argv_pretty(&buf, opts->git_am_opts.v);
987 - add_var(&script_snippet, "git_am_opt", buf.buf);
988 - strbuf_release(&buf);
989 - add_var(&script_snippet, "verbose",
990 - opts->flags & REBASE_VERBOSE ? "t" : "");
991 - add_var(&script_snippet, "diffstat",
992 - opts->flags & REBASE_DIFFSTAT ? "t" : "");
993 - add_var(&script_snippet, "force_rebase",
994 - opts->flags & REBASE_FORCE ? "t" : "");
995 - if (opts->switch_to)
996 - add_var(&script_snippet, "switch_to", opts->switch_to);
997 - add_var(&script_snippet, "action", opts->action ? opts->action : "");
998 - add_var(&script_snippet, "signoff", opts->signoff ? "--signoff" : "");
999 - add_var(&script_snippet, "allow_rerere_autoupdate",
1000 - opts->allow_rerere_autoupdate ?
1001 - opts->allow_rerere_autoupdate == RERERE_AUTOUPDATE ?
1002 - "--rerere-autoupdate" : "--no-rerere-autoupdate" : "");
1003 - add_var(&script_snippet, "keep_empty", opts->keep_empty ? "yes" : "");
1004 - add_var(&script_snippet, "autosquash", opts->autosquash ? "t" : "");
1005 - add_var(&script_snippet, "gpg_sign_opt", opts->gpg_sign_opt);
1006 - add_var(&script_snippet, "cmd", opts->cmd);
1007 - add_var(&script_snippet, "allow_empty_message",
1008 - opts->allow_empty_message ? "--allow-empty-message" : "");
1009 - add_var(&script_snippet, "rebase_merges",
1010 - opts->rebase_merges ? "t" : "");
1011 - add_var(&script_snippet, "rebase_cousins",
1012 - opts->rebase_cousins ? "t" : "");
1013 - add_var(&script_snippet, "strategy", opts->strategy);
1014 - add_var(&script_snippet, "strategy_opts", opts->strategy_opts);
1015 - add_var(&script_snippet, "rebase_root", opts->root ? "t" : "");
1016 - add_var(&script_snippet, "squash_onto",
1017 - opts->squash_onto ? oid_to_hex(opts->squash_onto) : "");
1018 - add_var(&script_snippet, "git_format_patch_opt",
1019 - opts->git_format_patch_opt.buf);
1020 -
1021 - if (is_merge(opts) &&
1022 - !(opts->flags & REBASE_INTERACTIVE_EXPLICIT)) {
1023 - strbuf_addstr(&script_snippet,
1024 - "GIT_SEQUENCE_EDITOR=:; export GIT_SEQUENCE_EDITOR; ");
1025 - opts->autosquash = 0;
1026 - }
1027 -
1028 - switch (opts->type) {
1029 - case REBASE_PRESERVE_MERGES:
1030 - backend = "git-rebase--preserve-merges";
1031 - backend_func = "git_rebase__preserve_merges";
1032 - break;
1033 - default:
948 + else
949 BUG("Unhandled rebase type %d", opts->type);
1035 - break;
1036 - }
1037 -
1038 - strbuf_addf(&script_snippet,
1039 - ". git-sh-setup && . %s && %s", backend, backend_func);
1040 - argv[0] = script_snippet.buf;
950
1042 - status = run_command_v_opt(argv, RUN_USING_SHELL);
1043 -finished_rebase:
951 if (opts->dont_finish_rebase)
952 ; /* do nothing */
953 else if (opts->type == REBASE_MERGE)
@@ -1058,8 +965,6 @@ finished_rebase:
965 die("Nothing to do");
966 }
967
1061 - strbuf_release(&script_snippet);
1062 -
968 return status ? -1 : 0;
969 }
970
@@ -1313,6 +1218,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1218 char *squash_onto_name = NULL;
1219 int reschedule_failed_exec = -1;
1220 int allow_preemptive_ff = 1;
1221 + int preserve_merges_selected = 0;
1222 struct option builtin_rebase_options[] = {
1223 OPT_STRING(0, "onto", &options.onto_name,
1224 N_("revision"),
@@ -1377,10 +1283,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1283 N_("let the user edit the list of commits to rebase"),
1284 PARSE_OPT_NOARG | PARSE_OPT_NONEG,
1285 parse_opt_interactive),
1380 - OPT_SET_INT_F('p', "preserve-merges", &options.type,
1286 + OPT_SET_INT_F('p', "preserve-merges", &preserve_merges_selected,
1287 N_("(DEPRECATED) try to recreate merges instead of "
1288 "ignoring them"),
1383 - REBASE_PRESERVE_MERGES, PARSE_OPT_HIDDEN),
1289 + 1, PARSE_OPT_HIDDEN),
1290 OPT_RERERE_AUTOUPDATE(&options.allow_rerere_autoupdate),
1291 OPT_CALLBACK_F(0, "empty", &options, "{drop,keep,ask}",
1292 N_("how to handle commits that become empty"),
@@ -1448,8 +1354,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1354 strbuf_reset(&buf);
1355 strbuf_addf(&buf, "%s/rewritten", merge_dir());
1356 if (is_directory(buf.buf)) {
1451 - options.type = REBASE_PRESERVE_MERGES;
1452 - options.flags |= REBASE_INTERACTIVE_EXPLICIT;
1357 + die("`rebase -p` is no longer supported");
1358 } else {
1359 strbuf_reset(&buf);
1360 strbuf_addf(&buf, "%s/interactive", merge_dir());
@@ -1470,6 +1375,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1375 builtin_rebase_options,
1376 builtin_rebase_usage, 0);
1377
1378 + if (preserve_merges_selected)
1379 + die(_("--preserve-merges was replaced by --rebase-merges"));
1380 +
1381 if (action != ACTION_NONE && total_argc != 2) {
1382 usage_with_options(builtin_rebase_usage,
1383 builtin_rebase_options);
@@ -1479,10 +1387,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1387 usage_with_options(builtin_rebase_usage,
1388 builtin_rebase_options);
1389
1482 - if (options.type == REBASE_PRESERVE_MERGES)
1483 - warning(_("git rebase --preserve-merges is deprecated. "
1484 - "Use --rebase-merges instead."));
1485 -
1390 if (keep_base) {
1391 if (options.onto_name)
1392 die(_("cannot combine '--keep-base' with '--onto'"));
@@ -1728,7 +1632,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1632 case REBASE_APPLY:
1633 die(_("--strategy requires --merge or --interactive"));
1634 case REBASE_MERGE:
1731 - case REBASE_PRESERVE_MERGES:
1635 /* compatible */
1636 break;
1637 case REBASE_UNSPECIFIED:
@@ -1780,7 +1683,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1683
1684 switch (options.type) {
1685 case REBASE_MERGE:
1783 - case REBASE_PRESERVE_MERGES:
1686 options.state_dir = merge_dir();
1687 break;
1688 case REBASE_APPLY:
@@ -1805,28 +1707,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1707 options.reschedule_failed_exec = reschedule_failed_exec;
1708
1709 if (options.signoff) {
1808 - if (options.type == REBASE_PRESERVE_MERGES)
1809 - die("cannot combine '--signoff' with "
1810 - "'--preserve-merges'");
1710 strvec_push(&options.git_am_opts, "--signoff");
1711 options.flags |= REBASE_FORCE;
1712 }
1713
1815 - if (options.type == REBASE_PRESERVE_MERGES) {
1816 - /*
1817 - * Note: incompatibility with --signoff handled in signoff block above
1818 - * Note: incompatibility with --interactive is just a strong warning;
1819 - * git-rebase.txt caveats with "unless you know what you are doing"
1820 - */
1821 - if (options.rebase_merges)
1822 - die(_("cannot combine '--preserve-merges' with "
1823 - "'--rebase-merges'"));
1824 -
1825 - if (options.reschedule_failed_exec)
1826 - die(_("error: cannot combine '--preserve-merges' with "
1827 - "'--reschedule-failed-exec'"));
1828 - }
1829 -
1714 if (!options.root) {
1715 if (argc < 1) {
1716 struct branch *branch;
git-rebase--preserve-merges.sh deleted
-1057
@@ -1,1057 +0,0 @@
1 -# This shell script fragment is sourced by git-rebase to implement its
2 -# preserve-merges mode.
3 -#
4 -# Copyright (c) 2006 Johannes E. Schindelin
5 -#
6 -# The file containing rebase commands, comments, and empty lines.
7 -# This file is created by "git rebase -i" then edited by the user. As
8 -# the lines are processed, they are removed from the front of this
9 -# file and written to the tail of $done.
10 -todo="$state_dir"/git-rebase-todo
11 -
12 -# The rebase command lines that have already been processed. A line
13 -# is moved here when it is first handled, before any associated user
14 -# actions.
15 -done="$state_dir"/done
16 -
17 -# The commit message that is planned to be used for any changes that
18 -# need to be committed following a user interaction.
19 -msg="$state_dir"/message
20 -
21 -# The file into which is accumulated the suggested commit message for
22 -# squash/fixup commands. When the first of a series of squash/fixups
23 -# is seen, the file is created and the commit message from the
24 -# previous commit and from the first squash/fixup commit are written
25 -# to it. The commit message for each subsequent squash/fixup commit
26 -# is appended to the file as it is processed.
27 -#
28 -# The first line of the file is of the form
29 -# # This is a combination of $count commits.
30 -# where $count is the number of commits whose messages have been
31 -# written to the file so far (including the initial "pick" commit).
32 -# Each time that a commit message is processed, this line is read and
33 -# updated. It is deleted just before the combined commit is made.
34 -squash_msg="$state_dir"/message-squash
35 -
36 -# If the current series of squash/fixups has not yet included a squash
37 -# command, then this file exists and holds the commit message of the
38 -# original "pick" commit. (If the series ends without a "squash"
39 -# command, then this can be used as the commit message of the combined
40 -# commit without opening the editor.)
41 -fixup_msg="$state_dir"/message-fixup
42 -
43 -# $rewritten is the name of a directory containing files for each
44 -# commit that is reachable by at least one merge base of $head and
45 -# $upstream. They are not necessarily rewritten, but their children
46 -# might be. This ensures that commits on merged, but otherwise
47 -# unrelated side branches are left alone. (Think "X" in the man page's
48 -# example.)
49 -rewritten="$state_dir"/rewritten
50 -
51 -dropped="$state_dir"/dropped
52 -
53 -end="$state_dir"/end
54 -msgnum="$state_dir"/msgnum
55 -
56 -# A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
57 -# GIT_AUTHOR_DATE that will be used for the commit that is currently
58 -# being rebased.
59 -author_script="$state_dir"/author-script
60 -
61 -# When an "edit" rebase command is being processed, the SHA1 of the
62 -# commit to be edited is recorded in this file. When "git rebase
63 -# --continue" is executed, if there are any staged changes then they
64 -# will be amended to the HEAD commit, but only provided the HEAD
65 -# commit is still the commit to be edited. When any other rebase
66 -# command is processed, this file is deleted.
67 -amend="$state_dir"/amend
68 -
69 -# For the post-rewrite hook, we make a list of rewritten commits and
70 -# their new sha1s. The rewritten-pending list keeps the sha1s of
71 -# commits that have been processed, but not committed yet,
72 -# e.g. because they are waiting for a 'squash' command.
73 -rewritten_list="$state_dir"/rewritten-list
74 -rewritten_pending="$state_dir"/rewritten-pending
75 -
76 -# Work around Git for Windows' Bash whose "read" does not strip CRLF
77 -# and leaves CR at the end instead.
78 -cr=$(printf "\015")
79 -
80 -resolvemsg="
81 -$(gettext 'Resolve all conflicts manually, mark them as resolved with
82 -"git add/rm <conflicted_files>", then run "git rebase --continue".
83 -You can instead skip this commit: run "git rebase --skip".
84 -To abort and get back to the state before "git rebase", run "git rebase --abort".')
85 -"
86 -
87 -write_basic_state () {
88 - echo "$head_name" > "$state_dir"/head-name &&
89 - echo "$onto" > "$state_dir"/onto &&
90 - echo "$orig_head" > "$state_dir"/orig-head &&
91 - test t = "$GIT_QUIET" && : > "$state_dir"/quiet
92 - test t = "$verbose" && : > "$state_dir"/verbose
93 - test -n "$strategy" && echo "$strategy" > "$state_dir"/strategy
94 - test -n "$strategy_opts" && echo "$strategy_opts" > \
95 - "$state_dir"/strategy_opts
96 - test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \
97 - "$state_dir"/allow_rerere_autoupdate
98 - test -n "$gpg_sign_opt" && echo "$gpg_sign_opt" > "$state_dir"/gpg_sign_opt
99 - test -n "$signoff" && echo "$signoff" >"$state_dir"/signoff
100 - test -n "$reschedule_failed_exec" && : > "$state_dir"/reschedule-failed-exec
101 -}
102 -
103 -apply_autostash () {
104 - if test -f "$state_dir/autostash"
105 - then
106 - stash_sha1=$(cat "$state_dir/autostash")
107 - if git stash apply $stash_sha1 >/dev/null 2>&1
108 - then
109 - echo "$(gettext 'Applied autostash.')" >&2
110 - else
111 - git stash store -m "autostash" -q $stash_sha1 ||
112 - die "$(eval_gettext "Cannot store \$stash_sha1")"
113 - gettext 'Applying autostash resulted in conflicts.
114 -Your changes are safe in the stash.
115 -You can run "git stash pop" or "git stash drop" at any time.
116 -' >&2
117 - fi
118 - fi
119 -}
120 -
121 -output () {
122 - case "$verbose" in
123 - '')
124 - output=$("$@" 2>&1 )
125 - status=$?
126 - test $status != 0 && printf "%s\n" "$output"
127 - return $status
128 - ;;
129 - *)
130 - "$@"
131 - ;;
132 - esac
133 -}
134 -
135 -strategy_args=${strategy:+--strategy=$strategy}
136 -test -n "$strategy_opts" &&
137 -eval '
138 - for strategy_opt in '"$strategy_opts"'
139 - do
140 - strategy_args="$strategy_args -X$(git rev-parse --sq-quote "${strategy_opt#--}")"
141 - done
142 -'
143 -
144 -GIT_CHERRY_PICK_HELP="$resolvemsg"
145 -export GIT_CHERRY_PICK_HELP
146 -
147 -comment_char=$(git config --get core.commentchar 2>/dev/null)
148 -case "$comment_char" in
149 -'' | auto)
150 - comment_char="#"
151 - ;;
152 -?)
153 - ;;
154 -*)
155 - comment_char=$(echo "$comment_char" | cut -c1)
156 - ;;
157 -esac
158 -
159 -warn () {
160 - printf '%s\n' "$*" >&2
161 -}
162 -
163 -# Output the commit message for the specified commit.
164 -commit_message () {
165 - git cat-file commit "$1" | sed "1,/^$/d"
166 -}
167 -
168 -orig_reflog_action="$GIT_REFLOG_ACTION"
169 -
170 -comment_for_reflog () {
171 - case "$orig_reflog_action" in
172 - ''|rebase*)
173 - GIT_REFLOG_ACTION="rebase -i ($1)"
174 - export GIT_REFLOG_ACTION
175 - ;;
176 - esac
177 -}
178 -
179 -last_count=
180 -mark_action_done () {
181 - sed -e 1q < "$todo" >> "$done"
182 - sed -e 1d < "$todo" >> "$todo".new
183 - mv -f "$todo".new "$todo"
184 - new_count=$(( $(git stripspace --strip-comments <"$done" | wc -l) ))
185 - echo $new_count >"$msgnum"
186 - total=$(($new_count + $(git stripspace --strip-comments <"$todo" | wc -l)))
187 - echo $total >"$end"
188 - if test "$last_count" != "$new_count"
189 - then
190 - last_count=$new_count
191 - eval_gettext "Rebasing (\$new_count/\$total)"; printf "\r"
192 - test -z "$verbose" || echo
193 - fi
194 -}
195 -
196 -append_todo_help () {
197 - gettext "
198 -Commands:
199 -p, pick <commit> = use commit
200 -r, reword <commit> = use commit, but edit the commit message
201 -e, edit <commit> = use commit, but stop for amending
202 -s, squash <commit> = use commit, but meld into previous commit
203 -f, fixup <commit> = like \"squash\", but discard this commit's log message
204 -x, exec <commit> = run command (the rest of the line) using shell
205 -d, drop <commit> = remove commit
206 -l, label <label> = label current HEAD with a name
207 -t, reset <label> = reset HEAD to a label
208 -m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
209 -. create a merge commit using the original merge commit's
210 -. message (or the oneline, if no original merge commit was
211 -. specified). Use -c <commit> to reword the commit message.
212 -
213 -These lines can be re-ordered; they are executed from top to bottom.
214 -" | git stripspace --comment-lines >>"$todo"
215 -
216 - if test $(get_missing_commit_check_level) = error
217 - then
218 - gettext "
219 -Do not remove any line. Use 'drop' explicitly to remove a commit.
220 -" | git stripspace --comment-lines >>"$todo"
221 - else
222 - gettext "
223 -If you remove a line here THAT COMMIT WILL BE LOST.
224 -" | git stripspace --comment-lines >>"$todo"
225 - fi
226 -}
227 -
228 -make_patch () {
229 - sha1_and_parents="$(git rev-list --parents -1 "$1")"
230 - case "$sha1_and_parents" in
231 - ?*' '?*' '?*)
232 - git diff --cc $sha1_and_parents
233 - ;;
234 - ?*' '?*)
235 - git diff-tree -p "$1^!"
236 - ;;
237 - *)
238 - echo "Root commit"
239 - ;;
240 - esac > "$state_dir"/patch
241 - test -f "$msg" ||
242 - commit_message "$1" > "$msg"
243 - test -f "$author_script" ||
244 - get_author_ident_from_commit "$1" > "$author_script"
245 -}
246 -
247 -die_with_patch () {
248 - echo "$1" > "$state_dir"/stopped-sha
249 - git update-ref REBASE_HEAD "$1"
250 - make_patch "$1"
251 - die "$2"
252 -}
253 -
254 -exit_with_patch () {
255 - echo "$1" > "$state_dir"/stopped-sha
256 - git update-ref REBASE_HEAD "$1"
257 - make_patch $1
258 - git rev-parse --verify HEAD > "$amend"
259 - gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
260 - warn "$(eval_gettext "\
261 -You can amend the commit now, with
262 -
263 - git commit --amend \$gpg_sign_opt_quoted
264 -
265 -Once you are satisfied with your changes, run
266 -
267 - git rebase --continue")"
268 - warn
269 - exit $2
270 -}
271 -
272 -die_abort () {
273 - apply_autostash
274 - rm -rf "$state_dir"
275 - die "$1"
276 -}
277 -
278 -has_action () {
279 - test -n "$(git stripspace --strip-comments <"$1")"
280 -}
281 -
282 -is_empty_commit() {
283 - tree=$(git rev-parse -q --verify "$1"^{tree} 2>/dev/null) || {
284 - sha1=$1
285 - die "$(eval_gettext "\$sha1: not a commit that can be picked")"
286 - }
287 - ptree=$(git rev-parse -q --verify "$1"^^{tree} 2>/dev/null) ||
288 - ptree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
289 - test "$tree" = "$ptree"
290 -}
291 -
292 -is_merge_commit()
293 -{
294 - git rev-parse --verify --quiet "$1"^2 >/dev/null 2>&1
295 -}
296 -
297 -# Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
298 -# GIT_AUTHOR_DATE exported from the current environment.
299 -do_with_author () {
300 - (
301 - export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
302 - "$@"
303 - )
304 -}
305 -
306 -git_sequence_editor () {
307 - if test -z "$GIT_SEQUENCE_EDITOR"
308 - then
309 - GIT_SEQUENCE_EDITOR="$(git config sequence.editor)"
310 - if [ -z "$GIT_SEQUENCE_EDITOR" ]
311 - then
312 - GIT_SEQUENCE_EDITOR="$(git var GIT_EDITOR)" || return $?
313 - fi
314 - fi
315 -
316 - eval "$GIT_SEQUENCE_EDITOR" '"$@"'
317 -}
318 -
319 -pick_one () {
320 - ff=--ff
321 -
322 - case "$1" in -n) sha1=$2; ff= ;; *) sha1=$1 ;; esac
323 - case "$force_rebase" in '') ;; ?*) ff= ;; esac
324 - output git rev-parse --verify $sha1 || die "$(eval_gettext "Invalid commit name: \$sha1")"
325 -
326 - if is_empty_commit "$sha1"
327 - then
328 - empty_args="--allow-empty"
329 - fi
330 -
331 - pick_one_preserving_merges "$@"
332 -}
333 -
334 -pick_one_preserving_merges () {
335 - fast_forward=t
336 - case "$1" in
337 - -n)
338 - fast_forward=f
339 - sha1=$2
340 - ;;
341 - *)
342 - sha1=$1
343 - ;;
344 - esac
345 - sha1=$(git rev-parse $sha1)
346 -
347 - if test -f "$state_dir"/current-commit && test "$fast_forward" = t
348 - then
349 - while read current_commit
350 - do
351 - git rev-parse HEAD > "$rewritten"/$current_commit
352 - done <"$state_dir"/current-commit
353 - rm "$state_dir"/current-commit ||
354 - die "$(gettext "Cannot write current commit's replacement sha1")"
355 - fi
356 -
357 - echo $sha1 >> "$state_dir"/current-commit
358 -
359 - # rewrite parents; if none were rewritten, we can fast-forward.
360 - new_parents=
361 - pend=" $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)"
362 - if test "$pend" = " "
363 - then
364 - pend=" root"
365 - fi
366 - while [ "$pend" != "" ]
367 - do
368 - p=$(expr "$pend" : ' \([^ ]*\)')
369 - pend="${pend# $p}"
370 -
371 - if test -f "$rewritten"/$p
372 - then
373 - new_p=$(cat "$rewritten"/$p)
374 -
375 - # If the todo reordered commits, and our parent is marked for
376 - # rewriting, but hasn't been gotten to yet, assume the user meant to
377 - # drop it on top of the current HEAD
378 - if test -z "$new_p"
379 - then
380 - new_p=$(git rev-parse HEAD)
381 - fi
382 -
383 - test $p != $new_p && fast_forward=f
384 - case "$new_parents" in
385 - *$new_p*)
386 - ;; # do nothing; that parent is already there
387 - *)
388 - new_parents="$new_parents $new_p"
389 - ;;
390 - esac
391 - else
392 - if test -f "$dropped"/$p
393 - then
394 - fast_forward=f
395 - replacement="$(cat "$dropped"/$p)"
396 - test -z "$replacement" && replacement=root
397 - pend=" $replacement$pend"
398 - else
399 - new_parents="$new_parents $p"
400 - fi
401 - fi
402 - done
403 - case $fast_forward in
404 - t)
405 - output warn "$(eval_gettext "Fast-forward to \$sha1")"
406 - output git reset --hard $sha1 ||
407 - die "$(eval_gettext "Cannot fast-forward to \$sha1")"
408 - ;;
409 - f)
410 - first_parent=$(expr "$new_parents" : ' \([^ ]*\)')
411 -
412 - if [ "$1" != "-n" ]
413 - then
414 - # detach HEAD to current parent
415 - output git checkout $first_parent 2> /dev/null ||
416 - die "$(eval_gettext "Cannot move HEAD to \$first_parent")"
417 - fi
418 -
419 - case "$new_parents" in
420 - ' '*' '*)
421 - test "a$1" = a-n && die "$(eval_gettext "Refusing to squash a merge: \$sha1")"
422 -
423 - # redo merge
424 - author_script_content=$(get_author_ident_from_commit $sha1)
425 - eval "$author_script_content"
426 - msg_content="$(commit_message $sha1)"
427 - # No point in merging the first parent, that's HEAD
428 - new_parents=${new_parents# $first_parent}
429 - merge_args="--no-log --no-ff"
430 - if ! do_with_author output eval \
431 - git merge ${gpg_sign_opt:+$(git rev-parse \
432 - --sq-quote "$gpg_sign_opt")} \
433 - $allow_rerere_autoupdate "$merge_args" \
434 - "$strategy_args" \
435 - -m "$(git rev-parse --sq-quote "$msg_content")" \
436 - "$new_parents"
437 - then
438 - printf "%s\n" "$msg_content" > "$GIT_DIR"/MERGE_MSG
439 - die_with_patch $sha1 "$(eval_gettext "Error redoing merge \$sha1")"
440 - fi
441 - echo "$sha1 $(git rev-parse HEAD^0)" >> "$rewritten_list"
442 - ;;
443 - *)
444 - output eval git cherry-pick $allow_rerere_autoupdate \
445 - $allow_empty_message \
446 - ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
447 - "$strategy_args" "$@" ||
448 - die_with_patch $sha1 "$(eval_gettext "Could not pick \$sha1")"
449 - ;;
450 - esac
451 - ;;
452 - esac
453 -}
454 -
455 -this_nth_commit_message () {
456 - n=$1
457 - eval_gettext "This is the commit message #\${n}:"
458 -}
459 -
460 -skip_nth_commit_message () {
461 - n=$1
462 - eval_gettext "The commit message #\${n} will be skipped:"
463 -}
464 -
465 -update_squash_messages () {
466 - if test -f "$squash_msg"; then
467 - mv "$squash_msg" "$squash_msg".bak || exit
468 - count=$(($(sed -n \
469 - -e "1s/^$comment_char[^0-9]*\([0-9][0-9]*\).*/\1/p" \
470 - -e "q" < "$squash_msg".bak)+1))
471 - {
472 - printf '%s\n' "$comment_char $(eval_ngettext \
473 - "This is a combination of \$count commit." \
474 - "This is a combination of \$count commits." \
475 - $count)"
476 - sed -e 1d -e '2,/^./{
477 - /^$/d
478 - }' <"$squash_msg".bak
479 - } >"$squash_msg"
480 - else
481 - commit_message HEAD >"$fixup_msg" ||
482 - die "$(eval_gettext "Cannot write \$fixup_msg")"
483 - count=2
484 - {
485 - printf '%s\n' "$comment_char $(gettext "This is a combination of 2 commits.")"
486 - printf '%s\n' "$comment_char $(gettext "This is the 1st commit message:")"
487 - echo
488 - cat "$fixup_msg"
489 - } >"$squash_msg"
490 - fi
491 - case $1 in
492 - squash)
493 - rm -f "$fixup_msg"
494 - echo
495 - printf '%s\n' "$comment_char $(this_nth_commit_message $count)"
496 - echo
497 - commit_message $2
498 - ;;
499 - fixup)
500 - echo
501 - printf '%s\n' "$comment_char $(skip_nth_commit_message $count)"
502 - echo
503 - # Change the space after the comment character to TAB:
504 - commit_message $2 | git stripspace --comment-lines | sed -e 's/ / /'
505 - ;;
506 - esac >>"$squash_msg"
507 -}
508 -
509 -peek_next_command () {
510 - git stripspace --strip-comments <"$todo" | sed -n -e 's/ .*//p' -e q
511 -}
512 -
513 -# A squash/fixup has failed. Prepare the long version of the squash
514 -# commit message, then die_with_patch. This code path requires the
515 -# user to edit the combined commit message for all commits that have
516 -# been squashed/fixedup so far. So also erase the old squash
517 -# messages, effectively causing the combined commit to be used as the
518 -# new basis for any further squash/fixups. Args: sha1 rest
519 -die_failed_squash() {
520 - sha1=$1
521 - rest=$2
522 - mv "$squash_msg" "$msg" || exit
523 - rm -f "$fixup_msg"
524 - cp "$msg" "$GIT_DIR"/MERGE_MSG || exit
525 - warn
526 - warn "$(eval_gettext "Could not apply \$sha1... \$rest")"
527 - die_with_patch $sha1 ""
528 -}
529 -
530 -flush_rewritten_pending() {
531 - test -s "$rewritten_pending" || return
532 - newsha1="$(git rev-parse HEAD^0)"
533 - sed "s/$/ $newsha1/" < "$rewritten_pending" >> "$rewritten_list"
534 - rm -f "$rewritten_pending"
535 -}
536 -
537 -record_in_rewritten() {
538 - oldsha1="$(git rev-parse $1)"
539 - echo "$oldsha1" >> "$rewritten_pending"
540 -
541 - case "$(peek_next_command)" in
542 - squash|s|fixup|f)
543 - ;;
544 - *)
545 - flush_rewritten_pending
546 - ;;
547 - esac
548 -}
549 -
550 -do_pick () {
551 - sha1=$1
552 - rest=$2
553 - if test "$(git rev-parse HEAD)" = "$squash_onto"
554 - then
555 - # Set the correct commit message and author info on the
556 - # sentinel root before cherry-picking the original changes
557 - # without committing (-n). Finally, update the sentinel again
558 - # to include these changes. If the cherry-pick results in a
559 - # conflict, this means our behaviour is similar to a standard
560 - # failed cherry-pick during rebase, with a dirty index to
561 - # resolve before manually running git commit --amend then git
562 - # rebase --continue.
563 - git commit --allow-empty --allow-empty-message --amend \
564 - --no-post-rewrite -n -q -C $sha1 $signoff &&
565 - pick_one -n $sha1 &&
566 - git commit --allow-empty --allow-empty-message \
567 - --amend --no-post-rewrite -n -q -C $sha1 $signoff \
568 - ${gpg_sign_opt:+"$gpg_sign_opt"} ||
569 - die_with_patch $sha1 "$(eval_gettext "Could not apply \$sha1... \$rest")"
570 - else
571 - pick_one $sha1 ||
572 - die_with_patch $sha1 "$(eval_gettext "Could not apply \$sha1... \$rest")"
573 - fi
574 -}
575 -
576 -do_next () {
577 - rm -f "$msg" "$author_script" "$amend" "$state_dir"/stopped-sha || exit
578 - read -r command sha1 rest < "$todo"
579 - case "$command" in
580 - "$comment_char"*|''|noop|drop|d)
581 - mark_action_done
582 - ;;
583 - "$cr")
584 - # Work around CR left by "read" (e.g. with Git for Windows' Bash).
585 - mark_action_done
586 - ;;
587 - pick|p)
588 - comment_for_reflog pick
589 -
590 - mark_action_done
591 - do_pick $sha1 "$rest"
592 - record_in_rewritten $sha1
593 - ;;
594 - reword|r)
595 - comment_for_reflog reword
596 -
597 - mark_action_done
598 - do_pick $sha1 "$rest"
599 - git commit --amend --no-post-rewrite ${gpg_sign_opt:+"$gpg_sign_opt"} \
600 - $allow_empty_message || {
601 - warn "$(eval_gettext "\
602 -Could not amend commit after successfully picking \$sha1... \$rest
603 -This is most likely due to an empty commit message, or the pre-commit hook
604 -failed. If the pre-commit hook failed, you may need to resolve the issue before
605 -you are able to reword the commit.")"
606 - exit_with_patch $sha1 1
607 - }
608 - record_in_rewritten $sha1
609 - ;;
610 - edit|e)
611 - comment_for_reflog edit
612 -
613 - mark_action_done
614 - do_pick $sha1 "$rest"
615 - sha1_abbrev=$(git rev-parse --short $sha1)
616 - warn "$(eval_gettext "Stopped at \$sha1_abbrev... \$rest")"
617 - exit_with_patch $sha1 0
618 - ;;
619 - squash|s|fixup|f)
620 - case "$command" in
621 - squash|s)
622 - squash_style=squash
623 - ;;
624 - fixup|f)
625 - squash_style=fixup
626 - ;;
627 - esac
628 - comment_for_reflog $squash_style
629 -
630 - test -f "$done" && has_action "$done" ||
631 - die "$(eval_gettext "Cannot '\$squash_style' without a previous commit")"
632 -
633 - mark_action_done
634 - update_squash_messages $squash_style $sha1
635 - author_script_content=$(get_author_ident_from_commit HEAD)
636 - echo "$author_script_content" > "$author_script"
637 - eval "$author_script_content"
638 - if ! pick_one -n $sha1
639 - then
640 - git rev-parse --verify HEAD >"$amend"
641 - die_failed_squash $sha1 "$rest"
642 - fi
643 - case "$(peek_next_command)" in
644 - squash|s|fixup|f)
645 - # This is an intermediate commit; its message will only be
646 - # used in case of trouble. So use the long version:
647 - do_with_author output git commit --amend --no-verify -F "$squash_msg" \
648 - ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
649 - die_failed_squash $sha1 "$rest"
650 - ;;
651 - *)
652 - # This is the final command of this squash/fixup group
653 - if test -f "$fixup_msg"
654 - then
655 - do_with_author git commit --amend --no-verify -F "$fixup_msg" \
656 - ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
657 - die_failed_squash $sha1 "$rest"
658 - else
659 - cp "$squash_msg" "$GIT_DIR"/SQUASH_MSG || exit
660 - rm -f "$GIT_DIR"/MERGE_MSG
661 - do_with_author git commit --amend --no-verify -F "$GIT_DIR"/SQUASH_MSG -e \
662 - ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
663 - die_failed_squash $sha1 "$rest"
664 - fi
665 - rm -f "$squash_msg" "$fixup_msg"
666 - ;;
667 - esac
668 - record_in_rewritten $sha1
669 - ;;
670 - x|"exec")
671 - read -r command rest < "$todo"
672 - mark_action_done
673 - eval_gettextln "Executing: \$rest"
674 - "${SHELL:-@SHELL_PATH@}" -c "$rest" # Actual execution
675 - status=$?
676 - # Run in subshell because require_clean_work_tree can die.
677 - dirty=f
678 - (require_clean_work_tree "rebase" 2>/dev/null) || dirty=t
679 - if test "$status" -ne 0
680 - then
681 - warn "$(eval_gettext "Execution failed: \$rest")"
682 - test "$dirty" = f ||
683 - warn "$(gettext "and made changes to the index and/or the working tree")"
684 -
685 - warn "$(gettext "\
686 -You can fix the problem, and then run
687 -
688 - git rebase --continue")"
689 - warn
690 - if test $status -eq 127 # command not found
691 - then
692 - status=1
693 - fi
694 - exit "$status"
695 - elif test "$dirty" = t
696 - then
697 - # TRANSLATORS: after these lines is a command to be issued by the user
698 - warn "$(eval_gettext "\
699 -Execution succeeded: \$rest
700 -but left changes to the index and/or the working tree
701 -Commit or stash your changes, and then run
702 -
703 - git rebase --continue")"
704 - warn
705 - exit 1
706 - fi
707 - ;;
708 - *)
709 - warn "$(eval_gettext "Unknown command: \$command \$sha1 \$rest")"
710 - fixtodo="$(gettext "Please fix this using 'git rebase --edit-todo'.")"
711 - if git rev-parse --verify -q "$sha1" >/dev/null
712 - then
713 - die_with_patch $sha1 "$fixtodo"
714 - else
715 - die "$fixtodo"
716 - fi
717 - ;;
718 - esac
719 - test -s "$todo" && return
720 -
721 - comment_for_reflog finish &&
722 - newhead=$(git rev-parse HEAD) &&
723 - case $head_name in
724 - refs/*)
725 - message="$GIT_REFLOG_ACTION: $head_name onto $onto" &&
726 - git update-ref -m "$message" $head_name $newhead $orig_head &&
727 - git symbolic-ref \
728 - -m "$GIT_REFLOG_ACTION: returning to $head_name" \
729 - HEAD $head_name
730 - ;;
731 - esac && {
732 - test ! -f "$state_dir"/verbose ||
733 - git diff-tree --stat $orig_head..HEAD
734 - } &&
735 - {
736 - test -s "$rewritten_list" &&
737 - git notes copy --for-rewrite=rebase < "$rewritten_list" ||
738 - true # we don't care if this copying failed
739 - } &&
740 - hook="$(git rev-parse --git-path hooks/post-rewrite)"
741 - if test -x "$hook" && test -s "$rewritten_list"; then
742 - "$hook" rebase < "$rewritten_list"
743 - true # we don't care if this hook failed
744 - fi &&
745 - warn "$(eval_gettext "Successfully rebased and updated \$head_name.")"
746 -
747 - return 1 # not failure; just to break the do_rest loop
748 -}
749 -
750 -# can only return 0, when the infinite loop breaks
751 -do_rest () {
752 - while :
753 - do
754 - do_next || break
755 - done
756 -}
757 -
758 -expand_todo_ids() {
759 - git rebase--interactive --expand-ids
760 -}
761 -
762 -collapse_todo_ids() {
763 - git rebase--interactive --shorten-ids
764 -}
765 -
766 -# Switch to the branch in $into and notify it in the reflog
767 -checkout_onto () {
768 - GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name"
769 - output git checkout $onto || die_abort "$(gettext "could not detach HEAD")"
770 - git update-ref ORIG_HEAD $orig_head
771 -}
772 -
773 -get_missing_commit_check_level () {
774 - check_level=$(git config --get rebase.missingCommitsCheck)
775 - check_level=${check_level:-ignore}
776 - # Don't be case sensitive
777 - printf '%s' "$check_level" | tr 'A-Z' 'a-z'
778 -}
779 -
780 -# Initiate an action. If the cannot be any
781 -# further action it may exec a command
782 -# or exit and not return.
783 -#
784 -# TODO: Consider a cleaner return model so it
785 -# never exits and always return 0 if process
786 -# is complete.
787 -#
788 -# Parameter 1 is the action to initiate.
789 -#
790 -# Returns 0 if the action was able to complete
791 -# and if 1 if further processing is required.
792 -initiate_action () {
793 - case "$1" in
794 - continue)
795 - # do we have anything to commit?
796 - if git diff-index --cached --quiet HEAD --
797 - then
798 - # Nothing to commit -- skip this commit
799 -
800 - test ! -f "$GIT_DIR"/CHERRY_PICK_HEAD ||
801 - rm "$GIT_DIR"/CHERRY_PICK_HEAD ||
802 - die "$(gettext "Could not remove CHERRY_PICK_HEAD")"
803 - else
804 - if ! test -f "$author_script"
805 - then
806 - gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
807 - die "$(eval_gettext "\
808 -You have staged changes in your working tree.
809 -If these changes are meant to be
810 -squashed into the previous commit, run:
811 -
812 - git commit --amend \$gpg_sign_opt_quoted
813 -
814 -If they are meant to go into a new commit, run:
815 -
816 - git commit \$gpg_sign_opt_quoted
817 -
818 -In both cases, once you're done, continue with:
819 -
820 - git rebase --continue
821 -")"
822 - fi
823 - . "$author_script" ||
824 - die "$(gettext "Error trying to find the author identity to amend commit")"
825 - if test -f "$amend"
826 - then
827 - current_head=$(git rev-parse --verify HEAD)
828 - test "$current_head" = $(cat "$amend") ||
829 - die "$(gettext "\
830 -You have uncommitted changes in your working tree. Please commit them
831 -first and then run 'git rebase --continue' again.")"
832 - do_with_author git commit --amend --no-verify -F "$msg" -e \
833 - ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
834 - die "$(gettext "Could not commit staged changes.")"
835 - else
836 - do_with_author git commit --no-verify -F "$msg" -e \
837 - ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
838 - die "$(gettext "Could not commit staged changes.")"
839 - fi
840 - fi
841 -
842 - if test -r "$state_dir"/stopped-sha
843 - then
844 - record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
845 - fi
846 -
847 - require_clean_work_tree "rebase"
848 - do_rest
849 - return 0
850 - ;;
851 - skip)
852 - git rerere clear
853 - do_rest
854 - return 0
855 - ;;
856 - edit-todo)
857 - git stripspace --strip-comments <"$todo" >"$todo".new
858 - mv -f "$todo".new "$todo"
859 - collapse_todo_ids
860 - append_todo_help
861 - gettext "
862 -You are editing the todo file of an ongoing interactive rebase.
863 -To continue rebase after editing, run:
864 - git rebase --continue
865 -
866 -" | git stripspace --comment-lines >>"$todo"
867 -
868 - git_sequence_editor "$todo" ||
869 - die "$(gettext "Could not execute editor")"
870 - expand_todo_ids
871 -
872 - exit
873 - ;;
874 - show-current-patch)
875 - exec git show REBASE_HEAD --
876 - ;;
877 - *)
878 - return 1 # continue
879 - ;;
880 - esac
881 -}
882 -
883 -setup_reflog_action () {
884 - comment_for_reflog start
885 -
886 - if test ! -z "$switch_to"
887 - then
888 - GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to"
889 - output git checkout "$switch_to" -- ||
890 - die "$(eval_gettext "Could not checkout \$switch_to")"
891 -
892 - comment_for_reflog start
893 - fi
894 -}
895 -
896 -init_basic_state () {
897 - orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")"
898 - mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")"
899 - rm -f "$(git rev-parse --git-path REBASE_HEAD)"
900 -
901 - : > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")"
902 - write_basic_state
903 -}
904 -
905 -init_revisions_and_shortrevisions () {
906 - shorthead=$(git rev-parse --short $orig_head)
907 - shortonto=$(git rev-parse --short $onto)
908 - if test -z "$rebase_root"
909 - # this is now equivalent to ! -z "$upstream"
910 - then
911 - shortupstream=$(git rev-parse --short $upstream)
912 - revisions=$upstream...$orig_head
913 - shortrevisions=$shortupstream..$shorthead
914 - else
915 - revisions=$onto...$orig_head
916 - shortrevisions=$shorthead
917 - test -z "$squash_onto" ||
918 - echo "$squash_onto" >"$state_dir"/squash-onto
919 - fi
920 -}
921 -
922 -complete_action() {
923 - test -s "$todo" || echo noop >> "$todo"
924 - test -z "$autosquash" || git rebase--interactive --rearrange-squash || exit
925 - test -n "$cmd" && git rebase--interactive --add-exec-commands --cmd "$cmd"
926 -
927 - todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
928 - todocount=${todocount##* }
929 -
930 -cat >>"$todo" <<EOF
931 -
932 -$comment_char $(eval_ngettext \
933 - "Rebase \$shortrevisions onto \$shortonto (\$todocount command)" \
934 - "Rebase \$shortrevisions onto \$shortonto (\$todocount commands)" \
935 - "$todocount")
936 -EOF
937 - append_todo_help
938 - gettext "
939 -However, if you remove everything, the rebase will be aborted.
940 -
941 -" | git stripspace --comment-lines >>"$todo"
942 -
943 - if test -z "$keep_empty"
944 - then
945 - printf '%s\n' "$comment_char $(gettext "Note that empty commits are commented out")" >>"$todo"
946 - fi
947 -
948 -
949 - has_action "$todo" ||
950 - return 2
951 -
952 - cp "$todo" "$todo".backup
953 - collapse_todo_ids
954 - git_sequence_editor "$todo" ||
955 - die_abort "$(gettext "Could not execute editor")"
956 -
957 - has_action "$todo" ||
958 - return 2
959 -
960 - git rebase--interactive --check-todo-list || {
961 - ret=$?
962 - checkout_onto
963 - exit $ret
964 - }
965 -
966 - expand_todo_ids
967 - checkout_onto
968 - do_rest
969 -}
970 -
971 -git_rebase__preserve_merges () {
972 - initiate_action "$action"
973 - ret=$?
974 - if test $ret = 0; then
975 - return 0
976 - fi
977 -
978 - setup_reflog_action
979 - init_basic_state
980 -
981 - if test -z "$rebase_root"
982 - then
983 - mkdir "$rewritten" &&
984 - for c in $(git merge-base --all $orig_head $upstream)
985 - do
986 - echo $onto > "$rewritten"/$c ||
987 - die "$(gettext "Could not init rewritten commits")"
988 - done
989 - else
990 - mkdir "$rewritten" &&
991 - echo $onto > "$rewritten"/root ||
992 - die "$(gettext "Could not init rewritten commits")"
993 - fi
994 -
995 - init_revisions_and_shortrevisions
996 -
997 - format=$(git config --get rebase.instructionFormat)
998 - # the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse
999 - git rev-list --format="%m%H ${format:-%s}" \
1000 - --reverse --left-right --topo-order \
1001 - $revisions ${restrict_revision+^$restrict_revision} | \
1002 - sed -n "s/^>//p" |
1003 - while read -r sha1 rest
1004 - do
1005 - if test -z "$keep_empty" && is_empty_commit $sha1 && ! is_merge_commit $sha1
1006 - then
1007 - comment_out="$comment_char "
1008 - else
1009 - comment_out=
1010 - fi
1011 -
1012 - if test -z "$rebase_root"
1013 - then
1014 - preserve=t
1015 - for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
1016 - do
1017 - if test -f "$rewritten"/$p
1018 - then
1019 - preserve=f
1020 - fi
1021 - done
1022 - else
1023 - preserve=f
1024 - fi
1025 - if test f = "$preserve"
1026 - then
1027 - touch "$rewritten"/$sha1
1028 - printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo"
1029 - fi
1030 - done
1031 -
1032 - # Watch for commits that been dropped by --cherry-pick
1033 - mkdir "$dropped"
1034 - # Save all non-cherry-picked changes
1035 - git rev-list $revisions --left-right --cherry-pick | \
1036 - sed -n "s/^>//p" > "$state_dir"/not-cherry-picks
1037 - # Now all commits and note which ones are missing in
1038 - # not-cherry-picks and hence being dropped
1039 - git rev-list $revisions |
1040 - while read rev
1041 - do
1042 - if test -f "$rewritten"/$rev &&
1043 - ! sane_grep "$rev" "$state_dir"/not-cherry-picks >/dev/null
1044 - then
1045 - # Use -f2 because if rev-list is telling us this commit is
1046 - # not worthwhile, we don't want to track its multiple heads,
1047 - # just the history of its first-parent for others that will
1048 - # be rebasing on top of it
1049 - git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$dropped"/$rev
1050 - sha1=$(git rev-list -1 $rev)
1051 - sane_grep -v "^[a-z][a-z]* $sha1" <"$todo" > "${todo}2" ; mv "${todo}2" "$todo"
1052 - rm "$rewritten"/$rev
1053 - fi
1054 - done
1055 -
1056 - complete_action
1057 -}