]> git.ipfire.org Git - thirdparty/git.git/blame - git-rebase--interactive.sh
rebase -i: rewrite checkout_onto() in C
[thirdparty/git.git] / git-rebase--interactive.sh
CommitLineData
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 14todo="$state_dir"/git-rebase-todo
80883bb3 15
89c7ae9c 16GIT_CHERRY_PICK_HELP="$resolvemsg"
804c7174
WC
17export GIT_CHERRY_PICK_HELP
18
882cd237
JS
19comment_char=$(git config --get core.commentchar 2>/dev/null)
20case "$comment_char" in
21'' | auto)
22 comment_char="#"
23 ;;
24?)
25 ;;
26*)
27 comment_char=$(echo "$comment_char" | cut -c1)
28 ;;
29esac
180bad3d 30
c54b7817 31die_abort () {
33ba9c64 32 apply_autostash
431b7e78 33 rm -rf "$state_dir"
c54b7817
JS
34 die "$1"
35}
36
376ccb8c 37has_action () {
180bad3d 38 test -n "$(git stripspace --strip-comments <"$1")"
376ccb8c
JS
39}
40
821881d8
PO
41git_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 54expand_todo_ids() {
3546c8d9 55 git rebase--helper --expand-ids
75c69766
JH
56}
57
58collapse_todo_ids() {
3546c8d9 59 git rebase--helper --shorten-ids
f59baa50
NS
60}
61
37079959
GR
62get_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.
81initiate_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 104init_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
113init_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
130complete_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
138cat >>"$todo" <<EOF
139
140$comment_char $(eval_ngettext \
141 "Rebase \$shortrevisions onto \$shortonto (\$todocount command)" \
142 "Rebase \$shortrevisions onto \$shortonto (\$todocount commands)" \
143 "$todocount")
144EOF
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
178git_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}