1#!/bin/sh
2
3test_description='pulling into void'
4
5. ./test-lib.sh
6
7modify () {
8 sed -e "$1" <"$2" >"$2.x" &&
9 mv "$2.x" "$2"
10}
11
12test_expect_success setup '
13 echo file >file &&
14 git add file &&
15 git commit -a -m original
16'
17
18test_expect_success 'pulling into void' '
19 git init cloned &&
20 (
21 cd cloned &&
22 git pull ..
23 ) &&
24 test -f file &&
25 test -f cloned/file &&
26 test_cmp file cloned/file
27'
28
29test_expect_success 'pulling into void using master:master' '
30 git init cloned-uho &&
31 (
32 cd cloned-uho &&
33 git pull .. master:master
34 ) &&
35 test -f file &&
36 test -f cloned-uho/file &&
37 test_cmp file cloned-uho/file
38'
39
40test_expect_success 'pulling into void does not overwrite untracked files' '
41 git init cloned-untracked &&
42 (
43 cd cloned-untracked &&
44 echo untracked >file &&
45 test_must_fail git pull .. master &&
46 echo untracked >expect &&
47 test_cmp expect file
48 )
49'
50
51test_expect_success 'pulling into void does not overwrite staged files' '
52 git init cloned-staged-colliding &&
53 (
54 cd cloned-staged-colliding &&
55 echo "alternate content" >file &&
56 git add file &&
57 test_must_fail git pull .. master &&
58 echo "alternate content" >expect &&
59 test_cmp expect file &&
60 git cat-file blob :file >file.index &&
61 test_cmp expect file.index
62 )
63'
64
65test_expect_success 'pulling into void does not remove new staged files' '
66 git init cloned-staged-new &&
67 (
68 cd cloned-staged-new &&
69 echo "new tracked file" >newfile &&
70 git add newfile &&
71 git pull .. master &&
72 echo "new tracked file" >expect &&
73 test_cmp expect newfile &&
74 git cat-file blob :newfile >newfile.index &&
75 test_cmp expect newfile.index
76 )
77'
78
79test_expect_success 'pulling into void must not create an octopus' '
80 git init cloned-octopus &&
81 (
82 cd cloned-octopus &&
83 test_must_fail git pull .. master master &&
84 ! test -f file
85 )
86'
87
88test_expect_success 'test . as a remote' '
89
90 git branch copy master &&
91 git config branch.copy.remote . &&
92 git config branch.copy.merge refs/heads/master &&
93 echo updated >file &&
94 git commit -a -m updated &&
95 git checkout copy &&
96 test `cat file` = file &&
97 git pull &&
98 test `cat file` = updated
99'
100
101test_expect_success 'the default remote . should not break explicit pull' '
102 git checkout -b second master^ &&
103 echo modified >file &&
104 git commit -a -m modified &&
105 git checkout copy &&
106 git reset --hard HEAD^ &&
107 test `cat file` = file &&
108 git pull . second &&
109 test `cat file` = modified
110'
111
112test_expect_success '--rebase' '
113 git branch to-rebase &&
114 echo modified again > file &&
115 git commit -m file file &&
116 git checkout to-rebase &&
117 echo new > file2 &&
118 git add file2 &&
119 git commit -m "new file" &&
120 git tag before-rebase &&
121 git pull --rebase . copy &&
122 test $(git rev-parse HEAD^) = $(git rev-parse copy) &&
123 test new = $(git show HEAD:file2)
124'
125test_expect_success 'pull.rebase' '
126 git reset --hard before-rebase &&
127 test_config pull.rebase true &&
128 git pull . copy &&
129 test $(git rev-parse HEAD^) = $(git rev-parse copy) &&
130 test new = $(git show HEAD:file2)
131'
132
133test_expect_success 'branch.to-rebase.rebase' '
134 git reset --hard before-rebase &&
135 test_config branch.to-rebase.rebase true &&
136 git pull . copy &&
137 test $(git rev-parse HEAD^) = $(git rev-parse copy) &&
138 test new = $(git show HEAD:file2)
139'
140
141test_expect_success 'branch.to-rebase.rebase should override pull.rebase' '
142 git reset --hard before-rebase &&
143 test_config pull.rebase true &&
144 test_config branch.to-rebase.rebase false &&
145 git pull . copy &&
146 test $(git rev-parse HEAD^) != $(git rev-parse copy) &&
147 test new = $(git show HEAD:file2)
148'
149
150# add a feature branch, keep-merge, that is merged into master, so the
151# test can try preserving the merge commit (or not) with various
152# --rebase flags/pull.rebase settings.
153test_expect_success 'preserve merge setup' '
154 git reset --hard before-rebase &&
155 git checkout -b keep-merge second^ &&
156 test_commit file3 &&
157 git checkout to-rebase &&
158 git merge keep-merge &&
159 git tag before-preserve-rebase
160'
161
162test_expect_success 'pull.rebase=false create a new merge commit' '
163 git reset --hard before-preserve-rebase &&
164 test_config pull.rebase false &&
165 git pull . copy &&
166 test $(git rev-parse HEAD^1) = $(git rev-parse before-preserve-rebase) &&
167 test $(git rev-parse HEAD^2) = $(git rev-parse copy) &&
168 test file3 = $(git show HEAD:file3.t)
169'
170
171test_expect_success 'pull.rebase=true flattens keep-merge' '
172 git reset --hard before-preserve-rebase &&
173 test_config pull.rebase true &&
174 git pull . copy &&
175 test $(git rev-parse HEAD^^) = $(git rev-parse copy) &&
176 test file3 = $(git show HEAD:file3.t)
177'
178
179test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' '
180 git reset --hard before-preserve-rebase &&
181 test_config pull.rebase 1 &&
182 git pull . copy &&
183 test $(git rev-parse HEAD^^) = $(git rev-parse copy) &&
184 test file3 = $(git show HEAD:file3.t)
185'
186
187test_expect_success 'pull.rebase=preserve rebases and merges keep-merge' '
188 git reset --hard before-preserve-rebase &&
189 test_config pull.rebase preserve &&
190 git pull . copy &&
191 test $(git rev-parse HEAD^^) = $(git rev-parse copy) &&
192 test $(git rev-parse HEAD^2) = $(git rev-parse keep-merge)
193'
194
195test_expect_success 'pull.rebase=invalid fails' '
196 git reset --hard before-preserve-rebase &&
197 test_config pull.rebase invalid &&
198 ! git pull . copy
199'
200
201test_expect_success '--rebase=false create a new merge commit' '
202 git reset --hard before-preserve-rebase &&
203 test_config pull.rebase true &&
204 git pull --rebase=false . copy &&
205 test $(git rev-parse HEAD^1) = $(git rev-parse before-preserve-rebase) &&
206 test $(git rev-parse HEAD^2) = $(git rev-parse copy) &&
207 test file3 = $(git show HEAD:file3.t)
208'
209
210test_expect_success '--rebase=true rebases and flattens keep-merge' '
211 git reset --hard before-preserve-rebase &&
212 test_config pull.rebase preserve &&
213 git pull --rebase=true . copy &&
214 test $(git rev-parse HEAD^^) = $(git rev-parse copy) &&
215 test file3 = $(git show HEAD:file3.t)
216'
217
218test_expect_success '--rebase=preserve rebases and merges keep-merge' '
219 git reset --hard before-preserve-rebase &&
220 test_config pull.rebase true &&
221 git pull --rebase=preserve . copy &&
222 test $(git rev-parse HEAD^^) = $(git rev-parse copy) &&
223 test $(git rev-parse HEAD^2) = $(git rev-parse keep-merge)
224'
225
226test_expect_success '--rebase=invalid fails' '
227 git reset --hard before-preserve-rebase &&
228 ! git pull --rebase=invalid . copy
229'
230
231test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' '
232 git reset --hard before-preserve-rebase &&
233 test_config pull.rebase preserve &&
234 git pull --rebase . copy &&
235 test $(git rev-parse HEAD^^) = $(git rev-parse copy) &&
236 test file3 = $(git show HEAD:file3.t)
237'
238
239test_expect_success '--rebase with rebased upstream' '
240
241 git remote add -f me . &&
242 git checkout copy &&
243 git tag copy-orig &&
244 git reset --hard HEAD^ &&
245 echo conflicting modification > file &&
246 git commit -m conflict file &&
247 git checkout to-rebase &&
248 echo file > file2 &&
249 git commit -m to-rebase file2 &&
250 git tag to-rebase-orig &&
251 git pull --rebase me copy &&
252 test "conflicting modification" = "$(cat file)" &&
253 test file = $(cat file2)
254
255'
256
257test_expect_success '--rebase with rebased default upstream' '
258
259 git update-ref refs/remotes/me/copy copy-orig &&
260 git checkout --track -b to-rebase2 me/copy &&
261 git reset --hard to-rebase-orig &&
262 git pull --rebase &&
263 test "conflicting modification" = "$(cat file)" &&
264 test file = $(cat file2)
265
266'
267
268test_expect_success 'rebased upstream + fetch + pull --rebase' '
269
270 git update-ref refs/remotes/me/copy copy-orig &&
271 git reset --hard to-rebase-orig &&
272 git checkout --track -b to-rebase3 me/copy &&
273 git reset --hard to-rebase-orig &&
274 git fetch &&
275 git pull --rebase &&
276 test "conflicting modification" = "$(cat file)" &&
277 test file = "$(cat file2)"
278
279'
280
281test_expect_success 'pull --rebase dies early with dirty working directory' '
282
283 git checkout to-rebase &&
284 git update-ref refs/remotes/me/copy copy^ &&
285 COPY=$(git rev-parse --verify me/copy) &&
286 git rebase --onto $COPY copy &&
287 test_config branch.to-rebase.remote me &&
288 test_config branch.to-rebase.merge refs/heads/copy &&
289 test_config branch.to-rebase.rebase true &&
290 echo dirty >> file &&
291 git add file &&
292 test_must_fail git pull &&
293 test $COPY = $(git rev-parse --verify me/copy) &&
294 git checkout HEAD -- file &&
295 git pull &&
296 test $COPY != $(git rev-parse --verify me/copy)
297
298'
299
300test_expect_success 'pull --rebase works on branch yet to be born' '
301 git rev-parse master >expect &&
302 mkdir empty_repo &&
303 (cd empty_repo &&
304 git init &&
305 git pull --rebase .. master &&
306 git rev-parse HEAD >../actual
307 ) &&
308 test_cmp expect actual
309'
310
311test_expect_success 'setup for detecting upstreamed changes' '
312 mkdir src &&
313 (cd src &&
314 git init &&
315 printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" > stuff &&
316 git add stuff &&
317 git commit -m "Initial revision"
318 ) &&
319 git clone src dst &&
320 (cd src &&
321 modify s/5/43/ stuff &&
322 git commit -a -m "5->43" &&
323 modify s/6/42/ stuff &&
324 git commit -a -m "Make it bigger"
325 ) &&
326 (cd dst &&
327 modify s/5/43/ stuff &&
328 git commit -a -m "Independent discovery of 5->43"
329 )
330'
331
332test_expect_success 'git pull --rebase detects upstreamed changes' '
333 (cd dst &&
334 git pull --rebase &&
335 test -z "$(git ls-files -u)"
336 )
337'
338
339test_expect_success 'setup for avoiding reapplying old patches' '
340 (cd dst &&
341 test_might_fail git rebase --abort &&
342 git reset --hard origin/master
343 ) &&
344 git clone --bare src src-replace.git &&
345 rm -rf src &&
346 mv src-replace.git src &&
347 (cd dst &&
348 modify s/2/22/ stuff &&
349 git commit -a -m "Change 2" &&
350 modify s/3/33/ stuff &&
351 git commit -a -m "Change 3" &&
352 modify s/4/44/ stuff &&
353 git commit -a -m "Change 4" &&
354 git push &&
355
356 modify s/44/55/ stuff &&
357 git commit --amend -a -m "Modified Change 4"
358 )
359'
360
361test_expect_success 'git pull --rebase does not reapply old patches' '
362 (cd dst &&
363 test_must_fail git pull --rebase &&
364 test 1 = $(find .git/rebase-apply -name "000*" | wc -l)
365 )
366'
367
368test_expect_success 'git pull --rebase against local branch' '
369 git checkout -b copy2 to-rebase-orig &&
370 git pull --rebase . to-rebase &&
371 test "conflicting modification" = "$(cat file)" &&
372 test file = "$(cat file2)"
373'
374
375test_done