]>
Commit | Line | Data |
---|---|---|
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. | |
4 | # | |
5 | # Copyright (c) 2006 Johannes E. Schindelin | |
6 | # | |
7 | # The original idea comes from Eric W. Biederman, in | |
8 | # https://public-inbox.org/git/m1odwkyuf5.fsf_-_@ebiederm.dsl.xmission.com/ | |
9 | # | |
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 | |
13 | # file and written to the tail of $done. | |
14 | todo="$state_dir"/git-rebase-todo | |
15 | ||
16 | GIT_CHERRY_PICK_HELP="$resolvemsg" | |
17 | export GIT_CHERRY_PICK_HELP | |
18 | ||
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 | |
30 | ||
31 | die_abort () { | |
32 | apply_autostash | |
33 | rm -rf "$state_dir" | |
34 | die "$1" | |
35 | } | |
36 | ||
37 | has_action () { | |
38 | test -n "$(git stripspace --strip-comments <"$1")" | |
39 | } | |
40 | ||
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 | ||
54 | expand_todo_ids() { | |
55 | git rebase--helper --expand-ids | |
56 | } | |
57 | ||
58 | collapse_todo_ids() { | |
59 | git rebase--helper --shorten-ids | |
60 | } | |
61 | ||
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 | ||
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 | |
83 | continue) | |
84 | exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ | |
85 | --continue | |
86 | ;; | |
87 | skip) | |
88 | git rerere clear | |
89 | exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ | |
90 | --continue | |
91 | ;; | |
92 | edit-todo) | |
93 | exec git rebase--helper --edit-todo | |
94 | ;; | |
95 | show-current-patch) | |
96 | exec git show REBASE_HEAD -- | |
97 | ;; | |
98 | *) | |
99 | return 1 # continue | |
100 | ;; | |
101 | esac | |
102 | } | |
103 | ||
104 | init_basic_state () { | |
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)" | |
108 | ||
109 | : > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")" | |
110 | write_basic_state | |
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 | |
125 | test -z "$squash_onto" || | |
126 | echo "$squash_onto" >"$state_dir"/squash-onto | |
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 | |
145 | git rebase--helper --append-todo-help ${keep_empty:+--keep-empty} | |
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=$? | |
160 | git rebase--helper --checkout-onto "$onto_name" "$onto" \ | |
161 | "$orig_head" ${verbose:+--verbose} | |
162 | exit $ret | |
163 | } | |
164 | ||
165 | expand_todo_ids | |
166 | ||
167 | test -n "$force_rebase" || | |
168 | onto="$(git rebase--helper --skip-unnecessary-picks)" || | |
169 | die "Could not skip unnecessary pick commands" | |
170 | ||
171 | git rebase--helper --checkout-onto "$onto_name" "$onto" "$orig_head" \ | |
172 | ${verbose:+--verbose} | |
173 | require_clean_work_tree "rebase" | |
174 | exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ | |
175 | --continue | |
176 | } | |
177 | ||
178 | git_rebase__interactive () { | |
179 | initiate_action "$action" | |
180 | ret=$? | |
181 | if test $ret = 0; then | |
182 | return 0 | |
183 | fi | |
184 | ||
185 | git rebase--helper --prepare-branch "$switch_to" ${verbose:+--verbose} | |
186 | init_basic_state | |
187 | ||
188 | init_revisions_and_shortrevisions | |
189 | ||
190 | git rebase--helper --make-script ${keep_empty:+--keep-empty} \ | |
191 | ${rebase_merges:+--rebase-merges} \ | |
192 | ${rebase_cousins:+--rebase-cousins} \ | |
193 | $revisions ${restrict_revision+^$restrict_revision} >"$todo" || | |
194 | die "$(gettext "Could not generate todo list")" | |
195 | ||
196 | complete_action | |
197 | } |