]>
Commit | Line | Data |
---|---|---|
11d62145 JN |
1 | # This shell script fragment is sourced by git-rebase to implement |
2 | # its interactive mode. "git rebase --interactive" makes it easy | |
3 | # to fix up commits in the middle of a series and rearrange commits. | |
1b1dce4b JS |
4 | # |
5 | # Copyright (c) 2006 Johannes E. Schindelin | |
1b1dce4b JS |
6 | # |
7 | # The original idea comes from Eric W. Biederman, in | |
5840eb9d | 8 | # https://public-inbox.org/git/m1odwkyuf5.fsf_-_@ebiederm.dsl.xmission.com/ |
572a7c52 | 9 | # |
80883bb3 MH |
10 | # The file containing rebase commands, comments, and empty lines. |
11 | # This file is created by "git rebase -i" then edited by the user. As | |
12 | # the lines are processed, they are removed from the front of this | |
6bb4e485 | 13 | # file and written to the tail of $done. |
431b7e78 | 14 | todo="$state_dir"/git-rebase-todo |
80883bb3 | 15 | |
89c7ae9c | 16 | GIT_CHERRY_PICK_HELP="$resolvemsg" |
804c7174 WC |
17 | export GIT_CHERRY_PICK_HELP |
18 | ||
882cd237 JS |
19 | comment_char=$(git config --get core.commentchar 2>/dev/null) |
20 | case "$comment_char" in | |
21 | '' | auto) | |
22 | comment_char="#" | |
23 | ;; | |
24 | ?) | |
25 | ;; | |
26 | *) | |
27 | comment_char=$(echo "$comment_char" | cut -c1) | |
28 | ;; | |
29 | esac | |
180bad3d | 30 | |
c54b7817 | 31 | die_abort () { |
33ba9c64 | 32 | apply_autostash |
431b7e78 | 33 | rm -rf "$state_dir" |
c54b7817 JS |
34 | die "$1" |
35 | } | |
36 | ||
376ccb8c | 37 | has_action () { |
180bad3d | 38 | test -n "$(git stripspace --strip-comments <"$1")" |
376ccb8c JS |
39 | } |
40 | ||
821881d8 PO |
41 | git_sequence_editor () { |
42 | if test -z "$GIT_SEQUENCE_EDITOR" | |
43 | then | |
44 | GIT_SEQUENCE_EDITOR="$(git config sequence.editor)" | |
45 | if [ -z "$GIT_SEQUENCE_EDITOR" ] | |
46 | then | |
47 | GIT_SEQUENCE_EDITOR="$(git var GIT_EDITOR)" || return $? | |
48 | fi | |
49 | fi | |
50 | ||
51 | eval "$GIT_SEQUENCE_EDITOR" '"$@"' | |
52 | } | |
53 | ||
75c69766 | 54 | expand_todo_ids() { |
3546c8d9 | 55 | git rebase--helper --expand-ids |
75c69766 JH |
56 | } |
57 | ||
58 | collapse_todo_ids() { | |
3546c8d9 | 59 | git rebase--helper --shorten-ids |
f59baa50 NS |
60 | } |
61 | ||
37079959 GR |
62 | get_missing_commit_check_level () { |
63 | check_level=$(git config --get rebase.missingCommitsCheck) | |
64 | check_level=${check_level:-ignore} | |
65 | # Don't be case sensitive | |
66 | printf '%s' "$check_level" | tr 'A-Z' 'a-z' | |
67 | } | |
68 | ||
27c499bf WS |
69 | # Initiate an action. If the cannot be any |
70 | # further action it may exec a command | |
71 | # or exit and not return. | |
72 | # | |
73 | # TODO: Consider a cleaner return model so it | |
74 | # never exits and always return 0 if process | |
75 | # is complete. | |
76 | # | |
77 | # Parameter 1 is the action to initiate. | |
78 | # | |
79 | # Returns 0 if the action was able to complete | |
80 | # and if 1 if further processing is required. | |
81 | initiate_action () { | |
82 | case "$1" in | |
d48f97aa | 83 | continue) |
9384c0ca AG |
84 | exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ |
85 | --continue | |
d48f97aa WS |
86 | ;; |
87 | skip) | |
88 | git rerere clear | |
9384c0ca AG |
89 | exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ |
90 | --continue | |
d48f97aa WS |
91 | ;; |
92 | edit-todo) | |
64a43cbd | 93 | exec git rebase--helper --edit-todo |
d48f97aa WS |
94 | ;; |
95 | show-current-patch) | |
96 | exec git show REBASE_HEAD -- | |
97 | ;; | |
27c499bf WS |
98 | *) |
99 | return 1 # continue | |
100 | ;; | |
d48f97aa | 101 | esac |
27c499bf | 102 | } |
26cd160c | 103 | |
27c499bf | 104 | init_basic_state () { |
d48f97aa WS |
105 | orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")" |
106 | mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")" | |
107 | rm -f "$(git rev-parse --git-path REBASE_HEAD)" | |
90e1818f | 108 | |
d48f97aa WS |
109 | : > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")" |
110 | write_basic_state | |
27c499bf WS |
111 | } |
112 | ||
113 | init_revisions_and_shortrevisions () { | |
114 | shorthead=$(git rev-parse --short $orig_head) | |
115 | shortonto=$(git rev-parse --short $onto) | |
116 | if test -z "$rebase_root" | |
117 | # this is now equivalent to ! -z "$upstream" | |
118 | then | |
119 | shortupstream=$(git rev-parse --short $upstream) | |
120 | revisions=$upstream...$orig_head | |
121 | shortrevisions=$shortupstream..$shorthead | |
122 | else | |
123 | revisions=$onto...$orig_head | |
124 | shortrevisions=$shorthead | |
21d0764c JS |
125 | test -z "$squash_onto" || |
126 | echo "$squash_onto" >"$state_dir"/squash-onto | |
27c499bf WS |
127 | fi |
128 | } | |
129 | ||
130 | complete_action() { | |
131 | test -s "$todo" || echo noop >> "$todo" | |
132 | test -z "$autosquash" || git rebase--helper --rearrange-squash || exit | |
133 | test -n "$cmd" && git rebase--helper --add-exec-commands "$cmd" | |
134 | ||
135 | todocount=$(git stripspace --strip-comments <"$todo" | wc -l) | |
136 | todocount=${todocount##* } | |
137 | ||
138 | cat >>"$todo" <<EOF | |
139 | ||
140 | $comment_char $(eval_ngettext \ | |
141 | "Rebase \$shortrevisions onto \$shortonto (\$todocount command)" \ | |
142 | "Rebase \$shortrevisions onto \$shortonto (\$todocount commands)" \ | |
143 | "$todocount") | |
144 | EOF | |
145e05ac | 145 | git rebase--helper --append-todo-help ${keep_empty:+--keep-empty} |
27c499bf WS |
146 | |
147 | has_action "$todo" || | |
148 | return 2 | |
149 | ||
150 | cp "$todo" "$todo".backup | |
151 | collapse_todo_ids | |
152 | git_sequence_editor "$todo" || | |
153 | die_abort "$(gettext "Could not execute editor")" | |
154 | ||
155 | has_action "$todo" || | |
156 | return 2 | |
157 | ||
158 | git rebase--helper --check-todo-list || { | |
159 | ret=$? | |
4df66c40 AG |
160 | git rebase--helper --checkout-onto "$onto_name" "$onto" \ |
161 | "$orig_head" ${verbose:+--verbose} | |
27c499bf WS |
162 | exit $ret |
163 | } | |
164 | ||
165 | expand_todo_ids | |
166 | ||
9384c0ca | 167 | test -n "$force_rebase" || |
27c499bf WS |
168 | onto="$(git rebase--helper --skip-unnecessary-picks)" || |
169 | die "Could not skip unnecessary pick commands" | |
170 | ||
4df66c40 AG |
171 | git rebase--helper --checkout-onto "$onto_name" "$onto" "$orig_head" \ |
172 | ${verbose:+--verbose} | |
9384c0ca AG |
173 | require_clean_work_tree "rebase" |
174 | exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ | |
175 | --continue | |
27c499bf WS |
176 | } |
177 | ||
178 | git_rebase__interactive () { | |
179 | initiate_action "$action" | |
180 | ret=$? | |
181 | if test $ret = 0; then | |
182 | return 0 | |
183 | fi | |
184 | ||
2c58483a | 185 | git rebase--helper --prepare-branch "$switch_to" ${verbose:+--verbose} |
27c499bf WS |
186 | init_basic_state |
187 | ||
27c499bf WS |
188 | init_revisions_and_shortrevisions |
189 | ||
c04549b2 | 190 | git rebase--helper --make-script ${keep_empty:+--keep-empty} \ |
8f6aed71 | 191 | ${rebase_merges:+--rebase-merges} \ |
7543f6f4 | 192 | ${rebase_cousins:+--rebase-cousins} \ |
c04549b2 WS |
193 | $revisions ${restrict_revision+^$restrict_revision} >"$todo" || |
194 | die "$(gettext "Could not generate todo list")" | |
950b487c WS |
195 | |
196 | complete_action | |
197 | } |