1#!/bin/sh
2
3test_description='pushing to a repository using the atomic push option'
4
5. ./test-lib.sh
6
7mk_repo_pair () {
8 rm -rf workbench upstream &&
9 test_create_repo upstream &&
10 test_create_repo workbench &&
11 (
12 cd upstream &&
13 git config receive.denyCurrentBranch warn
14 ) &&
15 (
16 cd workbench &&
17 git remote add up ../upstream
18 )
19}
20
21# Compare the ref ($1) in upstream with a ref value from workbench ($2)
22# i.e. test_refs second HEAD@{2}
23test_refs () {
24 test $# = 2 &&
25 git -C upstream rev-parse --verify "$1" >expect &&
26 git -C workbench rev-parse --verify "$2" >actual &&
27 test_cmp expect actual
28}
29
30test_expect_success 'atomic push works for a single branch' '
31 mk_repo_pair &&
32 (
33 cd workbench &&
34 test_commit one &&
35 git push --mirror up &&
36 test_commit two &&
37 git push --atomic up master
38 ) &&
39 test_refs master master
40'
41
42test_expect_success 'atomic push works for two branches' '
43 mk_repo_pair &&
44 (
45 cd workbench &&
46 test_commit one &&
47 git branch second &&
48 git push --mirror up &&
49 test_commit two &&
50 git checkout second &&
51 test_commit three &&
52 git push --atomic up master second
53 ) &&
54 test_refs master master &&
55 test_refs second second
56'
57
58test_expect_success 'atomic push works in combination with --mirror' '
59 mk_repo_pair &&
60 (
61 cd workbench &&
62 test_commit one &&
63 git checkout -b second &&
64 test_commit two &&
65 git push --atomic --mirror up
66 ) &&
67 test_refs master master &&
68 test_refs second second
69'
70
71test_expect_success 'atomic push works in combination with --force' '
72 mk_repo_pair &&
73 (
74 cd workbench &&
75 test_commit one &&
76 git branch second master &&
77 test_commit two_a &&
78 git checkout second &&
79 test_commit two_b &&
80 test_commit three_b &&
81 test_commit four &&
82 git push --mirror up &&
83 # The actual test is below
84 git checkout master &&
85 test_commit three_a &&
86 git checkout second &&
87 git reset --hard HEAD^ &&
88 git push --force --atomic up master second
89 ) &&
90 test_refs master master &&
91 test_refs second second
92'
93
94# set up two branches where master can be pushed but second can not
95# (non-fast-forward). Since second can not be pushed the whole operation
96# will fail and leave master untouched.
97test_expect_success 'atomic push fails if one branch fails' '
98 mk_repo_pair &&
99 (
100 cd workbench &&
101 test_commit one &&
102 git checkout -b second master &&
103 test_commit two &&
104 test_commit three &&
105 test_commit four &&
106 git push --mirror up &&
107 git reset --hard HEAD~2 &&
108 test_commit five &&
109 git checkout master &&
110 test_commit six &&
111 test_must_fail git push --atomic --all up
112 ) &&
113 test_refs master HEAD@{7} &&
114 test_refs second HEAD@{4}
115'
116
117test_expect_success 'atomic push fails if one tag fails remotely' '
118 # prepare the repo
119 mk_repo_pair &&
120 (
121 cd workbench &&
122 test_commit one &&
123 git checkout -b second master &&
124 test_commit two &&
125 git push --mirror up
126 ) &&
127 # a third party modifies the server side:
128 (
129 cd upstream &&
130 git checkout second &&
131 git tag test_tag second
132 ) &&
133 # see if we can now push both branches.
134 (
135 cd workbench &&
136 git checkout master &&
137 test_commit three &&
138 git checkout second &&
139 test_commit four &&
140 git tag test_tag &&
141 test_must_fail git push --tags --atomic up master second
142 ) &&
143 test_refs master HEAD@{3} &&
144 test_refs second HEAD@{1}
145'
146
147test_expect_success 'atomic push obeys update hook preventing a branch to be pushed' '
148 mk_repo_pair &&
149 (
150 cd workbench &&
151 test_commit one &&
152 git checkout -b second master &&
153 test_commit two &&
154 git push --mirror up
155 ) &&
156 (
157 cd upstream &&
158 HOOKDIR="$(git rev-parse --git-dir)/hooks" &&
159 HOOK="$HOOKDIR/update" &&
160 mkdir -p "$HOOKDIR" &&
161 write_script "$HOOK" <<-\EOF
162 # only allow update to master from now on
163 test "$1" = "refs/heads/master"
164 EOF
165 ) &&
166 (
167 cd workbench &&
168 git checkout master &&
169 test_commit three &&
170 git checkout second &&
171 test_commit four &&
172 test_must_fail git push --atomic up master second
173 ) &&
174 test_refs master HEAD@{3} &&
175 test_refs second HEAD@{1}
176'
177
178test_expect_success 'atomic push is not advertised if configured' '
179 mk_repo_pair &&
180 (
181 cd upstream
182 git config receive.advertiseatomic 0
183 ) &&
184 (
185 cd workbench &&
186 test_commit one &&
187 git push --mirror up &&
188 test_commit two &&
189 test_must_fail git push --atomic up master
190 ) &&
191 test_refs master HEAD@{1}
192'
193
194test_done