]>
Commit | Line | Data |
---|---|---|
135dadef JH |
1 | #!/bin/sh |
2 | ||
3 | test_description='check various push.default settings' | |
3ac8f630 | 4 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
334afbc7 JS |
5 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
6 | ||
135dadef JH |
7 | . ./test-lib.sh |
8 | ||
9 | test_expect_success 'setup bare remotes' ' | |
10 | git init --bare repo1 && | |
11 | git remote add parent1 repo1 && | |
12 | git init --bare repo2 && | |
13 | git remote add parent2 repo2 && | |
14 | test_commit one && | |
15 | git push parent1 HEAD && | |
16 | git push parent2 HEAD | |
17 | ' | |
18 | ||
321e75c5 MM |
19 | # $1 = local revision |
20 | # $2 = remote revision (tested to be equal to the local one) | |
396243fa | 21 | # $3 = [optional] repo to check for actual output (repo1 by default) |
321e75c5 MM |
22 | check_pushed_commit () { |
23 | git log -1 --format='%h %s' "$1" >expect && | |
396243fa | 24 | git --git-dir="${3:-repo1}" log -1 --format='%h %s' "$2" >actual && |
321e75c5 MM |
25 | test_cmp expect actual |
26 | } | |
27 | ||
28 | # $1 = push.default value | |
29 | # $2 = expected target branch for the push | |
396243fa | 30 | # $3 = [optional] repo to check for actual output (repo1 by default) |
321e75c5 | 31 | test_push_success () { |
ce026cc7 | 32 | git ${1:+-c} ${1:+push.default="$1"} push && |
396243fa | 33 | check_pushed_commit HEAD "$2" "$3" |
321e75c5 MM |
34 | } |
35 | ||
36 | # $1 = push.default value | |
37 | # check that push fails and does not modify any remote branch | |
38 | test_push_failure () { | |
39 | git --git-dir=repo1 log --no-walk --format='%h %s' --all >expect && | |
ce026cc7 | 40 | test_must_fail git ${1:+-c} ${1:+push.default="$1"} push && |
321e75c5 MM |
41 | git --git-dir=repo1 log --no-walk --format='%h %s' --all >actual && |
42 | test_cmp expect actual | |
43 | } | |
44 | ||
6e1696b7 RR |
45 | # $1 = success or failure |
46 | # $2 = push.default value | |
3ac8f630 | 47 | # $3 = branch to check for actual output (main or foo) |
6e1696b7 RR |
48 | # $4 = [optional] switch to triangular workflow |
49 | test_pushdefault_workflow () { | |
50 | workflow=central | |
51 | pushdefault=parent1 | |
52 | if test -n "${4-}"; then | |
53 | workflow=triangular | |
54 | pushdefault=parent2 | |
55 | fi | |
56 | test_expect_success "push.default = $2 $1 in $workflow workflows" " | |
3ac8f630 JS |
57 | test_config branch.main.remote parent1 && |
58 | test_config branch.main.merge refs/heads/foo && | |
6e1696b7 RR |
59 | test_config remote.pushdefault $pushdefault && |
60 | test_commit commit-for-$2${4+-triangular} && | |
61 | test_push_$1 $2 $3 ${4+repo2} | |
62 | " | |
63 | } | |
64 | ||
135dadef | 65 | test_expect_success '"upstream" pushes to configured upstream' ' |
3ac8f630 JS |
66 | git checkout main && |
67 | test_config branch.main.remote parent1 && | |
68 | test_config branch.main.merge refs/heads/foo && | |
135dadef | 69 | test_commit two && |
321e75c5 | 70 | test_push_success upstream foo |
135dadef JH |
71 | ' |
72 | ||
73 | test_expect_success '"upstream" does not push on unconfigured remote' ' | |
3ac8f630 JS |
74 | git checkout main && |
75 | test_unconfig branch.main.remote && | |
135dadef | 76 | test_commit three && |
321e75c5 | 77 | test_push_failure upstream |
135dadef JH |
78 | ' |
79 | ||
80 | test_expect_success '"upstream" does not push on unconfigured branch' ' | |
3ac8f630 JS |
81 | git checkout main && |
82 | test_config branch.main.remote parent1 && | |
83 | test_unconfig branch.main.merge && | |
135dadef | 84 | test_commit four && |
321e75c5 | 85 | test_push_failure upstream |
135dadef JH |
86 | ' |
87 | ||
88 | test_expect_success '"upstream" does not push when remotes do not match' ' | |
3ac8f630 JS |
89 | git checkout main && |
90 | test_config branch.main.remote parent1 && | |
91 | test_config branch.main.merge refs/heads/foo && | |
135dadef JH |
92 | test_config push.default upstream && |
93 | test_commit five && | |
94 | test_must_fail git push parent2 | |
95 | ' | |
96 | ||
8a649be7 TK |
97 | test_expect_success '"current" does not push when multiple remotes and none origin' ' |
98 | git checkout main && | |
99 | test_config push.default current && | |
100 | test_commit current-multi && | |
101 | test_must_fail git push | |
102 | ' | |
103 | ||
104 | test_expect_success '"current" pushes when remote explicitly specified' ' | |
105 | git checkout main && | |
106 | test_config push.default current && | |
107 | test_commit current-specified && | |
108 | git push parent1 | |
109 | ' | |
110 | ||
111 | test_expect_success '"current" pushes to origin when no remote specified among multiple' ' | |
112 | git checkout main && | |
113 | test_config remote.origin.url repo1 && | |
114 | test_config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" && | |
115 | test_commit current-origin && | |
116 | test_push_success current main | |
117 | ' | |
118 | ||
119 | test_expect_success '"current" pushes to single remote even when not specified' ' | |
120 | git checkout main && | |
121 | test_when_finished git remote add parent1 repo1 && | |
122 | git remote remove parent1 && | |
123 | test_commit current-implied && | |
124 | test_push_success current main repo2 | |
125 | ' | |
126 | ||
127 | test_expect_success 'push from/to new branch with non-defaulted remote fails with upstream, matching, current and simple ' ' | |
b55e6775 MM |
128 | git checkout -b new-branch && |
129 | test_push_failure simple && | |
130 | test_push_failure matching && | |
8a649be7 TK |
131 | test_push_failure upstream && |
132 | test_push_failure current | |
133 | ' | |
134 | ||
135 | test_expect_success 'push from/to new branch fails with upstream and simple ' ' | |
136 | git checkout -b new-branch-1 && | |
137 | test_config branch.new-branch-1.remote parent1 && | |
138 | test_push_failure simple && | |
b55e6775 MM |
139 | test_push_failure upstream |
140 | ' | |
141 | ||
8a649be7 TK |
142 | # The behavior here is surprising but not entirely wrong: |
143 | # - the current branch is used to determine the target remote | |
144 | # - the "matching" push default pushes matching branches, *ignoring* the | |
145 | # current new branch as it does not have upstream tracking | |
146 | # - the default push succeeds | |
147 | # | |
148 | # A previous test expected this to fail, but for the wrong reasons: | |
149 | # it expected a fail becaause the branch is new and cannot be pushed, but | |
150 | # in fact it was failing because of an ambiguous remote | |
151 | # | |
152 | test_expect_failure 'push from/to new branch fails with matching ' ' | |
153 | git checkout -b new-branch-2 && | |
154 | test_config branch.new-branch-2.remote parent1 && | |
155 | test_push_failure matching | |
156 | ' | |
157 | ||
158 | test_expect_success 'push from/to branch with tracking fails with nothing ' ' | |
159 | git checkout -b tracked-branch && | |
160 | test_config branch.tracked-branch.remote parent1 && | |
161 | test_config branch.tracked-branch.merge refs/heads/tracked-branch && | |
162 | test_push_failure nothing | |
163 | ' | |
164 | ||
05d57750 TK |
165 | test_expect_success 'push from/to new branch succeeds with upstream if push.autoSetupRemote' ' |
166 | git checkout -b new-branch-a && | |
167 | test_config push.autoSetupRemote true && | |
168 | test_config branch.new-branch-a.remote parent1 && | |
169 | test_push_success upstream new-branch-a | |
170 | ' | |
171 | ||
172 | test_expect_success 'push from/to new branch succeeds with simple if push.autoSetupRemote' ' | |
173 | git checkout -b new-branch-c && | |
174 | test_config push.autoSetupRemote true && | |
175 | test_config branch.new-branch-c.remote parent1 && | |
176 | test_push_success simple new-branch-c | |
177 | ' | |
178 | ||
4d04658d JS |
179 | test_expect_success '"matching" fails if none match' ' |
180 | git init --bare empty && | |
181 | test_must_fail git push empty : 2>actual && | |
6789275d | 182 | test_grep "Perhaps you should specify a branch" actual |
4d04658d JS |
183 | ' |
184 | ||
b284495e DK |
185 | test_expect_success 'push ambiguously named branch with upstream, matching and simple' ' |
186 | git checkout -b ambiguous && | |
187 | test_config branch.ambiguous.remote parent1 && | |
188 | test_config branch.ambiguous.merge refs/heads/ambiguous && | |
189 | git tag ambiguous && | |
190 | test_push_success simple ambiguous && | |
191 | test_push_success matching ambiguous && | |
192 | test_push_success upstream ambiguous | |
193 | ' | |
194 | ||
b55e6775 MM |
195 | test_expect_success 'push from/to new branch with current creates remote branch' ' |
196 | test_config branch.new-branch.remote repo1 && | |
197 | git checkout new-branch && | |
198 | test_push_success current new-branch | |
199 | ' | |
200 | ||
201 | test_expect_success 'push to existing branch, with no upstream configured' ' | |
3ac8f630 JS |
202 | test_config branch.main.remote repo1 && |
203 | git checkout main && | |
b55e6775 MM |
204 | test_push_failure simple && |
205 | test_push_failure upstream | |
206 | ' | |
207 | ||
208 | test_expect_success 'push to existing branch, upstream configured with same name' ' | |
3ac8f630 JS |
209 | test_config branch.main.remote repo1 && |
210 | test_config branch.main.merge refs/heads/main && | |
211 | git checkout main && | |
b55e6775 | 212 | test_commit six && |
3ac8f630 | 213 | test_push_success upstream main && |
b55e6775 | 214 | test_commit seven && |
3ac8f630 | 215 | test_push_success simple main |
b55e6775 MM |
216 | ' |
217 | ||
218 | test_expect_success 'push to existing branch, upstream configured with different name' ' | |
3ac8f630 JS |
219 | test_config branch.main.remote repo1 && |
220 | test_config branch.main.merge refs/heads/other-name && | |
221 | git checkout main && | |
b55e6775 MM |
222 | test_commit eight && |
223 | test_push_success upstream other-name && | |
224 | test_commit nine && | |
225 | test_push_failure simple && | |
226 | git --git-dir=repo1 log -1 --format="%h %s" "other-name" >expect-other-name && | |
3ac8f630 | 227 | test_push_success current main && |
b55e6775 MM |
228 | git --git-dir=repo1 log -1 --format="%h %s" "other-name" >actual-other-name && |
229 | test_cmp expect-other-name actual-other-name | |
230 | ' | |
231 | ||
3ac8f630 | 232 | # We are on 'main', which integrates with 'foo' from parent1 |
6e1696b7 RR |
233 | # remote (set in test_pushdefault_workflow helper). Push to |
234 | # parent1 in centralized, and push to parent2 in triangular workflow. | |
3ac8f630 JS |
235 | # The parent1 repository has 'main' and 'foo' branches, while |
236 | # the parent2 repository has only 'main' branch. | |
6e1696b7 RR |
237 | # |
238 | # test_pushdefault_workflow() arguments: | |
239 | # $1 = success or failure | |
240 | # $2 = push.default value | |
3ac8f630 | 241 | # $3 = branch to check for actual output (main or foo) |
6e1696b7 RR |
242 | # $4 = [optional] switch to triangular workflow |
243 | ||
3ac8f630 JS |
244 | # update parent1's main (which is not our upstream) |
245 | test_pushdefault_workflow success current main | |
6e1696b7 RR |
246 | |
247 | # update parent1's foo (which is our upstream) | |
248 | test_pushdefault_workflow success upstream foo | |
249 | ||
7a40cf15 | 250 | # upstream is foo which is not the name of the current branch |
3ac8f630 | 251 | test_pushdefault_workflow failure simple main |
6e1696b7 | 252 | |
3ac8f630 JS |
253 | # main and foo are updated |
254 | test_pushdefault_workflow success matching main | |
6e1696b7 | 255 | |
3ac8f630 JS |
256 | # main is updated |
257 | test_pushdefault_workflow success current main triangular | |
6e1696b7 RR |
258 | |
259 | # upstream mode cannot be used in triangular | |
260 | test_pushdefault_workflow failure upstream foo triangular | |
261 | ||
262 | # in triangular, 'simple' works as 'current' and update the branch | |
263 | # with the same name. | |
3ac8f630 | 264 | test_pushdefault_workflow success simple main triangular |
6e1696b7 | 265 | |
3ac8f630 JS |
266 | # main is updated (parent2 does not have foo) |
267 | test_pushdefault_workflow success matching main triangular | |
6e1696b7 | 268 | |
00a6fa07 JK |
269 | # default tests, when no push-default is specified. This |
270 | # should behave the same as "simple" in non-triangular | |
271 | # settings, and as "current" otherwise. | |
272 | ||
273 | test_expect_success 'default behavior allows "simple" push' ' | |
3ac8f630 JS |
274 | test_config branch.main.remote parent1 && |
275 | test_config branch.main.merge refs/heads/main && | |
00a6fa07 | 276 | test_config remote.pushdefault parent1 && |
3ac8f630 JS |
277 | test_commit default-main-main && |
278 | test_push_success "" main | |
00a6fa07 JK |
279 | ' |
280 | ||
281 | test_expect_success 'default behavior rejects non-simple push' ' | |
3ac8f630 JS |
282 | test_config branch.main.remote parent1 && |
283 | test_config branch.main.merge refs/heads/foo && | |
00a6fa07 | 284 | test_config remote.pushdefault parent1 && |
3ac8f630 | 285 | test_commit default-main-foo && |
00a6fa07 JK |
286 | test_push_failure "" |
287 | ' | |
288 | ||
289 | test_expect_success 'default triangular behavior acts like "current"' ' | |
3ac8f630 JS |
290 | test_config branch.main.remote parent1 && |
291 | test_config branch.main.merge refs/heads/foo && | |
00a6fa07 JK |
292 | test_config remote.pushdefault parent2 && |
293 | test_commit default-triangular && | |
3ac8f630 | 294 | test_push_success "" main repo2 |
00a6fa07 JK |
295 | ' |
296 | ||
135dadef | 297 | test_done |