diff: correct interaction between --exit-code and -I<pattern>
[git] / t / t5533-push-cas.sh
1 #!/bin/sh
2
3 test_description='compare & swap push force/delete safety'
4
5 . ./test-lib.sh
6
7 setup_srcdst_basic () {
8         rm -fr src dst &&
9         git clone --no-local . src &&
10         git clone --no-local src dst &&
11         (
12                 cd src && git checkout HEAD^0
13         )
14 }
15
16 test_expect_success setup '
17         # create template repository
18         test_commit A &&
19         test_commit B &&
20         test_commit C
21 '
22
23 test_expect_success 'push to update (protected)' '
24         setup_srcdst_basic &&
25         (
26                 cd dst &&
27                 test_commit D &&
28                 test_must_fail git push --force-with-lease=master:master origin master 2>err &&
29                 grep "stale info" err
30         ) &&
31         git ls-remote . refs/heads/master >expect &&
32         git ls-remote src refs/heads/master >actual &&
33         test_cmp expect actual
34 '
35
36 test_expect_success 'push to update (protected, forced)' '
37         setup_srcdst_basic &&
38         (
39                 cd dst &&
40                 test_commit D &&
41                 git push --force --force-with-lease=master:master origin master 2>err &&
42                 grep "forced update" err
43         ) &&
44         git ls-remote dst refs/heads/master >expect &&
45         git ls-remote src refs/heads/master >actual &&
46         test_cmp expect actual
47 '
48
49 test_expect_success 'push to update (protected, tracking)' '
50         setup_srcdst_basic &&
51         (
52                 cd src &&
53                 git checkout master &&
54                 test_commit D &&
55                 git checkout HEAD^0
56         ) &&
57         git ls-remote src refs/heads/master >expect &&
58         (
59                 cd dst &&
60                 test_commit E &&
61                 git ls-remote . refs/remotes/origin/master >expect &&
62                 test_must_fail git push --force-with-lease=master origin master &&
63                 git ls-remote . refs/remotes/origin/master >actual &&
64                 test_cmp expect actual
65         ) &&
66         git ls-remote src refs/heads/master >actual &&
67         test_cmp expect actual
68 '
69
70 test_expect_success 'push to update (protected, tracking, forced)' '
71         setup_srcdst_basic &&
72         (
73                 cd src &&
74                 git checkout master &&
75                 test_commit D &&
76                 git checkout HEAD^0
77         ) &&
78         (
79                 cd dst &&
80                 test_commit E &&
81                 git ls-remote . refs/remotes/origin/master >expect &&
82                 git push --force --force-with-lease=master origin master
83         ) &&
84         git ls-remote dst refs/heads/master >expect &&
85         git ls-remote src refs/heads/master >actual &&
86         test_cmp expect actual
87 '
88
89 test_expect_success 'push to update (allowed)' '
90         setup_srcdst_basic &&
91         (
92                 cd dst &&
93                 test_commit D &&
94                 git push --force-with-lease=master:master^ origin master
95         ) &&
96         git ls-remote dst refs/heads/master >expect &&
97         git ls-remote src refs/heads/master >actual &&
98         test_cmp expect actual
99 '
100
101 test_expect_success 'push to update (allowed, tracking)' '
102         setup_srcdst_basic &&
103         (
104                 cd dst &&
105                 test_commit D &&
106                 git push --force-with-lease=master origin master 2>err &&
107                 ! grep "forced update" err
108         ) &&
109         git ls-remote dst refs/heads/master >expect &&
110         git ls-remote src refs/heads/master >actual &&
111         test_cmp expect actual
112 '
113
114 test_expect_success 'push to update (allowed even though no-ff)' '
115         setup_srcdst_basic &&
116         (
117                 cd dst &&
118                 git reset --hard HEAD^ &&
119                 test_commit D &&
120                 git push --force-with-lease=master origin master 2>err &&
121                 grep "forced update" err
122         ) &&
123         git ls-remote dst refs/heads/master >expect &&
124         git ls-remote src refs/heads/master >actual &&
125         test_cmp expect actual
126 '
127
128 test_expect_success 'push to delete (protected)' '
129         setup_srcdst_basic &&
130         git ls-remote src refs/heads/master >expect &&
131         (
132                 cd dst &&
133                 test_must_fail git push --force-with-lease=master:master^ origin :master
134         ) &&
135         git ls-remote src refs/heads/master >actual &&
136         test_cmp expect actual
137 '
138
139 test_expect_success 'push to delete (protected, forced)' '
140         setup_srcdst_basic &&
141         (
142                 cd dst &&
143                 git push --force --force-with-lease=master:master^ origin :master
144         ) &&
145         git ls-remote src refs/heads/master >actual &&
146         test_must_be_empty actual
147 '
148
149 test_expect_success 'push to delete (allowed)' '
150         setup_srcdst_basic &&
151         (
152                 cd dst &&
153                 git push --force-with-lease=master origin :master 2>err &&
154                 grep deleted err
155         ) &&
156         git ls-remote src refs/heads/master >actual &&
157         test_must_be_empty actual
158 '
159
160 test_expect_success 'cover everything with default force-with-lease (protected)' '
161         setup_srcdst_basic &&
162         (
163                 cd src &&
164                 git branch naster master^
165         ) &&
166         git ls-remote src refs/heads/\* >expect &&
167         (
168                 cd dst &&
169                 test_must_fail git push --force-with-lease origin master master:naster
170         ) &&
171         git ls-remote src refs/heads/\* >actual &&
172         test_cmp expect actual
173 '
174
175 test_expect_success 'cover everything with default force-with-lease (allowed)' '
176         setup_srcdst_basic &&
177         (
178                 cd src &&
179                 git branch naster master^
180         ) &&
181         (
182                 cd dst &&
183                 git fetch &&
184                 git push --force-with-lease origin master master:naster
185         ) &&
186         git ls-remote dst refs/heads/master |
187         sed -e "s/master/naster/" >expect &&
188         git ls-remote src refs/heads/naster >actual &&
189         test_cmp expect actual
190 '
191
192 test_expect_success 'new branch covered by force-with-lease' '
193         setup_srcdst_basic &&
194         (
195                 cd dst &&
196                 git branch branch master &&
197                 git push --force-with-lease=branch origin branch
198         ) &&
199         git ls-remote dst refs/heads/branch >expect &&
200         git ls-remote src refs/heads/branch >actual &&
201         test_cmp expect actual
202 '
203
204 test_expect_success 'new branch covered by force-with-lease (explicit)' '
205         setup_srcdst_basic &&
206         (
207                 cd dst &&
208                 git branch branch master &&
209                 git push --force-with-lease=branch: origin branch
210         ) &&
211         git ls-remote dst refs/heads/branch >expect &&
212         git ls-remote src refs/heads/branch >actual &&
213         test_cmp expect actual
214 '
215
216 test_expect_success 'new branch already exists' '
217         setup_srcdst_basic &&
218         (
219                 cd src &&
220                 git checkout -b branch master &&
221                 test_commit F
222         ) &&
223         (
224                 cd dst &&
225                 git branch branch master &&
226                 test_must_fail git push --force-with-lease=branch: origin branch
227         )
228 '
229
230 test_expect_success 'background updates of REMOTE can be mitigated with a non-updated REMOTE-push' '
231         rm -rf src dst &&
232         git init --bare src.bare &&
233         test_when_finished "rm -rf src.bare" &&
234         git clone --no-local src.bare dst &&
235         test_when_finished "rm -rf dst" &&
236         (
237                 cd dst &&
238                 test_commit G &&
239                 git remote add origin-push ../src.bare &&
240                 git push origin-push master:master
241         ) &&
242         git clone --no-local src.bare dst2 &&
243         test_when_finished "rm -rf dst2" &&
244         (
245                 cd dst2 &&
246                 test_commit H &&
247                 git push
248         ) &&
249         (
250                 cd dst &&
251                 test_commit I &&
252                 git fetch origin &&
253                 test_must_fail git push --force-with-lease origin-push &&
254                 git fetch origin-push &&
255                 git push --force-with-lease origin-push
256         )
257 '
258
259 test_done