1 | #!/usr/bin/env python |
---|
2 | # |
---|
3 | # commit_tests.py: testing fancy commit cases. |
---|
4 | # |
---|
5 | # Subversion is a tool for revision control. |
---|
6 | # See http://subversion.tigris.org for more information. |
---|
7 | # |
---|
8 | # ==================================================================== |
---|
9 | # Copyright (c) 2000-2008 CollabNet. All rights reserved. |
---|
10 | # |
---|
11 | # This software is licensed as described in the file COPYING, which |
---|
12 | # you should have received as part of this distribution. The terms |
---|
13 | # are also available at http://subversion.tigris.org/license-1.html. |
---|
14 | # If newer versions of this license are posted there, you may use a |
---|
15 | # newer version instead, at your option. |
---|
16 | # |
---|
17 | ###################################################################### |
---|
18 | |
---|
19 | # General modules |
---|
20 | import sys, os, re |
---|
21 | |
---|
22 | # Our testing module |
---|
23 | import svntest |
---|
24 | from svntest import wc |
---|
25 | |
---|
26 | # (abbreviation) |
---|
27 | Skip = svntest.testcase.Skip |
---|
28 | SkipUnless = svntest.testcase.SkipUnless |
---|
29 | XFail = svntest.testcase.XFail |
---|
30 | Item = svntest.wc.StateItem |
---|
31 | |
---|
32 | from svntest.main import server_has_revprop_commit, \ |
---|
33 | server_gets_client_capabilities |
---|
34 | from svntest.actions import inject_conflict_into_wc |
---|
35 | |
---|
36 | ###################################################################### |
---|
37 | # Utilities |
---|
38 | # |
---|
39 | |
---|
40 | def is_non_posix_os_or_cygwin_platform(): |
---|
41 | return (not svntest.main.is_posix_os()) or sys.platform == 'cygwin' |
---|
42 | |
---|
43 | def get_standard_state(wc_dir): |
---|
44 | """Return a status list reflecting the local mods made by |
---|
45 | make_standard_slew_of_changes().""" |
---|
46 | |
---|
47 | state = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
48 | |
---|
49 | state.tweak('', 'A/D', 'A/D/G/pi', status=' M') |
---|
50 | state.tweak('A/B/lambda', status='M ') |
---|
51 | state.tweak('A/B/E', 'A/D/H/chi', status='R ') |
---|
52 | state.tweak('A/B/E/alpha', 'A/B/E/beta', 'A/C', 'A/D/gamma', |
---|
53 | 'A/D/G/rho', status='D ') |
---|
54 | state.tweak('A/D/H/omega', status='MM') |
---|
55 | |
---|
56 | # New things |
---|
57 | state.add({ |
---|
58 | 'Q' : Item(status='A ', wc_rev=0), |
---|
59 | 'Q/floo' : Item(status='A ', wc_rev=0), |
---|
60 | 'A/D/H/gloo' : Item(status='A ', wc_rev=0), |
---|
61 | 'A/B/E/bloo' : Item(status='A ', wc_rev=0), |
---|
62 | }) |
---|
63 | |
---|
64 | return state |
---|
65 | |
---|
66 | |
---|
67 | def make_standard_slew_of_changes(wc_dir): |
---|
68 | """Make a specific set of local mods to WC_DIR. These will be used |
---|
69 | by every commit-test. Verify the 'svn status' output, and return the |
---|
70 | (pre-commit) status tree.""" |
---|
71 | |
---|
72 | # Cache current working directory, move into wc_dir |
---|
73 | was_cwd = os.getcwd() |
---|
74 | os.chdir(wc_dir) |
---|
75 | |
---|
76 | # Add a directory |
---|
77 | os.mkdir('Q') |
---|
78 | svntest.main.run_svn(None, 'add', 'Q') |
---|
79 | |
---|
80 | # Remove two directories |
---|
81 | svntest.main.run_svn(None, 'rm', os.path.join('A', 'B', 'E')) |
---|
82 | svntest.main.run_svn(None, 'rm', os.path.join('A', 'C')) |
---|
83 | |
---|
84 | # Replace one of the removed directories |
---|
85 | svntest.main.run_svn(None, 'add', os.path.join('A', 'B', 'E')) |
---|
86 | |
---|
87 | # Make property mods to two directories |
---|
88 | svntest.main.run_svn(None, 'propset', 'foo', 'bar', os.curdir) |
---|
89 | svntest.main.run_svn(None, 'propset', 'foo2', 'bar2', os.path.join('A', 'D')) |
---|
90 | |
---|
91 | # Add three files |
---|
92 | svntest.main.file_append(os.path.join('A', 'B', 'E', 'bloo'), "hi") |
---|
93 | svntest.main.file_append(os.path.join('A', 'D', 'H', 'gloo'), "hello") |
---|
94 | svntest.main.file_append(os.path.join('Q', 'floo'), "yo") |
---|
95 | svntest.main.run_svn(None, 'add', os.path.join('A', 'B', 'E', 'bloo')) |
---|
96 | svntest.main.run_svn(None, 'add', os.path.join('A', 'D', 'H', 'gloo')) |
---|
97 | svntest.main.run_svn(None, 'add', os.path.join('Q', 'floo')) |
---|
98 | |
---|
99 | # Remove three files |
---|
100 | svntest.main.run_svn(None, 'rm', os.path.join('A', 'D', 'G', 'rho')) |
---|
101 | svntest.main.run_svn(None, 'rm', os.path.join('A', 'D', 'H', 'chi')) |
---|
102 | svntest.main.run_svn(None, 'rm', os.path.join('A', 'D', 'gamma')) |
---|
103 | |
---|
104 | # Replace one of the removed files |
---|
105 | svntest.main.file_append(os.path.join('A', 'D', 'H', 'chi'), "chi") |
---|
106 | svntest.main.run_svn(None, 'add', os.path.join('A', 'D', 'H', 'chi')) |
---|
107 | |
---|
108 | # Make textual mods to two files |
---|
109 | svntest.main.file_append(os.path.join('A', 'B', 'lambda'), "new ltext") |
---|
110 | svntest.main.file_append(os.path.join('A', 'D', 'H', 'omega'), "new otext") |
---|
111 | |
---|
112 | # Make property mods to three files |
---|
113 | svntest.main.run_svn(None, 'propset', 'blue', 'azul', |
---|
114 | os.path.join('A', 'D', 'H', 'omega')) |
---|
115 | svntest.main.run_svn(None, 'propset', 'green', 'verde', |
---|
116 | os.path.join('Q', 'floo')) |
---|
117 | svntest.main.run_svn(None, 'propset', 'red', 'rojo', |
---|
118 | os.path.join('A', 'D', 'G', 'pi')) |
---|
119 | |
---|
120 | # Restore the CWD. |
---|
121 | os.chdir(was_cwd) |
---|
122 | |
---|
123 | # Build an expected status tree. |
---|
124 | expected_status = get_standard_state(wc_dir) |
---|
125 | |
---|
126 | # Verify status -- all local mods should be present. |
---|
127 | svntest.actions.run_and_verify_status(wc_dir, expected_status) |
---|
128 | |
---|
129 | return expected_status |
---|
130 | |
---|
131 | |
---|
132 | ###################################################################### |
---|
133 | # Tests |
---|
134 | # |
---|
135 | # Each test must return on success or raise on failure. |
---|
136 | |
---|
137 | |
---|
138 | #---------------------------------------------------------------------- |
---|
139 | |
---|
140 | def commit_one_file(sbox): |
---|
141 | "commit one file" |
---|
142 | |
---|
143 | sbox.build() |
---|
144 | wc_dir = sbox.wc_dir |
---|
145 | |
---|
146 | expected_status = make_standard_slew_of_changes(wc_dir) |
---|
147 | |
---|
148 | omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega') |
---|
149 | |
---|
150 | # Create expected state. |
---|
151 | expected_output = svntest.wc.State(wc_dir, { |
---|
152 | 'A/D/H/omega' : Item(verb='Sending'), |
---|
153 | }) |
---|
154 | expected_status.tweak('A/D/H/omega', wc_rev=2, status=' ') |
---|
155 | |
---|
156 | # Commit the one file. |
---|
157 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
158 | expected_output, |
---|
159 | expected_status, |
---|
160 | None, |
---|
161 | omega_path) |
---|
162 | |
---|
163 | |
---|
164 | #---------------------------------------------------------------------- |
---|
165 | |
---|
166 | def commit_one_new_file(sbox): |
---|
167 | "commit one newly added file" |
---|
168 | |
---|
169 | sbox.build() |
---|
170 | wc_dir = sbox.wc_dir |
---|
171 | |
---|
172 | expected_status = make_standard_slew_of_changes(wc_dir) |
---|
173 | |
---|
174 | gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo') |
---|
175 | |
---|
176 | # Create expected state. |
---|
177 | expected_output = svntest.wc.State(wc_dir, { |
---|
178 | 'A/D/H/gloo' : Item(verb='Adding'), |
---|
179 | }) |
---|
180 | expected_status.tweak('A/D/H/gloo', wc_rev=2, status=' ') |
---|
181 | |
---|
182 | # Commit the one file. |
---|
183 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
184 | expected_output, |
---|
185 | expected_status, |
---|
186 | None, |
---|
187 | gloo_path) |
---|
188 | |
---|
189 | |
---|
190 | #---------------------------------------------------------------------- |
---|
191 | |
---|
192 | def commit_one_new_binary_file(sbox): |
---|
193 | "commit one newly added binary file" |
---|
194 | |
---|
195 | sbox.build() |
---|
196 | wc_dir = sbox.wc_dir |
---|
197 | |
---|
198 | expected_status = make_standard_slew_of_changes(wc_dir) |
---|
199 | |
---|
200 | gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo') |
---|
201 | svntest.main.run_svn(None, 'propset', 'svn:mime-type', |
---|
202 | 'application/octet-stream', gloo_path) |
---|
203 | |
---|
204 | # Create expected state. |
---|
205 | expected_output = svntest.wc.State(wc_dir, { |
---|
206 | 'A/D/H/gloo' : Item(verb='Adding (bin)'), |
---|
207 | }) |
---|
208 | expected_status.tweak('A/D/H/gloo', wc_rev=2, status=' ') |
---|
209 | |
---|
210 | # Commit the one file. |
---|
211 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
212 | expected_output, |
---|
213 | expected_status, |
---|
214 | None, |
---|
215 | gloo_path) |
---|
216 | |
---|
217 | |
---|
218 | #---------------------------------------------------------------------- |
---|
219 | |
---|
220 | def commit_multiple_targets(sbox): |
---|
221 | "commit multiple targets" |
---|
222 | |
---|
223 | sbox.build() |
---|
224 | wc_dir = sbox.wc_dir |
---|
225 | |
---|
226 | # This test will commit three targets: psi, B, and pi. In that order. |
---|
227 | |
---|
228 | # Make local mods to many files. |
---|
229 | AB_path = os.path.join(wc_dir, 'A', 'B') |
---|
230 | lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda') |
---|
231 | rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho') |
---|
232 | pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi') |
---|
233 | omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega') |
---|
234 | psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi') |
---|
235 | svntest.main.file_append(lambda_path, 'new appended text for lambda') |
---|
236 | svntest.main.file_append(rho_path, 'new appended text for rho') |
---|
237 | svntest.main.file_append(pi_path, 'new appended text for pi') |
---|
238 | svntest.main.file_append(omega_path, 'new appended text for omega') |
---|
239 | svntest.main.file_append(psi_path, 'new appended text for psi') |
---|
240 | |
---|
241 | # Just for kicks, add a property to A/D/G as well. We'll make sure |
---|
242 | # that it *doesn't* get committed. |
---|
243 | ADG_path = os.path.join(wc_dir, 'A', 'D', 'G') |
---|
244 | svntest.main.run_svn(None, 'propset', 'foo', 'bar', ADG_path) |
---|
245 | |
---|
246 | # Create expected output tree for 'svn ci'. We should see changes |
---|
247 | # only on these three targets, no others. |
---|
248 | expected_output = svntest.wc.State(wc_dir, { |
---|
249 | 'A/D/H/psi' : Item(verb='Sending'), |
---|
250 | 'A/B/lambda' : Item(verb='Sending'), |
---|
251 | 'A/D/G/pi' : Item(verb='Sending'), |
---|
252 | }) |
---|
253 | |
---|
254 | # Create expected status tree; all local revisions should be at 1, |
---|
255 | # but our three targets should be at 2. |
---|
256 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
257 | expected_status.tweak('A/D/H/psi', 'A/B/lambda', 'A/D/G/pi', wc_rev=2) |
---|
258 | |
---|
259 | # rho and omega should still display as locally modified: |
---|
260 | expected_status.tweak('A/D/G/rho', 'A/D/H/omega', status='M ') |
---|
261 | |
---|
262 | # A/D/G should still have a local property set, too. |
---|
263 | expected_status.tweak('A/D/G', status=' M') |
---|
264 | |
---|
265 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
266 | expected_output, |
---|
267 | expected_status, |
---|
268 | None, |
---|
269 | psi_path, AB_path, pi_path) |
---|
270 | |
---|
271 | #---------------------------------------------------------------------- |
---|
272 | |
---|
273 | |
---|
274 | def commit_multiple_targets_2(sbox): |
---|
275 | "commit multiple targets, 2nd variation" |
---|
276 | |
---|
277 | sbox.build() |
---|
278 | wc_dir = sbox.wc_dir |
---|
279 | |
---|
280 | # This test will commit four targets: psi, B, omega and pi. In that order. |
---|
281 | |
---|
282 | # Make local mods to many files. |
---|
283 | AB_path = os.path.join(wc_dir, 'A', 'B') |
---|
284 | lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda') |
---|
285 | rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho') |
---|
286 | pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi') |
---|
287 | omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega') |
---|
288 | psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi') |
---|
289 | svntest.main.file_append(lambda_path, 'new appended text for lambda') |
---|
290 | svntest.main.file_append(rho_path, 'new appended text for rho') |
---|
291 | svntest.main.file_append(pi_path, 'new appended text for pi') |
---|
292 | svntest.main.file_append(omega_path, 'new appended text for omega') |
---|
293 | svntest.main.file_append(psi_path, 'new appended text for psi') |
---|
294 | |
---|
295 | # Just for kicks, add a property to A/D/G as well. We'll make sure |
---|
296 | # that it *doesn't* get committed. |
---|
297 | ADG_path = os.path.join(wc_dir, 'A', 'D', 'G') |
---|
298 | svntest.main.run_svn(None, 'propset', 'foo', 'bar', ADG_path) |
---|
299 | |
---|
300 | # Created expected output tree for 'svn ci'. We should see changes |
---|
301 | # only on these three targets, no others. |
---|
302 | expected_output = svntest.wc.State(wc_dir, { |
---|
303 | 'A/D/H/psi' : Item(verb='Sending'), |
---|
304 | 'A/B/lambda' : Item(verb='Sending'), |
---|
305 | 'A/D/H/omega' : Item(verb='Sending'), |
---|
306 | 'A/D/G/pi' : Item(verb='Sending'), |
---|
307 | }) |
---|
308 | |
---|
309 | # Create expected status tree; all local revisions should be at 1, |
---|
310 | # but our four targets should be at 2. |
---|
311 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
312 | expected_status.tweak('A/D/H/psi', 'A/B/lambda', 'A/D/G/pi', 'A/D/H/omega', |
---|
313 | wc_rev=2) |
---|
314 | |
---|
315 | # rho should still display as locally modified: |
---|
316 | expected_status.tweak('A/D/G/rho', status='M ') |
---|
317 | |
---|
318 | # A/D/G should still have a local property set, too. |
---|
319 | expected_status.tweak('A/D/G', status=' M') |
---|
320 | |
---|
321 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
322 | expected_output, |
---|
323 | expected_status, |
---|
324 | None, |
---|
325 | psi_path, AB_path, |
---|
326 | omega_path, pi_path) |
---|
327 | |
---|
328 | #---------------------------------------------------------------------- |
---|
329 | |
---|
330 | def commit_inclusive_dir(sbox): |
---|
331 | "commit wc_dir/A/D -- includes D. (anchor=A, tgt=D)" |
---|
332 | |
---|
333 | sbox.build() |
---|
334 | wc_dir = sbox.wc_dir |
---|
335 | |
---|
336 | expected_status = make_standard_slew_of_changes(wc_dir) |
---|
337 | |
---|
338 | D_path = os.path.join(wc_dir, 'A', 'D') |
---|
339 | |
---|
340 | # Create expected state. |
---|
341 | expected_output = svntest.wc.State(wc_dir, { |
---|
342 | 'A/D' : Item(verb='Sending'), |
---|
343 | 'A/D/G/pi' : Item(verb='Sending'), |
---|
344 | 'A/D/G/rho' : Item(verb='Deleting'), |
---|
345 | 'A/D/H/gloo' : Item(verb='Adding'), |
---|
346 | 'A/D/H/chi' : Item(verb='Replacing'), |
---|
347 | 'A/D/H/omega' : Item(verb='Sending'), |
---|
348 | 'A/D/gamma' : Item(verb='Deleting'), |
---|
349 | }) |
---|
350 | |
---|
351 | expected_status.remove('A/D/G/rho', 'A/D/gamma') |
---|
352 | expected_status.tweak('A/D', 'A/D/G/pi', 'A/D/H/omega', |
---|
353 | wc_rev=2, status=' ') |
---|
354 | expected_status.tweak('A/D/H/chi', 'A/D/H/gloo', wc_rev=2, status=' ') |
---|
355 | |
---|
356 | # Commit the one file. |
---|
357 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
358 | expected_output, |
---|
359 | expected_status, |
---|
360 | None, |
---|
361 | D_path) |
---|
362 | |
---|
363 | #---------------------------------------------------------------------- |
---|
364 | |
---|
365 | def commit_top_dir(sbox): |
---|
366 | "commit wc_dir -- (anchor=wc_dir, tgt={})" |
---|
367 | |
---|
368 | sbox.build() |
---|
369 | wc_dir = sbox.wc_dir |
---|
370 | |
---|
371 | expected_status = make_standard_slew_of_changes(wc_dir) |
---|
372 | |
---|
373 | # Create expected state. |
---|
374 | expected_output = svntest.wc.State(wc_dir, { |
---|
375 | '' : Item(verb='Sending'), |
---|
376 | 'Q' : Item(verb='Adding'), |
---|
377 | 'Q/floo' : Item(verb='Adding'), |
---|
378 | 'A/B/E' : Item(verb='Replacing'), |
---|
379 | 'A/B/E/bloo' : Item(verb='Adding'), |
---|
380 | 'A/B/lambda' : Item(verb='Sending'), |
---|
381 | 'A/C' : Item(verb='Deleting'), |
---|
382 | 'A/D' : Item(verb='Sending'), |
---|
383 | 'A/D/G/pi' : Item(verb='Sending'), |
---|
384 | 'A/D/G/rho' : Item(verb='Deleting'), |
---|
385 | 'A/D/H/gloo' : Item(verb='Adding'), |
---|
386 | 'A/D/H/chi' : Item(verb='Replacing'), |
---|
387 | 'A/D/H/omega' : Item(verb='Sending'), |
---|
388 | 'A/D/gamma' : Item(verb='Deleting'), |
---|
389 | }) |
---|
390 | |
---|
391 | expected_status.remove('A/D/G/rho', 'A/D/gamma', 'A/C', |
---|
392 | 'A/B/E/alpha', 'A/B/E/beta') |
---|
393 | expected_status.tweak('A/D', 'A/D/G/pi', 'A/D/H/omega', 'Q/floo', '', |
---|
394 | wc_rev=2, status=' ') |
---|
395 | expected_status.tweak('A/D/H/chi', 'Q', 'A/B/E', 'A/B/E/bloo', 'A/B/lambda', |
---|
396 | 'A/D/H/gloo', wc_rev=2, status=' ') |
---|
397 | |
---|
398 | # Commit the one file. |
---|
399 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
400 | expected_output, |
---|
401 | expected_status, |
---|
402 | None, |
---|
403 | wc_dir) |
---|
404 | |
---|
405 | #---------------------------------------------------------------------- |
---|
406 | |
---|
407 | # Regression test for bug reported by Jon Trowbridge: |
---|
408 | # |
---|
409 | # From: Jon Trowbridge <trow@ximian.com> |
---|
410 | # Subject: svn segfaults if you commit a file that hasn't been added |
---|
411 | # To: dev@subversion.tigris.org |
---|
412 | # Date: 17 Jul 2001 03:20:55 -0500 |
---|
413 | # Message-Id: <995358055.16975.5.camel@morimoto> |
---|
414 | # |
---|
415 | # The problem is that report_single_mod in libsvn_wc/adm_crawler.c is |
---|
416 | # called with its entry parameter as NULL, but the code doesn't |
---|
417 | # check that entry is non-NULL before trying to dereference it. |
---|
418 | # |
---|
419 | # This bug never had an issue number. |
---|
420 | # |
---|
421 | def commit_unversioned_thing(sbox): |
---|
422 | "committing unversioned object produces error" |
---|
423 | |
---|
424 | sbox.build() |
---|
425 | wc_dir = sbox.wc_dir |
---|
426 | |
---|
427 | # Create an unversioned file in the wc. |
---|
428 | svntest.main.file_append(os.path.join(wc_dir, 'blorg'), "nothing to see") |
---|
429 | |
---|
430 | # Commit a non-existent file and *expect* failure: |
---|
431 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
432 | None, |
---|
433 | None, |
---|
434 | "is not under version control", |
---|
435 | os.path.join(wc_dir,'blorg')) |
---|
436 | |
---|
437 | #---------------------------------------------------------------------- |
---|
438 | |
---|
439 | # regression test for bug #391 |
---|
440 | |
---|
441 | def nested_dir_replacements(sbox): |
---|
442 | "replace two nested dirs, verify empty contents" |
---|
443 | |
---|
444 | sbox.build() |
---|
445 | wc_dir = sbox.wc_dir |
---|
446 | |
---|
447 | # Delete and re-add A/D (a replacement), and A/D/H (another replace). |
---|
448 | svntest.main.run_svn(None, 'rm', os.path.join(wc_dir, 'A', 'D')) |
---|
449 | svntest.main.run_svn(None, 'add', '--depth=empty', |
---|
450 | os.path.join(wc_dir, 'A', 'D')) |
---|
451 | svntest.main.run_svn(None, 'add', '--depth=empty', |
---|
452 | os.path.join(wc_dir, 'A', 'D', 'H')) |
---|
453 | |
---|
454 | # For kicks, add new file A/D/bloo. |
---|
455 | svntest.main.file_append(os.path.join(wc_dir, 'A', 'D', 'bloo'), "hi") |
---|
456 | svntest.main.run_svn(None, 'add', os.path.join(wc_dir, 'A', 'D', 'bloo')) |
---|
457 | |
---|
458 | # Verify pre-commit status: |
---|
459 | # |
---|
460 | # - A/D and A/D/H should both be scheduled as "R" at rev 1 |
---|
461 | # (rev 1 because they both existed before at rev 1) |
---|
462 | # |
---|
463 | # - A/D/bloo scheduled as "A" at rev 0 |
---|
464 | # (rev 0 because it did not exist before) |
---|
465 | # |
---|
466 | # - ALL other children of A/D scheduled as "D" at rev 1 |
---|
467 | |
---|
468 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
469 | expected_status.tweak('A/D', 'A/D/H', status='R ', wc_rev=1) |
---|
470 | expected_status.add({ |
---|
471 | 'A/D/bloo' : Item(status='A ', wc_rev=0), |
---|
472 | }) |
---|
473 | expected_status.tweak('A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', |
---|
474 | 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi', 'A/D/gamma', |
---|
475 | status='D ') |
---|
476 | |
---|
477 | svntest.actions.run_and_verify_status(wc_dir, expected_status) |
---|
478 | |
---|
479 | # Build expected post-commit trees: |
---|
480 | |
---|
481 | # Create expected output tree. |
---|
482 | expected_output = svntest.wc.State(wc_dir, { |
---|
483 | 'A/D' : Item(verb='Replacing'), |
---|
484 | 'A/D/H' : Item(verb='Adding'), |
---|
485 | 'A/D/bloo' : Item(verb='Adding'), |
---|
486 | }) |
---|
487 | |
---|
488 | # Created expected status tree. |
---|
489 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
490 | expected_status.tweak('A/D', 'A/D/H', wc_rev=2) |
---|
491 | expected_status.add({ |
---|
492 | 'A/D/bloo' : Item(status=' ', wc_rev=2), |
---|
493 | }) |
---|
494 | expected_status.remove('A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', |
---|
495 | 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi', 'A/D/gamma') |
---|
496 | |
---|
497 | # Commit from the top of the working copy and verify output & status. |
---|
498 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
499 | expected_output, |
---|
500 | expected_status, |
---|
501 | None, |
---|
502 | wc_dir) |
---|
503 | |
---|
504 | #---------------------------------------------------------------------- |
---|
505 | |
---|
506 | # Testing part 1 of the "Greg Hudson" problem -- specifically, that |
---|
507 | # our use of the "existence=deleted" flag is working properly in cases |
---|
508 | # where the parent directory's revision lags behind a deleted child's |
---|
509 | # revision. |
---|
510 | |
---|
511 | def hudson_part_1(sbox): |
---|
512 | "hudson prob 1.0: delete file, commit, update" |
---|
513 | |
---|
514 | sbox.build() |
---|
515 | wc_dir = sbox.wc_dir |
---|
516 | |
---|
517 | # Remove gamma from the working copy. |
---|
518 | gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma') |
---|
519 | svntest.main.run_svn(None, 'rm', gamma_path) |
---|
520 | |
---|
521 | # Create expected commit output. |
---|
522 | expected_output = svntest.wc.State(wc_dir, { |
---|
523 | 'A/D/gamma' : Item(verb='Deleting'), |
---|
524 | }) |
---|
525 | |
---|
526 | # After committing, status should show no sign of gamma. |
---|
527 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
528 | expected_status.remove('A/D/gamma') |
---|
529 | |
---|
530 | # Commit the deletion of gamma and verify. |
---|
531 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
532 | expected_output, |
---|
533 | expected_status, |
---|
534 | None, wc_dir) |
---|
535 | |
---|
536 | # Now gamma should be marked as `deleted' under the hood. When we |
---|
537 | # update, we should no output, and a perfect, virginal status list |
---|
538 | # at revision 2. (The `deleted' entry should be removed.) |
---|
539 | |
---|
540 | # Expected output of update: nothing. |
---|
541 | expected_output = svntest.wc.State(wc_dir, {}) |
---|
542 | |
---|
543 | # Expected disk tree: everything but gamma |
---|
544 | expected_disk = svntest.main.greek_state.copy() |
---|
545 | expected_disk.remove('A/D/gamma') |
---|
546 | |
---|
547 | # Expected status after update: totally clean revision 2, minus gamma. |
---|
548 | expected_status = svntest.actions.get_virginal_state(wc_dir, 2) |
---|
549 | expected_status.remove('A/D/gamma') |
---|
550 | |
---|
551 | svntest.actions.run_and_verify_update(wc_dir, |
---|
552 | expected_output, |
---|
553 | expected_disk, |
---|
554 | expected_status) |
---|
555 | |
---|
556 | |
---|
557 | #---------------------------------------------------------------------- |
---|
558 | |
---|
559 | # Testing part 1 of the "Greg Hudson" problem -- variation on previous |
---|
560 | # test, removing a directory instead of a file this time. |
---|
561 | |
---|
562 | def hudson_part_1_variation_1(sbox): |
---|
563 | "hudson prob 1.1: delete dir, commit, update" |
---|
564 | |
---|
565 | sbox.build() |
---|
566 | wc_dir = sbox.wc_dir |
---|
567 | |
---|
568 | # Remove H from the working copy. |
---|
569 | H_path = os.path.join(wc_dir, 'A', 'D', 'H') |
---|
570 | svntest.main.run_svn(None, 'rm', H_path) |
---|
571 | |
---|
572 | # Create expected commit output. |
---|
573 | expected_output = svntest.wc.State(wc_dir, { |
---|
574 | 'A/D/H' : Item(verb='Deleting'), |
---|
575 | }) |
---|
576 | |
---|
577 | # After committing, status should show no sign of H or its contents |
---|
578 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
579 | expected_status.remove('A/D/H', 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi') |
---|
580 | |
---|
581 | # Commit the deletion of H and verify. |
---|
582 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
583 | expected_output, |
---|
584 | expected_status, |
---|
585 | None, wc_dir) |
---|
586 | |
---|
587 | # Now H should be marked as `deleted' under the hood. When we |
---|
588 | # update, we should no see output, and a perfect, virginal status |
---|
589 | # list at revision 2. (The `deleted' entry should be removed.) |
---|
590 | |
---|
591 | # Expected output of update: H gets a no-op deletion. |
---|
592 | expected_output = svntest.wc.State(wc_dir, {}) |
---|
593 | |
---|
594 | # Expected disk tree: everything except files in H |
---|
595 | expected_disk = svntest.main.greek_state.copy() |
---|
596 | expected_disk.remove('A/D/H', 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi') |
---|
597 | |
---|
598 | # Expected status after update: totally clean revision 2, minus H. |
---|
599 | expected_status = svntest.actions.get_virginal_state(wc_dir, 2) |
---|
600 | expected_status.remove('A/D/H', 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi') |
---|
601 | |
---|
602 | svntest.actions.run_and_verify_update(wc_dir, |
---|
603 | expected_output, |
---|
604 | expected_disk, |
---|
605 | expected_status) |
---|
606 | |
---|
607 | #---------------------------------------------------------------------- |
---|
608 | |
---|
609 | # Testing part 1 of the "Greg Hudson" problem -- variation 2. In this |
---|
610 | # test, we make sure that a file that is BOTH `deleted' and scheduled |
---|
611 | # for addition can be correctly committed & merged. |
---|
612 | |
---|
613 | def hudson_part_1_variation_2(sbox): |
---|
614 | "hudson prob 1.2: delete, commit, re-add, commit" |
---|
615 | |
---|
616 | sbox.build() |
---|
617 | wc_dir = sbox.wc_dir |
---|
618 | |
---|
619 | # Remove gamma from the working copy. |
---|
620 | gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma') |
---|
621 | svntest.main.run_svn(None, 'rm', gamma_path) |
---|
622 | |
---|
623 | # Create expected commit output. |
---|
624 | expected_output = svntest.wc.State(wc_dir, { |
---|
625 | 'A/D/gamma' : Item(verb='Deleting'), |
---|
626 | }) |
---|
627 | |
---|
628 | # After committing, status should show no sign of gamma. |
---|
629 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
630 | expected_status.remove('A/D/gamma') |
---|
631 | |
---|
632 | # Commit the deletion of gamma and verify. |
---|
633 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
634 | expected_output, |
---|
635 | expected_status, |
---|
636 | None, wc_dir) |
---|
637 | |
---|
638 | # Now gamma should be marked as `deleted' under the hood. |
---|
639 | # Go ahead and re-add gamma, so that is *also* scheduled for addition. |
---|
640 | svntest.main.file_append(gamma_path, "added gamma") |
---|
641 | svntest.main.run_svn(None, 'add', gamma_path) |
---|
642 | |
---|
643 | # For sanity, examine status: it should show a revision 2 tree with |
---|
644 | # gamma scheduled for addition. |
---|
645 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
646 | expected_status.tweak('A/D/gamma', wc_rev=0, status='A ') |
---|
647 | |
---|
648 | svntest.actions.run_and_verify_status(wc_dir, expected_status) |
---|
649 | |
---|
650 | # Create expected commit output. |
---|
651 | expected_output = svntest.wc.State(wc_dir, { |
---|
652 | 'A/D/gamma' : Item(verb='Adding'), |
---|
653 | }) |
---|
654 | |
---|
655 | # After committing, status should show only gamma at revision 3. |
---|
656 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
657 | expected_status.tweak('A/D/gamma', wc_rev=3) |
---|
658 | |
---|
659 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
660 | expected_output, |
---|
661 | expected_status, |
---|
662 | None, wc_dir) |
---|
663 | |
---|
664 | |
---|
665 | #---------------------------------------------------------------------- |
---|
666 | |
---|
667 | # Testing part 2 of the "Greg Hudson" problem. |
---|
668 | # |
---|
669 | # In this test, we make sure that we're UNABLE to commit a propchange |
---|
670 | # on an out-of-date directory. |
---|
671 | |
---|
672 | def hudson_part_2(sbox): |
---|
673 | "hudson prob 2.0: prop commit on old dir fails" |
---|
674 | |
---|
675 | sbox.build() |
---|
676 | wc_dir = sbox.wc_dir |
---|
677 | |
---|
678 | # Remove gamma from the working copy. |
---|
679 | D_path = os.path.join(wc_dir, 'A', 'D') |
---|
680 | gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma') |
---|
681 | svntest.main.run_svn(None, 'rm', gamma_path) |
---|
682 | |
---|
683 | # Create expected commit output. |
---|
684 | expected_output = svntest.wc.State(wc_dir, { |
---|
685 | 'A/D/gamma' : Item(verb='Deleting'), |
---|
686 | }) |
---|
687 | |
---|
688 | # After committing, status should show no sign of gamma. |
---|
689 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
690 | expected_status.remove('A/D/gamma') |
---|
691 | |
---|
692 | # Commit the deletion of gamma and verify. |
---|
693 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
694 | expected_output, |
---|
695 | expected_status, |
---|
696 | None, wc_dir) |
---|
697 | |
---|
698 | # Now gamma should be marked as `deleted' under the hood, at |
---|
699 | # revision 2. Meanwhile, A/D is still lagging at revision 1. |
---|
700 | |
---|
701 | # Make a propchange on A/D |
---|
702 | svntest.main.run_svn(None, 'ps', 'foo', 'bar', D_path) |
---|
703 | |
---|
704 | # Commit and *expect* a repository Merge failure: |
---|
705 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
706 | None, |
---|
707 | None, |
---|
708 | "[Oo]ut.of.date", |
---|
709 | wc_dir) |
---|
710 | |
---|
711 | #---------------------------------------------------------------------- |
---|
712 | |
---|
713 | # Test a possible regression in our 'deleted' post-commit handling. |
---|
714 | # |
---|
715 | # This test moves files from one subdir to another, commits, then |
---|
716 | # updates the empty directory. Nothing should be printed, assuming |
---|
717 | # all the moved files are properly marked as 'deleted' and reported to |
---|
718 | # the server. |
---|
719 | |
---|
720 | def hudson_part_2_1(sbox): |
---|
721 | "hudson prob 2.1: move files, update empty dir" |
---|
722 | |
---|
723 | sbox.build() |
---|
724 | wc_dir = sbox.wc_dir |
---|
725 | |
---|
726 | # Move all the files in H to G |
---|
727 | H_path = os.path.join(wc_dir, 'A', 'D', 'H') |
---|
728 | G_path = os.path.join(wc_dir, 'A', 'D', 'G') |
---|
729 | chi_path = os.path.join(H_path, 'chi') |
---|
730 | psi_path = os.path.join(H_path, 'psi') |
---|
731 | omega_path = os.path.join(H_path, 'omega') |
---|
732 | |
---|
733 | svntest.main.run_svn(None, 'mv', chi_path, G_path) |
---|
734 | svntest.main.run_svn(None, 'mv', psi_path, G_path) |
---|
735 | svntest.main.run_svn(None, 'mv', omega_path, G_path) |
---|
736 | |
---|
737 | # Create expected commit output. |
---|
738 | expected_output = svntest.wc.State(wc_dir, { |
---|
739 | 'A/D/H/chi' : Item(verb='Deleting'), |
---|
740 | 'A/D/H/omega' : Item(verb='Deleting'), |
---|
741 | 'A/D/H/psi' : Item(verb='Deleting'), |
---|
742 | 'A/D/G/chi' : Item(verb='Adding'), |
---|
743 | 'A/D/G/omega' : Item(verb='Adding'), |
---|
744 | 'A/D/G/psi' : Item(verb='Adding'), |
---|
745 | }) |
---|
746 | |
---|
747 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
748 | expected_status.remove('A/D/H/chi') |
---|
749 | expected_status.remove('A/D/H/omega') |
---|
750 | expected_status.remove('A/D/H/psi') |
---|
751 | expected_status.add({ 'A/D/G/chi' : |
---|
752 | Item(wc_rev=2, status=' ') }) |
---|
753 | expected_status.add({ 'A/D/G/omega' : |
---|
754 | Item(wc_rev=2, status=' ') }) |
---|
755 | expected_status.add({ 'A/D/G/psi' : |
---|
756 | Item(wc_rev=2, status=' ') }) |
---|
757 | |
---|
758 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
759 | expected_output, |
---|
760 | expected_status, |
---|
761 | None, wc_dir) |
---|
762 | |
---|
763 | # Now, assuming all three files in H are marked as 'deleted', an |
---|
764 | # update of H should print absolutely nothing. |
---|
765 | expected_output = svntest.wc.State(wc_dir, { }) |
---|
766 | |
---|
767 | # Reuse expected_status |
---|
768 | expected_status.tweak(wc_rev=2) |
---|
769 | |
---|
770 | expected_disk = svntest.main.greek_state.copy() |
---|
771 | expected_disk.remove('A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi') |
---|
772 | expected_disk.add({ |
---|
773 | 'A/D/G/chi' : Item("This is the file 'chi'.\n"), |
---|
774 | }) |
---|
775 | expected_disk.add({ |
---|
776 | 'A/D/G/omega' : Item("This is the file 'omega'.\n"), |
---|
777 | }) |
---|
778 | expected_disk.add({ |
---|
779 | 'A/D/G/psi' : Item("This is the file 'psi'.\n"), |
---|
780 | }) |
---|
781 | |
---|
782 | svntest.actions.run_and_verify_update(wc_dir, |
---|
783 | expected_output, |
---|
784 | expected_disk, |
---|
785 | expected_status) |
---|
786 | |
---|
787 | #---------------------------------------------------------------------- |
---|
788 | |
---|
789 | def hook_test(sbox): |
---|
790 | "hook testing" |
---|
791 | |
---|
792 | sbox.build() |
---|
793 | |
---|
794 | # Get paths to the working copy and repository |
---|
795 | wc_dir = sbox.wc_dir |
---|
796 | repo_dir = sbox.repo_dir |
---|
797 | |
---|
798 | # Create a hook that appends its name to a log file. |
---|
799 | hook_format = """import sys |
---|
800 | fp = open(sys.argv[1] + '/hooks.log', 'a') |
---|
801 | fp.write("%s\\n") |
---|
802 | fp.close()""" |
---|
803 | |
---|
804 | # Setup the hook configs to log data to a file |
---|
805 | start_commit_hook = svntest.main.get_start_commit_hook_path(repo_dir) |
---|
806 | svntest.main.create_python_hook_script(start_commit_hook, |
---|
807 | hook_format % "start_commit_hook") |
---|
808 | |
---|
809 | pre_commit_hook = svntest.main.get_pre_commit_hook_path(repo_dir) |
---|
810 | svntest.main.create_python_hook_script(pre_commit_hook, |
---|
811 | hook_format % "pre_commit_hook") |
---|
812 | |
---|
813 | post_commit_hook = svntest.main.get_post_commit_hook_path(repo_dir) |
---|
814 | svntest.main.create_python_hook_script(post_commit_hook, |
---|
815 | hook_format % "post_commit_hook") |
---|
816 | |
---|
817 | # Modify iota just so there is something to commit. |
---|
818 | iota_path = os.path.join(wc_dir, "iota") |
---|
819 | svntest.main.file_append(iota_path, "More stuff in iota") |
---|
820 | |
---|
821 | # Commit, no output expected. |
---|
822 | svntest.actions.run_and_verify_svn(None, [], [], |
---|
823 | 'ci', '--quiet', |
---|
824 | '-m', 'log msg', wc_dir) |
---|
825 | |
---|
826 | # Now check the logfile |
---|
827 | expected_data = [ 'start_commit_hook\n', 'pre_commit_hook\n', 'post_commit_hook\n' ] |
---|
828 | |
---|
829 | logfilename = os.path.join(repo_dir, "hooks.log") |
---|
830 | if os.path.exists(logfilename): |
---|
831 | fp = open(logfilename) |
---|
832 | else: |
---|
833 | raise svntest.verify.SVNUnexpectedOutput("hook logfile %s not found")\ |
---|
834 | % logfilename |
---|
835 | |
---|
836 | actual_data = fp.readlines() |
---|
837 | fp.close() |
---|
838 | os.unlink(logfilename) |
---|
839 | svntest.verify.compare_and_display_lines('wrong hook logfile content', |
---|
840 | 'STDERR', |
---|
841 | expected_data, actual_data) |
---|
842 | |
---|
843 | #---------------------------------------------------------------------- |
---|
844 | |
---|
845 | # Regression test for bug #469, whereby merge() was once reporting |
---|
846 | # erroneous conflicts due to Ancestor < Target < Source, in terms of |
---|
847 | # node-rev-id parentage. |
---|
848 | |
---|
849 | def merge_mixed_revisions(sbox): |
---|
850 | "commit mixed-rev wc (no erroneous merge error)" |
---|
851 | |
---|
852 | sbox.build() |
---|
853 | wc_dir = sbox.wc_dir |
---|
854 | |
---|
855 | # Make some convenient paths. |
---|
856 | iota_path = os.path.join(wc_dir, 'iota') |
---|
857 | H_path = os.path.join(wc_dir, 'A', 'D', 'H') |
---|
858 | chi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'chi') |
---|
859 | omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega') |
---|
860 | |
---|
861 | # Here's the reproduction formula, in 5 parts. |
---|
862 | # Hoo, what a buildup of state! |
---|
863 | |
---|
864 | # 1. echo "moo" >> iota; echo "moo" >> A/D/H/chi; svn ci |
---|
865 | svntest.main.file_append(iota_path, "moo") |
---|
866 | svntest.main.file_append(chi_path, "moo") |
---|
867 | |
---|
868 | expected_output = svntest.wc.State(wc_dir, { |
---|
869 | 'iota' : Item(verb='Sending'), |
---|
870 | 'A/D/H/chi' : Item(verb='Sending'), |
---|
871 | }) |
---|
872 | |
---|
873 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
874 | expected_status.tweak('iota', 'A/D/H/chi', wc_rev=2) |
---|
875 | |
---|
876 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
877 | expected_output, |
---|
878 | expected_status, |
---|
879 | None, wc_dir) |
---|
880 | |
---|
881 | |
---|
882 | # 2. svn up A/D/H |
---|
883 | expected_status = svntest.wc.State(wc_dir, { |
---|
884 | 'A/D/H' : Item(status=' ', wc_rev=2), |
---|
885 | 'A/D/H/chi' : Item(status=' ', wc_rev=2), |
---|
886 | 'A/D/H/omega' : Item(status=' ', wc_rev=2), |
---|
887 | 'A/D/H/psi' : Item(status=' ', wc_rev=2), |
---|
888 | }) |
---|
889 | expected_disk = svntest.wc.State('', { |
---|
890 | 'omega' : Item("This is the file 'omega'.\n"), |
---|
891 | 'chi' : Item("This is the file 'chi'.\nmoo"), |
---|
892 | 'psi' : Item("This is the file 'psi'.\n"), |
---|
893 | }) |
---|
894 | expected_output = svntest.wc.State(wc_dir, { }) |
---|
895 | svntest.actions.run_and_verify_update(H_path, |
---|
896 | expected_output, |
---|
897 | expected_disk, |
---|
898 | expected_status) |
---|
899 | |
---|
900 | |
---|
901 | # 3. echo "moo" >> iota; svn ci iota |
---|
902 | svntest.main.file_append(iota_path, "moo2") |
---|
903 | expected_output = svntest.wc.State(wc_dir, { |
---|
904 | 'iota' : Item(verb='Sending'), |
---|
905 | }) |
---|
906 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
907 | expected_status.tweak('A/D/H', 'A/D/H/omega', 'A/D/H/chi', 'A/D/H/psi', |
---|
908 | wc_rev=2) |
---|
909 | expected_status.tweak('iota', wc_rev=3) |
---|
910 | |
---|
911 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
912 | expected_output, |
---|
913 | expected_status, |
---|
914 | None, wc_dir) |
---|
915 | |
---|
916 | |
---|
917 | # 4. echo "moo" >> A/D/H/chi; svn ci A/D/H/chi |
---|
918 | svntest.main.file_append(chi_path, "moo3") |
---|
919 | expected_output = svntest.wc.State(wc_dir, { |
---|
920 | 'A/D/H/chi' : Item(verb='Sending'), |
---|
921 | }) |
---|
922 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
923 | expected_status.tweak('A/D/H/chi', wc_rev=4) |
---|
924 | expected_status.tweak('A/D/H', 'A/D/H/omega', 'A/D/H/psi', wc_rev=2) |
---|
925 | expected_status.tweak('iota', wc_rev=3) |
---|
926 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
927 | expected_output, |
---|
928 | expected_status, |
---|
929 | None, wc_dir) |
---|
930 | |
---|
931 | # 5. echo "moo" >> iota; svn ci iota |
---|
932 | svntest.main.file_append(iota_path, "moomoo") |
---|
933 | expected_output = svntest.wc.State(wc_dir, { |
---|
934 | 'iota' : Item(verb='Sending'), |
---|
935 | }) |
---|
936 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
937 | expected_status.tweak('A/D/H', 'A/D/H/omega', 'A/D/H/psi', wc_rev=2) |
---|
938 | expected_status.tweak('A/D/H/chi', wc_rev=4) |
---|
939 | expected_status.tweak('iota', wc_rev=5) |
---|
940 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
941 | expected_output, |
---|
942 | expected_status, |
---|
943 | None, wc_dir) |
---|
944 | |
---|
945 | # At this point, here is what our tree should look like: |
---|
946 | # _ 1 ( 5) working_copies/commit_tests-10 |
---|
947 | # _ 1 ( 5) working_copies/commit_tests-10/A |
---|
948 | # _ 1 ( 5) working_copies/commit_tests-10/A/B |
---|
949 | # _ 1 ( 5) working_copies/commit_tests-10/A/B/E |
---|
950 | # _ 1 ( 5) working_copies/commit_tests-10/A/B/E/alpha |
---|
951 | # _ 1 ( 5) working_copies/commit_tests-10/A/B/E/beta |
---|
952 | # _ 1 ( 5) working_copies/commit_tests-10/A/B/F |
---|
953 | # _ 1 ( 5) working_copies/commit_tests-10/A/B/lambda |
---|
954 | # _ 1 ( 5) working_copies/commit_tests-10/A/C |
---|
955 | # _ 1 ( 5) working_copies/commit_tests-10/A/D |
---|
956 | # _ 1 ( 5) working_copies/commit_tests-10/A/D/G |
---|
957 | # _ 1 ( 5) working_copies/commit_tests-10/A/D/G/pi |
---|
958 | # _ 1 ( 5) working_copies/commit_tests-10/A/D/G/rho |
---|
959 | # _ 1 ( 5) working_copies/commit_tests-10/A/D/G/tau |
---|
960 | # _ 2 ( 5) working_copies/commit_tests-10/A/D/H |
---|
961 | # _ 4 ( 5) working_copies/commit_tests-10/A/D/H/chi |
---|
962 | # _ 2 ( 5) working_copies/commit_tests-10/A/D/H/omega |
---|
963 | # _ 2 ( 5) working_copies/commit_tests-10/A/D/H/psi |
---|
964 | # _ 1 ( 5) working_copies/commit_tests-10/A/D/gamma |
---|
965 | # _ 1 ( 5) working_copies/commit_tests-10/A/mu |
---|
966 | # _ 5 ( 5) working_copies/commit_tests-10/iota |
---|
967 | |
---|
968 | # At this point, we're ready to modify omega and iota, and commit |
---|
969 | # from the top. We should *not* get a conflict! |
---|
970 | |
---|
971 | svntest.main.file_append(iota_path, "finalmoo") |
---|
972 | svntest.main.file_append(omega_path, "finalmoo") |
---|
973 | |
---|
974 | expected_output = svntest.wc.State(wc_dir, { |
---|
975 | 'iota' : Item(verb='Sending'), |
---|
976 | 'A/D/H/omega' : Item(verb='Sending'), |
---|
977 | }) |
---|
978 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
979 | expected_status.tweak('iota', 'A/D/H/omega', wc_rev=6) |
---|
980 | expected_status.tweak('A/D/H', 'A/D/H/psi', wc_rev=2) |
---|
981 | expected_status.tweak('A/D/H/chi', wc_rev=4) |
---|
982 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
983 | expected_output, |
---|
984 | expected_status, |
---|
985 | None, wc_dir) |
---|
986 | |
---|
987 | #---------------------------------------------------------------------- |
---|
988 | |
---|
989 | def commit_uri_unsafe(sbox): |
---|
990 | "commit files and dirs with URI-unsafe characters" |
---|
991 | |
---|
992 | sbox.build() |
---|
993 | wc_dir = sbox.wc_dir |
---|
994 | |
---|
995 | # Note: on Windows, files can't have angle brackets in them, so we |
---|
996 | # don't tests that case. |
---|
997 | if svntest.main.windows or sys.platform == 'cygwin': |
---|
998 | angle_name = '_angle_' |
---|
999 | nasty_name = '#![]{}()__%' |
---|
1000 | else: |
---|
1001 | angle_name = '<angle>' |
---|
1002 | nasty_name = '#![]{}()<>%' |
---|
1003 | |
---|
1004 | # Make some convenient paths. |
---|
1005 | hash_dir = os.path.join(wc_dir, '#hash#') |
---|
1006 | nasty_dir = os.path.join(wc_dir, nasty_name) |
---|
1007 | space_path = os.path.join(wc_dir, 'A', 'D', 'space path') |
---|
1008 | bang_path = os.path.join(wc_dir, 'A', 'D', 'H', 'bang!') |
---|
1009 | bracket_path = os.path.join(wc_dir, 'A', 'D', 'H', 'bra[ket') |
---|
1010 | brace_path = os.path.join(wc_dir, 'A', 'D', 'H', 'bra{e') |
---|
1011 | angle_path = os.path.join(wc_dir, 'A', 'D', 'H', angle_name) |
---|
1012 | paren_path = os.path.join(wc_dir, 'A', 'D', 'pare)(theses') |
---|
1013 | percent_path = os.path.join(wc_dir, '#hash#', 'percen%') |
---|
1014 | nasty_path = os.path.join(wc_dir, 'A', nasty_name) |
---|
1015 | |
---|
1016 | os.mkdir(hash_dir) |
---|
1017 | os.mkdir(nasty_dir) |
---|
1018 | svntest.main.file_append(space_path, "This path has a space in it.") |
---|
1019 | svntest.main.file_append(bang_path, "This path has a bang in it.") |
---|
1020 | svntest.main.file_append(bracket_path, "This path has a bracket in it.") |
---|
1021 | svntest.main.file_append(brace_path, "This path has a brace in it.") |
---|
1022 | svntest.main.file_append(angle_path, "This path has angle brackets in it.") |
---|
1023 | svntest.main.file_append(paren_path, "This path has parentheses in it.") |
---|
1024 | svntest.main.file_append(percent_path, "This path has a percent in it.") |
---|
1025 | svntest.main.file_append(nasty_path, "This path has all sorts of ick in it.") |
---|
1026 | |
---|
1027 | add_list = [hash_dir, |
---|
1028 | nasty_dir, # not xml-safe |
---|
1029 | space_path, |
---|
1030 | bang_path, |
---|
1031 | bracket_path, |
---|
1032 | brace_path, |
---|
1033 | angle_path, # not xml-safe |
---|
1034 | paren_path, |
---|
1035 | percent_path, |
---|
1036 | nasty_path, # not xml-safe |
---|
1037 | ] |
---|
1038 | for item in add_list: |
---|
1039 | svntest.main.run_svn(None, 'add', '--depth=empty', item) |
---|
1040 | |
---|
1041 | expected_output = svntest.wc.State(wc_dir, { |
---|
1042 | '#hash#' : Item(verb='Adding'), |
---|
1043 | nasty_name : Item(verb='Adding'), |
---|
1044 | 'A/D/space path' : Item(verb='Adding'), |
---|
1045 | 'A/D/H/bang!' : Item(verb='Adding'), |
---|
1046 | 'A/D/H/bra[ket' : Item(verb='Adding'), |
---|
1047 | 'A/D/H/bra{e' : Item(verb='Adding'), |
---|
1048 | 'A/D/H/' + angle_name : Item(verb='Adding'), |
---|
1049 | 'A/D/pare)(theses' : Item(verb='Adding'), |
---|
1050 | '#hash#/percen%' : Item(verb='Adding'), |
---|
1051 | 'A/' + nasty_name : Item(verb='Adding'), |
---|
1052 | }) |
---|
1053 | |
---|
1054 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
1055 | |
---|
1056 | # Items in our add list will be at rev 2 |
---|
1057 | for item in expected_output.desc.keys(): |
---|
1058 | expected_status.add({ item : Item(wc_rev=2, status=' ') }) |
---|
1059 | |
---|
1060 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1061 | expected_output, |
---|
1062 | expected_status, |
---|
1063 | None, wc_dir) |
---|
1064 | |
---|
1065 | |
---|
1066 | #---------------------------------------------------------------------- |
---|
1067 | |
---|
1068 | def commit_deleted_edited(sbox): |
---|
1069 | "commit deleted yet edited files" |
---|
1070 | |
---|
1071 | sbox.build() |
---|
1072 | wc_dir = sbox.wc_dir |
---|
1073 | |
---|
1074 | # Make some convenient paths. |
---|
1075 | iota_path = os.path.join(wc_dir, 'iota') |
---|
1076 | mu_path = os.path.join(wc_dir, 'A', 'mu') |
---|
1077 | |
---|
1078 | # Edit the files. |
---|
1079 | svntest.main.file_append(iota_path, "This file has been edited.") |
---|
1080 | svntest.main.file_append(mu_path, "This file has been edited.") |
---|
1081 | |
---|
1082 | # Schedule the files for removal. |
---|
1083 | svntest.main.run_svn(None, 'remove', '--force', iota_path) |
---|
1084 | svntest.main.run_svn(None, 'remove', '--force', mu_path) |
---|
1085 | |
---|
1086 | # Make our output list |
---|
1087 | expected_output = svntest.wc.State(wc_dir, { |
---|
1088 | 'iota' : Item(verb='Deleting'), |
---|
1089 | 'A/mu' : Item(verb='Deleting'), |
---|
1090 | }) |
---|
1091 | |
---|
1092 | # Items in the status list are all at rev 1, except the two things |
---|
1093 | # we changed...but then, they don't exist at all. |
---|
1094 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
1095 | expected_status.remove('iota', 'A/mu') |
---|
1096 | |
---|
1097 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1098 | expected_output, |
---|
1099 | expected_status, |
---|
1100 | None, wc_dir) |
---|
1101 | |
---|
1102 | #---------------------------------------------------------------------- |
---|
1103 | |
---|
1104 | def commit_in_dir_scheduled_for_addition(sbox): |
---|
1105 | "commit a file inside dir scheduled for addition" |
---|
1106 | |
---|
1107 | sbox.build() |
---|
1108 | wc_dir = sbox.wc_dir |
---|
1109 | |
---|
1110 | A_path = os.path.join(wc_dir, 'A') |
---|
1111 | Z_path = os.path.join(wc_dir, 'Z') |
---|
1112 | mu_path = os.path.join(wc_dir, 'Z', 'mu') |
---|
1113 | |
---|
1114 | svntest.main.run_svn(None, 'move', A_path, Z_path) |
---|
1115 | |
---|
1116 | # Commit a copied thing inside an added-with-history directory, |
---|
1117 | # expecting a specific error to occur! |
---|
1118 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1119 | None, |
---|
1120 | None, |
---|
1121 | "unversioned", |
---|
1122 | mu_path) |
---|
1123 | |
---|
1124 | Q_path = os.path.join(wc_dir, 'Q') |
---|
1125 | bloo_path = os.path.join(Q_path, 'bloo') |
---|
1126 | |
---|
1127 | os.mkdir(Q_path) |
---|
1128 | svntest.main.file_append(bloo_path, "New contents.") |
---|
1129 | svntest.main.run_svn(None, 'add', Q_path) |
---|
1130 | |
---|
1131 | # Commit a regular added thing inside an added directory, |
---|
1132 | # expecting a specific error to occur! |
---|
1133 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1134 | None, |
---|
1135 | None, |
---|
1136 | "not under version control", |
---|
1137 | bloo_path) |
---|
1138 | |
---|
1139 | #---------------------------------------------------------------------- |
---|
1140 | |
---|
1141 | # Does this make sense now that deleted files are always removed from the wc? |
---|
1142 | def commit_rmd_and_deleted_file(sbox): |
---|
1143 | "commit deleted (and missing) file" |
---|
1144 | |
---|
1145 | sbox.build() |
---|
1146 | wc_dir = sbox.wc_dir |
---|
1147 | mu_path = os.path.join(wc_dir, 'A', 'mu') |
---|
1148 | |
---|
1149 | # 'svn remove' mu |
---|
1150 | svntest.main.run_svn(None, 'rm', mu_path) |
---|
1151 | |
---|
1152 | # Commit, hoping to see no errors |
---|
1153 | svntest.actions.run_and_verify_svn("Output on stderr where none expected", |
---|
1154 | svntest.verify.AnyOutput, [], |
---|
1155 | 'commit', '-m', 'logmsg', mu_path) |
---|
1156 | |
---|
1157 | #---------------------------------------------------------------------- |
---|
1158 | |
---|
1159 | # Issue #644 which failed over ra_neon. |
---|
1160 | def commit_add_file_twice(sbox): |
---|
1161 | "issue 644 attempt to add a file twice" |
---|
1162 | |
---|
1163 | sbox.build() |
---|
1164 | wc_dir = sbox.wc_dir |
---|
1165 | |
---|
1166 | # Create a file |
---|
1167 | gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo') |
---|
1168 | svntest.main.file_append(gloo_path, "hello") |
---|
1169 | svntest.main.run_svn(None, 'add', gloo_path) |
---|
1170 | |
---|
1171 | # Create expected output tree. |
---|
1172 | expected_output = svntest.wc.State(wc_dir, { |
---|
1173 | 'A/D/H/gloo' : Item(verb='Adding'), |
---|
1174 | }) |
---|
1175 | |
---|
1176 | # Created expected status tree. |
---|
1177 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
1178 | expected_status.add({ |
---|
1179 | 'A/D/H/gloo' : Item(status=' ', wc_rev=2), |
---|
1180 | }) |
---|
1181 | |
---|
1182 | # Commit should succeed |
---|
1183 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1184 | expected_output, |
---|
1185 | expected_status, |
---|
1186 | None, |
---|
1187 | wc_dir) |
---|
1188 | |
---|
1189 | # Update to state before commit |
---|
1190 | svntest.main.run_svn(None, 'up', '-r', '1', wc_dir) |
---|
1191 | |
---|
1192 | # Create the file again |
---|
1193 | svntest.main.file_append(gloo_path, "hello") |
---|
1194 | svntest.main.run_svn(None, 'add', gloo_path) |
---|
1195 | |
---|
1196 | # Commit and *expect* a failure: |
---|
1197 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1198 | None, |
---|
1199 | None, |
---|
1200 | "already exists", |
---|
1201 | wc_dir) |
---|
1202 | |
---|
1203 | #---------------------------------------------------------------------- |
---|
1204 | |
---|
1205 | # There was a problem that committing from a directory that had a |
---|
1206 | # longer name than the working copy directory caused the commit notify |
---|
1207 | # messages to display truncated/random filenames. |
---|
1208 | |
---|
1209 | def commit_from_long_dir(sbox): |
---|
1210 | "commit from a dir with a longer name than the wc" |
---|
1211 | |
---|
1212 | sbox.build() |
---|
1213 | wc_dir = sbox.wc_dir |
---|
1214 | |
---|
1215 | was_dir = os.getcwd() |
---|
1216 | abs_wc_dir = os.path.realpath(os.path.join(was_dir, wc_dir)) |
---|
1217 | |
---|
1218 | # something to commit |
---|
1219 | svntest.main.file_append(os.path.join(wc_dir, 'iota'), "modified iota") |
---|
1220 | |
---|
1221 | # Create expected output tree. |
---|
1222 | expected_output = svntest.wc.State('', { |
---|
1223 | 'iota' : Item(verb='Sending'), |
---|
1224 | }) |
---|
1225 | |
---|
1226 | # Any length name was enough to provoke the original bug, but |
---|
1227 | # keeping its length less than that of the filename 'iota' avoided |
---|
1228 | # random behaviour, but still caused the test to fail |
---|
1229 | extra_name = 'xx' |
---|
1230 | |
---|
1231 | os.chdir(wc_dir) |
---|
1232 | os.mkdir(extra_name) |
---|
1233 | os.chdir(extra_name) |
---|
1234 | |
---|
1235 | svntest.actions.run_and_verify_commit(abs_wc_dir, |
---|
1236 | expected_output, |
---|
1237 | None, |
---|
1238 | None, |
---|
1239 | abs_wc_dir) |
---|
1240 | |
---|
1241 | #---------------------------------------------------------------------- |
---|
1242 | |
---|
1243 | def commit_with_lock(sbox): |
---|
1244 | "try to commit when directory is locked" |
---|
1245 | |
---|
1246 | sbox.build() |
---|
1247 | # modify gamma and lock its directory |
---|
1248 | wc_dir = sbox.wc_dir |
---|
1249 | |
---|
1250 | D_path = os.path.join(wc_dir, 'A', 'D') |
---|
1251 | gamma_path = os.path.join(D_path, 'gamma') |
---|
1252 | svntest.main.file_append(gamma_path, "modified gamma") |
---|
1253 | svntest.actions.lock_admin_dir(D_path) |
---|
1254 | |
---|
1255 | # this commit should fail |
---|
1256 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1257 | None, |
---|
1258 | None, |
---|
1259 | 'svn: Working copy \'.*\' locked', |
---|
1260 | wc_dir) |
---|
1261 | |
---|
1262 | # unlock directory |
---|
1263 | svntest.actions.run_and_verify_svn("Output on stderr where none expected", |
---|
1264 | [], [], |
---|
1265 | 'cleanup', D_path) |
---|
1266 | |
---|
1267 | # this commit should succeed |
---|
1268 | expected_output = svntest.wc.State(wc_dir, { |
---|
1269 | 'A/D/gamma' : Item(verb='Sending'), |
---|
1270 | }) |
---|
1271 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
1272 | expected_status.tweak('A/D/gamma', wc_rev=2) |
---|
1273 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1274 | expected_output, |
---|
1275 | expected_status, |
---|
1276 | None, |
---|
1277 | wc_dir) |
---|
1278 | |
---|
1279 | #---------------------------------------------------------------------- |
---|
1280 | |
---|
1281 | # Explicitly commit the current directory. This did at one point fail |
---|
1282 | # in post-commit processing due to a path canonicalization problem. |
---|
1283 | |
---|
1284 | def commit_current_dir(sbox): |
---|
1285 | "commit the current directory" |
---|
1286 | |
---|
1287 | sbox.build() |
---|
1288 | |
---|
1289 | wc_dir = sbox.wc_dir |
---|
1290 | svntest.main.run_svn(None, 'propset', 'pname', 'pval', wc_dir) |
---|
1291 | |
---|
1292 | was_cwd = os.getcwd() |
---|
1293 | |
---|
1294 | os.chdir(wc_dir) |
---|
1295 | |
---|
1296 | expected_output = svntest.wc.State('.', { |
---|
1297 | '.' : Item(verb='Sending'), |
---|
1298 | }) |
---|
1299 | svntest.actions.run_and_verify_commit('.', |
---|
1300 | expected_output, |
---|
1301 | None, |
---|
1302 | None, |
---|
1303 | '.') |
---|
1304 | os.chdir(was_cwd) |
---|
1305 | |
---|
1306 | # I can't get the status check to work as part of run_and_verify_commit. |
---|
1307 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
1308 | expected_status.tweak('', wc_rev=2, status=' ') |
---|
1309 | svntest.actions.run_and_verify_status(wc_dir, expected_status) |
---|
1310 | |
---|
1311 | #---------------------------------------------------------------------- |
---|
1312 | |
---|
1313 | # Check that the pending txn gets removed from the repository after |
---|
1314 | # a failed commit. |
---|
1315 | |
---|
1316 | def failed_commit(sbox): |
---|
1317 | "commit with conflicts and check txn in repo" |
---|
1318 | |
---|
1319 | sbox.build() |
---|
1320 | wc_dir = sbox.wc_dir |
---|
1321 | |
---|
1322 | # Make the other working copy |
---|
1323 | other_wc_dir = sbox.add_wc_path('other') |
---|
1324 | svntest.actions.duplicate_dir(wc_dir, other_wc_dir) |
---|
1325 | |
---|
1326 | # Make different changes in the two working copies |
---|
1327 | iota_path = os.path.join(wc_dir, "iota") |
---|
1328 | svntest.main.file_append(iota_path, "More stuff in iota") |
---|
1329 | |
---|
1330 | other_iota_path = os.path.join(other_wc_dir, "iota") |
---|
1331 | svntest.main.file_append(other_iota_path, "More different stuff in iota") |
---|
1332 | |
---|
1333 | # Commit both working copies. The second commit should fail. |
---|
1334 | svntest.actions.run_and_verify_svn("Output on stderr where none expected", |
---|
1335 | svntest.verify.AnyOutput, [], |
---|
1336 | 'commit', '-m', 'log', wc_dir) |
---|
1337 | |
---|
1338 | svntest.actions.run_and_verify_svn("Output on stderr expected", |
---|
1339 | None, svntest.verify.AnyOutput, |
---|
1340 | 'commit', '-m', 'log', other_wc_dir) |
---|
1341 | |
---|
1342 | # Now list the txns in the repo. The list should be empty. |
---|
1343 | exit_code, output, errput = svntest.main.run_svnadmin('lstxns', |
---|
1344 | sbox.repo_dir) |
---|
1345 | svntest.verify.compare_and_display_lines( |
---|
1346 | "Error running 'svnadmin lstxns'.", |
---|
1347 | 'STDERR', [], errput) |
---|
1348 | svntest.verify.compare_and_display_lines( |
---|
1349 | "Output of 'svnadmin lstxns' is unexpected.", |
---|
1350 | 'STDOUT', [], output) |
---|
1351 | |
---|
1352 | #---------------------------------------------------------------------- |
---|
1353 | |
---|
1354 | # Commit from multiple working copies is not yet supported. At |
---|
1355 | # present an error is generated and none of the working copies change. |
---|
1356 | # Related to issue 959, this test here doesn't use svn:externals but the |
---|
1357 | # behaviour needs to be considered. |
---|
1358 | |
---|
1359 | def commit_multiple_wc(sbox): |
---|
1360 | "attempted commit from multiple wc fails" |
---|
1361 | |
---|
1362 | sbox.build() |
---|
1363 | wc_dir = sbox.wc_dir |
---|
1364 | |
---|
1365 | # Checkout a second working copy |
---|
1366 | wc2_dir = os.path.join(wc_dir, 'A', 'wc2') |
---|
1367 | url = sbox.repo_url |
---|
1368 | svntest.actions.run_and_verify_svn("Output on stderr where none expected", |
---|
1369 | svntest.verify.AnyOutput, [], |
---|
1370 | 'checkout', |
---|
1371 | url, wc2_dir) |
---|
1372 | |
---|
1373 | # Modify both working copies |
---|
1374 | mu_path = os.path.join(wc_dir, 'A', 'mu') |
---|
1375 | svntest.main.file_append(mu_path, 'appended mu text') |
---|
1376 | lambda2_path = os.path.join(wc2_dir, 'A', 'B', 'lambda') |
---|
1377 | svntest.main.file_append(lambda2_path, 'appended lambda2 text') |
---|
1378 | |
---|
1379 | # Verify modified status |
---|
1380 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
1381 | expected_status.tweak('A/mu', status='M ') |
---|
1382 | svntest.actions.run_and_verify_status(wc_dir, expected_status) |
---|
1383 | expected_status2 = svntest.actions.get_virginal_state(wc2_dir, 1) |
---|
1384 | expected_status2.tweak('A/B/lambda', status='M ') |
---|
1385 | svntest.actions.run_and_verify_status(wc2_dir, expected_status2) |
---|
1386 | |
---|
1387 | # Commit should fail, even though one target is a "child" of the other. |
---|
1388 | svntest.actions.run_and_verify_svn("Unexpectedly not locked", |
---|
1389 | None, svntest.verify.AnyOutput, |
---|
1390 | 'commit', '-m', 'log', |
---|
1391 | wc_dir, wc2_dir) |
---|
1392 | |
---|
1393 | # Verify status unchanged |
---|
1394 | svntest.actions.run_and_verify_status(wc_dir, expected_status) |
---|
1395 | svntest.actions.run_and_verify_status(wc2_dir, expected_status2) |
---|
1396 | |
---|
1397 | |
---|
1398 | def commit_nonrecursive(sbox): |
---|
1399 | "commit named targets with -N (issues #1195, #1239)" |
---|
1400 | |
---|
1401 | sbox.build() |
---|
1402 | wc_dir = sbox.wc_dir |
---|
1403 | |
---|
1404 | ### Note: the original recipes used 'add -N'. These days, we use |
---|
1405 | ### --depth={empty,files}, and both the code and the comments below |
---|
1406 | ### have been adjusted to reflect this. |
---|
1407 | |
---|
1408 | ##################################################### |
---|
1409 | ### Issue #1195: |
---|
1410 | ### |
---|
1411 | ### 1. Create these directories and files: |
---|
1412 | ### |
---|
1413 | ### file1 |
---|
1414 | ### dir1 |
---|
1415 | ### dir1/file2 |
---|
1416 | ### dir1/file3 |
---|
1417 | ### dir1/dir2 |
---|
1418 | ### dir1/dir2/file4 |
---|
1419 | ### |
---|
1420 | ### 2. run 'svn add --depth=empty <all of the above>' |
---|
1421 | ### |
---|
1422 | ### 3. run 'svn ci -N <all of the above>' |
---|
1423 | ### |
---|
1424 | ### (The bug was that only 4 entities would get committed, when it |
---|
1425 | ### should be 6: dir2/ and file4 were left out.) |
---|
1426 | |
---|
1427 | # These paths are relative to the top of the test's working copy. |
---|
1428 | file1_path = 'file1' |
---|
1429 | dir1_path = 'dir1' |
---|
1430 | file2_path = os.path.join('dir1', 'file2') |
---|
1431 | file3_path = os.path.join('dir1', 'file3') |
---|
1432 | dir2_path = os.path.join('dir1', 'dir2') |
---|
1433 | file4_path = os.path.join('dir1', 'dir2', 'file4') |
---|
1434 | |
---|
1435 | # Create the new files and directories. |
---|
1436 | svntest.main.file_append(os.path.join(wc_dir, file1_path), 'this is file1') |
---|
1437 | os.mkdir(os.path.join(wc_dir, dir1_path)) |
---|
1438 | svntest.main.file_append(os.path.join(wc_dir, file2_path), 'this is file2') |
---|
1439 | svntest.main.file_append(os.path.join(wc_dir, file3_path), 'this is file3') |
---|
1440 | os.mkdir(os.path.join(wc_dir, dir2_path)) |
---|
1441 | svntest.main.file_append(os.path.join(wc_dir, file4_path), 'this is file4') |
---|
1442 | |
---|
1443 | # Add them to version control. |
---|
1444 | svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [], |
---|
1445 | 'add', '--depth=empty', |
---|
1446 | os.path.join(wc_dir, file1_path), |
---|
1447 | os.path.join(wc_dir, dir1_path), |
---|
1448 | os.path.join(wc_dir, file2_path), |
---|
1449 | os.path.join(wc_dir, file3_path), |
---|
1450 | os.path.join(wc_dir, dir2_path), |
---|
1451 | os.path.join(wc_dir, file4_path)) |
---|
1452 | |
---|
1453 | # Commit. We should see all 6 items (2 dirs, 4 files) get sent. |
---|
1454 | expected_output = svntest.wc.State( |
---|
1455 | wc_dir, |
---|
1456 | { file1_path : Item(verb='Adding'), |
---|
1457 | dir1_path : Item(verb='Adding'), |
---|
1458 | file2_path : Item(verb='Adding'), |
---|
1459 | file3_path : Item(verb='Adding'), |
---|
1460 | dir2_path : Item(verb='Adding'), |
---|
1461 | file4_path : Item(verb='Adding'), |
---|
1462 | } |
---|
1463 | ) |
---|
1464 | |
---|
1465 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
1466 | expected_status.add({ |
---|
1467 | file1_path : Item(status=' ', wc_rev=2), |
---|
1468 | dir1_path : Item(status=' ', wc_rev=2), |
---|
1469 | file2_path : Item(status=' ', wc_rev=2), |
---|
1470 | file3_path : Item(status=' ', wc_rev=2), |
---|
1471 | dir2_path : Item(status=' ', wc_rev=2), |
---|
1472 | file4_path : Item(status=' ', wc_rev=2), |
---|
1473 | }) |
---|
1474 | |
---|
1475 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1476 | expected_output, |
---|
1477 | expected_status, |
---|
1478 | None, |
---|
1479 | '-N', |
---|
1480 | os.path.join(wc_dir, file1_path), |
---|
1481 | os.path.join(wc_dir, dir1_path), |
---|
1482 | os.path.join(wc_dir, file2_path), |
---|
1483 | os.path.join(wc_dir, file3_path), |
---|
1484 | os.path.join(wc_dir, dir2_path), |
---|
1485 | os.path.join(wc_dir, file4_path)) |
---|
1486 | |
---|
1487 | ####################################################################### |
---|
1488 | ### |
---|
1489 | ### There's some complex history here; please bear with me. |
---|
1490 | ### |
---|
1491 | ### First there was issue #1239, which had the following recipe: |
---|
1492 | ### |
---|
1493 | ### 1. Create these directories and files: |
---|
1494 | ### |
---|
1495 | ### dirA |
---|
1496 | ### dirA/fileA |
---|
1497 | ### dirA/fileB |
---|
1498 | ### dirA/dirB |
---|
1499 | ### dirA/dirB/fileC |
---|
1500 | ### dirA/dirB/nocommit |
---|
1501 | ### |
---|
1502 | ### 2. run 'svn add --depth=empty <all of the above>' |
---|
1503 | ### |
---|
1504 | ### 3. run 'svn ci -N <all but nocommit>' |
---|
1505 | ### |
---|
1506 | ### (In this recipe, 'add -N' has been changed to 'add --depth...', |
---|
1507 | ### but 'ci -N' has been left as-is, for reasons explained below.) |
---|
1508 | ### |
---|
1509 | ### Issue #1239 claimed a two-part bug: that step 3 would try to |
---|
1510 | ### commit the file `nocommit' when it shouldn't, and that it would |
---|
1511 | ### get an error anyway: |
---|
1512 | ### |
---|
1513 | ### Adding wc/dirA |
---|
1514 | ### Adding wc/dirA/fileA |
---|
1515 | ### Adding wc/dirA/fileB |
---|
1516 | ### Adding wc/dirA/dirB |
---|
1517 | ### Adding wc/dirA/dirB/nocommit |
---|
1518 | ### Adding wc/dirA/dirB/fileC |
---|
1519 | ### Transmitting file data ....svn: A problem occurred; \ |
---|
1520 | ### see later errors for details |
---|
1521 | ### svn: Commit succeeded, but other errors follow: |
---|
1522 | ### svn: Problem running log |
---|
1523 | ### svn: Error bumping revisions post-commit (details follow): |
---|
1524 | ### svn: in directory |
---|
1525 | ### 'F:/Programmation/Projets/subversion/svnant/test/wc/dirA' |
---|
1526 | ### svn: start_handler: error processing command 'committed' in |
---|
1527 | ### 'F:/Programmation/Projets/subversion/svnant/test/wc/dirA' |
---|
1528 | ### svn: Working copy not locked |
---|
1529 | ### svn: directory not locked |
---|
1530 | ### (F:/Programmation/Projets/subversion/svnant/test/wc) |
---|
1531 | ### |
---|
1532 | ### However, this was all in the days before --depth, and depended |
---|
1533 | ### on an idiosyncratic interpretation of -N, one which required |
---|
1534 | ### commit to behave differently from other commands taking -N. |
---|
1535 | ### |
---|
1536 | ### These days, -N should be equivalent to --depth=files in almost |
---|
1537 | ### all cases. There are some exceptions (e.g., status), and commit |
---|
1538 | ### is one of them: 'commit -N' means 'commit --depth=empty'. |
---|
1539 | ### |
---|
1540 | ### The original implementation, as well as this test, mistakenly |
---|
1541 | ### mapped 'commit -N' to 'commit --depth=files'; that was a bug that |
---|
1542 | ### made 'svn ci -N' incompatible with 1.4 and earlier versions. |
---|
1543 | ### |
---|
1544 | ### See also 'commit_propmods_with_depth_empty' in depth_tests.py . |
---|
1545 | |
---|
1546 | # Now add these directories and files, except the last: |
---|
1547 | dirA_path = 'dirA' |
---|
1548 | fileA_path = os.path.join('dirA', 'fileA') |
---|
1549 | fileB_path = os.path.join('dirA', 'fileB') |
---|
1550 | dirB_path = os.path.join('dirA', 'dirB') |
---|
1551 | nope_1_path = os.path.join(dirB_path, 'nope_1') |
---|
1552 | nope_2_path = os.path.join(dirB_path, 'nope_2') |
---|
1553 | |
---|
1554 | # Create the new files and directories. |
---|
1555 | os.mkdir(os.path.join(wc_dir, dirA_path)) |
---|
1556 | svntest.main.file_append(os.path.join(wc_dir, fileA_path), 'fileA') |
---|
1557 | svntest.main.file_append(os.path.join(wc_dir, fileB_path), 'fileB') |
---|
1558 | os.mkdir(os.path.join(wc_dir, dirB_path)) |
---|
1559 | svntest.main.file_append(os.path.join(wc_dir, nope_1_path), 'nope_1') |
---|
1560 | svntest.main.file_append(os.path.join(wc_dir, nope_2_path), 'nope_2') |
---|
1561 | |
---|
1562 | # Add them to version control. |
---|
1563 | svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [], |
---|
1564 | 'add', '-N', |
---|
1565 | os.path.join(wc_dir, dirA_path), |
---|
1566 | os.path.join(wc_dir, fileA_path), |
---|
1567 | # don't add fileB |
---|
1568 | os.path.join(wc_dir, dirB_path), |
---|
1569 | os.path.join(wc_dir, nope_1_path), |
---|
1570 | # don't add nope_2 |
---|
1571 | ) |
---|
1572 | |
---|
1573 | expected_output = svntest.wc.State( |
---|
1574 | wc_dir, |
---|
1575 | { dirA_path : Item(verb='Adding'), |
---|
1576 | # no children! |
---|
1577 | } |
---|
1578 | ) |
---|
1579 | |
---|
1580 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
1581 | |
---|
1582 | # Expect the leftovers from the first part of the test. |
---|
1583 | expected_status.add({ |
---|
1584 | file1_path : Item(status=' ', wc_rev=2), |
---|
1585 | dir1_path : Item(status=' ', wc_rev=2), |
---|
1586 | file2_path : Item(status=' ', wc_rev=2), |
---|
1587 | file3_path : Item(status=' ', wc_rev=2), |
---|
1588 | dir2_path : Item(status=' ', wc_rev=2), |
---|
1589 | file4_path : Item(status=' ', wc_rev=2), |
---|
1590 | }) |
---|
1591 | |
---|
1592 | # Expect some commits and some non-commits from this part of the test. |
---|
1593 | expected_status.add({ |
---|
1594 | dirA_path : Item(status=' ', wc_rev=3), |
---|
1595 | fileA_path : Item(status='A ', wc_rev=0), |
---|
1596 | # no fileB |
---|
1597 | dirB_path : Item(status='A ', wc_rev=0), |
---|
1598 | nope_1_path : Item(status='A ', wc_rev=0), |
---|
1599 | # no nope_2 |
---|
1600 | }) |
---|
1601 | |
---|
1602 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1603 | expected_output, |
---|
1604 | expected_status, |
---|
1605 | None, |
---|
1606 | '-N', os.path.join(wc_dir, dirA_path)) |
---|
1607 | |
---|
1608 | #---------------------------------------------------------------------- |
---|
1609 | # Regression for #1017: ra_neon was allowing the deletion of out-of-date |
---|
1610 | # files or dirs, which majorly violates Subversion's semantics. |
---|
1611 | # An out-of-date error should be raised if the object to be committed has |
---|
1612 | # already been deleted or modified in the repo. |
---|
1613 | |
---|
1614 | def commit_out_of_date_deletions(sbox): |
---|
1615 | "commit deletion of out-of-date file or dir" |
---|
1616 | |
---|
1617 | # Path WC 1 WC backup |
---|
1618 | # =========== ==== ========= |
---|
1619 | # A/C pset del |
---|
1620 | # A/I del pset |
---|
1621 | # A/B/F del del |
---|
1622 | # A/D/H/omega text del |
---|
1623 | # A/B/E/alpha pset del |
---|
1624 | # A/D/H/chi del text |
---|
1625 | # A/B/E/beta del pset |
---|
1626 | # A/D/H/psi del del |
---|
1627 | |
---|
1628 | sbox.build() |
---|
1629 | wc_dir = sbox.wc_dir |
---|
1630 | |
---|
1631 | # Need another empty dir |
---|
1632 | I_path = os.path.join(wc_dir, 'A', 'I') |
---|
1633 | os.mkdir(I_path) |
---|
1634 | svntest.main.run_svn(None, 'add', I_path) |
---|
1635 | svntest.main.run_svn(None, 'ci', '-m', 'prep', wc_dir) |
---|
1636 | svntest.main.run_svn(None, 'up', wc_dir) |
---|
1637 | |
---|
1638 | # Make a backup copy of the working copy |
---|
1639 | wc_backup = sbox.add_wc_path('backup') |
---|
1640 | svntest.actions.duplicate_dir(wc_dir, wc_backup) |
---|
1641 | |
---|
1642 | # Edits in wc 1 |
---|
1643 | C_path = os.path.join(wc_dir, 'A', 'C') |
---|
1644 | omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega') |
---|
1645 | alpha_path = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') |
---|
1646 | svntest.main.run_svn(None, 'propset', 'fooprop', 'foopropval', C_path) |
---|
1647 | svntest.main.file_append(omega_path, 'appended omega text') |
---|
1648 | svntest.main.run_svn(None, 'propset', 'fooprop', 'foopropval', alpha_path) |
---|
1649 | |
---|
1650 | # Deletions in wc 1 |
---|
1651 | I_path = os.path.join(wc_dir, 'A', 'I') |
---|
1652 | F_path = os.path.join(wc_dir, 'A', 'B', 'F') |
---|
1653 | chi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'chi') |
---|
1654 | beta_path = os.path.join(wc_dir, 'A', 'B', 'E', 'beta') |
---|
1655 | psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi') |
---|
1656 | svntest.main.run_svn(None, 'rm', I_path, F_path, chi_path, beta_path, |
---|
1657 | psi_path) |
---|
1658 | |
---|
1659 | # Commit in wc 1 |
---|
1660 | expected_output = svntest.wc.State(wc_dir, { |
---|
1661 | 'A/C' : Item(verb='Sending'), |
---|
1662 | 'A/I' : Item(verb='Deleting'), |
---|
1663 | 'A/B/F' : Item(verb='Deleting'), |
---|
1664 | 'A/D/H/omega' : Item(verb='Sending'), |
---|
1665 | 'A/B/E/alpha' : Item(verb='Sending'), |
---|
1666 | 'A/D/H/chi' : Item(verb='Deleting'), |
---|
1667 | 'A/B/E/beta' : Item(verb='Deleting'), |
---|
1668 | 'A/D/H/psi' : Item(verb='Deleting'), |
---|
1669 | }) |
---|
1670 | expected_status = svntest.actions.get_virginal_state(wc_dir, 2) |
---|
1671 | expected_status.tweak('A/C', 'A/D/H/omega', 'A/B/E/alpha', wc_rev=3, |
---|
1672 | status=' ') |
---|
1673 | expected_status.remove('A/B/F', 'A/D/H/chi', 'A/B/E/beta', 'A/D/H/psi') |
---|
1674 | commit = svntest.actions.run_and_verify_commit |
---|
1675 | commit(wc_dir, expected_output, expected_status, None, wc_dir) |
---|
1676 | |
---|
1677 | # Edits in wc backup |
---|
1678 | I_path = os.path.join(wc_backup, 'A', 'I') |
---|
1679 | chi_path = os.path.join(wc_backup, 'A', 'D', 'H', 'chi') |
---|
1680 | beta_path = os.path.join(wc_backup, 'A', 'B', 'E','beta') |
---|
1681 | svntest.main.run_svn(None, 'propset', 'fooprop', 'foopropval', I_path) |
---|
1682 | svntest.main.file_append(chi_path, 'appended chi text') |
---|
1683 | svntest.main.run_svn(None, 'propset', 'fooprop', 'foopropval', beta_path) |
---|
1684 | |
---|
1685 | # Deletions in wc backup |
---|
1686 | C_path = os.path.join(wc_backup, 'A', 'C') |
---|
1687 | F_path = os.path.join(wc_backup, 'A', 'B', 'F') |
---|
1688 | omega_path = os.path.join(wc_backup, 'A', 'D', 'H', 'omega') |
---|
1689 | alpha_path = os.path.join(wc_backup, 'A', 'B', 'E', 'alpha') |
---|
1690 | psi_path = os.path.join(wc_backup, 'A', 'D', 'H', 'psi') |
---|
1691 | svntest.main.run_svn(None, 'rm', C_path, F_path, omega_path, alpha_path, |
---|
1692 | psi_path) |
---|
1693 | |
---|
1694 | # A commit of any one of these files or dirs should fail |
---|
1695 | error_re = "out of date" |
---|
1696 | commit(wc_backup, None, None, error_re, C_path) |
---|
1697 | commit(wc_backup, None, None, error_re, I_path) |
---|
1698 | commit(wc_backup, None, None, error_re, F_path) |
---|
1699 | commit(wc_backup, None, None, error_re, omega_path) |
---|
1700 | commit(wc_backup, None, None, error_re, alpha_path) |
---|
1701 | commit(wc_backup, None, None, error_re, chi_path) |
---|
1702 | commit(wc_backup, None, None, error_re, beta_path) |
---|
1703 | commit(wc_backup, None, None, error_re, psi_path) |
---|
1704 | |
---|
1705 | def commit_with_bad_log_message(sbox): |
---|
1706 | "commit with a log message containing bad data" |
---|
1707 | |
---|
1708 | sbox.build() |
---|
1709 | wc_dir = sbox.wc_dir |
---|
1710 | |
---|
1711 | iota_path = os.path.join(wc_dir, 'iota') |
---|
1712 | log_msg_path = os.path.join(wc_dir, 'log-message') |
---|
1713 | |
---|
1714 | # Make a random change, so there's something to commit. |
---|
1715 | svntest.main.file_append(iota_path, 'fish') |
---|
1716 | |
---|
1717 | # Create a log message containing a zero-byte. |
---|
1718 | svntest.main.file_append(log_msg_path, '\x00') |
---|
1719 | |
---|
1720 | # Commit and expect an error. |
---|
1721 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1722 | None, None, |
---|
1723 | "contains a zero byte", |
---|
1724 | '-F', log_msg_path, |
---|
1725 | iota_path) |
---|
1726 | |
---|
1727 | def commit_with_mixed_line_endings(sbox): |
---|
1728 | "commit with log message with mixed EOL" |
---|
1729 | |
---|
1730 | sbox.build() |
---|
1731 | wc_dir = sbox.wc_dir |
---|
1732 | |
---|
1733 | expected_status = make_standard_slew_of_changes(wc_dir) |
---|
1734 | |
---|
1735 | iota_path = os.path.join(wc_dir, 'iota') |
---|
1736 | log_msg_path = os.path.join(wc_dir, 'log-message') |
---|
1737 | |
---|
1738 | # Make a random change, so there's something to commit. |
---|
1739 | svntest.main.file_append(iota_path, 'kebab') |
---|
1740 | |
---|
1741 | # Create a log message containing a zero-byte. |
---|
1742 | svntest.main.file_append(log_msg_path, "test\nthis\n\rcase\r\n--This line, and those below, will be ignored--\n") |
---|
1743 | |
---|
1744 | # Commit and expect an error. |
---|
1745 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1746 | None, None, |
---|
1747 | "Error normalizing log message to internal format", |
---|
1748 | '-F', log_msg_path, |
---|
1749 | iota_path) |
---|
1750 | |
---|
1751 | def commit_with_mixed_line_endings_in_ignored_part(sbox): |
---|
1752 | "commit with log message with mixed EOL in tail" |
---|
1753 | |
---|
1754 | sbox.build() |
---|
1755 | wc_dir = sbox.wc_dir |
---|
1756 | |
---|
1757 | expected_status = make_standard_slew_of_changes(wc_dir) |
---|
1758 | |
---|
1759 | iota_path = os.path.join(wc_dir, 'iota') |
---|
1760 | log_msg_path = os.path.join(wc_dir, 'log-message') |
---|
1761 | |
---|
1762 | # Make a random change, so there's something to commit. |
---|
1763 | svntest.main.file_append(iota_path, 'cheeseburger') |
---|
1764 | |
---|
1765 | # Create a log message containing a zero-byte. |
---|
1766 | svntest.main.file_append(log_msg_path, "test\n--This line, and those below, will be ignored--\nfoo\r\nbar\nbaz\n\r") |
---|
1767 | |
---|
1768 | # Create expected state. |
---|
1769 | expected_output = svntest.wc.State(wc_dir, { |
---|
1770 | 'iota' : Item(verb='Sending'), |
---|
1771 | }) |
---|
1772 | expected_status.tweak('iota', wc_rev=2, status=' ') |
---|
1773 | |
---|
1774 | # Commit the one file. |
---|
1775 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1776 | expected_output, |
---|
1777 | expected_status, |
---|
1778 | None, |
---|
1779 | iota_path) |
---|
1780 | |
---|
1781 | def from_wc_top_with_bad_editor(sbox): |
---|
1782 | "commit with invalid external editor cmd" |
---|
1783 | |
---|
1784 | # Shortly after revision 5407, Vladimir Prus posted this bug recipe: |
---|
1785 | # |
---|
1786 | # #!/bin/bash |
---|
1787 | # cd /tmp |
---|
1788 | # rm -rf repo wc |
---|
1789 | # svnadmin create repo |
---|
1790 | # svn mkdir file:///tmp/repo/foo -m "" |
---|
1791 | # svn co file:///tmp/repo/foo wc |
---|
1792 | # cd wc |
---|
1793 | # svn ps svn:externals "lib http://something.org/lib" . |
---|
1794 | # svn ci |
---|
1795 | # |
---|
1796 | # The final 'svn ci' would seg fault because of a problem in |
---|
1797 | # calculating the paths to insert in the initial log message that |
---|
1798 | # gets passed to the editor. |
---|
1799 | # |
---|
1800 | # So this regression test is primarily about making sure the seg |
---|
1801 | # fault is gone, and only secondarily about testing that we get the |
---|
1802 | # expected error from passing a bad editor cmd to Subversion. |
---|
1803 | |
---|
1804 | sbox.build() |
---|
1805 | wc_dir = sbox.wc_dir |
---|
1806 | |
---|
1807 | svntest.actions.run_and_verify_svn("Unexpected failure from propset.", |
---|
1808 | svntest.verify.AnyOutput, [], |
---|
1809 | 'pset', 'fish', 'food', wc_dir) |
---|
1810 | os.chdir(wc_dir) |
---|
1811 | exit_code, out, err = svntest.actions.run_and_verify_svn( |
---|
1812 | "Commit succeeded when should have failed.", |
---|
1813 | None, svntest.verify.AnyOutput, |
---|
1814 | 'ci', '--editor-cmd', 'no_such-editor') |
---|
1815 | |
---|
1816 | err = " ".join(map(str.strip, err)) |
---|
1817 | if not (re.match(".*no_such-editor.*", err) |
---|
1818 | and re.match(".*Commit failed.*", err)): |
---|
1819 | print("Commit failed, but not in the way expected.") |
---|
1820 | raise svntest.Failure |
---|
1821 | |
---|
1822 | |
---|
1823 | def mods_in_schedule_delete(sbox): |
---|
1824 | "commit with mods in schedule delete" |
---|
1825 | |
---|
1826 | sbox.build() |
---|
1827 | wc_dir = sbox.wc_dir |
---|
1828 | |
---|
1829 | # Schedule a delete, then put in local mods |
---|
1830 | C_path = os.path.join(wc_dir, 'A', 'C') |
---|
1831 | svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [], |
---|
1832 | 'rm', C_path) |
---|
1833 | foo_path = os.path.join(C_path, 'foo') |
---|
1834 | foo_contents = 'zig\nzag\n' |
---|
1835 | svntest.main.file_append(foo_path, foo_contents) |
---|
1836 | |
---|
1837 | # Commit should succeed |
---|
1838 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
1839 | expected_status.remove('A/C') |
---|
1840 | expected_output = svntest.wc.State(wc_dir, { |
---|
1841 | 'A/C' : Item(verb='Deleting'), |
---|
1842 | }) |
---|
1843 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
1844 | expected_output, expected_status, |
---|
1845 | None, wc_dir) |
---|
1846 | |
---|
1847 | # Unversioned file still exists |
---|
1848 | actual_contents = svntest.main.file_read(foo_path) |
---|
1849 | if actual_contents != foo_contents: |
---|
1850 | raise svntest.Failure |
---|
1851 | |
---|
1852 | |
---|
1853 | #---------------------------------------------------------------------- |
---|
1854 | |
---|
1855 | def tab_test(sbox): |
---|
1856 | "tabs in paths" |
---|
1857 | # For issue #1954. |
---|
1858 | |
---|
1859 | sbox.build() |
---|
1860 | wc_dir = sbox.wc_dir |
---|
1861 | |
---|
1862 | tab_file = os.path.join(wc_dir, 'A', "tab\tfile") |
---|
1863 | tab_dir = os.path.join(wc_dir, 'A', "tab\tdir") |
---|
1864 | source_url = sbox.repo_url + "/source_dir" |
---|
1865 | tab_url = sbox.repo_url + "/tab%09dir" |
---|
1866 | |
---|
1867 | svntest.main.file_append(tab_file, "This file has a tab in it.") |
---|
1868 | os.mkdir(tab_dir) |
---|
1869 | |
---|
1870 | def match_bad_tab_path(path, errlines): |
---|
1871 | match_re = ".*: Invalid control character '0x09' in path .*" |
---|
1872 | for line in errlines: |
---|
1873 | if re.match (match_re, line): |
---|
1874 | break |
---|
1875 | else: |
---|
1876 | raise svntest.Failure("Failed to find match_re in " + str(errlines)) |
---|
1877 | |
---|
1878 | # add file to wc |
---|
1879 | exit_code, outlines, errlines = svntest.main.run_svn(1, 'add', tab_file) |
---|
1880 | match_bad_tab_path(tab_file, errlines) |
---|
1881 | |
---|
1882 | # add dir to wc |
---|
1883 | exit_code, outlines, errlines = svntest.main.run_svn(1, 'add', tab_dir) |
---|
1884 | match_bad_tab_path(tab_dir, errlines) |
---|
1885 | |
---|
1886 | # mkdir URL |
---|
1887 | exit_code, outlines, errlines = svntest.main.run_svn(1, 'mkdir', |
---|
1888 | '-m', 'msg', tab_url) |
---|
1889 | match_bad_tab_path(tab_dir, errlines) |
---|
1890 | |
---|
1891 | # copy URL |
---|
1892 | svntest.main.run_svn(1, |
---|
1893 | 'mkdir', '-m', 'msg', source_url) |
---|
1894 | exit_code, outlines, errlines = svntest.main.run_svn(1, 'copy', |
---|
1895 | '-m', 'msg', |
---|
1896 | source_url, tab_url) |
---|
1897 | match_bad_tab_path(tab_dir, errlines) |
---|
1898 | |
---|
1899 | # mv URL |
---|
1900 | exit_code, outlines, errlines = svntest.main.run_svn(1, 'mv', '-m', 'msg', |
---|
1901 | source_url, tab_url) |
---|
1902 | match_bad_tab_path(tab_dir, errlines) |
---|
1903 | |
---|
1904 | #---------------------------------------------------------------------- |
---|
1905 | |
---|
1906 | def local_mods_are_not_commits(sbox): |
---|
1907 | "local ops should not be treated like commits" |
---|
1908 | |
---|
1909 | # For issue #2285. |
---|
1910 | # |
---|
1911 | # Some commands can run on either a URL or a local path. These |
---|
1912 | # commands take a log message, intended for the URL case. |
---|
1913 | # Therefore, they should make sure that getting a log message for |
---|
1914 | # a local operation errors (because not committing). |
---|
1915 | # |
---|
1916 | # This is in commit_tests.py because the unifying theme is that |
---|
1917 | # commits are *not* happening. And because there was no better |
---|
1918 | # place to put it :-). |
---|
1919 | |
---|
1920 | sbox.build() |
---|
1921 | wc_dir = sbox.wc_dir |
---|
1922 | expected_error = '.*Local, non-commit operations do not take a log message.*' |
---|
1923 | |
---|
1924 | # copy wc->wc |
---|
1925 | svntest.actions.run_and_verify_svn(None, None, expected_error, |
---|
1926 | 'cp', '-m', 'log msg', |
---|
1927 | os.path.join(wc_dir, 'iota'), |
---|
1928 | os.path.join(wc_dir, 'iota2')) |
---|
1929 | |
---|
1930 | # copy repos->wc |
---|
1931 | svntest.actions.run_and_verify_svn(None, None, expected_error, |
---|
1932 | 'cp', '-m', 'log msg', |
---|
1933 | sbox.repo_url + "/iota", |
---|
1934 | os.path.join(wc_dir, 'iota2')) |
---|
1935 | |
---|
1936 | # delete |
---|
1937 | svntest.actions.run_and_verify_svn(None, None, expected_error, |
---|
1938 | 'rm', '-m', 'log msg', |
---|
1939 | os.path.join(wc_dir, 'A', 'D', 'gamma')) |
---|
1940 | |
---|
1941 | # mkdir |
---|
1942 | svntest.actions.run_and_verify_svn(None, None, expected_error, |
---|
1943 | 'mkdir', '-m', 'log msg', |
---|
1944 | os.path.join(wc_dir, 'newdir')) |
---|
1945 | |
---|
1946 | # rename |
---|
1947 | svntest.actions.run_and_verify_svn(None, None, expected_error, |
---|
1948 | 'cp', '-m', 'log msg', |
---|
1949 | os.path.join(wc_dir, 'A', 'mu'), |
---|
1950 | os.path.join(wc_dir, 'A', 'yu')) |
---|
1951 | |
---|
1952 | # Helper for hook tests: returns the "hook failed" line, with precise |
---|
1953 | # wording that changed with Subversion 1.5. |
---|
1954 | def hook_failure_message(hookname): |
---|
1955 | if svntest.main.server_minor_version < 5: |
---|
1956 | return "'%s' hook failed with error output:\n" % hookname |
---|
1957 | else: |
---|
1958 | if hookname in ["start-commit", "pre-commit"]: |
---|
1959 | action = "Commit" |
---|
1960 | elif hookname == "pre-revprop-change": |
---|
1961 | action = "Revprop change" |
---|
1962 | elif hookname == "pre-lock": |
---|
1963 | action = "Lock" |
---|
1964 | elif hookname == "pre-unlock": |
---|
1965 | action = "Unlock" |
---|
1966 | else: |
---|
1967 | action = None |
---|
1968 | if action is None: |
---|
1969 | message = "%s hook failed (exit code 1)" % (hookname,) |
---|
1970 | else: |
---|
1971 | message = "%s blocked by %s hook (exit code 1)" % (action, hookname) |
---|
1972 | return message + " with output:\n" |
---|
1973 | |
---|
1974 | |
---|
1975 | #---------------------------------------------------------------------- |
---|
1976 | # Test if the post-commit error message is returned back to the svn |
---|
1977 | # client and is displayed as a warning. |
---|
1978 | # |
---|
1979 | def post_commit_hook_test(sbox): |
---|
1980 | "post commit hook failure case testing" |
---|
1981 | |
---|
1982 | sbox.build() |
---|
1983 | |
---|
1984 | # Get paths to the working copy and repository |
---|
1985 | wc_dir = sbox.wc_dir |
---|
1986 | repo_dir = sbox.repo_dir |
---|
1987 | |
---|
1988 | # Disable commits |
---|
1989 | svntest.actions.create_failing_post_commit_hook(repo_dir) |
---|
1990 | |
---|
1991 | # Modify iota just so there is something to commit. |
---|
1992 | iota_path = os.path.join(wc_dir, "iota") |
---|
1993 | svntest.main.file_append(iota_path, "lakalakalakalaka") |
---|
1994 | |
---|
1995 | # Now, commit and examine the output (we happen to know that the |
---|
1996 | # filesystem will report an absolute path because that's the way the |
---|
1997 | # filesystem is created by this test suite. |
---|
1998 | expected_output = [ "Sending "+ iota_path + "\n", |
---|
1999 | "Transmitting file data .\n", |
---|
2000 | "Committed revision 2.\n", |
---|
2001 | "\n", |
---|
2002 | "Warning: " + hook_failure_message('post-commit'), |
---|
2003 | "Post-commit hook failed\n", |
---|
2004 | ] |
---|
2005 | |
---|
2006 | svntest.actions.run_and_verify_svn(None, expected_output, [], |
---|
2007 | 'ci', '-m', 'log msg', iota_path) |
---|
2008 | |
---|
2009 | #---------------------------------------------------------------------- |
---|
2010 | # Commit two targets non-recursively, but both targets should be the |
---|
2011 | # same folder (in multiple variations). Test that svn handles this correctly. |
---|
2012 | def commit_same_folder_in_targets(sbox): |
---|
2013 | "commit two targets, both the same folder" |
---|
2014 | |
---|
2015 | sbox.build() |
---|
2016 | wc_dir = sbox.wc_dir |
---|
2017 | |
---|
2018 | iota_path = os.path.join(wc_dir, 'iota') |
---|
2019 | |
---|
2020 | svntest.main.file_append(iota_path, "added extra line to file iota") |
---|
2021 | |
---|
2022 | # Create expected output tree. |
---|
2023 | expected_output = svntest.wc.State(wc_dir, { |
---|
2024 | 'iota' : Item(verb='Sending'), |
---|
2025 | }) |
---|
2026 | |
---|
2027 | # Created expected status tree. |
---|
2028 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
2029 | expected_status.tweak('iota', wc_rev=2) |
---|
2030 | |
---|
2031 | # Commit the wc_dir and iota. |
---|
2032 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
2033 | expected_output, |
---|
2034 | expected_status, |
---|
2035 | None, |
---|
2036 | '-N', |
---|
2037 | wc_dir, |
---|
2038 | iota_path) |
---|
2039 | |
---|
2040 | #---------------------------------------------------------------------- |
---|
2041 | # test for issue 2459: verify that commit fails when a file with mixed |
---|
2042 | # eol-styles is included, and show an error message which includes the |
---|
2043 | # filename. |
---|
2044 | def commit_inconsistent_eol(sbox): |
---|
2045 | "commit files with inconsistent eol should fail" |
---|
2046 | |
---|
2047 | sbox.build() |
---|
2048 | wc_dir = sbox.wc_dir |
---|
2049 | |
---|
2050 | iota_path = os.path.join(wc_dir, 'iota') |
---|
2051 | mu_path = os.path.join(wc_dir, 'A', 'mu') |
---|
2052 | |
---|
2053 | svntest.main.run_svn(None, 'propset', 'svn:eol-style', 'native', iota_path) |
---|
2054 | svntest.main.file_append_binary(iota_path, |
---|
2055 | "added extra line to file iota\012" |
---|
2056 | "added extra line to file iota\015") |
---|
2057 | svntest.main.file_append(mu_path, "added extra line to file mu\n" |
---|
2058 | "added extra line to file mu\n") |
---|
2059 | |
---|
2060 | expected_err = ".*iota.*" |
---|
2061 | |
---|
2062 | svntest.actions.run_and_verify_svn(None, None, expected_err, |
---|
2063 | 'commit', '-m', 'log message', |
---|
2064 | wc_dir) |
---|
2065 | |
---|
2066 | |
---|
2067 | def mkdir_with_revprop(sbox): |
---|
2068 | "set revision props during remote mkdir" |
---|
2069 | |
---|
2070 | sbox.build() |
---|
2071 | remote_dir = sbox.repo_url + "/dir" |
---|
2072 | |
---|
2073 | svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg', |
---|
2074 | '--with-revprop', 'bug=42', remote_dir) |
---|
2075 | |
---|
2076 | expected = svntest.verify.UnorderedOutput( |
---|
2077 | ['Unversioned properties on revision 2:\n', |
---|
2078 | ' svn:author\n',' svn:date\n', ' svn:log\n', |
---|
2079 | ' bug\n']) |
---|
2080 | svntest.actions.run_and_verify_svn(None, expected, [], 'proplist', |
---|
2081 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2082 | svntest.actions.run_and_verify_svn(None, '42', [], 'propget', 'bug', |
---|
2083 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2084 | |
---|
2085 | |
---|
2086 | def delete_with_revprop(sbox): |
---|
2087 | "set revision props during remote delete" |
---|
2088 | |
---|
2089 | sbox.build() |
---|
2090 | remote_dir = sbox.repo_url + "/dir" |
---|
2091 | svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg', |
---|
2092 | remote_dir) |
---|
2093 | |
---|
2094 | svntest.actions.run_and_verify_svn(None, None, [], 'delete', '-m', 'msg', |
---|
2095 | '--with-revprop', 'bug=52', remote_dir) |
---|
2096 | |
---|
2097 | expected = svntest.verify.UnorderedOutput( |
---|
2098 | ['Unversioned properties on revision 3:\n', |
---|
2099 | ' svn:author\n',' svn:date\n', ' svn:log\n', |
---|
2100 | ' bug\n']) |
---|
2101 | svntest.actions.run_and_verify_svn(None, expected, [], 'proplist', |
---|
2102 | '--revprop', '-r', 3, sbox.repo_url) |
---|
2103 | svntest.actions.run_and_verify_svn(None, '52', [], 'propget', 'bug', |
---|
2104 | '--revprop', '-r', 3, sbox.repo_url) |
---|
2105 | |
---|
2106 | |
---|
2107 | def commit_with_revprop(sbox): |
---|
2108 | "set revision props during commit" |
---|
2109 | |
---|
2110 | sbox.build() |
---|
2111 | wc_dir = sbox.wc_dir |
---|
2112 | expected_status = make_standard_slew_of_changes(wc_dir) |
---|
2113 | |
---|
2114 | omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega') |
---|
2115 | gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo') |
---|
2116 | expected_output = svntest.wc.State(wc_dir, { |
---|
2117 | 'A/D/H/omega' : Item(verb='Sending'), |
---|
2118 | 'A/D/H/gloo' : Item(verb='Adding'), |
---|
2119 | }) |
---|
2120 | |
---|
2121 | expected_status.tweak('A/D/H/omega', wc_rev=2, status=' ') |
---|
2122 | expected_status.tweak('A/D/H/gloo', wc_rev=2, status=' ') |
---|
2123 | |
---|
2124 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
2125 | expected_output, |
---|
2126 | expected_status, |
---|
2127 | None, |
---|
2128 | '-m', 'msg', |
---|
2129 | '--with-revprop', 'bug=62', |
---|
2130 | omega_path, gloo_path) |
---|
2131 | |
---|
2132 | expected = svntest.verify.UnorderedOutput( |
---|
2133 | ['Unversioned properties on revision 2:\n', |
---|
2134 | ' svn:author\n',' svn:date\n', ' svn:log\n', |
---|
2135 | ' bug\n']) |
---|
2136 | svntest.actions.run_and_verify_svn(None, expected, [], 'proplist', |
---|
2137 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2138 | svntest.actions.run_and_verify_svn(None, '62', [], 'propget', 'bug', |
---|
2139 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2140 | |
---|
2141 | |
---|
2142 | def import_with_revprop(sbox): |
---|
2143 | "set revision props during import" |
---|
2144 | |
---|
2145 | sbox.build() |
---|
2146 | local_dir = os.path.join(sbox.wc_dir, 'folder') |
---|
2147 | local_file = os.path.join(sbox.wc_dir, 'folder', 'file') |
---|
2148 | os.mkdir(local_dir) |
---|
2149 | svntest.main.file_write(local_file, "xxxx") |
---|
2150 | |
---|
2151 | svntest.actions.run_and_verify_svn(None, None, [], 'import', '-m', 'msg', |
---|
2152 | '--with-revprop', 'bug=72', local_dir, |
---|
2153 | sbox.repo_url) |
---|
2154 | |
---|
2155 | expected = svntest.verify.UnorderedOutput( |
---|
2156 | ['Unversioned properties on revision 2:\n', |
---|
2157 | ' svn:author\n',' svn:date\n', ' svn:log\n', |
---|
2158 | ' bug\n']) |
---|
2159 | svntest.actions.run_and_verify_svn(None, expected, [], 'proplist', |
---|
2160 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2161 | svntest.actions.run_and_verify_svn(None, '72', [], 'propget', 'bug', |
---|
2162 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2163 | |
---|
2164 | |
---|
2165 | def copy_R2R_with_revprop(sbox): |
---|
2166 | "set revision props during repos-to-repos copy" |
---|
2167 | |
---|
2168 | sbox.build() |
---|
2169 | remote_dir1 = sbox.repo_url + "/dir1" |
---|
2170 | remote_dir2 = sbox.repo_url + "/dir2" |
---|
2171 | svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg', |
---|
2172 | remote_dir1) |
---|
2173 | |
---|
2174 | svntest.actions.run_and_verify_svn(None, None, [], 'copy', '-m', 'msg', |
---|
2175 | '--with-revprop', 'bug=82', remote_dir1, |
---|
2176 | remote_dir2) |
---|
2177 | |
---|
2178 | expected = svntest.verify.UnorderedOutput( |
---|
2179 | ['Unversioned properties on revision 3:\n', |
---|
2180 | ' svn:author\n',' svn:date\n', ' svn:log\n', |
---|
2181 | ' bug\n']) |
---|
2182 | svntest.actions.run_and_verify_svn(None, expected, [], 'proplist', |
---|
2183 | '--revprop', '-r', 3, sbox.repo_url) |
---|
2184 | svntest.actions.run_and_verify_svn(None, '82', [], 'propget', 'bug', |
---|
2185 | '--revprop', '-r', 3, sbox.repo_url) |
---|
2186 | |
---|
2187 | |
---|
2188 | def copy_WC2R_with_revprop(sbox): |
---|
2189 | "set revision props during wc-to-repos copy" |
---|
2190 | |
---|
2191 | sbox.build() |
---|
2192 | remote_dir = sbox.repo_url + "/dir" |
---|
2193 | local_dir = os.path.join(sbox.wc_dir, 'folder') |
---|
2194 | svntest.actions.run_and_verify_svn(None, None, [], |
---|
2195 | 'mkdir', local_dir) |
---|
2196 | |
---|
2197 | svntest.actions.run_and_verify_svn(None, None, [], 'copy', '-m', 'msg', |
---|
2198 | '--with-revprop', 'bug=92', local_dir, |
---|
2199 | remote_dir) |
---|
2200 | |
---|
2201 | expected = svntest.verify.UnorderedOutput( |
---|
2202 | ['Unversioned properties on revision 2:\n', |
---|
2203 | ' svn:author\n',' svn:date\n', ' svn:log\n', |
---|
2204 | ' bug\n']) |
---|
2205 | svntest.actions.run_and_verify_svn(None, expected, [], 'proplist', |
---|
2206 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2207 | svntest.actions.run_and_verify_svn(None, '92', [], 'propget', 'bug', |
---|
2208 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2209 | |
---|
2210 | |
---|
2211 | def move_R2R_with_revprop(sbox): |
---|
2212 | "set revision props during repos-to-repos move" |
---|
2213 | |
---|
2214 | sbox.build() |
---|
2215 | remote_dir1 = sbox.repo_url + "/dir1" |
---|
2216 | remote_dir2 = sbox.repo_url + "/dir2" |
---|
2217 | svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg', |
---|
2218 | remote_dir1) |
---|
2219 | |
---|
2220 | svntest.actions.run_and_verify_svn(None, None, [], 'move', '-m', 'msg', |
---|
2221 | '--with-revprop', 'bug=102', remote_dir1, |
---|
2222 | remote_dir2) |
---|
2223 | |
---|
2224 | expected = svntest.verify.UnorderedOutput( |
---|
2225 | ['Unversioned properties on revision 3:\n', |
---|
2226 | ' svn:author\n',' svn:date\n', ' svn:log\n', |
---|
2227 | ' bug\n']) |
---|
2228 | svntest.actions.run_and_verify_svn(None, expected, [], 'proplist', |
---|
2229 | '--revprop', '-r', 3, sbox.repo_url) |
---|
2230 | svntest.actions.run_and_verify_svn(None, '102', [], 'propget', 'bug', |
---|
2231 | '--revprop', '-r', 3, sbox.repo_url) |
---|
2232 | |
---|
2233 | |
---|
2234 | def propedit_with_revprop(sbox): |
---|
2235 | "set revision props during remote property edit" |
---|
2236 | |
---|
2237 | sbox.build() |
---|
2238 | svntest.main.use_editor('append_foo') |
---|
2239 | |
---|
2240 | svntest.actions.run_and_verify_svn(None, None, [], 'propedit', '-m', 'msg', |
---|
2241 | '--with-revprop', 'bug=112', 'prop', |
---|
2242 | sbox.repo_url) |
---|
2243 | |
---|
2244 | expected = svntest.verify.UnorderedOutput( |
---|
2245 | ['Unversioned properties on revision 2:\n', |
---|
2246 | ' svn:author\n',' svn:date\n', ' svn:log\n', |
---|
2247 | ' bug\n']) |
---|
2248 | svntest.actions.run_and_verify_svn(None, expected, [], 'proplist', |
---|
2249 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2250 | svntest.actions.run_and_verify_svn(None, '112', [], 'propget', 'bug', |
---|
2251 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2252 | |
---|
2253 | |
---|
2254 | def set_multiple_props_with_revprop(sbox): |
---|
2255 | "set multiple revision props during remote mkdir" |
---|
2256 | |
---|
2257 | sbox.build() |
---|
2258 | remote_dir = sbox.repo_url + "/dir" |
---|
2259 | |
---|
2260 | svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg', |
---|
2261 | '--with-revprop', 'bug=32', |
---|
2262 | '--with-revprop', 'ref=22', remote_dir) |
---|
2263 | |
---|
2264 | expected = svntest.verify.UnorderedOutput( |
---|
2265 | ['Unversioned properties on revision 2:\n', |
---|
2266 | ' svn:author\n',' svn:date\n', ' svn:log\n', |
---|
2267 | ' bug\n', ' ref\n']) |
---|
2268 | svntest.actions.run_and_verify_svn(None, expected, [], 'proplist', |
---|
2269 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2270 | svntest.actions.run_and_verify_svn(None, '32', [], 'propget', 'bug', |
---|
2271 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2272 | svntest.actions.run_and_verify_svn(None, '22', [], 'propget', 'ref', |
---|
2273 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2274 | |
---|
2275 | |
---|
2276 | def use_empty_value_in_revprop_pair(sbox): |
---|
2277 | "set revprop without value ('') during remote mkdir" |
---|
2278 | |
---|
2279 | sbox.build() |
---|
2280 | remote_dir = sbox.repo_url + "/dir" |
---|
2281 | |
---|
2282 | svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg', |
---|
2283 | '--with-revprop', 'bug=', |
---|
2284 | '--with-revprop', 'ref=', remote_dir) |
---|
2285 | |
---|
2286 | expected = svntest.verify.UnorderedOutput( |
---|
2287 | ['Unversioned properties on revision 2:\n', |
---|
2288 | ' svn:author\n',' svn:date\n', ' svn:log\n', |
---|
2289 | ' bug\n', ' ref\n']) |
---|
2290 | svntest.actions.run_and_verify_svn(None, expected, [], 'proplist', |
---|
2291 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2292 | svntest.actions.run_and_verify_svn(None, '', [], 'propget', 'bug', |
---|
2293 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2294 | svntest.actions.run_and_verify_svn(None, '', [], 'propget', 'ref', |
---|
2295 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2296 | |
---|
2297 | |
---|
2298 | def no_equals_in_revprop_pair(sbox): |
---|
2299 | "set revprop without '=' during remote mkdir" |
---|
2300 | |
---|
2301 | sbox.build() |
---|
2302 | remote_dir = sbox.repo_url + "/dir" |
---|
2303 | svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg', |
---|
2304 | '--with-revprop', 'bug', |
---|
2305 | '--with-revprop', 'ref', remote_dir) |
---|
2306 | |
---|
2307 | expected = svntest.verify.UnorderedOutput( |
---|
2308 | ['Unversioned properties on revision 2:\n', |
---|
2309 | ' svn:author\n',' svn:date\n', ' svn:log\n', |
---|
2310 | ' bug\n', ' ref\n']) |
---|
2311 | svntest.actions.run_and_verify_svn(None, expected, [], 'proplist', |
---|
2312 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2313 | svntest.actions.run_and_verify_svn(None, '', [], 'propget', 'bug', |
---|
2314 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2315 | svntest.actions.run_and_verify_svn(None, '', [], 'propget', 'ref', |
---|
2316 | '--revprop', '-r', 2, sbox.repo_url) |
---|
2317 | |
---|
2318 | |
---|
2319 | def set_invalid_revprops(sbox): |
---|
2320 | "set invalid revision props during remote mkdir" |
---|
2321 | |
---|
2322 | sbox.build() |
---|
2323 | remote_dir = sbox.repo_url + "/dir" |
---|
2324 | # Try to set svn: revprops. |
---|
2325 | expected = '.*Standard properties can\'t.*' |
---|
2326 | svntest.actions.run_and_verify_svn(None, [], expected, 'mkdir', '-m', 'msg', |
---|
2327 | '--with-revprop', 'svn:author=42', remote_dir) |
---|
2328 | svntest.actions.run_and_verify_svn(None, [], expected, 'mkdir', '-m', 'msg', |
---|
2329 | '--with-revprop', 'svn:log=42', remote_dir) |
---|
2330 | svntest.actions.run_and_verify_svn(None, [], expected, 'mkdir', '-m', 'msg', |
---|
2331 | '--with-revprop', 'svn:date=42', remote_dir) |
---|
2332 | svntest.actions.run_and_verify_svn(None, [], expected, 'mkdir', '-m', 'msg', |
---|
2333 | '--with-revprop', 'svn:foo=bar', remote_dir) |
---|
2334 | |
---|
2335 | # Empty revprop pair. |
---|
2336 | svntest.actions.run_and_verify_svn(None, [], |
---|
2337 | 'svn: Revision property pair is empty', |
---|
2338 | 'mkdir', '-m', 'msg', |
---|
2339 | '--with-revprop', '', |
---|
2340 | remote_dir) |
---|
2341 | |
---|
2342 | #---------------------------------------------------------------------- |
---|
2343 | |
---|
2344 | def start_commit_hook_test(sbox): |
---|
2345 | "start-commit hook failure case testing" |
---|
2346 | |
---|
2347 | sbox.build() |
---|
2348 | |
---|
2349 | # Get paths to the working copy and repository |
---|
2350 | wc_dir = sbox.wc_dir |
---|
2351 | repo_dir = sbox.repo_dir |
---|
2352 | |
---|
2353 | # Create a hook that outputs a message to stderr and returns exit code 1 |
---|
2354 | hook_code = """import sys |
---|
2355 | sys.stderr.write("Start-commit hook failed") |
---|
2356 | sys.exit(1)""" |
---|
2357 | |
---|
2358 | # Setup the hook configs to log data to a file |
---|
2359 | start_commit_hook = svntest.main.get_start_commit_hook_path(repo_dir) |
---|
2360 | svntest.main.create_python_hook_script(start_commit_hook, hook_code) |
---|
2361 | |
---|
2362 | # Modify iota just so there is something to commit. |
---|
2363 | iota_path = os.path.join(wc_dir, "iota") |
---|
2364 | svntest.main.file_append(iota_path, "More stuff in iota") |
---|
2365 | |
---|
2366 | # Commit, expect error code 1 |
---|
2367 | exit_code, actual_stdout, actual_stderr = svntest.main.run_svn( |
---|
2368 | 1, 'ci', '--quiet', '-m', 'log msg', wc_dir) |
---|
2369 | |
---|
2370 | # No stdout expected |
---|
2371 | svntest.verify.compare_and_display_lines('Start-commit hook test', |
---|
2372 | 'STDOUT', [], actual_stdout) |
---|
2373 | |
---|
2374 | # Compare only the last two lines of stderr since the preceding ones |
---|
2375 | # contain source code file and line numbers. |
---|
2376 | if len(actual_stderr) > 2: |
---|
2377 | actual_stderr = actual_stderr[-2:] |
---|
2378 | expected_stderr = [ "svn: " + hook_failure_message('start-commit'), |
---|
2379 | "Start-commit hook failed\n" |
---|
2380 | ] |
---|
2381 | svntest.verify.compare_and_display_lines('Start-commit hook test', |
---|
2382 | 'STDERR', |
---|
2383 | expected_stderr, actual_stderr) |
---|
2384 | |
---|
2385 | #---------------------------------------------------------------------- |
---|
2386 | |
---|
2387 | def pre_commit_hook_test(sbox): |
---|
2388 | "pre-commit hook failure case testing" |
---|
2389 | |
---|
2390 | sbox.build() |
---|
2391 | |
---|
2392 | # Get paths to the working copy and repository |
---|
2393 | wc_dir = sbox.wc_dir |
---|
2394 | repo_dir = sbox.repo_dir |
---|
2395 | |
---|
2396 | # Create a hook that outputs a message to stderr and returns exit code 1 |
---|
2397 | hook_code = """import sys |
---|
2398 | sys.stderr.write("Pre-commit hook failed") |
---|
2399 | sys.exit(1)""" |
---|
2400 | |
---|
2401 | # Setup the hook configs to log data to a file |
---|
2402 | pre_commit_hook = svntest.main.get_pre_commit_hook_path(repo_dir) |
---|
2403 | svntest.main.create_python_hook_script(pre_commit_hook, hook_code) |
---|
2404 | |
---|
2405 | # Modify iota just so there is something to commit. |
---|
2406 | iota_path = os.path.join(wc_dir, "iota") |
---|
2407 | svntest.main.file_append(iota_path, "More stuff in iota") |
---|
2408 | |
---|
2409 | # Commit, expect error code 1 |
---|
2410 | exit_code, actual_stdout, actual_stderr = svntest.main.run_svn( |
---|
2411 | 1, 'ci', '--quiet', '-m', 'log msg', wc_dir) |
---|
2412 | |
---|
2413 | # No stdout expected |
---|
2414 | svntest.verify.compare_and_display_lines('Pre-commit hook test', |
---|
2415 | 'STDOUT', [], actual_stdout) |
---|
2416 | |
---|
2417 | # Compare only the last two lines of stderr since the preceding ones |
---|
2418 | # contain source code file and line numbers. |
---|
2419 | if len(actual_stderr) > 2: |
---|
2420 | actual_stderr = actual_stderr[-2:] |
---|
2421 | expected_stderr = [ "svn: " + hook_failure_message('pre-commit'), |
---|
2422 | "Pre-commit hook failed\n" |
---|
2423 | ] |
---|
2424 | svntest.verify.compare_and_display_lines('Pre-commit hook test', |
---|
2425 | 'STDERR', |
---|
2426 | expected_stderr, actual_stderr) |
---|
2427 | |
---|
2428 | #---------------------------------------------------------------------- |
---|
2429 | |
---|
2430 | def versioned_log_message(sbox): |
---|
2431 | "'svn commit -F foo' when foo is a versioned file" |
---|
2432 | |
---|
2433 | sbox.build() |
---|
2434 | |
---|
2435 | os.chdir(sbox.wc_dir) |
---|
2436 | |
---|
2437 | iota_path = os.path.join('iota') |
---|
2438 | mu_path = os.path.join('A', 'mu') |
---|
2439 | log_path = os.path.join('A', 'D', 'H', 'omega') |
---|
2440 | |
---|
2441 | svntest.main.file_append(iota_path, "2") |
---|
2442 | |
---|
2443 | # try to check in a change using a versioned file as your log entry. |
---|
2444 | svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput, |
---|
2445 | 'ci', '-F', log_path) |
---|
2446 | |
---|
2447 | # force it. should not produce any errors. |
---|
2448 | svntest.actions.run_and_verify_svn(None, None, [], |
---|
2449 | 'ci', '-F', log_path, '--force-log') |
---|
2450 | |
---|
2451 | svntest.main.file_append(mu_path, "2") |
---|
2452 | |
---|
2453 | # try the same thing, but specifying the file to commit explicitly. |
---|
2454 | svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput, |
---|
2455 | 'ci', '-F', log_path, mu_path) |
---|
2456 | |
---|
2457 | # force it... should succeed. |
---|
2458 | svntest.actions.run_and_verify_svn(None, None, [], |
---|
2459 | 'ci', |
---|
2460 | '-F', log_path, |
---|
2461 | '--force-log', mu_path) |
---|
2462 | |
---|
2463 | #---------------------------------------------------------------------- |
---|
2464 | |
---|
2465 | def changelist_near_conflict(sbox): |
---|
2466 | "'svn commit --changelist=foo' above a conflict" |
---|
2467 | |
---|
2468 | sbox.build() |
---|
2469 | |
---|
2470 | wc_dir = sbox.wc_dir |
---|
2471 | iota_path = os.path.join(wc_dir, "iota") |
---|
2472 | mu_path = os.path.join(wc_dir, "A", "mu") |
---|
2473 | gloo_path = os.path.join(wc_dir, "A", "D", "H", "gloo") |
---|
2474 | |
---|
2475 | expected_status = make_standard_slew_of_changes(wc_dir) |
---|
2476 | |
---|
2477 | # Create a changelist. |
---|
2478 | changelist_name = "logical-changeset" |
---|
2479 | svntest.actions.run_and_verify_svn(None, None, [], |
---|
2480 | "changelist", changelist_name, |
---|
2481 | mu_path, gloo_path) |
---|
2482 | |
---|
2483 | # Create a conflict (making r2 in the process). |
---|
2484 | inject_conflict_into_wc(sbox, 'iota', iota_path, |
---|
2485 | None, expected_status, 2) |
---|
2486 | |
---|
2487 | # Commit the changelist. |
---|
2488 | expected_output = svntest.wc.State(wc_dir, { |
---|
2489 | "A/D/H/gloo" : Item(verb='Adding'), |
---|
2490 | }) |
---|
2491 | expected_status.tweak("A/D/H/gloo", wc_rev=3, status=" ") |
---|
2492 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
2493 | expected_output, |
---|
2494 | expected_status, |
---|
2495 | None, |
---|
2496 | "--changelist=" + changelist_name, |
---|
2497 | "-m", "msg", wc_dir) |
---|
2498 | |
---|
2499 | |
---|
2500 | #---------------------------------------------------------------------- |
---|
2501 | |
---|
2502 | def commit_out_of_date_file(sbox): |
---|
2503 | "try to commit a file that is out-of-date" |
---|
2504 | |
---|
2505 | sbox.build() |
---|
2506 | wc_dir = sbox.wc_dir |
---|
2507 | |
---|
2508 | # Make a backup copy of the working copy |
---|
2509 | wc_backup = sbox.add_wc_path('backup') |
---|
2510 | svntest.actions.duplicate_dir(wc_dir, wc_backup) |
---|
2511 | |
---|
2512 | pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi') |
---|
2513 | backup_pi_path = os.path.join(wc_backup, 'A', 'D', 'G', 'pi') |
---|
2514 | |
---|
2515 | svntest.main.file_append(pi_path, "new line\n") |
---|
2516 | expected_output = svntest.wc.State(wc_dir, { |
---|
2517 | "A/D/G/pi" : Item(verb='Sending'), |
---|
2518 | }) |
---|
2519 | expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
---|
2520 | expected_status.tweak("A/D/G/pi", wc_rev=2, status=" ") |
---|
2521 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
2522 | expected_output, |
---|
2523 | expected_status, |
---|
2524 | None, |
---|
2525 | "-m", "log message", wc_dir) |
---|
2526 | |
---|
2527 | svntest.main.file_append(backup_pi_path, "hello") |
---|
2528 | expected_err = ".*(pi.*out of date|Out of date.*pi).*" |
---|
2529 | svntest.actions.run_and_verify_svn(None, None, expected_err, |
---|
2530 | 'commit', '-m', 'log message', |
---|
2531 | wc_backup) |
---|
2532 | |
---|
2533 | def start_commit_detect_capabilities(sbox): |
---|
2534 | "start-commit hook sees client capabilities" # Issue #2991 |
---|
2535 | sbox.build() |
---|
2536 | wc_dir = sbox.wc_dir |
---|
2537 | repos_dir = sbox.repo_dir |
---|
2538 | |
---|
2539 | # Create a start-commit hook that detects the "mergeinfo" capability. |
---|
2540 | hook_text = "import sys\n" + \ |
---|
2541 | "fp = open(sys.argv[1] + '/hooks.log', 'w')\n" + \ |
---|
2542 | "caps = sys.argv[3].split(':')\n" + \ |
---|
2543 | "if 'mergeinfo' in caps:\n" + \ |
---|
2544 | " fp.write('yes')\n" + \ |
---|
2545 | "else:\n" + \ |
---|
2546 | " fp.write('no')\n" + \ |
---|
2547 | "fp.close()\n" |
---|
2548 | |
---|
2549 | start_commit_hook = svntest.main.get_start_commit_hook_path(repos_dir) |
---|
2550 | svntest.main.create_python_hook_script(start_commit_hook, hook_text) |
---|
2551 | |
---|
2552 | # Commit something. |
---|
2553 | iota_path = os.path.join(wc_dir, "iota") |
---|
2554 | svntest.main.file_append(iota_path, "More stuff in iota") |
---|
2555 | svntest.actions.run_and_verify_svn(None, [], [], 'ci', '--quiet', |
---|
2556 | '-m', 'log msg', wc_dir) |
---|
2557 | |
---|
2558 | # Check that "mergeinfo" was detected. |
---|
2559 | log_path = os.path.join(repos_dir, "hooks.log") |
---|
2560 | if os.path.exists(log_path): |
---|
2561 | data = open(log_path).read() |
---|
2562 | os.unlink(log_path) |
---|
2563 | else: |
---|
2564 | raise svntest.verify.SVNUnexpectedOutput("'%s' not found") % log_path |
---|
2565 | if data != 'yes': |
---|
2566 | raise svntest.Failure |
---|
2567 | |
---|
2568 | def commit_url(sbox): |
---|
2569 | "'svn commit SOME_URL' should error" |
---|
2570 | sbox.build() |
---|
2571 | wc_dir = sbox.wc_dir |
---|
2572 | repos_url = sbox.repo_url |
---|
2573 | |
---|
2574 | # Commit directly to a URL |
---|
2575 | svntest.actions.run_and_verify_commit(None, |
---|
2576 | None, |
---|
2577 | None, |
---|
2578 | "Must give local path", |
---|
2579 | repos_url) |
---|
2580 | |
---|
2581 | # Test for issue #3198 |
---|
2582 | def commit_added_missing(sbox): |
---|
2583 | "commit a missing to-be-added file should fail" |
---|
2584 | |
---|
2585 | sbox.build() |
---|
2586 | wc_dir = sbox.wc_dir |
---|
2587 | mu_path = os.path.join(wc_dir, 'A', 'mu') |
---|
2588 | a_path = os.path.join(wc_dir, 'A', 'a.txt') |
---|
2589 | b_path = os.path.join(wc_dir, 'A', 'b.txt') |
---|
2590 | |
---|
2591 | # Make two copies of mu: a and b |
---|
2592 | svntest.main.run_svn(None, 'cp', mu_path, a_path) |
---|
2593 | svntest.main.run_svn(None, 'cp', mu_path, b_path) |
---|
2594 | |
---|
2595 | # remove b, make it missing |
---|
2596 | os.remove(b_path) |
---|
2597 | |
---|
2598 | # Commit, hoping to see an error |
---|
2599 | svntest.actions.run_and_verify_svn("Commit should have failed", |
---|
2600 | [], ".* is scheduled for addition, but is missing", |
---|
2601 | 'commit', '-m', 'logmsg', wc_dir) |
---|
2602 | |
---|
2603 | #---------------------------------------------------------------------- |
---|
2604 | |
---|
2605 | # Helper for commit-failure tests |
---|
2606 | def commit_fails_at_path(path, wc_dir, error_re): |
---|
2607 | svntest.actions.run_and_verify_commit(wc_dir, |
---|
2608 | None, |
---|
2609 | None, |
---|
2610 | error_re, |
---|
2611 | path) |
---|
2612 | |
---|
2613 | def tree_conflicts_block_commit(sbox): |
---|
2614 | "tree conflicts block commit" |
---|
2615 | |
---|
2616 | # Commit is not allowed in a directory containing tree conflicts. |
---|
2617 | # This test corresponds to use cases 1-3 (with file victims) in |
---|
2618 | # notes/tree-conflicts/use-cases.txt. |
---|
2619 | |
---|
2620 | svntest.actions.build_greek_tree_conflicts(sbox) |
---|
2621 | wc_dir = sbox.wc_dir |
---|
2622 | A = os.path.join(wc_dir, 'A') |
---|
2623 | D = os.path.join(wc_dir, 'A', 'D') |
---|
2624 | G = os.path.join(wc_dir, 'A', 'D', 'G') |
---|
2625 | |
---|
2626 | error_re = "remains in conflict" |
---|
2627 | commit_fails_at_path(wc_dir, wc_dir, error_re) |
---|
2628 | commit_fails_at_path(A, A, error_re) |
---|
2629 | commit_fails_at_path(D, D, error_re) |
---|
2630 | commit_fails_at_path(G, G, error_re) |
---|
2631 | commit_fails_at_path(os.path.join(G, 'pi'), G, error_re) |
---|
2632 | |
---|
2633 | |
---|
2634 | def tree_conflicts_resolved(sbox): |
---|
2635 | "tree conflicts resolved" |
---|
2636 | |
---|
2637 | # Commit is allowed after tree conflicts are resolved. |
---|
2638 | # This test corresponds to use cases 1-3 in |
---|
2639 | # notes/tree-conflicts/use-cases.txt. |
---|
2640 | |
---|
2641 | svntest.actions.build_greek_tree_conflicts(sbox) |
---|
2642 | wc_dir = sbox.wc_dir |
---|
2643 | |
---|
2644 | # Duplicate wc for tests |
---|
2645 | wc_dir_2 = sbox.add_wc_path('2') |
---|
2646 | svntest.actions.duplicate_dir(wc_dir, wc_dir_2) |
---|
2647 | |
---|
2648 | # Mark the tree conflict victims as resolved |
---|
2649 | G = os.path.join(wc_dir, 'A', 'D', 'G') |
---|
2650 | victims = [ os.path.join(G, v) for v in ['pi', 'rho', 'tau'] ] |
---|
2651 | svntest.actions.run_and_verify_resolved(victims) |
---|
2652 | |
---|
2653 | expected_status = svntest.actions.get_virginal_state(wc_dir, 2) |
---|
2654 | expected_status.tweak('A/D/G/pi', status='D ') |
---|
2655 | expected_status.tweak('A/D/G/rho', status='A ', copied='+', wc_rev='-') |
---|
2656 | expected_status.remove('A/D/G/tau') |
---|
2657 | |
---|
2658 | svntest.actions.run_and_verify_status(wc_dir, expected_status) |
---|
2659 | |
---|
2660 | # Recursively resolved in parent directory -- expect same result |
---|
2661 | G2 = os.path.join(wc_dir_2, 'A', 'D', 'G') |
---|
2662 | victims = [ os.path.join(G2, v) for v in ['pi', 'rho', 'tau'] ] |
---|
2663 | svntest.actions.run_and_verify_resolved(victims, G2, '-R') |
---|
2664 | |
---|
2665 | expected_status.wc_dir = wc_dir_2 |
---|
2666 | svntest.actions.run_and_verify_status(wc_dir_2, expected_status) |
---|
2667 | |
---|
2668 | |
---|
2669 | ######################################################################## |
---|
2670 | # Run the tests |
---|
2671 | |
---|
2672 | # list all tests here, starting with None: |
---|
2673 | test_list = [ None, |
---|
2674 | commit_one_file, |
---|
2675 | commit_one_new_file, |
---|
2676 | commit_one_new_binary_file, |
---|
2677 | commit_multiple_targets, |
---|
2678 | commit_multiple_targets_2, |
---|
2679 | commit_inclusive_dir, |
---|
2680 | commit_top_dir, |
---|
2681 | commit_unversioned_thing, |
---|
2682 | nested_dir_replacements, |
---|
2683 | hudson_part_1, |
---|
2684 | hudson_part_1_variation_1, |
---|
2685 | hudson_part_1_variation_2, |
---|
2686 | hudson_part_2, |
---|
2687 | hudson_part_2_1, |
---|
2688 | hook_test, |
---|
2689 | merge_mixed_revisions, |
---|
2690 | commit_uri_unsafe, |
---|
2691 | commit_deleted_edited, |
---|
2692 | commit_in_dir_scheduled_for_addition, |
---|
2693 | commit_rmd_and_deleted_file, |
---|
2694 | commit_add_file_twice, |
---|
2695 | commit_from_long_dir, |
---|
2696 | commit_with_lock, |
---|
2697 | commit_current_dir, |
---|
2698 | commit_multiple_wc, |
---|
2699 | commit_nonrecursive, |
---|
2700 | failed_commit, |
---|
2701 | XFail(commit_out_of_date_deletions, svntest.main.is_ra_type_svn), |
---|
2702 | commit_with_bad_log_message, |
---|
2703 | commit_with_mixed_line_endings, |
---|
2704 | commit_with_mixed_line_endings_in_ignored_part, |
---|
2705 | from_wc_top_with_bad_editor, |
---|
2706 | mods_in_schedule_delete, |
---|
2707 | Skip(tab_test, is_non_posix_os_or_cygwin_platform), |
---|
2708 | local_mods_are_not_commits, |
---|
2709 | post_commit_hook_test, |
---|
2710 | commit_same_folder_in_targets, |
---|
2711 | commit_inconsistent_eol, |
---|
2712 | SkipUnless(mkdir_with_revprop, server_has_revprop_commit), |
---|
2713 | SkipUnless(delete_with_revprop, server_has_revprop_commit), |
---|
2714 | SkipUnless(commit_with_revprop, server_has_revprop_commit), |
---|
2715 | SkipUnless(import_with_revprop, server_has_revprop_commit), |
---|
2716 | SkipUnless(copy_R2R_with_revprop, server_has_revprop_commit), |
---|
2717 | SkipUnless(copy_WC2R_with_revprop, server_has_revprop_commit), |
---|
2718 | SkipUnless(move_R2R_with_revprop, server_has_revprop_commit), |
---|
2719 | SkipUnless(propedit_with_revprop, server_has_revprop_commit), |
---|
2720 | SkipUnless(set_multiple_props_with_revprop, |
---|
2721 | server_has_revprop_commit), |
---|
2722 | SkipUnless(use_empty_value_in_revprop_pair, |
---|
2723 | server_has_revprop_commit), |
---|
2724 | SkipUnless(no_equals_in_revprop_pair, server_has_revprop_commit), |
---|
2725 | SkipUnless(set_invalid_revprops, server_has_revprop_commit), |
---|
2726 | start_commit_hook_test, |
---|
2727 | pre_commit_hook_test, |
---|
2728 | versioned_log_message, |
---|
2729 | changelist_near_conflict, |
---|
2730 | commit_out_of_date_file, |
---|
2731 | SkipUnless(start_commit_detect_capabilities, |
---|
2732 | server_gets_client_capabilities), |
---|
2733 | commit_url, |
---|
2734 | commit_added_missing, |
---|
2735 | tree_conflicts_block_commit, |
---|
2736 | tree_conflicts_resolved, |
---|
2737 | ] |
---|
2738 | |
---|
2739 | if __name__ == '__main__': |
---|
2740 | svntest.main.run_tests(test_list) |
---|
2741 | # NOTREACHED |
---|
2742 | |
---|
2743 | |
---|
2744 | ### End of file. |
---|