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
-}