Raw
1 #!/bin/sh
2
3 test_description='messages from rebase operation'
4
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
8 . ./test-lib.sh
9
10 test_expect_success 'setup' '
11 # Commit dates are hardcoded to 2005, and the reflog entries will have
12 # a matching timestamp. Maintenance may thus immediately expire
13 # reflogs if it was running.
14 git config set gc.reflogExpire never &&
15 git config set gc.reflogExpireUnreachable never &&
16
17 test_commit O fileO &&
18 test_commit X fileX &&
19 git branch fast-forward &&
20 test_commit A fileA &&
21 test_commit B fileB &&
22 test_commit Y fileY &&
23
24 git checkout -b conflicts O &&
25 test_commit P &&
26 test_commit conflict-X fileX &&
27 test_commit Q &&
28
29 git checkout -b topic O &&
30 git cherry-pick A B &&
31 test_commit Z fileZ &&
32 git tag start
33 '
34
35 test_expect_success 'rebase -m' '
36 git rebase -m main >actual &&
37 test_must_be_empty actual
38 '
39
40 test_expect_success 'rebase against main twice' '
41 git rebase --apply main >out &&
42 test_grep "Current branch topic is up to date" out
43 '
44
45 test_expect_success 'rebase against main twice with --force' '
46 git rebase --force-rebase --apply main >out &&
47 test_grep "Current branch topic is up to date, rebase forced" out
48 '
49
50 test_expect_success 'rebase against main twice from another branch' '
51 git checkout topic^ &&
52 git rebase --apply main topic >out &&
53 test_grep "Current branch topic is up to date" out
54 '
55
56 test_expect_success 'rebase fast-forward to main' '
57 git checkout topic^ &&
58 git rebase --apply topic >out &&
59 test_grep "Fast-forwarded HEAD to topic" out
60 '
61
62 test_expect_success 'rebase --stat' '
63 git reset --hard start &&
64 git rebase --stat main >diffstat.txt &&
65 test_grep "^ fileX | *1 +$" diffstat.txt
66 '
67
68 test_expect_success 'rebase w/config rebase.stat' '
69 git reset --hard start &&
70 git config rebase.stat true &&
71 git rebase main >diffstat.txt &&
72 test_grep "^ fileX | *1 +$" diffstat.txt
73 '
74
75 test_expect_success 'rebase -n overrides config rebase.stat config' '
76 git reset --hard start &&
77 git config rebase.stat true &&
78 git rebase -n main >diffstat.txt &&
79 test_grep ! "^ fileX | *1 +$" diffstat.txt
80 '
81
82 test_expect_success 'rebase --onto outputs the invalid ref' '
83 test_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err &&
84 test_grep "invalid-ref" err
85 '
86
87 test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '
88 test_must_fail git rebase -Cnot-a-number HEAD 2>err &&
89 test_grep "numerical value" err &&
90 test_must_fail git rebase --whitespace=bad HEAD 2>err &&
91 test_grep "Invalid whitespace option" err
92 '
93
94 write_reflog_expect () {
95 if test $mode = --apply
96 then
97 sed 's/(continue)/(pick)/'
98 else
99 cat
100 fi >expect
101 }
102
103 test_reflog () {
104 mode=$1
105 reflog_action="$2"
106
107 test_expect_success "rebase $mode reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" '
108 git checkout conflicts &&
109 test_when_finished "git reset --hard Q" &&
110
111 (
112 if test -n "$reflog_action"
113 then
114 GIT_REFLOG_ACTION="$reflog_action" &&
115 export GIT_REFLOG_ACTION
116 fi &&
117 test_must_fail git rebase $mode main &&
118 echo resolved >fileX &&
119 git add fileX &&
120 git rebase --continue
121 ) &&
122
123 git log -g --format=%gs -5 >actual &&
124 write_reflog_expect <<-EOF &&
125 ${reflog_action:-rebase} (finish): returning to refs/heads/conflicts
126 ${reflog_action:-rebase} (pick): Q
127 ${reflog_action:-rebase} (continue): conflict-X
128 ${reflog_action:-rebase} (pick): P
129 ${reflog_action:-rebase} (start): checkout main
130 EOF
131 test_cmp expect actual &&
132
133 git log -g --format=%gs -1 conflicts >actual &&
134 write_reflog_expect <<-EOF &&
135 ${reflog_action:-rebase} (finish): refs/heads/conflicts onto $(git rev-parse main)
136 EOF
137 test_cmp expect actual &&
138
139 # check there is only one new entry in the branch reflog
140 test_cmp_rev conflicts@{1} Q
141 '
142
143 test_expect_success "rebase $mode fast-forward reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" '
144 git checkout fast-forward &&
145 test_when_finished "git reset --hard X" &&
146
147 (
148 if test -n "$reflog_action"
149 then
150 GIT_REFLOG_ACTION="$reflog_action" &&
151 export GIT_REFLOG_ACTION
152 fi &&
153 git rebase $mode main
154 ) &&
155
156 git log -g --format=%gs -2 >actual &&
157 write_reflog_expect <<-EOF &&
158 ${reflog_action:-rebase} (finish): returning to refs/heads/fast-forward
159 ${reflog_action:-rebase} (start): checkout main
160 EOF
161 test_cmp expect actual &&
162
163 git log -g --format=%gs -1 fast-forward >actual &&
164 write_reflog_expect <<-EOF &&
165 ${reflog_action:-rebase} (finish): refs/heads/fast-forward onto $(git rev-parse main)
166 EOF
167 test_cmp expect actual &&
168
169 # check there is only one new entry in the branch reflog
170 test_cmp_rev fast-forward@{1} X
171 '
172
173 test_expect_success "rebase $mode --skip reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" '
174 git checkout conflicts &&
175 test_when_finished "git reset --hard Q" &&
176
177 (
178 if test -n "$reflog_action"
179 then
180 GIT_REFLOG_ACTION="$reflog_action" &&
181 export GIT_REFLOG_ACTION
182 fi &&
183 test_must_fail git rebase $mode main &&
184 git rebase --skip
185 ) &&
186
187 git log -g --format=%gs -4 >actual &&
188 write_reflog_expect <<-EOF &&
189 ${reflog_action:-rebase} (finish): returning to refs/heads/conflicts
190 ${reflog_action:-rebase} (pick): Q
191 ${reflog_action:-rebase} (pick): P
192 ${reflog_action:-rebase} (start): checkout main
193 EOF
194 test_cmp expect actual
195 '
196
197 test_expect_success "rebase $mode --abort reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" '
198 git checkout conflicts &&
199 test_when_finished "git reset --hard Q" &&
200
201 git log -g -1 conflicts >branch-expect &&
202 (
203 if test -n "$reflog_action"
204 then
205 GIT_REFLOG_ACTION="$reflog_action" &&
206 export GIT_REFLOG_ACTION
207 fi &&
208 test_must_fail git rebase $mode main &&
209 git rebase --abort
210 ) &&
211
212 git log -g --format=%gs -3 >actual &&
213 write_reflog_expect <<-EOF &&
214 ${reflog_action:-rebase} (abort): returning to refs/heads/conflicts
215 ${reflog_action:-rebase} (pick): P
216 ${reflog_action:-rebase} (start): checkout main
217 EOF
218 test_cmp expect actual &&
219
220 # check branch reflog is unchanged
221 git log -g -1 conflicts >branch-actual &&
222 test_cmp branch-expect branch-actual
223 '
224
225 test_expect_success "rebase $mode --abort detached HEAD reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" '
226 git checkout Q &&
227 test_when_finished "git reset --hard Q" &&
228
229 (
230 if test -n "$reflog_action"
231 then
232 GIT_REFLOG_ACTION="$reflog_action" &&
233 export GIT_REFLOG_ACTION
234 fi &&
235 test_must_fail git rebase $mode main &&
236 git rebase --abort
237 ) &&
238
239 git log -g --format=%gs -3 >actual &&
240 write_reflog_expect <<-EOF &&
241 ${reflog_action:-rebase} (abort): returning to $(git rev-parse Q)
242 ${reflog_action:-rebase} (pick): P
243 ${reflog_action:-rebase} (start): checkout main
244 EOF
245 test_cmp expect actual
246 '
247 }
248
249 test_reflog --merge
250 test_reflog --merge my-reflog-action
251 test_reflog --apply
252 test_reflog --apply my-reflog-action
253
254 test_expect_success 'rebase -i onto unrelated history' '
255 git init unrelated &&
256 test_commit -C unrelated 1 &&
257 git -C unrelated remote add -f origin "$PWD" &&
258 git -C unrelated branch --set-upstream-to=origin/main &&
259 git -C unrelated -c core.editor=true rebase -i -v --stat >actual &&
260 test_grep "Changes to " actual &&
261 test_grep "5 files changed" actual
262 '
263
264 test_done