Merge branch 'jc/calloc-fix'
[git] / t / t5150-request-pull.sh
1 #!/bin/sh
2
3 test_description='Test workflows involving pull request.'
4
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
8 . ./test-lib.sh
9
10 if ! test_have_prereq PERL
11 then
12         skip_all='skipping request-pull tests, perl not available'
13         test_done
14 fi
15
16 test_expect_success 'setup' '
17
18         git init --bare upstream.git &&
19         git init --bare downstream.git &&
20         git clone upstream.git upstream-private &&
21         git clone downstream.git local &&
22
23         trash_url="file://$TRASH_DIRECTORY" &&
24         downstream_url="$trash_url/downstream.git/" &&
25         upstream_url="$trash_url/upstream.git/" &&
26
27         (
28                 cd upstream-private &&
29                 cat <<-\EOT >mnemonic.txt &&
30                 Thirtey days hath November,
31                 Aprile, June, and September:
32                 EOT
33                 git add mnemonic.txt &&
34                 test_tick &&
35                 git commit -m "\"Thirty days\", a reminder of month lengths" &&
36                 git tag -m "version 1" -a initial &&
37                 git push --tags origin main
38         ) &&
39         (
40                 cd local &&
41                 git remote add upstream "$trash_url/upstream.git" &&
42                 git fetch upstream &&
43                 git pull upstream main &&
44                 cat <<-\EOT >>mnemonic.txt &&
45                 Of twyecescore-eightt is but eine,
46                 And all the remnante be thrycescore-eine.
47                 O’course Leap yare comes an’pynes,
48                 Ev’rie foure yares, gote it ryghth.
49                 An’twyecescore-eight is but twyecescore-nyne.
50                 EOT
51                 git add mnemonic.txt &&
52                 test_tick &&
53                 git commit -m "More detail" &&
54                 git tag -m "version 2" -a full &&
55                 git checkout -b simplify HEAD^ &&
56                 mv mnemonic.txt mnemonic.standard &&
57                 cat <<-\EOT >mnemonic.clarified &&
58                 Thirty days has September,
59                 All the rest I can’t remember.
60                 EOT
61                 git add -N mnemonic.standard mnemonic.clarified &&
62                 git commit -a -m "Adapt to use modern, simpler English
63
64 But keep the old version, too, in case some people prefer it." &&
65                 git checkout main
66         )
67
68 '
69
70 test_expect_success 'setup: two scripts for reading pull requests' '
71
72         downstream_url_for_sed=$(
73                 printf "%s\n" "$downstream_url" |
74                 sed -e '\''s/\\/\\\\/g'\'' -e '\''s/[[/.*^$]/\\&/g'\''
75         ) &&
76
77         cat <<-\EOT >read-request.sed &&
78         #!/bin/sed -nf
79         # Note that a request could ask for "tag $tagname"
80         / in the Git repository at:$/!d
81         n
82         /^$/ n
83         s/ tag \([^ ]*\)$/ tag--\1/
84         s/^[    ]*\(.*\) \([^ ]*\)/please pull\
85         \1\
86         \2/p
87         q
88         EOT
89
90         cat <<-EOT >fuzz.sed
91         #!/bin/sed -nf
92         s/$downstream_url_for_sed/URL/g
93         s/$OID_REGEX/OBJECT_NAME/g
94         s/A U Thor/AUTHOR/g
95         s/[-0-9]\{10\} [:0-9]\{8\} [-+][0-9]\{4\}/DATE/g
96         s/        [^ ].*/        SUBJECT/g
97         s/  [^ ].* (DATE)/  SUBJECT (DATE)/g
98         s|tags/full|BRANCH|g
99         s/mnemonic.txt/FILENAME/g
100         s/^version [0-9]/VERSION/
101         /^ FILENAME | *[0-9]* [-+]*\$/ b diffstat
102         /^AUTHOR ([0-9]*):\$/ b shortlog
103         p
104         b
105         : diffstat
106         n
107         / [0-9]* files* changed/ {
108                 a\\
109         DIFFSTAT
110                 b
111         }
112         b diffstat
113         : shortlog
114         /^        [a-zA-Z]/ n
115         /^[a-zA-Z]* ([0-9]*):\$/ n
116         /^\$/ N
117         /^\n[a-zA-Z]* ([0-9]*):\$/!{
118                 a\\
119         SHORTLOG
120                 D
121         }
122         n
123         b shortlog
124         EOT
125
126 '
127
128 test_expect_success 'pull request when forgot to push' '
129
130         rm -fr downstream.git &&
131         git init --bare downstream.git &&
132         (
133                 cd local &&
134                 git checkout initial &&
135                 git merge --ff-only main &&
136                 test_must_fail git request-pull initial "$downstream_url" \
137                         2>../err
138         ) &&
139         grep "No match for commit .*" err &&
140         grep "Are you sure you pushed" err
141
142 '
143
144 test_expect_success 'pull request after push' '
145
146         rm -fr downstream.git &&
147         git init --bare downstream.git &&
148         (
149                 cd local &&
150                 git checkout initial &&
151                 git merge --ff-only main &&
152                 git push origin main:for-upstream &&
153                 git request-pull initial origin main:for-upstream >../request
154         ) &&
155         sed -nf read-request.sed <request >digest &&
156         {
157                 read task &&
158                 read repository &&
159                 read branch
160         } <digest &&
161         (
162                 cd upstream-private &&
163                 git checkout initial &&
164                 git pull --ff-only "$repository" "$branch"
165         ) &&
166         test "$branch" = for-upstream &&
167         test_cmp local/mnemonic.txt upstream-private/mnemonic.txt
168
169 '
170
171 test_expect_success 'request asks HEAD to be pulled' '
172
173         rm -fr downstream.git &&
174         git init --bare downstream.git &&
175         (
176                 cd local &&
177                 git checkout initial &&
178                 git merge --ff-only main &&
179                 git push --tags origin main simplify &&
180                 git push origin main:for-upstream &&
181                 git request-pull initial "$downstream_url" >../request
182         ) &&
183         sed -nf read-request.sed <request >digest &&
184         {
185                 read task &&
186                 read repository &&
187                 read branch
188         } <digest &&
189         test -z "$branch"
190
191 '
192
193 test_expect_success 'pull request format' '
194
195         rm -fr downstream.git &&
196         git init --bare downstream.git &&
197         cat <<-\EOT >expect &&
198         The following changes since commit OBJECT_NAME:
199
200           SUBJECT (DATE)
201
202         are available in the Git repository at:
203
204           URL BRANCH
205
206         for you to fetch changes up to OBJECT_NAME:
207
208           SUBJECT (DATE)
209
210         ----------------------------------------------------------------
211         VERSION
212
213         ----------------------------------------------------------------
214         SHORTLOG
215
216         DIFFSTAT
217         EOT
218         (
219                 cd local &&
220                 git checkout initial &&
221                 git merge --ff-only main &&
222                 git push origin tags/full &&
223                 git request-pull initial "$downstream_url" tags/full >../request
224         ) &&
225         <request sed -nf fuzz.sed >request.fuzzy &&
226         test_cmp expect request.fuzzy &&
227
228         (
229                 cd local &&
230                 git request-pull initial "$downstream_url" tags/full:refs/tags/full
231         ) >request &&
232         sed -nf fuzz.sed <request >request.fuzzy &&
233         test_cmp expect request.fuzzy &&
234
235         (
236                 cd local &&
237                 git request-pull initial "$downstream_url" full
238         ) >request &&
239         grep " tags/full\$" request
240 '
241
242 test_expect_success 'request-pull ignores OPTIONS_KEEPDASHDASH poison' '
243
244         (
245                 cd local &&
246                 OPTIONS_KEEPDASHDASH=Yes &&
247                 export OPTIONS_KEEPDASHDASH &&
248                 git checkout initial &&
249                 git merge --ff-only main &&
250                 git push origin main:for-upstream &&
251                 git request-pull -- initial "$downstream_url" main:for-upstream >../request
252         )
253
254 '
255
256 test_expect_success 'request-pull quotes regex metacharacters properly' '
257
258         rm -fr downstream.git &&
259         git init --bare downstream.git &&
260         (
261                 cd local &&
262                 git checkout initial &&
263                 git merge --ff-only main &&
264                 git tag -mrelease v2.0 &&
265                 git push origin refs/tags/v2.0:refs/tags/v2-0 &&
266                 test_must_fail git request-pull initial "$downstream_url" tags/v2.0 \
267                         2>../err
268         ) &&
269         grep "No match for commit .*" err &&
270         grep "Are you sure you pushed" err
271
272 '
273
274 test_expect_success 'pull request with mismatched object' '
275
276         rm -fr downstream.git &&
277         git init --bare downstream.git &&
278         (
279                 cd local &&
280                 git checkout initial &&
281                 git merge --ff-only main &&
282                 git push origin HEAD:refs/tags/full &&
283                 test_must_fail git request-pull initial "$downstream_url" tags/full \
284                         2>../err
285         ) &&
286         grep "points to a different object" err &&
287         grep "Are you sure you pushed" err
288
289 '
290
291 test_expect_success 'pull request with stale object' '
292
293         rm -fr downstream.git &&
294         git init --bare downstream.git &&
295         (
296                 cd local &&
297                 git checkout initial &&
298                 git merge --ff-only main &&
299                 git push origin refs/tags/full &&
300                 git tag -f -m"Thirty-one days" full &&
301                 test_must_fail git request-pull initial "$downstream_url" tags/full \
302                         2>../err
303         ) &&
304         grep "points to a different object" err &&
305         grep "Are you sure you pushed" err
306
307 '
308
309 test_done