Merge branch 'wp/add-p-goto'
[git] / t / t5400-send-pack.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
5
6 test_description='See why rewinding head breaks send-pack
7
8 '
9 . ./test-lib.sh
10
11 cnt=64
12 test_expect_success setup '
13         test_tick &&
14         mkdir mozart mozart/is &&
15         echo "Commit #0" >mozart/is/pink &&
16         git update-index --add mozart/is/pink &&
17         tree=$(git write-tree) &&
18         commit=$(echo "Commit #0" | git commit-tree $tree) &&
19         zero=$commit &&
20         parent=$zero &&
21         i=0 &&
22         while test $i -le $cnt
23         do
24             i=$(($i+1)) &&
25             test_tick &&
26             echo "Commit #$i" >mozart/is/pink &&
27             git update-index --add mozart/is/pink &&
28             tree=$(git write-tree) &&
29             commit=$(echo "Commit #$i" | git commit-tree $tree -p $parent) &&
30             git update-ref refs/tags/commit$i $commit &&
31             parent=$commit || return 1
32         done &&
33         git update-ref HEAD "$commit" &&
34         git clone ./. victim &&
35         cd victim &&
36         git log &&
37         cd .. &&
38         git update-ref HEAD "$zero" &&
39         parent=$zero &&
40         i=0 &&
41         while test $i -le $cnt
42         do
43             i=$(($i+1)) &&
44             test_tick &&
45             echo "Rebase #$i" >mozart/is/pink &&
46             git update-index --add mozart/is/pink &&
47             tree=$(git write-tree) &&
48             commit=$(echo "Rebase #$i" | git commit-tree $tree -p $parent) &&
49             git update-ref refs/tags/rebase$i $commit &&
50             parent=$commit || return 1
51         done &&
52         git update-ref HEAD "$commit" &&
53         echo Rebase &&
54         git log'
55
56 test_expect_success 'pack the source repository' '
57         git repack -a -d &&
58         git prune
59 '
60
61 test_expect_success 'pack the destination repository' '
62         cd victim &&
63         git repack -a -d &&
64         git prune &&
65         cd ..
66 '
67
68 test_expect_success \
69         'pushing rewound head should not barf but require --force' '
70         # should not fail but refuse to update.
71         if git send-pack ./victim/.git/ master
72         then
73                 # now it should fail with Pasky patch
74                 echo >&2 Gaah, it should have failed.
75                 false
76         else
77                 echo >&2 Thanks, it correctly failed.
78                 true
79         fi &&
80         if cmp victim/.git/refs/heads/master .git/refs/heads/master
81         then
82                 # should have been left as it was!
83                 false
84         else
85                 true
86         fi &&
87         # this should update
88         git send-pack --force ./victim/.git/ master &&
89         cmp victim/.git/refs/heads/master .git/refs/heads/master
90 '
91
92 test_expect_success \
93         'push can be used to delete a ref' '
94         cd victim &&
95         git branch extra master &&
96         cd .. &&
97         test -f victim/.git/refs/heads/extra &&
98         git send-pack ./victim/.git/ :extra master &&
99         ! test -f victim/.git/refs/heads/extra
100 '
101
102 unset GIT_CONFIG
103 HOME=`pwd`/no-such-directory
104 export HOME ;# this way we force the victim/.git/config to be used.
105
106 test_expect_success \
107         'pushing a delete should be denied with denyDeletes' '
108         cd victim &&
109         git config receive.denyDeletes true &&
110         git branch extra master &&
111         cd .. &&
112         test -f victim/.git/refs/heads/extra &&
113         test_must_fail git send-pack ./victim/.git/ :extra master
114 '
115 rm -f victim/.git/refs/heads/extra
116
117 test_expect_success \
118         'pushing with --force should be denied with denyNonFastforwards' '
119         cd victim &&
120         git config receive.denyNonFastforwards true &&
121         cd .. &&
122         git update-ref refs/heads/master master^ || return 1
123         git send-pack --force ./victim/.git/ master && return 1
124         ! test_cmp .git/refs/heads/master victim/.git/refs/heads/master
125 '
126
127 test_expect_success \
128         'pushing does not include non-head refs' '
129         mkdir parent && cd parent &&
130         git init && touch file && git add file && git commit -m add &&
131         cd .. &&
132         git clone parent child && cd child && git push --all &&
133         cd ../parent &&
134         git branch -a >branches && ! grep origin/master branches
135 '
136
137 rewound_push_setup() {
138         rm -rf parent child &&
139         mkdir parent && cd parent &&
140         git init && echo one >file && git add file && git commit -m one &&
141         echo two >file && git commit -a -m two &&
142         cd .. &&
143         git clone parent child && cd child && git reset --hard HEAD^
144 }
145
146 rewound_push_succeeded() {
147         cmp ../parent/.git/refs/heads/master .git/refs/heads/master
148 }
149
150 rewound_push_failed() {
151         if rewound_push_succeeded
152         then
153                 false
154         else
155                 true
156         fi
157 }
158
159 test_expect_success \
160         'pushing explicit refspecs respects forcing' '
161         rewound_push_setup &&
162         if git send-pack ../parent/.git refs/heads/master:refs/heads/master
163         then
164                 false
165         else
166                 true
167         fi && rewound_push_failed &&
168         git send-pack ../parent/.git +refs/heads/master:refs/heads/master &&
169         rewound_push_succeeded
170 '
171
172 test_expect_success \
173         'pushing wildcard refspecs respects forcing' '
174         rewound_push_setup &&
175         if git send-pack ../parent/.git refs/heads/*:refs/heads/*
176         then
177                 false
178         else
179                 true
180         fi && rewound_push_failed &&
181         git send-pack ../parent/.git +refs/heads/*:refs/heads/* &&
182         rewound_push_succeeded
183 '
184
185 test_done