Fix compiler warning due to missing function prototype.
[svn.git] / subversion / tests / cmdline / commit_tests.py
blobd5b9668016268820554549a46c08a2e1226cb955
1 #!/usr/bin/env python
3 # commit_tests.py: testing fancy commit cases.
5 # Subversion is a tool for revision control.
6 # See http://subversion.tigris.org for more information.
8 # ====================================================================
9 # Copyright (c) 2000-2007 CollabNet. All rights reserved.
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.
17 ######################################################################
19 # General modules
20 import string, sys, os, re
22 # Our testing module
23 import svntest
25 # (abbreviation)
26 Skip = svntest.testcase.Skip
27 SkipUnless = svntest.testcase.SkipUnless
28 XFail = svntest.testcase.XFail
29 Item = svntest.wc.StateItem
31 from svntest.main import server_has_revprop_commit, \
32 server_gets_client_capabilities
33 from svntest.actions import inject_conflict_into_wc
35 ######################################################################
36 # Utilities
39 def is_non_posix_os_or_cygwin_platform():
40 return (not svntest.main.is_posix_os()) or sys.platform == 'cygwin'
42 def get_standard_state(wc_dir):
43 """Return a status list reflecting the local mods made by
44 make_standard_slew_of_changes()."""
46 state = svntest.actions.get_virginal_state(wc_dir, 1)
48 state.tweak('', 'A/D', 'A/D/G/pi', status=' M')
49 state.tweak('A/B/lambda', status='M ')
50 state.tweak('A/B/E', 'A/D/H/chi', status='R ')
51 state.tweak('A/B/E/alpha', 'A/B/E/beta', 'A/C', 'A/D/gamma',
52 'A/D/G/rho', status='D ')
53 state.tweak('A/D/H/omega', status='MM')
55 # New things
56 state.add({
57 'Q' : Item(status='A ', wc_rev=0),
58 'Q/floo' : Item(status='A ', wc_rev=0),
59 'A/D/H/gloo' : Item(status='A ', wc_rev=0),
60 'A/B/E/bloo' : Item(status='A ', wc_rev=0),
63 return state
66 def make_standard_slew_of_changes(wc_dir):
67 """Make a specific set of local mods to WC_DIR. These will be used
68 by every commit-test. Verify the 'svn status' output, and return the
69 (pre-commit) status tree."""
71 # Cache current working directory, move into wc_dir
72 was_cwd = os.getcwd()
73 os.chdir(wc_dir)
75 # Add a directory
76 os.mkdir('Q')
77 svntest.main.run_svn(None, 'add', 'Q')
79 # Remove two directories
80 svntest.main.run_svn(None, 'rm', os.path.join('A', 'B', 'E'))
81 svntest.main.run_svn(None, 'rm', os.path.join('A', 'C'))
83 # Replace one of the removed directories
84 svntest.main.run_svn(None, 'add', os.path.join('A', 'B', 'E'))
86 # Make property mods to two directories
87 svntest.main.run_svn(None, 'propset', 'foo', 'bar', os.curdir)
88 svntest.main.run_svn(None, 'propset', 'foo2', 'bar2', os.path.join('A', 'D'))
90 # Add three files
91 svntest.main.file_append(os.path.join('A', 'B', 'E', 'bloo'), "hi")
92 svntest.main.file_append(os.path.join('A', 'D', 'H', 'gloo'), "hello")
93 svntest.main.file_append(os.path.join('Q', 'floo'), "yo")
94 svntest.main.run_svn(None, 'add', os.path.join('A', 'B', 'E', 'bloo'))
95 svntest.main.run_svn(None, 'add', os.path.join('A', 'D', 'H', 'gloo'))
96 svntest.main.run_svn(None, 'add', os.path.join('Q', 'floo'))
98 # Remove three files
99 svntest.main.run_svn(None, 'rm', os.path.join('A', 'D', 'G', 'rho'))
100 svntest.main.run_svn(None, 'rm', os.path.join('A', 'D', 'H', 'chi'))
101 svntest.main.run_svn(None, 'rm', os.path.join('A', 'D', 'gamma'))
103 # Replace one of the removed files
104 svntest.main.file_append(os.path.join('A', 'D', 'H', 'chi'), "chi")
105 svntest.main.run_svn(None, 'add', os.path.join('A', 'D', 'H', 'chi'))
107 # Make textual mods to two files
108 svntest.main.file_append(os.path.join('A', 'B', 'lambda'), "new ltext")
109 svntest.main.file_append(os.path.join('A', 'D', 'H', 'omega'), "new otext")
111 # Make property mods to three files
112 svntest.main.run_svn(None, 'propset', 'blue', 'azul',
113 os.path.join('A', 'D', 'H', 'omega'))
114 svntest.main.run_svn(None, 'propset', 'green', 'verde',
115 os.path.join('Q', 'floo'))
116 svntest.main.run_svn(None, 'propset', 'red', 'rojo',
117 os.path.join('A', 'D', 'G', 'pi'))
119 # Restore the CWD.
120 os.chdir(was_cwd)
122 # Build an expected status tree.
123 expected_status = get_standard_state(wc_dir)
125 # Verify status -- all local mods should be present.
126 svntest.actions.run_and_verify_status(wc_dir, expected_status)
128 return expected_status
131 ######################################################################
132 # Tests
134 # Each test must return on success or raise on failure.
137 #----------------------------------------------------------------------
139 def commit_one_file(sbox):
140 "commit one file"
142 sbox.build()
143 wc_dir = sbox.wc_dir
145 expected_status = make_standard_slew_of_changes(wc_dir)
147 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
149 # Create expected state.
150 expected_output = svntest.wc.State(wc_dir, {
151 'A/D/H/omega' : Item(verb='Sending'),
153 expected_status.tweak('A/D/H/omega', wc_rev=2, status=' ')
155 # Commit the one file.
156 svntest.actions.run_and_verify_commit(wc_dir,
157 expected_output,
158 expected_status,
159 None,
160 omega_path)
163 #----------------------------------------------------------------------
165 def commit_one_new_file(sbox):
166 "commit one newly added file"
168 sbox.build()
169 wc_dir = sbox.wc_dir
171 expected_status = make_standard_slew_of_changes(wc_dir)
173 gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo')
175 # Create expected state.
176 expected_output = svntest.wc.State(wc_dir, {
177 'A/D/H/gloo' : Item(verb='Adding'),
179 expected_status.tweak('A/D/H/gloo', wc_rev=2, status=' ')
181 # Commit the one file.
182 svntest.actions.run_and_verify_commit(wc_dir,
183 expected_output,
184 expected_status,
185 None,
186 gloo_path)
189 #----------------------------------------------------------------------
191 def commit_one_new_binary_file(sbox):
192 "commit one newly added binary file"
194 sbox.build()
195 wc_dir = sbox.wc_dir
197 expected_status = make_standard_slew_of_changes(wc_dir)
199 gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo')
200 svntest.main.run_svn(None, 'propset', 'svn:mime-type',
201 'application/octet-stream', gloo_path)
203 # Create expected state.
204 expected_output = svntest.wc.State(wc_dir, {
205 'A/D/H/gloo' : Item(verb='Adding (bin)'),
207 expected_status.tweak('A/D/H/gloo', wc_rev=2, status=' ')
209 # Commit the one file.
210 svntest.actions.run_and_verify_commit(wc_dir,
211 expected_output,
212 expected_status,
213 None,
214 gloo_path)
217 #----------------------------------------------------------------------
219 def commit_multiple_targets(sbox):
220 "commit multiple targets"
222 sbox.build()
223 wc_dir = sbox.wc_dir
225 # This test will commit three targets: psi, B, and pi. In that order.
227 # Make local mods to many files.
228 AB_path = os.path.join(wc_dir, 'A', 'B')
229 lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
230 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
231 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
232 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
233 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
234 svntest.main.file_append(lambda_path, 'new appended text for lambda')
235 svntest.main.file_append(rho_path, 'new appended text for rho')
236 svntest.main.file_append(pi_path, 'new appended text for pi')
237 svntest.main.file_append(omega_path, 'new appended text for omega')
238 svntest.main.file_append(psi_path, 'new appended text for psi')
240 # Just for kicks, add a property to A/D/G as well. We'll make sure
241 # that it *doesn't* get committed.
242 ADG_path = os.path.join(wc_dir, 'A', 'D', 'G')
243 svntest.main.run_svn(None, 'propset', 'foo', 'bar', ADG_path)
245 # Create expected output tree for 'svn ci'. We should see changes
246 # only on these three targets, no others.
247 expected_output = svntest.wc.State(wc_dir, {
248 'A/D/H/psi' : Item(verb='Sending'),
249 'A/B/lambda' : Item(verb='Sending'),
250 'A/D/G/pi' : Item(verb='Sending'),
253 # Create expected status tree; all local revisions should be at 1,
254 # but our three targets should be at 2.
255 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
256 expected_status.tweak('A/D/H/psi', 'A/B/lambda', 'A/D/G/pi', wc_rev=2)
258 # rho and omega should still display as locally modified:
259 expected_status.tweak('A/D/G/rho', 'A/D/H/omega', status='M ')
261 # A/D/G should still have a local property set, too.
262 expected_status.tweak('A/D/G', status=' M')
264 svntest.actions.run_and_verify_commit(wc_dir,
265 expected_output,
266 expected_status,
267 None,
268 psi_path, AB_path, pi_path)
270 #----------------------------------------------------------------------
273 def commit_multiple_targets_2(sbox):
274 "commit multiple targets, 2nd variation"
276 sbox.build()
277 wc_dir = sbox.wc_dir
279 # This test will commit four targets: psi, B, omega and pi. In that order.
281 # Make local mods to many files.
282 AB_path = os.path.join(wc_dir, 'A', 'B')
283 lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
284 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
285 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
286 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
287 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
288 svntest.main.file_append(lambda_path, 'new appended text for lambda')
289 svntest.main.file_append(rho_path, 'new appended text for rho')
290 svntest.main.file_append(pi_path, 'new appended text for pi')
291 svntest.main.file_append(omega_path, 'new appended text for omega')
292 svntest.main.file_append(psi_path, 'new appended text for psi')
294 # Just for kicks, add a property to A/D/G as well. We'll make sure
295 # that it *doesn't* get committed.
296 ADG_path = os.path.join(wc_dir, 'A', 'D', 'G')
297 svntest.main.run_svn(None, 'propset', 'foo', 'bar', ADG_path)
299 # Created expected output tree for 'svn ci'. We should see changes
300 # only on these three targets, no others.
301 expected_output = svntest.wc.State(wc_dir, {
302 'A/D/H/psi' : Item(verb='Sending'),
303 'A/B/lambda' : Item(verb='Sending'),
304 'A/D/H/omega' : Item(verb='Sending'),
305 'A/D/G/pi' : Item(verb='Sending'),
308 # Create expected status tree; all local revisions should be at 1,
309 # but our four targets should be at 2.
310 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
311 expected_status.tweak('A/D/H/psi', 'A/B/lambda', 'A/D/G/pi', 'A/D/H/omega',
312 wc_rev=2)
314 # rho should still display as locally modified:
315 expected_status.tweak('A/D/G/rho', status='M ')
317 # A/D/G should still have a local property set, too.
318 expected_status.tweak('A/D/G', status=' M')
320 svntest.actions.run_and_verify_commit(wc_dir,
321 expected_output,
322 expected_status,
323 None,
324 psi_path, AB_path,
325 omega_path, pi_path)
327 #----------------------------------------------------------------------
329 def commit_inclusive_dir(sbox):
330 "commit wc_dir/A/D -- includes D. (anchor=A, tgt=D)"
332 sbox.build()
333 wc_dir = sbox.wc_dir
335 expected_status = make_standard_slew_of_changes(wc_dir)
337 D_path = os.path.join(wc_dir, 'A', 'D')
339 # Create expected state.
340 expected_output = svntest.wc.State(wc_dir, {
341 'A/D' : Item(verb='Sending'),
342 'A/D/G/pi' : Item(verb='Sending'),
343 'A/D/G/rho' : Item(verb='Deleting'),
344 'A/D/H/gloo' : Item(verb='Adding'),
345 'A/D/H/chi' : Item(verb='Replacing'),
346 'A/D/H/omega' : Item(verb='Sending'),
347 'A/D/gamma' : Item(verb='Deleting'),
350 expected_status.remove('A/D/G/rho', 'A/D/gamma')
351 expected_status.tweak('A/D', 'A/D/G/pi', 'A/D/H/omega',
352 wc_rev=2, status=' ')
353 expected_status.tweak('A/D/H/chi', 'A/D/H/gloo', wc_rev=2, status=' ')
355 # Commit the one file.
356 svntest.actions.run_and_verify_commit(wc_dir,
357 expected_output,
358 expected_status,
359 None,
360 D_path)
362 #----------------------------------------------------------------------
364 def commit_top_dir(sbox):
365 "commit wc_dir -- (anchor=wc_dir, tgt={})"
367 sbox.build()
368 wc_dir = sbox.wc_dir
370 expected_status = make_standard_slew_of_changes(wc_dir)
372 # Create expected state.
373 expected_output = svntest.wc.State(wc_dir, {
374 '' : Item(verb='Sending'),
375 'Q' : Item(verb='Adding'),
376 'Q/floo' : Item(verb='Adding'),
377 'A/B/E' : Item(verb='Replacing'),
378 'A/B/E/bloo' : Item(verb='Adding'),
379 'A/B/lambda' : Item(verb='Sending'),
380 'A/C' : Item(verb='Deleting'),
381 'A/D' : Item(verb='Sending'),
382 'A/D/G/pi' : Item(verb='Sending'),
383 'A/D/G/rho' : Item(verb='Deleting'),
384 'A/D/H/gloo' : Item(verb='Adding'),
385 'A/D/H/chi' : Item(verb='Replacing'),
386 'A/D/H/omega' : Item(verb='Sending'),
387 'A/D/gamma' : Item(verb='Deleting'),
390 expected_status.remove('A/D/G/rho', 'A/D/gamma', 'A/C',
391 'A/B/E/alpha', 'A/B/E/beta')
392 expected_status.tweak('A/D', 'A/D/G/pi', 'A/D/H/omega', 'Q/floo', '',
393 wc_rev=2, status=' ')
394 expected_status.tweak('A/D/H/chi', 'Q', 'A/B/E', 'A/B/E/bloo', 'A/B/lambda',
395 'A/D/H/gloo', wc_rev=2, status=' ')
397 # Commit the one file.
398 svntest.actions.run_and_verify_commit(wc_dir,
399 expected_output,
400 expected_status,
401 None,
402 wc_dir)
404 #----------------------------------------------------------------------
406 # Regression test for bug reported by Jon Trowbridge:
408 # From: Jon Trowbridge <trow@ximian.com>
409 # Subject: svn segfaults if you commit a file that hasn't been added
410 # To: dev@subversion.tigris.org
411 # Date: 17 Jul 2001 03:20:55 -0500
412 # Message-Id: <995358055.16975.5.camel@morimoto>
414 # The problem is that report_single_mod in libsvn_wc/adm_crawler.c is
415 # called with its entry parameter as NULL, but the code doesn't
416 # check that entry is non-NULL before trying to dereference it.
418 # This bug never had an issue number.
420 def commit_unversioned_thing(sbox):
421 "committing unversioned object produces error"
423 sbox.build()
424 wc_dir = sbox.wc_dir
426 # Create an unversioned file in the wc.
427 svntest.main.file_append(os.path.join(wc_dir, 'blorg'), "nothing to see")
429 # Commit a non-existent file and *expect* failure:
430 svntest.actions.run_and_verify_commit(wc_dir,
431 None,
432 None,
433 "is not under version control",
434 os.path.join(wc_dir,'blorg'))
436 #----------------------------------------------------------------------
438 # regression test for bug #391
440 def nested_dir_replacements(sbox):
441 "replace two nested dirs, verify empty contents"
443 sbox.build()
444 wc_dir = sbox.wc_dir
446 # Delete and re-add A/D (a replacement), and A/D/H (another replace).
447 svntest.main.run_svn(None, 'rm', os.path.join(wc_dir, 'A', 'D'))
448 svntest.main.run_svn(None, 'add', '--depth=empty',
449 os.path.join(wc_dir, 'A', 'D'))
450 svntest.main.run_svn(None, 'add', '--depth=empty',
451 os.path.join(wc_dir, 'A', 'D', 'H'))
453 # For kicks, add new file A/D/bloo.
454 svntest.main.file_append(os.path.join(wc_dir, 'A', 'D', 'bloo'), "hi")
455 svntest.main.run_svn(None, 'add', os.path.join(wc_dir, 'A', 'D', 'bloo'))
457 # Verify pre-commit status:
459 # - A/D and A/D/H should both be scheduled as "R" at rev 1
460 # (rev 1 because they both existed before at rev 1)
462 # - A/D/bloo scheduled as "A" at rev 0
463 # (rev 0 because it did not exist before)
465 # - ALL other children of A/D scheduled as "D" at rev 1
467 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
468 expected_status.tweak('A/D', 'A/D/H', status='R ', wc_rev=1)
469 expected_status.add({
470 'A/D/bloo' : Item(status='A ', wc_rev=0),
472 expected_status.tweak('A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau',
473 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi', 'A/D/gamma',
474 status='D ')
476 svntest.actions.run_and_verify_status(wc_dir, expected_status)
478 # Build expected post-commit trees:
480 # Create expected output tree.
481 expected_output = svntest.wc.State(wc_dir, {
482 'A/D' : Item(verb='Replacing'),
483 'A/D/H' : Item(verb='Adding'),
484 'A/D/bloo' : Item(verb='Adding'),
487 # Created expected status tree.
488 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
489 expected_status.tweak('A/D', 'A/D/H', wc_rev=2)
490 expected_status.add({
491 'A/D/bloo' : Item(status=' ', wc_rev=2),
493 expected_status.remove('A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau',
494 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi', 'A/D/gamma')
496 # Commit from the top of the working copy and verify output & status.
497 svntest.actions.run_and_verify_commit(wc_dir,
498 expected_output,
499 expected_status,
500 None,
501 wc_dir)
503 #----------------------------------------------------------------------
505 # Testing part 1 of the "Greg Hudson" problem -- specifically, that
506 # our use of the "existence=deleted" flag is working properly in cases
507 # where the parent directory's revision lags behind a deleted child's
508 # revision.
510 def hudson_part_1(sbox):
511 "hudson prob 1.0: delete file, commit, update"
513 sbox.build()
514 wc_dir = sbox.wc_dir
516 # Remove gamma from the working copy.
517 gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
518 svntest.main.run_svn(None, 'rm', gamma_path)
520 # Create expected commit output.
521 expected_output = svntest.wc.State(wc_dir, {
522 'A/D/gamma' : Item(verb='Deleting'),
525 # After committing, status should show no sign of gamma.
526 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
527 expected_status.remove('A/D/gamma')
529 # Commit the deletion of gamma and verify.
530 svntest.actions.run_and_verify_commit(wc_dir,
531 expected_output,
532 expected_status,
533 None, wc_dir)
535 # Now gamma should be marked as `deleted' under the hood. When we
536 # update, we should no output, and a perfect, virginal status list
537 # at revision 2. (The `deleted' entry should be removed.)
539 # Expected output of update: nothing.
540 expected_output = svntest.wc.State(wc_dir, {})
542 # Expected disk tree: everything but gamma
543 expected_disk = svntest.main.greek_state.copy()
544 expected_disk.remove('A/D/gamma')
546 # Expected status after update: totally clean revision 2, minus gamma.
547 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
548 expected_status.remove('A/D/gamma')
550 svntest.actions.run_and_verify_update(wc_dir,
551 expected_output,
552 expected_disk,
553 expected_status)
556 #----------------------------------------------------------------------
558 # Testing part 1 of the "Greg Hudson" problem -- variation on previous
559 # test, removing a directory instead of a file this time.
561 def hudson_part_1_variation_1(sbox):
562 "hudson prob 1.1: delete dir, commit, update"
564 sbox.build()
565 wc_dir = sbox.wc_dir
567 # Remove H from the working copy.
568 H_path = os.path.join(wc_dir, 'A', 'D', 'H')
569 svntest.main.run_svn(None, 'rm', H_path)
571 # Create expected commit output.
572 expected_output = svntest.wc.State(wc_dir, {
573 'A/D/H' : Item(verb='Deleting'),
576 # After committing, status should show no sign of H or its contents
577 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
578 expected_status.remove('A/D/H', 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi')
580 # Commit the deletion of H and verify.
581 svntest.actions.run_and_verify_commit(wc_dir,
582 expected_output,
583 expected_status,
584 None, wc_dir)
586 # Now H should be marked as `deleted' under the hood. When we
587 # update, we should no see output, and a perfect, virginal status
588 # list at revision 2. (The `deleted' entry should be removed.)
590 # Expected output of update: H gets a no-op deletion.
591 expected_output = svntest.wc.State(wc_dir, {})
593 # Expected disk tree: everything except files in H
594 expected_disk = svntest.main.greek_state.copy()
595 expected_disk.remove('A/D/H', 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi')
597 # Expected status after update: totally clean revision 2, minus H.
598 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
599 expected_status.remove('A/D/H', 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi')
601 svntest.actions.run_and_verify_update(wc_dir,
602 expected_output,
603 expected_disk,
604 expected_status)
606 #----------------------------------------------------------------------
608 # Testing part 1 of the "Greg Hudson" problem -- variation 2. In this
609 # test, we make sure that a file that is BOTH `deleted' and scheduled
610 # for addition can be correctly committed & merged.
612 def hudson_part_1_variation_2(sbox):
613 "hudson prob 1.2: delete, commit, re-add, commit"
615 sbox.build()
616 wc_dir = sbox.wc_dir
618 # Remove gamma from the working copy.
619 gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
620 svntest.main.run_svn(None, 'rm', gamma_path)
622 # Create expected commit output.
623 expected_output = svntest.wc.State(wc_dir, {
624 'A/D/gamma' : Item(verb='Deleting'),
627 # After committing, status should show no sign of gamma.
628 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
629 expected_status.remove('A/D/gamma')
631 # Commit the deletion of gamma and verify.
632 svntest.actions.run_and_verify_commit(wc_dir,
633 expected_output,
634 expected_status,
635 None, wc_dir)
637 # Now gamma should be marked as `deleted' under the hood.
638 # Go ahead and re-add gamma, so that is *also* scheduled for addition.
639 svntest.main.file_append(gamma_path, "added gamma")
640 svntest.main.run_svn(None, 'add', gamma_path)
642 # For sanity, examine status: it should show a revision 2 tree with
643 # gamma scheduled for addition.
644 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
645 expected_status.tweak('A/D/gamma', wc_rev=0, status='A ')
647 svntest.actions.run_and_verify_status(wc_dir, expected_status)
649 # Create expected commit output.
650 expected_output = svntest.wc.State(wc_dir, {
651 'A/D/gamma' : Item(verb='Adding'),
654 # After committing, status should show only gamma at revision 3.
655 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
656 expected_status.tweak('A/D/gamma', wc_rev=3)
658 svntest.actions.run_and_verify_commit(wc_dir,
659 expected_output,
660 expected_status,
661 None, wc_dir)
664 #----------------------------------------------------------------------
666 # Testing part 2 of the "Greg Hudson" problem.
668 # In this test, we make sure that we're UNABLE to commit a propchange
669 # on an out-of-date directory.
671 def hudson_part_2(sbox):
672 "hudson prob 2.0: prop commit on old dir fails"
674 sbox.build()
675 wc_dir = sbox.wc_dir
677 # Remove gamma from the working copy.
678 D_path = os.path.join(wc_dir, 'A', 'D')
679 gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
680 svntest.main.run_svn(None, 'rm', gamma_path)
682 # Create expected commit output.
683 expected_output = svntest.wc.State(wc_dir, {
684 'A/D/gamma' : Item(verb='Deleting'),
687 # After committing, status should show no sign of gamma.
688 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
689 expected_status.remove('A/D/gamma')
691 # Commit the deletion of gamma and verify.
692 svntest.actions.run_and_verify_commit(wc_dir,
693 expected_output,
694 expected_status,
695 None, wc_dir)
697 # Now gamma should be marked as `deleted' under the hood, at
698 # revision 2. Meanwhile, A/D is still lagging at revision 1.
700 # Make a propchange on A/D
701 svntest.main.run_svn(None, 'ps', 'foo', 'bar', D_path)
703 # Commit and *expect* a repository Merge failure:
704 svntest.actions.run_and_verify_commit(wc_dir,
705 None,
706 None,
707 "[Oo]ut.of.date",
708 wc_dir)
710 #----------------------------------------------------------------------
712 # Test a possible regression in our 'deleted' post-commit handling.
714 # This test moves files from one subdir to another, commits, then
715 # updates the empty directory. Nothing should be printed, assuming
716 # all the moved files are properly marked as 'deleted' and reported to
717 # the server.
719 def hudson_part_2_1(sbox):
720 "hudson prob 2.1: move files, update empty dir"
722 sbox.build()
723 wc_dir = sbox.wc_dir
725 # Move all the files in H to G
726 H_path = os.path.join(wc_dir, 'A', 'D', 'H')
727 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
728 chi_path = os.path.join(H_path, 'chi')
729 psi_path = os.path.join(H_path, 'psi')
730 omega_path = os.path.join(H_path, 'omega')
732 svntest.main.run_svn(None, 'mv', chi_path, G_path)
733 svntest.main.run_svn(None, 'mv', psi_path, G_path)
734 svntest.main.run_svn(None, 'mv', omega_path, G_path)
736 # Create expected commit output.
737 expected_output = svntest.wc.State(wc_dir, {
738 'A/D/H/chi' : Item(verb='Deleting'),
739 'A/D/H/omega' : Item(verb='Deleting'),
740 'A/D/H/psi' : Item(verb='Deleting'),
741 'A/D/G/chi' : Item(verb='Adding'),
742 'A/D/G/omega' : Item(verb='Adding'),
743 'A/D/G/psi' : Item(verb='Adding'),
746 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
747 expected_status.remove('A/D/H/chi')
748 expected_status.remove('A/D/H/omega')
749 expected_status.remove('A/D/H/psi')
750 expected_status.add({ 'A/D/G/chi' :
751 Item(wc_rev=2, status=' ') })
752 expected_status.add({ 'A/D/G/omega' :
753 Item(wc_rev=2, status=' ') })
754 expected_status.add({ 'A/D/G/psi' :
755 Item(wc_rev=2, status=' ') })
757 svntest.actions.run_and_verify_commit(wc_dir,
758 expected_output,
759 expected_status,
760 None, wc_dir)
762 # Now, assuming all three files in H are marked as 'deleted', an
763 # update of H should print absolutely nothing.
764 expected_output = svntest.wc.State(wc_dir, { })
766 # Reuse expected_status
767 expected_status.tweak(wc_rev=2)
769 expected_disk = svntest.main.greek_state.copy()
770 expected_disk.remove('A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi')
771 expected_disk.add({
772 'A/D/G/chi' : Item("This is the file 'chi'.\n"),
774 expected_disk.add({
775 'A/D/G/omega' : Item("This is the file 'omega'.\n"),
777 expected_disk.add({
778 'A/D/G/psi' : Item("This is the file 'psi'.\n"),
781 svntest.actions.run_and_verify_update(wc_dir,
782 expected_output,
783 expected_disk,
784 expected_status)
786 #----------------------------------------------------------------------
788 def hook_test(sbox):
789 "hook testing"
791 sbox.build()
793 # Get paths to the working copy and repository
794 wc_dir = sbox.wc_dir
795 repo_dir = sbox.repo_dir
797 # Create a hook that appends its name to a log file.
798 hook_format = """import sys
799 fp = open(sys.argv[1] + '/hooks.log', 'a')
800 fp.write("%s\\n")
801 fp.close()"""
803 # Setup the hook configs to log data to a file
804 start_commit_hook = svntest.main.get_start_commit_hook_path(repo_dir)
805 svntest.main.create_python_hook_script(start_commit_hook,
806 hook_format % "start_commit_hook")
808 pre_commit_hook = svntest.main.get_pre_commit_hook_path(repo_dir)
809 svntest.main.create_python_hook_script(pre_commit_hook,
810 hook_format % "pre_commit_hook")
812 post_commit_hook = svntest.main.get_post_commit_hook_path(repo_dir)
813 svntest.main.create_python_hook_script(post_commit_hook,
814 hook_format % "post_commit_hook")
816 # Modify iota just so there is something to commit.
817 iota_path = os.path.join(wc_dir, "iota")
818 svntest.main.file_append(iota_path, "More stuff in iota")
820 # Commit, no output expected.
821 svntest.actions.run_and_verify_svn(None, [], [],
822 'ci', '--quiet',
823 '-m', 'log msg', wc_dir)
825 # Now check the logfile
826 expected_data = [ 'start_commit_hook\n', 'pre_commit_hook\n', 'post_commit_hook\n' ]
828 logfilename = os.path.join(repo_dir, "hooks.log")
829 if os.path.exists(logfilename):
830 fp = open(logfilename)
831 else:
832 raise svntest.verify.SVNUnexpectedOutput("hook logfile %s not found")\
833 % logfilename
835 actual_data = fp.readlines()
836 fp.close()
837 os.unlink(logfilename)
838 svntest.verify.compare_and_display_lines('wrong hook logfile content',
839 'STDERR',
840 expected_data, actual_data)
842 #----------------------------------------------------------------------
844 # Regression test for bug #469, whereby merge() was once reporting
845 # erroneous conflicts due to Ancestor < Target < Source, in terms of
846 # node-rev-id parentage.
848 def merge_mixed_revisions(sbox):
849 "commit mixed-rev wc (no erroneous merge error)"
851 sbox.build()
852 wc_dir = sbox.wc_dir
854 # Make some convenient paths.
855 iota_path = os.path.join(wc_dir, 'iota')
856 H_path = os.path.join(wc_dir, 'A', 'D', 'H')
857 chi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'chi')
858 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
860 # Here's the reproduction formula, in 5 parts.
861 # Hoo, what a buildup of state!
863 # 1. echo "moo" >> iota; echo "moo" >> A/D/H/chi; svn ci
864 svntest.main.file_append(iota_path, "moo")
865 svntest.main.file_append(chi_path, "moo")
867 expected_output = svntest.wc.State(wc_dir, {
868 'iota' : Item(verb='Sending'),
869 'A/D/H/chi' : Item(verb='Sending'),
872 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
873 expected_status.tweak('iota', 'A/D/H/chi', wc_rev=2)
875 svntest.actions.run_and_verify_commit(wc_dir,
876 expected_output,
877 expected_status,
878 None, wc_dir)
881 # 2. svn up A/D/H
882 expected_status = svntest.wc.State(wc_dir, {
883 'A/D/H' : Item(status=' ', wc_rev=2),
884 'A/D/H/chi' : Item(status=' ', wc_rev=2),
885 'A/D/H/omega' : Item(status=' ', wc_rev=2),
886 'A/D/H/psi' : Item(status=' ', wc_rev=2),
888 expected_disk = svntest.wc.State('', {
889 'omega' : Item("This is the file 'omega'.\n"),
890 'chi' : Item("This is the file 'chi'.\nmoo"),
891 'psi' : Item("This is the file 'psi'.\n"),
893 expected_output = svntest.wc.State(wc_dir, { })
894 svntest.actions.run_and_verify_update(H_path,
895 expected_output,
896 expected_disk,
897 expected_status)
900 # 3. echo "moo" >> iota; svn ci iota
901 svntest.main.file_append(iota_path, "moo2")
902 expected_output = svntest.wc.State(wc_dir, {
903 'iota' : Item(verb='Sending'),
905 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
906 expected_status.tweak('A/D/H', 'A/D/H/omega', 'A/D/H/chi', 'A/D/H/psi',
907 wc_rev=2)
908 expected_status.tweak('iota', wc_rev=3)
910 svntest.actions.run_and_verify_commit(wc_dir,
911 expected_output,
912 expected_status,
913 None, wc_dir)
916 # 4. echo "moo" >> A/D/H/chi; svn ci A/D/H/chi
917 svntest.main.file_append(chi_path, "moo3")
918 expected_output = svntest.wc.State(wc_dir, {
919 'A/D/H/chi' : Item(verb='Sending'),
921 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
922 expected_status.tweak('A/D/H/chi', wc_rev=4)
923 expected_status.tweak('A/D/H', 'A/D/H/omega', 'A/D/H/psi', wc_rev=2)
924 expected_status.tweak('iota', wc_rev=3)
925 svntest.actions.run_and_verify_commit(wc_dir,
926 expected_output,
927 expected_status,
928 None, wc_dir)
930 # 5. echo "moo" >> iota; svn ci iota
931 svntest.main.file_append(iota_path, "moomoo")
932 expected_output = svntest.wc.State(wc_dir, {
933 'iota' : Item(verb='Sending'),
935 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
936 expected_status.tweak('A/D/H', 'A/D/H/omega', 'A/D/H/psi', wc_rev=2)
937 expected_status.tweak('A/D/H/chi', wc_rev=4)
938 expected_status.tweak('iota', wc_rev=5)
939 svntest.actions.run_and_verify_commit(wc_dir,
940 expected_output,
941 expected_status,
942 None, wc_dir)
944 # At this point, here is what our tree should look like:
945 # _ 1 ( 5) working_copies/commit_tests-10
946 # _ 1 ( 5) working_copies/commit_tests-10/A
947 # _ 1 ( 5) working_copies/commit_tests-10/A/B
948 # _ 1 ( 5) working_copies/commit_tests-10/A/B/E
949 # _ 1 ( 5) working_copies/commit_tests-10/A/B/E/alpha
950 # _ 1 ( 5) working_copies/commit_tests-10/A/B/E/beta
951 # _ 1 ( 5) working_copies/commit_tests-10/A/B/F
952 # _ 1 ( 5) working_copies/commit_tests-10/A/B/lambda
953 # _ 1 ( 5) working_copies/commit_tests-10/A/C
954 # _ 1 ( 5) working_copies/commit_tests-10/A/D
955 # _ 1 ( 5) working_copies/commit_tests-10/A/D/G
956 # _ 1 ( 5) working_copies/commit_tests-10/A/D/G/pi
957 # _ 1 ( 5) working_copies/commit_tests-10/A/D/G/rho
958 # _ 1 ( 5) working_copies/commit_tests-10/A/D/G/tau
959 # _ 2 ( 5) working_copies/commit_tests-10/A/D/H
960 # _ 4 ( 5) working_copies/commit_tests-10/A/D/H/chi
961 # _ 2 ( 5) working_copies/commit_tests-10/A/D/H/omega
962 # _ 2 ( 5) working_copies/commit_tests-10/A/D/H/psi
963 # _ 1 ( 5) working_copies/commit_tests-10/A/D/gamma
964 # _ 1 ( 5) working_copies/commit_tests-10/A/mu
965 # _ 5 ( 5) working_copies/commit_tests-10/iota
967 # At this point, we're ready to modify omega and iota, and commit
968 # from the top. We should *not* get a conflict!
970 svntest.main.file_append(iota_path, "finalmoo")
971 svntest.main.file_append(omega_path, "finalmoo")
973 expected_output = svntest.wc.State(wc_dir, {
974 'iota' : Item(verb='Sending'),
975 'A/D/H/omega' : Item(verb='Sending'),
977 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
978 expected_status.tweak('iota', 'A/D/H/omega', wc_rev=6)
979 expected_status.tweak('A/D/H', 'A/D/H/psi', wc_rev=2)
980 expected_status.tweak('A/D/H/chi', wc_rev=4)
981 svntest.actions.run_and_verify_commit(wc_dir,
982 expected_output,
983 expected_status,
984 None, wc_dir)
986 #----------------------------------------------------------------------
988 def commit_uri_unsafe(sbox):
989 "commit files and dirs with URI-unsafe characters"
991 sbox.build()
992 wc_dir = sbox.wc_dir
994 # Note: on Windows, files can't have angle brackets in them, so we
995 # don't tests that case.
996 if svntest.main.windows or sys.platform == 'cygwin':
997 angle_name = '_angle_'
998 nasty_name = '#![]{}()__%'
999 else:
1000 angle_name = '<angle>'
1001 nasty_name = '#![]{}()<>%'
1003 # Make some convenient paths.
1004 hash_dir = os.path.join(wc_dir, '#hash#')
1005 nasty_dir = os.path.join(wc_dir, nasty_name)
1006 space_path = os.path.join(wc_dir, 'A', 'D', 'space path')
1007 bang_path = os.path.join(wc_dir, 'A', 'D', 'H', 'bang!')
1008 bracket_path = os.path.join(wc_dir, 'A', 'D', 'H', 'bra[ket')
1009 brace_path = os.path.join(wc_dir, 'A', 'D', 'H', 'bra{e')
1010 angle_path = os.path.join(wc_dir, 'A', 'D', 'H', angle_name)
1011 paren_path = os.path.join(wc_dir, 'A', 'D', 'pare)(theses')
1012 percent_path = os.path.join(wc_dir, '#hash#', 'percen%')
1013 nasty_path = os.path.join(wc_dir, 'A', nasty_name)
1015 os.mkdir(hash_dir)
1016 os.mkdir(nasty_dir)
1017 svntest.main.file_append(space_path, "This path has a space in it.")
1018 svntest.main.file_append(bang_path, "This path has a bang in it.")
1019 svntest.main.file_append(bracket_path, "This path has a bracket in it.")
1020 svntest.main.file_append(brace_path, "This path has a brace in it.")
1021 svntest.main.file_append(angle_path, "This path has angle brackets in it.")
1022 svntest.main.file_append(paren_path, "This path has parentheses in it.")
1023 svntest.main.file_append(percent_path, "This path has a percent in it.")
1024 svntest.main.file_append(nasty_path, "This path has all sorts of ick in it.")
1026 add_list = [hash_dir,
1027 nasty_dir, # not xml-safe
1028 space_path,
1029 bang_path,
1030 bracket_path,
1031 brace_path,
1032 angle_path, # not xml-safe
1033 paren_path,
1034 percent_path,
1035 nasty_path, # not xml-safe
1037 for item in add_list:
1038 svntest.main.run_svn(None, 'add', '--depth=empty', item)
1040 expected_output = svntest.wc.State(wc_dir, {
1041 '#hash#' : Item(verb='Adding'),
1042 nasty_name : Item(verb='Adding'),
1043 'A/D/space path' : Item(verb='Adding'),
1044 'A/D/H/bang!' : Item(verb='Adding'),
1045 'A/D/H/bra[ket' : Item(verb='Adding'),
1046 'A/D/H/bra{e' : Item(verb='Adding'),
1047 'A/D/H/' + angle_name : Item(verb='Adding'),
1048 'A/D/pare)(theses' : Item(verb='Adding'),
1049 '#hash#/percen%' : Item(verb='Adding'),
1050 'A/' + nasty_name : Item(verb='Adding'),
1053 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1055 # Items in our add list will be at rev 2
1056 for item in expected_output.desc.keys():
1057 expected_status.add({ item : Item(wc_rev=2, status=' ') })
1059 svntest.actions.run_and_verify_commit(wc_dir,
1060 expected_output,
1061 expected_status,
1062 None, wc_dir)
1065 #----------------------------------------------------------------------
1067 def commit_deleted_edited(sbox):
1068 "commit deleted yet edited files"
1070 sbox.build()
1071 wc_dir = sbox.wc_dir
1073 # Make some convenient paths.
1074 iota_path = os.path.join(wc_dir, 'iota')
1075 mu_path = os.path.join(wc_dir, 'A', 'mu')
1077 # Edit the files.
1078 svntest.main.file_append(iota_path, "This file has been edited.")
1079 svntest.main.file_append(mu_path, "This file has been edited.")
1081 # Schedule the files for removal.
1082 svntest.main.run_svn(None, 'remove', '--force', iota_path)
1083 svntest.main.run_svn(None, 'remove', '--force', mu_path)
1085 # Make our output list
1086 expected_output = svntest.wc.State(wc_dir, {
1087 'iota' : Item(verb='Deleting'),
1088 'A/mu' : Item(verb='Deleting'),
1091 # Items in the status list are all at rev 1, except the two things
1092 # we changed...but then, they don't exist at all.
1093 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1094 expected_status.remove('iota', 'A/mu')
1096 svntest.actions.run_and_verify_commit(wc_dir,
1097 expected_output,
1098 expected_status,
1099 None, wc_dir)
1101 #----------------------------------------------------------------------
1103 def commit_in_dir_scheduled_for_addition(sbox):
1104 "commit a file inside dir scheduled for addition"
1106 sbox.build()
1107 wc_dir = sbox.wc_dir
1109 A_path = os.path.join(wc_dir, 'A')
1110 Z_path = os.path.join(wc_dir, 'Z')
1111 mu_path = os.path.join(wc_dir, 'Z', 'mu')
1113 svntest.main.run_svn(None, 'move', A_path, Z_path)
1115 # Commit a copied thing inside an added-with-history directory,
1116 # expecting a specific error to occur!
1117 svntest.actions.run_and_verify_commit(wc_dir,
1118 None,
1119 None,
1120 "unversioned",
1121 mu_path)
1123 Q_path = os.path.join(wc_dir, 'Q')
1124 bloo_path = os.path.join(Q_path, 'bloo')
1126 os.mkdir(Q_path)
1127 svntest.main.file_append(bloo_path, "New contents.")
1128 svntest.main.run_svn(None, 'add', Q_path)
1130 # Commit a regular added thing inside an added directory,
1131 # expecting a specific error to occur!
1132 svntest.actions.run_and_verify_commit(wc_dir,
1133 None,
1134 None,
1135 "not under version control",
1136 bloo_path)
1138 #----------------------------------------------------------------------
1140 # Does this make sense now that deleted files are always removed from the wc?
1141 def commit_rmd_and_deleted_file(sbox):
1142 "commit deleted (and missing) file"
1144 sbox.build()
1145 wc_dir = sbox.wc_dir
1146 mu_path = os.path.join(wc_dir, 'A', 'mu')
1148 # 'svn remove' mu
1149 svntest.main.run_svn(None, 'rm', mu_path)
1151 # Commit, hoping to see no errors
1152 svntest.actions.run_and_verify_svn("Output on stderr where none expected",
1153 svntest.verify.AnyOutput, [],
1154 'commit', '-m', 'logmsg', mu_path)
1156 #----------------------------------------------------------------------
1158 # Issue #644 which failed over ra_neon.
1159 def commit_add_file_twice(sbox):
1160 "issue 644 attempt to add a file twice"
1162 sbox.build()
1163 wc_dir = sbox.wc_dir
1165 # Create a file
1166 gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo')
1167 svntest.main.file_append(gloo_path, "hello")
1168 svntest.main.run_svn(None, 'add', gloo_path)
1170 # Create expected output tree.
1171 expected_output = svntest.wc.State(wc_dir, {
1172 'A/D/H/gloo' : Item(verb='Adding'),
1175 # Created expected status tree.
1176 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1177 expected_status.add({
1178 'A/D/H/gloo' : Item(status=' ', wc_rev=2),
1181 # Commit should succeed
1182 svntest.actions.run_and_verify_commit(wc_dir,
1183 expected_output,
1184 expected_status,
1185 None,
1186 wc_dir)
1188 # Update to state before commit
1189 svntest.main.run_svn(None, 'up', '-r', '1', wc_dir)
1191 # Create the file again
1192 svntest.main.file_append(gloo_path, "hello")
1193 svntest.main.run_svn(None, 'add', gloo_path)
1195 # Commit and *expect* a failure:
1196 svntest.actions.run_and_verify_commit(wc_dir,
1197 None,
1198 None,
1199 "already exists",
1200 wc_dir)
1202 #----------------------------------------------------------------------
1204 # There was a problem that committing from a directory that had a
1205 # longer name than the working copy directory caused the commit notify
1206 # messages to display truncated/random filenames.
1208 def commit_from_long_dir(sbox):
1209 "commit from a dir with a longer name than the wc"
1211 sbox.build()
1212 wc_dir = sbox.wc_dir
1214 was_dir = os.getcwd()
1215 abs_wc_dir = os.path.realpath(os.path.join(was_dir, wc_dir))
1217 # something to commit
1218 svntest.main.file_append(os.path.join(wc_dir, 'iota'), "modified iota")
1220 # Create expected output tree.
1221 expected_output = svntest.wc.State('', {
1222 'iota' : Item(verb='Sending'),
1225 # Any length name was enough to provoke the original bug, but
1226 # keeping its length less than that of the filename 'iota' avoided
1227 # random behaviour, but still caused the test to fail
1228 extra_name = 'xx'
1230 os.chdir(wc_dir)
1231 os.mkdir(extra_name)
1232 os.chdir(extra_name)
1234 svntest.actions.run_and_verify_commit(abs_wc_dir,
1235 expected_output,
1236 None,
1237 None,
1238 abs_wc_dir)
1240 #----------------------------------------------------------------------
1242 def commit_with_lock(sbox):
1243 "try to commit when directory is locked"
1245 sbox.build()
1246 # modify gamma and lock its directory
1247 wc_dir = sbox.wc_dir
1249 D_path = os.path.join(wc_dir, 'A', 'D')
1250 gamma_path = os.path.join(D_path, 'gamma')
1251 svntest.main.file_append(gamma_path, "modified gamma")
1252 svntest.actions.lock_admin_dir(D_path)
1254 # this commit should fail
1255 svntest.actions.run_and_verify_commit(wc_dir,
1256 None,
1257 None,
1258 'svn: Working copy \'.*\' locked',
1259 wc_dir)
1261 # unlock directory
1262 svntest.actions.run_and_verify_svn("Output on stderr where none expected",
1263 [], [],
1264 'cleanup', D_path)
1266 # this commit should succeed
1267 expected_output = svntest.wc.State(wc_dir, {
1268 'A/D/gamma' : Item(verb='Sending'),
1270 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1271 expected_status.tweak('A/D/gamma', wc_rev=2)
1272 svntest.actions.run_and_verify_commit(wc_dir,
1273 expected_output,
1274 expected_status,
1275 None,
1276 wc_dir)
1278 #----------------------------------------------------------------------
1280 # Explicitly commit the current directory. This did at one point fail
1281 # in post-commit processing due to a path canonicalization problem.
1283 def commit_current_dir(sbox):
1284 "commit the current directory"
1286 sbox.build()
1288 wc_dir = sbox.wc_dir
1289 svntest.main.run_svn(None, 'propset', 'pname', 'pval', wc_dir)
1291 was_cwd = os.getcwd()
1293 os.chdir(wc_dir)
1295 expected_output = svntest.wc.State('.', {
1296 '.' : Item(verb='Sending'),
1298 svntest.actions.run_and_verify_commit('.',
1299 expected_output,
1300 None,
1301 None,
1302 '.')
1303 os.chdir(was_cwd)
1305 # I can't get the status check to work as part of run_and_verify_commit.
1306 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1307 expected_status.tweak('', wc_rev=2, status=' ')
1308 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1310 #----------------------------------------------------------------------
1312 # Check that the pending txn gets removed from the repository after
1313 # a failed commit.
1315 def failed_commit(sbox):
1316 "commit with conflicts and check txn in repo"
1318 sbox.build()
1319 wc_dir = sbox.wc_dir
1321 # Make the other working copy
1322 other_wc_dir = sbox.add_wc_path('other')
1323 svntest.actions.duplicate_dir(wc_dir, other_wc_dir)
1325 # Make different changes in the two working copies
1326 iota_path = os.path.join(wc_dir, "iota")
1327 svntest.main.file_append(iota_path, "More stuff in iota")
1329 other_iota_path = os.path.join(other_wc_dir, "iota")
1330 svntest.main.file_append(other_iota_path, "More different stuff in iota")
1332 # Commit both working copies. The second commit should fail.
1333 svntest.actions.run_and_verify_svn("Output on stderr where none expected",
1334 svntest.verify.AnyOutput, [],
1335 'commit', '-m', 'log', wc_dir)
1337 svntest.actions.run_and_verify_svn("Output on stderr expected",
1338 None, svntest.verify.AnyOutput,
1339 'commit', '-m', 'log', other_wc_dir)
1341 # Now list the txns in the repo. The list should be empty.
1342 exit_code, output, errput = svntest.main.run_svnadmin('lstxns',
1343 sbox.repo_dir)
1344 svntest.verify.compare_and_display_lines(
1345 "Error running 'svnadmin lstxns'.",
1346 'STDERR', [], errput)
1347 svntest.verify.compare_and_display_lines(
1348 "Output of 'svnadmin lstxns' is unexpected.",
1349 'STDOUT', [], output)
1351 #----------------------------------------------------------------------
1353 # Commit from multiple working copies is not yet supported. At
1354 # present an error is generated and none of the working copies change.
1355 # Related to issue 959, this test here doesn't use svn:externals but the
1356 # behaviour needs to be considered.
1358 def commit_multiple_wc(sbox):
1359 "attempted commit from multiple wc fails"
1361 sbox.build()
1362 wc_dir = sbox.wc_dir
1364 # Checkout a second working copy
1365 wc2_dir = os.path.join(wc_dir, 'A', 'wc2')
1366 url = sbox.repo_url
1367 svntest.actions.run_and_verify_svn("Output on stderr where none expected",
1368 svntest.verify.AnyOutput, [],
1369 'checkout',
1370 url, wc2_dir)
1372 # Modify both working copies
1373 mu_path = os.path.join(wc_dir, 'A', 'mu')
1374 svntest.main.file_append(mu_path, 'appended mu text')
1375 lambda2_path = os.path.join(wc2_dir, 'A', 'B', 'lambda')
1376 svntest.main.file_append(lambda2_path, 'appended lambda2 text')
1378 # Verify modified status
1379 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1380 expected_status.tweak('A/mu', status='M ')
1381 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1382 expected_status2 = svntest.actions.get_virginal_state(wc2_dir, 1)
1383 expected_status2.tweak('A/B/lambda', status='M ')
1384 svntest.actions.run_and_verify_status(wc2_dir, expected_status2)
1386 # Commit should fail, even though one target is a "child" of the other.
1387 svntest.actions.run_and_verify_svn("Unexpectedly not locked",
1388 None, svntest.verify.AnyOutput,
1389 'commit', '-m', 'log',
1390 wc_dir, wc2_dir)
1392 # Verify status unchanged
1393 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1394 svntest.actions.run_and_verify_status(wc2_dir, expected_status2)
1397 def commit_nonrecursive(sbox):
1398 "commit named targets with -N (issues #1195, #1239)"
1400 sbox.build()
1401 wc_dir = sbox.wc_dir
1403 ### Note: the original recipes used 'add -N'. These days, we use
1404 ### --depth={empty,files}, and both the code and the comments below
1405 ### have been adjusted to reflect this.
1407 #####################################################
1408 ### Issue #1195:
1410 ### 1. Create these directories and files:
1412 ### file1
1413 ### dir1
1414 ### dir1/file2
1415 ### dir1/file3
1416 ### dir1/dir2
1417 ### dir1/dir2/file4
1419 ### 2. run 'svn add --depth=empty <all of the above>'
1421 ### 3. run 'svn ci -N <all of the above>'
1423 ### (The bug was that only 4 entities would get committed, when it
1424 ### should be 6: dir2/ and file4 were left out.)
1426 # These paths are relative to the top of the test's working copy.
1427 file1_path = 'file1'
1428 dir1_path = 'dir1'
1429 file2_path = os.path.join('dir1', 'file2')
1430 file3_path = os.path.join('dir1', 'file3')
1431 dir2_path = os.path.join('dir1', 'dir2')
1432 file4_path = os.path.join('dir1', 'dir2', 'file4')
1434 # Create the new files and directories.
1435 svntest.main.file_append(os.path.join(wc_dir, file1_path), 'this is file1')
1436 os.mkdir(os.path.join(wc_dir, dir1_path))
1437 svntest.main.file_append(os.path.join(wc_dir, file2_path), 'this is file2')
1438 svntest.main.file_append(os.path.join(wc_dir, file3_path), 'this is file3')
1439 os.mkdir(os.path.join(wc_dir, dir2_path))
1440 svntest.main.file_append(os.path.join(wc_dir, file4_path), 'this is file4')
1442 # Add them to version control.
1443 svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [],
1444 'add', '--depth=empty',
1445 os.path.join(wc_dir, file1_path),
1446 os.path.join(wc_dir, dir1_path),
1447 os.path.join(wc_dir, file2_path),
1448 os.path.join(wc_dir, file3_path),
1449 os.path.join(wc_dir, dir2_path),
1450 os.path.join(wc_dir, file4_path))
1452 # Commit. We should see all 6 items (2 dirs, 4 files) get sent.
1453 expected_output = svntest.wc.State(
1454 wc_dir,
1455 { file1_path : Item(verb='Adding'),
1456 dir1_path : Item(verb='Adding'),
1457 file2_path : Item(verb='Adding'),
1458 file3_path : Item(verb='Adding'),
1459 dir2_path : Item(verb='Adding'),
1460 file4_path : Item(verb='Adding'),
1464 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1465 expected_status.add({
1466 file1_path : Item(status=' ', wc_rev=2),
1467 dir1_path : Item(status=' ', wc_rev=2),
1468 file2_path : Item(status=' ', wc_rev=2),
1469 file3_path : Item(status=' ', wc_rev=2),
1470 dir2_path : Item(status=' ', wc_rev=2),
1471 file4_path : Item(status=' ', wc_rev=2),
1474 svntest.actions.run_and_verify_commit(wc_dir,
1475 expected_output,
1476 expected_status,
1477 None,
1478 '-N',
1479 os.path.join(wc_dir, file1_path),
1480 os.path.join(wc_dir, dir1_path),
1481 os.path.join(wc_dir, file2_path),
1482 os.path.join(wc_dir, file3_path),
1483 os.path.join(wc_dir, dir2_path),
1484 os.path.join(wc_dir, file4_path))
1486 #######################################################################
1488 ### There's some complex history here; please bear with me.
1490 ### First there was issue #1239, which had the following recipe:
1492 ### 1. Create these directories and files:
1494 ### dirA
1495 ### dirA/fileA
1496 ### dirA/fileB
1497 ### dirA/dirB
1498 ### dirA/dirB/fileC
1499 ### dirA/dirB/nocommit
1501 ### 2. run 'svn add --depth=empty <all of the above>'
1503 ### 3. run 'svn ci -N <all but nocommit>'
1505 ### (In this recipe, 'add -N' has been changed to 'add --depth...',
1506 ### but 'ci -N' has been left as-is, for reasons explained below.)
1508 ### Issue #1239 claimed a two-part bug: that step 3 would try to
1509 ### commit the file `nocommit' when it shouldn't, and that it would
1510 ### get an error anyway:
1512 ### Adding wc/dirA
1513 ### Adding wc/dirA/fileA
1514 ### Adding wc/dirA/fileB
1515 ### Adding wc/dirA/dirB
1516 ### Adding wc/dirA/dirB/nocommit
1517 ### Adding wc/dirA/dirB/fileC
1518 ### Transmitting file data ....svn: A problem occurred; \
1519 ### see later errors for details
1520 ### svn: Commit succeeded, but other errors follow:
1521 ### svn: Problem running log
1522 ### svn: Error bumping revisions post-commit (details follow):
1523 ### svn: in directory
1524 ### 'F:/Programmation/Projets/subversion/svnant/test/wc/dirA'
1525 ### svn: start_handler: error processing command 'committed' in
1526 ### 'F:/Programmation/Projets/subversion/svnant/test/wc/dirA'
1527 ### svn: Working copy not locked
1528 ### svn: directory not locked
1529 ### (F:/Programmation/Projets/subversion/svnant/test/wc)
1531 ### However, this was all in the days before --depth, and depended
1532 ### on an idiosyncratic interpretation of -N, one which required
1533 ### commit to behave differently from other commands taking -N.
1535 ### These days, -N should be equivalent to --depth=files in almost
1536 ### all cases. There are some exceptions (e.g., status), but commit
1537 ### is not an exception. Thus, the above recipe is now incorrect,
1538 ### because "wc/dirA/dirB" was given as an explicit target, and
1539 ### therefore the file "wc/dirA/dirB/nocommit" *should* have been
1540 ### committed after all, since it's a file child of a named target
1541 ### and -N means --depth=files.
1543 ### So we really need two tests: one for commit -N (--depth=files),
1544 ### and another for --depth=empty. I've changed this test to cover
1545 ### the -N case, and added 'commit_propmods_with_depth_empty' to
1546 ### depth_tests.py to cover the --depth=empty case.
1548 # Now add these directories and files, except the last:
1549 dirA_path = 'dirA'
1550 fileA_path = os.path.join('dirA', 'fileA')
1551 fileB_path = os.path.join('dirA', 'fileB')
1552 dirB_path = os.path.join('dirA', 'dirB')
1553 nope_1_path = os.path.join(dirB_path, 'nope_1')
1554 nope_2_path = os.path.join(dirB_path, 'nope_2')
1556 # Create the new files and directories.
1557 os.mkdir(os.path.join(wc_dir, dirA_path))
1558 svntest.main.file_append(os.path.join(wc_dir, fileA_path), 'fileA')
1559 svntest.main.file_append(os.path.join(wc_dir, fileB_path), 'fileB')
1560 os.mkdir(os.path.join(wc_dir, dirB_path))
1561 svntest.main.file_append(os.path.join(wc_dir, nope_1_path), 'nope_1')
1562 svntest.main.file_append(os.path.join(wc_dir, nope_2_path), 'nope_2')
1564 # Add them to version control.
1565 svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [],
1566 'add', '--depth=empty',
1567 os.path.join(wc_dir, dirA_path),
1568 os.path.join(wc_dir, fileA_path),
1569 os.path.join(wc_dir, fileB_path),
1570 os.path.join(wc_dir, dirB_path),
1571 os.path.join(wc_dir, nope_1_path),
1572 os.path.join(wc_dir, nope_2_path))
1574 expected_output = svntest.wc.State(
1575 wc_dir,
1576 { dirA_path : Item(verb='Adding'),
1577 fileA_path : Item(verb='Adding'),
1578 fileB_path : Item(verb='Adding'),
1582 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1584 # Expect the leftovers from the first part of the test.
1585 expected_status.add({
1586 file1_path : Item(status=' ', wc_rev=2),
1587 dir1_path : Item(status=' ', wc_rev=2),
1588 file2_path : Item(status=' ', wc_rev=2),
1589 file3_path : Item(status=' ', wc_rev=2),
1590 dir2_path : Item(status=' ', wc_rev=2),
1591 file4_path : Item(status=' ', wc_rev=2),
1594 # Expect some commits and some non-commits from this part of the test.
1595 expected_status.add({
1596 dirA_path : Item(status=' ', wc_rev=3),
1597 fileA_path : Item(status=' ', wc_rev=3),
1598 fileB_path : Item(status=' ', wc_rev=3),
1599 dirB_path : Item(status='A ', wc_rev=0),
1600 nope_1_path : Item(status='A ', wc_rev=0),
1601 nope_2_path : Item(status='A ', wc_rev=0)
1604 svntest.actions.run_and_verify_commit(wc_dir,
1605 expected_output,
1606 expected_status,
1607 None,
1608 '-N', os.path.join(wc_dir, dirA_path))
1610 #----------------------------------------------------------------------
1611 # Regression for #1017: ra_neon was allowing the deletion of out-of-date
1612 # files or dirs, which majorly violates Subversion's semantics.
1615 def commit_out_of_date_deletions(sbox):
1616 "commit deletion of out-of-date file or dir"
1618 sbox.build()
1619 wc_dir = sbox.wc_dir
1621 # Make a backup copy of the working copy
1622 wc_backup = sbox.add_wc_path('backup')
1623 svntest.actions.duplicate_dir(wc_dir, wc_backup)
1625 # Change omega's text, and make a propchange to A/C directory
1626 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
1627 C_path = os.path.join(wc_dir, 'A', 'C')
1628 svntest.main.file_append(omega_path, 'appended omega text')
1629 svntest.main.run_svn(None, 'propset', 'fooprop', 'foopropval', C_path)
1631 # Commit revision 2.
1632 expected_output = svntest.wc.State(wc_dir, {
1633 'A/D/H/omega' : Item(verb='Sending'),
1634 'A/C' : Item(verb='Sending'),
1636 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1637 expected_status.tweak('A/D/H/omega', 'A/C', wc_rev=2, status=' ')
1639 svntest.actions.run_and_verify_commit(wc_dir,
1640 expected_output,
1641 expected_status,
1642 None,
1643 wc_dir)
1645 # Now, in the second working copy, schedule both omega and C for deletion.
1646 omega_path = os.path.join(wc_backup, 'A', 'D', 'H', 'omega')
1647 C_path = os.path.join(wc_backup, 'A', 'C')
1648 svntest.main.run_svn(None, 'rm', omega_path, C_path)
1650 # Attempt to delete omega. This should return an (expected)
1651 # out-of-dateness error.
1652 exit_code, outlines, errlines = svntest.main.run_svn(1, 'commit', '-m',
1653 'blah', omega_path)
1654 for line in errlines:
1655 if re.match(".*[Oo]ut.of.date.*", line):
1656 break
1657 else:
1658 raise svntest.Failure
1660 # Attempt to delete directory C. This should return an (expected)
1661 # out-of-dateness error.
1662 exit_code, outlines, errlines = svntest.main.run_svn(1, 'commit', '-m',
1663 'blah', C_path)
1664 for line in errlines:
1665 if re.match(".*[Oo]ut.of.date.*", line):
1666 break
1667 else:
1668 raise svntest.Failure
1670 def commit_with_bad_log_message(sbox):
1671 "commit with a log message containing bad data"
1673 sbox.build()
1674 wc_dir = sbox.wc_dir
1676 iota_path = os.path.join(wc_dir, 'iota')
1677 log_msg_path = os.path.join(wc_dir, 'log-message')
1679 # Make a random change, so there's something to commit.
1680 svntest.main.file_append(iota_path, 'fish')
1682 # Create a log message containing a zero-byte.
1683 svntest.main.file_append(log_msg_path, '\x00')
1685 # Commit and expect an error.
1686 svntest.actions.run_and_verify_commit(wc_dir,
1687 None, None,
1688 "contains a zero byte",
1689 '-F', log_msg_path,
1690 iota_path)
1692 def from_wc_top_with_bad_editor(sbox):
1693 "commit with invalid external editor cmd"
1695 # Shortly after revision 5407, Vladimir Prus posted this bug recipe:
1697 # #!/bin/bash
1698 # cd /tmp
1699 # rm -rf repo wc
1700 # svnadmin create repo
1701 # svn mkdir file:///tmp/repo/foo -m ""
1702 # svn co file:///tmp/repo/foo wc
1703 # cd wc
1704 # svn ps svn:externals "lib http://something.org/lib" .
1705 # svn ci
1707 # The final 'svn ci' would seg fault because of a problem in
1708 # calculating the paths to insert in the initial log message that
1709 # gets passed to the editor.
1711 # So this regression test is primarily about making sure the seg
1712 # fault is gone, and only secondarily about testing that we get the
1713 # expected error from passing a bad editor cmd to Subversion.
1715 sbox.build()
1716 wc_dir = sbox.wc_dir
1718 svntest.actions.run_and_verify_svn("Unexpected failure from propset.",
1719 svntest.verify.AnyOutput, [],
1720 'pset', 'fish', 'food', wc_dir)
1721 os.chdir(wc_dir)
1722 exit_code, out, err = svntest.actions.run_and_verify_svn(
1723 "Commit succeeded when should have failed.",
1724 None, svntest.verify.AnyOutput,
1725 'ci', '--editor-cmd', 'no_such-editor')
1727 err = string.join(map(string.strip, err), ' ')
1728 if not (re.match(".*no_such-editor.*", err)
1729 and re.match(".*Commit failed.*", err)):
1730 print "Commit failed, but not in the way expected."
1731 raise svntest.Failure
1734 def mods_in_schedule_delete(sbox):
1735 "commit with mods in schedule delete"
1737 sbox.build()
1738 wc_dir = sbox.wc_dir
1740 # Schedule a delete, then put in local mods
1741 C_path = os.path.join(wc_dir, 'A', 'C')
1742 svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [],
1743 'rm', C_path)
1744 foo_path = os.path.join(C_path, 'foo')
1745 foo_contents = 'zig\nzag\n'
1746 svntest.main.file_append(foo_path, foo_contents)
1748 # Commit should succeed
1749 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1750 expected_status.remove('A/C')
1751 expected_output = svntest.wc.State(wc_dir, {
1752 'A/C' : Item(verb='Deleting'),
1754 svntest.actions.run_and_verify_commit(wc_dir,
1755 expected_output, expected_status,
1756 None, wc_dir)
1758 # Unversioned file still exists
1759 actual_contents = svntest.main.file_read(foo_path)
1760 if actual_contents != foo_contents:
1761 raise svntest.Failure
1764 #----------------------------------------------------------------------
1766 def tab_test(sbox):
1767 "tabs in paths"
1768 # For issue #1954.
1770 sbox.build()
1771 wc_dir = sbox.wc_dir
1773 tab_file = os.path.join(wc_dir, 'A', "tab\tfile")
1774 tab_dir = os.path.join(wc_dir, 'A', "tab\tdir")
1775 source_url = sbox.repo_url + "/source_dir"
1776 tab_url = sbox.repo_url + "/tab%09dir"
1778 svntest.main.file_append(tab_file, "This file has a tab in it.")
1779 os.mkdir(tab_dir)
1781 def match_bad_tab_path(path, errlines):
1782 match_re = ".*: Invalid control character '0x09' in path .*"
1783 for line in errlines:
1784 if re.match (match_re, line):
1785 break
1786 else:
1787 raise svntest.Failure("Failed to find match_re in " + str(errlines))
1789 # add file to wc
1790 exit_code, outlines, errlines = svntest.main.run_svn(1, 'add', tab_file)
1791 match_bad_tab_path(tab_file, errlines)
1793 # add dir to wc
1794 exit_code, outlines, errlines = svntest.main.run_svn(1, 'add', tab_dir)
1795 match_bad_tab_path(tab_dir, errlines)
1797 # mkdir URL
1798 exit_code, outlines, errlines = svntest.main.run_svn(1, 'mkdir',
1799 '-m', 'msg', tab_url)
1800 match_bad_tab_path(tab_dir, errlines)
1802 # copy URL
1803 svntest.main.run_svn(1,
1804 'mkdir', '-m', 'msg', source_url)
1805 exit_code, outlines, errlines = svntest.main.run_svn(1, 'copy',
1806 '-m', 'msg',
1807 source_url, tab_url)
1808 match_bad_tab_path(tab_dir, errlines)
1810 # mv URL
1811 exit_code, outlines, errlines = svntest.main.run_svn(1, 'mv', '-m', 'msg',
1812 source_url, tab_url)
1813 match_bad_tab_path(tab_dir, errlines)
1815 #----------------------------------------------------------------------
1817 def local_mods_are_not_commits(sbox):
1818 "local ops should not be treated like commits"
1820 # For issue #2285.
1822 # Some commands can run on either a URL or a local path. These
1823 # commands take a log message, intended for the URL case.
1824 # Therefore, they should make sure that getting a log message for
1825 # a local operation errors (because not committing).
1827 # This is in commit_tests.py because the unifying theme is that
1828 # commits are *not* happening. And because there was no better
1829 # place to put it :-).
1831 sbox.build()
1832 wc_dir = sbox.wc_dir
1833 expected_error = '.*Local, non-commit operations do not take a log message.*'
1835 # copy wc->wc
1836 svntest.actions.run_and_verify_svn(None, None, expected_error,
1837 'cp', '-m', 'log msg',
1838 os.path.join(wc_dir, 'iota'),
1839 os.path.join(wc_dir, 'iota2'))
1841 # copy repos->wc
1842 svntest.actions.run_and_verify_svn(None, None, expected_error,
1843 'cp', '-m', 'log msg',
1844 sbox.repo_url + "/iota",
1845 os.path.join(wc_dir, 'iota2'))
1847 # delete
1848 svntest.actions.run_and_verify_svn(None, None, expected_error,
1849 'rm', '-m', 'log msg',
1850 os.path.join(wc_dir, 'A', 'D', 'gamma'))
1852 # mkdir
1853 svntest.actions.run_and_verify_svn(None, None, expected_error,
1854 'mkdir', '-m', 'log msg',
1855 os.path.join(wc_dir, 'newdir'))
1857 # rename
1858 svntest.actions.run_and_verify_svn(None, None, expected_error,
1859 'cp', '-m', 'log msg',
1860 os.path.join(wc_dir, 'A', 'mu'),
1861 os.path.join(wc_dir, 'A', 'yu'))
1863 # Helper for hook tests: returns the "hook failed" line, with precise
1864 # wording that changed with Subversion 1.5.
1865 def hook_failure_message(hookname):
1866 if svntest.main.server_minor_version < 5:
1867 return "'%s' hook failed with error output:\n" % hookname
1868 else:
1869 if hookname in ["start-commit", "pre-commit"]:
1870 action = "Commit"
1871 elif hookname == "pre-revprop-change":
1872 action = "Revprop change"
1873 elif hookname == "pre-lock":
1874 action = "Lock"
1875 elif hookname == "pre-unlock":
1876 action = "Unlock"
1877 else:
1878 action = None
1879 if action is None:
1880 message = "%s hook failed (exit code 1)" % (hookname,)
1881 else:
1882 message = "%s blocked by %s hook (exit code 1)" % (action, hookname)
1883 return message + " with output:\n"
1886 #----------------------------------------------------------------------
1887 # Test if the post-commit error message is returned back to the svn
1888 # client and is displayed as a warning.
1890 def post_commit_hook_test(sbox):
1891 "post commit hook failure case testing"
1893 sbox.build()
1895 # Get paths to the working copy and repository
1896 wc_dir = sbox.wc_dir
1897 repo_dir = sbox.repo_dir
1899 # Disable commits
1900 svntest.actions.create_failing_post_commit_hook(repo_dir)
1902 # Modify iota just so there is something to commit.
1903 iota_path = os.path.join(wc_dir, "iota")
1904 svntest.main.file_append(iota_path, "lakalakalakalaka")
1906 # Now, commit and examine the output (we happen to know that the
1907 # filesystem will report an absolute path because that's the way the
1908 # filesystem is created by this test suite.
1909 expected_output = [ "Sending "+ iota_path + "\n",
1910 "Transmitting file data .\n",
1911 "Committed revision 2.\n",
1912 "\n",
1913 "Warning: " + hook_failure_message('post-commit'),
1914 "Post-commit hook failed\n",
1917 svntest.actions.run_and_verify_svn(None, expected_output, [],
1918 'ci', '-m', 'log msg', iota_path)
1920 #----------------------------------------------------------------------
1921 # Commit two targets non-recursively, but both targets should be the
1922 # same folder (in multiple variations). Test that svn handles this correctly.
1923 def commit_same_folder_in_targets(sbox):
1924 "commit two targets, both the same folder"
1926 sbox.build()
1927 wc_dir = sbox.wc_dir
1929 iota_path = os.path.join(wc_dir, 'iota')
1931 svntest.main.file_append(iota_path, "added extra line to file iota")
1933 # Create expected output tree.
1934 expected_output = svntest.wc.State(wc_dir, {
1935 'iota' : Item(verb='Sending'),
1938 # Created expected status tree.
1939 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1940 expected_status.tweak('iota', wc_rev=2)
1942 # Commit the wc_dir and iota.
1943 svntest.actions.run_and_verify_commit(wc_dir,
1944 expected_output,
1945 expected_status,
1946 None,
1947 '-N',
1948 wc_dir,
1949 iota_path)
1951 #----------------------------------------------------------------------
1952 # test for issue 2459: verify that commit fails when a file with mixed
1953 # eol-styles is included, and show an error message which includes the
1954 # filename.
1955 def commit_inconsistent_eol(sbox):
1956 "commit files with inconsistent eol should fail"
1958 sbox.build()
1959 wc_dir = sbox.wc_dir
1961 iota_path = os.path.join(wc_dir, 'iota')
1962 mu_path = os.path.join(wc_dir, 'A', 'mu')
1964 svntest.main.run_svn(None, 'propset', 'svn:eol-style', 'native', iota_path)
1965 svntest.main.file_append_binary(iota_path,
1966 "added extra line to file iota\012"
1967 "added extra line to file iota\015")
1968 svntest.main.file_append(mu_path, "added extra line to file mu\n"
1969 "added extra line to file mu\n")
1971 expected_err = ".*iota.*"
1973 svntest.actions.run_and_verify_svn(None, None, expected_err,
1974 'commit', '-m', 'log message',
1975 wc_dir)
1978 def mkdir_with_revprop(sbox):
1979 "set revision props during remote mkdir"
1981 sbox.build()
1982 remote_dir = sbox.repo_url + "/dir"
1984 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
1985 '--with-revprop', 'bug=42', remote_dir)
1987 expected = svntest.verify.UnorderedOutput(
1988 ['Unversioned properties on revision 2:\n',
1989 ' svn:author\n',' svn:date\n', ' svn:log\n',
1990 ' bug\n'])
1991 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
1992 '--revprop', '-r', 2, sbox.repo_url)
1993 svntest.actions.run_and_verify_svn(None, '42', [], 'propget', 'bug',
1994 '--revprop', '-r', 2, sbox.repo_url)
1997 def delete_with_revprop(sbox):
1998 "set revision props during remote delete"
2000 sbox.build()
2001 remote_dir = sbox.repo_url + "/dir"
2002 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2003 remote_dir)
2005 svntest.actions.run_and_verify_svn(None, None, [], 'delete', '-m', 'msg',
2006 '--with-revprop', 'bug=52', remote_dir)
2008 expected = svntest.verify.UnorderedOutput(
2009 ['Unversioned properties on revision 3:\n',
2010 ' svn:author\n',' svn:date\n', ' svn:log\n',
2011 ' bug\n'])
2012 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2013 '--revprop', '-r', 3, sbox.repo_url)
2014 svntest.actions.run_and_verify_svn(None, '52', [], 'propget', 'bug',
2015 '--revprop', '-r', 3, sbox.repo_url)
2018 def commit_with_revprop(sbox):
2019 "set revision props during commit"
2021 sbox.build()
2022 wc_dir = sbox.wc_dir
2023 expected_status = make_standard_slew_of_changes(wc_dir)
2025 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
2026 gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo')
2027 expected_output = svntest.wc.State(wc_dir, {
2028 'A/D/H/omega' : Item(verb='Sending'),
2029 'A/D/H/gloo' : Item(verb='Adding'),
2032 expected_status.tweak('A/D/H/omega', wc_rev=2, status=' ')
2033 expected_status.tweak('A/D/H/gloo', wc_rev=2, status=' ')
2035 svntest.actions.run_and_verify_commit(wc_dir,
2036 expected_output,
2037 expected_status,
2038 None,
2039 '-m', 'msg',
2040 '--with-revprop', 'bug=62',
2041 omega_path, gloo_path)
2043 expected = svntest.verify.UnorderedOutput(
2044 ['Unversioned properties on revision 2:\n',
2045 ' svn:author\n',' svn:date\n', ' svn:log\n',
2046 ' bug\n'])
2047 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2048 '--revprop', '-r', 2, sbox.repo_url)
2049 svntest.actions.run_and_verify_svn(None, '62', [], 'propget', 'bug',
2050 '--revprop', '-r', 2, sbox.repo_url)
2053 def import_with_revprop(sbox):
2054 "set revision props during import"
2056 sbox.build()
2057 local_dir = os.path.join(sbox.wc_dir, 'folder')
2058 local_file = os.path.join(sbox.wc_dir, 'folder', 'file')
2059 os.mkdir(local_dir)
2060 svntest.main.file_write(local_file, "xxxx")
2062 svntest.actions.run_and_verify_svn(None, None, [], 'import', '-m', 'msg',
2063 '--with-revprop', 'bug=72', local_dir,
2064 sbox.repo_url)
2066 expected = svntest.verify.UnorderedOutput(
2067 ['Unversioned properties on revision 2:\n',
2068 ' svn:author\n',' svn:date\n', ' svn:log\n',
2069 ' bug\n'])
2070 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2071 '--revprop', '-r', 2, sbox.repo_url)
2072 svntest.actions.run_and_verify_svn(None, '72', [], 'propget', 'bug',
2073 '--revprop', '-r', 2, sbox.repo_url)
2076 def copy_R2R_with_revprop(sbox):
2077 "set revision props during repos-to-repos copy"
2079 sbox.build()
2080 remote_dir1 = sbox.repo_url + "/dir1"
2081 remote_dir2 = sbox.repo_url + "/dir2"
2082 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2083 remote_dir1)
2085 svntest.actions.run_and_verify_svn(None, None, [], 'copy', '-m', 'msg',
2086 '--with-revprop', 'bug=82', remote_dir1,
2087 remote_dir2)
2089 expected = svntest.verify.UnorderedOutput(
2090 ['Unversioned properties on revision 3:\n',
2091 ' svn:author\n',' svn:date\n', ' svn:log\n',
2092 ' bug\n'])
2093 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2094 '--revprop', '-r', 3, sbox.repo_url)
2095 svntest.actions.run_and_verify_svn(None, '82', [], 'propget', 'bug',
2096 '--revprop', '-r', 3, sbox.repo_url)
2099 def copy_WC2R_with_revprop(sbox):
2100 "set revision props during wc-to-repos copy"
2102 sbox.build()
2103 remote_dir = sbox.repo_url + "/dir"
2104 local_dir = os.path.join(sbox.wc_dir, 'folder')
2105 svntest.actions.run_and_verify_svn(None, None, [],
2106 'mkdir', local_dir)
2108 svntest.actions.run_and_verify_svn(None, None, [], 'copy', '-m', 'msg',
2109 '--with-revprop', 'bug=92', local_dir,
2110 remote_dir)
2112 expected = svntest.verify.UnorderedOutput(
2113 ['Unversioned properties on revision 2:\n',
2114 ' svn:author\n',' svn:date\n', ' svn:log\n',
2115 ' bug\n'])
2116 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2117 '--revprop', '-r', 2, sbox.repo_url)
2118 svntest.actions.run_and_verify_svn(None, '92', [], 'propget', 'bug',
2119 '--revprop', '-r', 2, sbox.repo_url)
2122 def move_R2R_with_revprop(sbox):
2123 "set revision props during repos-to-repos move"
2125 sbox.build()
2126 remote_dir1 = sbox.repo_url + "/dir1"
2127 remote_dir2 = sbox.repo_url + "/dir2"
2128 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2129 remote_dir1)
2131 svntest.actions.run_and_verify_svn(None, None, [], 'move', '-m', 'msg',
2132 '--with-revprop', 'bug=102', remote_dir1,
2133 remote_dir2)
2135 expected = svntest.verify.UnorderedOutput(
2136 ['Unversioned properties on revision 3:\n',
2137 ' svn:author\n',' svn:date\n', ' svn:log\n',
2138 ' bug\n'])
2139 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2140 '--revprop', '-r', 3, sbox.repo_url)
2141 svntest.actions.run_and_verify_svn(None, '102', [], 'propget', 'bug',
2142 '--revprop', '-r', 3, sbox.repo_url)
2145 def propedit_with_revprop(sbox):
2146 "set revision props during remote property edit"
2148 sbox.build()
2149 svntest.main.use_editor('append_foo')
2151 svntest.actions.run_and_verify_svn(None, None, [], 'propedit', '-m', 'msg',
2152 '--with-revprop', 'bug=112', 'prop',
2153 sbox.repo_url)
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, '112', [], 'propget', 'bug',
2162 '--revprop', '-r', 2, sbox.repo_url)
2165 def set_multiple_props_with_revprop(sbox):
2166 "set multiple revision props during remote mkdir"
2168 sbox.build()
2169 remote_dir = sbox.repo_url + "/dir"
2171 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2172 '--with-revprop', 'bug=32',
2173 '--with-revprop', 'ref=22', remote_dir)
2175 expected = svntest.verify.UnorderedOutput(
2176 ['Unversioned properties on revision 2:\n',
2177 ' svn:author\n',' svn:date\n', ' svn:log\n',
2178 ' bug\n', ' ref\n'])
2179 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2180 '--revprop', '-r', 2, sbox.repo_url)
2181 svntest.actions.run_and_verify_svn(None, '32', [], 'propget', 'bug',
2182 '--revprop', '-r', 2, sbox.repo_url)
2183 svntest.actions.run_and_verify_svn(None, '22', [], 'propget', 'ref',
2184 '--revprop', '-r', 2, sbox.repo_url)
2187 def use_empty_value_in_revprop_pair(sbox):
2188 "set revprop without value ('') during remote mkdir"
2190 sbox.build()
2191 remote_dir = sbox.repo_url + "/dir"
2193 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2194 '--with-revprop', 'bug=',
2195 '--with-revprop', 'ref=', remote_dir)
2197 expected = svntest.verify.UnorderedOutput(
2198 ['Unversioned properties on revision 2:\n',
2199 ' svn:author\n',' svn:date\n', ' svn:log\n',
2200 ' bug\n', ' ref\n'])
2201 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2202 '--revprop', '-r', 2, sbox.repo_url)
2203 svntest.actions.run_and_verify_svn(None, '', [], 'propget', 'bug',
2204 '--revprop', '-r', 2, sbox.repo_url)
2205 svntest.actions.run_and_verify_svn(None, '', [], 'propget', 'ref',
2206 '--revprop', '-r', 2, sbox.repo_url)
2209 def no_equals_in_revprop_pair(sbox):
2210 "set revprop without '=' during remote mkdir"
2212 sbox.build()
2213 remote_dir = sbox.repo_url + "/dir"
2214 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2215 '--with-revprop', 'bug',
2216 '--with-revprop', 'ref', remote_dir)
2218 expected = svntest.verify.UnorderedOutput(
2219 ['Unversioned properties on revision 2:\n',
2220 ' svn:author\n',' svn:date\n', ' svn:log\n',
2221 ' bug\n', ' ref\n'])
2222 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2223 '--revprop', '-r', 2, sbox.repo_url)
2224 svntest.actions.run_and_verify_svn(None, '', [], 'propget', 'bug',
2225 '--revprop', '-r', 2, sbox.repo_url)
2226 svntest.actions.run_and_verify_svn(None, '', [], 'propget', 'ref',
2227 '--revprop', '-r', 2, sbox.repo_url)
2230 def set_invalid_revprops(sbox):
2231 "set invalid revision props during remote mkdir"
2233 sbox.build()
2234 remote_dir = sbox.repo_url + "/dir"
2235 # Try to set svn: revprops.
2236 expected = '.*Standard properties can\'t.*'
2237 svntest.actions.run_and_verify_svn(None, [], expected, 'mkdir', '-m', 'msg',
2238 '--with-revprop', 'svn:author=42', remote_dir)
2239 svntest.actions.run_and_verify_svn(None, [], expected, 'mkdir', '-m', 'msg',
2240 '--with-revprop', 'svn:log=42', remote_dir)
2241 svntest.actions.run_and_verify_svn(None, [], expected, 'mkdir', '-m', 'msg',
2242 '--with-revprop', 'svn:date=42', remote_dir)
2243 svntest.actions.run_and_verify_svn(None, [], expected, 'mkdir', '-m', 'msg',
2244 '--with-revprop', 'svn:foo=bar', remote_dir)
2246 # Empty revprop pair.
2247 svntest.actions.run_and_verify_svn(None, [],
2248 'svn: Revision property pair is empty',
2249 'mkdir', '-m', 'msg',
2250 '--with-revprop', '',
2251 remote_dir)
2253 #----------------------------------------------------------------------
2255 def start_commit_hook_test(sbox):
2256 "start-commit hook failure case testing"
2258 sbox.build()
2260 # Get paths to the working copy and repository
2261 wc_dir = sbox.wc_dir
2262 repo_dir = sbox.repo_dir
2264 # Create a hook that outputs a message to stderr and returns exit code 1
2265 hook_code = """import sys
2266 sys.stderr.write("Start-commit hook failed")
2267 sys.exit(1)"""
2269 # Setup the hook configs to log data to a file
2270 start_commit_hook = svntest.main.get_start_commit_hook_path(repo_dir)
2271 svntest.main.create_python_hook_script(start_commit_hook, hook_code)
2273 # Modify iota just so there is something to commit.
2274 iota_path = os.path.join(wc_dir, "iota")
2275 svntest.main.file_append(iota_path, "More stuff in iota")
2277 # Commit, expect error code 1
2278 exit_code, actual_stdout, actual_stderr = svntest.main.run_svn(
2279 1, 'ci', '--quiet', '-m', 'log msg', wc_dir)
2281 # No stdout expected
2282 svntest.verify.compare_and_display_lines('Start-commit hook test',
2283 'STDOUT', [], actual_stdout)
2285 # Compare only the last two lines of stderr since the preceding ones
2286 # contain source code file and line numbers.
2287 if len(actual_stderr) > 2:
2288 actual_stderr = actual_stderr[-2:]
2289 expected_stderr = [ "svn: " + hook_failure_message('start-commit'),
2290 "Start-commit hook failed\n"
2292 svntest.verify.compare_and_display_lines('Start-commit hook test',
2293 'STDERR',
2294 expected_stderr, actual_stderr)
2296 #----------------------------------------------------------------------
2298 def pre_commit_hook_test(sbox):
2299 "pre-commit hook failure case testing"
2301 sbox.build()
2303 # Get paths to the working copy and repository
2304 wc_dir = sbox.wc_dir
2305 repo_dir = sbox.repo_dir
2307 # Create a hook that outputs a message to stderr and returns exit code 1
2308 hook_code = """import sys
2309 sys.stderr.write("Pre-commit hook failed")
2310 sys.exit(1)"""
2312 # Setup the hook configs to log data to a file
2313 pre_commit_hook = svntest.main.get_pre_commit_hook_path(repo_dir)
2314 svntest.main.create_python_hook_script(pre_commit_hook, hook_code)
2316 # Modify iota just so there is something to commit.
2317 iota_path = os.path.join(wc_dir, "iota")
2318 svntest.main.file_append(iota_path, "More stuff in iota")
2320 # Commit, expect error code 1
2321 exit_code, actual_stdout, actual_stderr = svntest.main.run_svn(
2322 1, 'ci', '--quiet', '-m', 'log msg', wc_dir)
2324 # No stdout expected
2325 svntest.verify.compare_and_display_lines('Pre-commit hook test',
2326 'STDOUT', [], actual_stdout)
2328 # Compare only the last two lines of stderr since the preceding ones
2329 # contain source code file and line numbers.
2330 if len(actual_stderr) > 2:
2331 actual_stderr = actual_stderr[-2:]
2332 expected_stderr = [ "svn: " + hook_failure_message('pre-commit'),
2333 "Pre-commit hook failed\n"
2335 svntest.verify.compare_and_display_lines('Pre-commit hook test',
2336 'STDERR',
2337 expected_stderr, actual_stderr)
2339 #----------------------------------------------------------------------
2341 def versioned_log_message(sbox):
2342 "'svn commit -F foo' when foo is a versioned file"
2344 sbox.build()
2346 os.chdir(sbox.wc_dir)
2348 iota_path = os.path.join('iota')
2349 mu_path = os.path.join('A', 'mu')
2350 log_path = os.path.join('A', 'D', 'H', 'omega')
2352 svntest.main.file_append(iota_path, "2")
2354 # try to check in a change using a versioned file as your log entry.
2355 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
2356 'ci', '-F', log_path)
2358 # force it. should not produce any errors.
2359 svntest.actions.run_and_verify_svn(None, None, [],
2360 'ci', '-F', log_path, '--force-log')
2362 svntest.main.file_append(mu_path, "2")
2364 # try the same thing, but specifying the file to commit explicitly.
2365 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
2366 'ci', '-F', log_path, mu_path)
2368 # force it... should succeed.
2369 svntest.actions.run_and_verify_svn(None, None, [],
2370 'ci',
2371 '-F', log_path,
2372 '--force-log', mu_path)
2374 #----------------------------------------------------------------------
2376 def changelist_near_conflict(sbox):
2377 "'svn commit --changelist=foo' above a conflict"
2379 sbox.build()
2381 wc_dir = sbox.wc_dir
2382 iota_path = os.path.join(wc_dir, "iota")
2383 mu_path = os.path.join(wc_dir, "A", "mu")
2384 gloo_path = os.path.join(wc_dir, "A", "D", "H", "gloo")
2386 expected_status = make_standard_slew_of_changes(wc_dir)
2388 # Create a changelist.
2389 changelist_name = "logical-changeset"
2390 svntest.actions.run_and_verify_svn(None, None, [],
2391 "changelist", changelist_name,
2392 mu_path, gloo_path)
2394 # Create a conflict (making r2 in the process).
2395 inject_conflict_into_wc(sbox, 'iota', iota_path,
2396 None, expected_status, 2)
2398 # Commit the changelist.
2399 expected_output = svntest.wc.State(wc_dir, {
2400 "A/D/H/gloo" : Item(verb='Adding'),
2402 expected_status.tweak("A/D/H/gloo", wc_rev=3, status=" ")
2403 svntest.actions.run_and_verify_commit(wc_dir,
2404 expected_output,
2405 expected_status,
2406 None,
2407 "--changelist=" + changelist_name,
2408 "-m", "msg", wc_dir)
2411 #----------------------------------------------------------------------
2413 def commit_out_of_date_file(sbox):
2414 "try to commit a file that is out-of-date"
2416 sbox.build()
2417 wc_dir = sbox.wc_dir
2419 # Make a backup copy of the working copy
2420 wc_backup = sbox.add_wc_path('backup')
2421 svntest.actions.duplicate_dir(wc_dir, wc_backup)
2423 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
2424 backup_pi_path = os.path.join(wc_backup, 'A', 'D', 'G', 'pi')
2426 svntest.main.file_append(pi_path, "new line\n")
2427 expected_output = svntest.wc.State(wc_dir, {
2428 "A/D/G/pi" : Item(verb='Sending'),
2430 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2431 expected_status.tweak("A/D/G/pi", wc_rev=2, status=" ")
2432 svntest.actions.run_and_verify_commit(wc_dir,
2433 expected_output,
2434 expected_status,
2435 None,
2436 "-m", "log message", wc_dir)
2438 svntest.main.file_append(backup_pi_path, "hello")
2439 expected_err = ".*(pi.*out of date|Out of date.*pi).*"
2440 svntest.actions.run_and_verify_svn(None, None, expected_err,
2441 'commit', '-m', 'log message',
2442 wc_backup)
2444 def start_commit_detect_capabilities(sbox):
2445 "start-commit hook sees client capabilities" # Issue #2991
2446 sbox.build()
2447 wc_dir = sbox.wc_dir
2448 repos_dir = sbox.repo_dir
2450 # Create a start-commit hook that detects the "mergeinfo" capability.
2451 hook_text = "import sys\n" + \
2452 "fp = open(sys.argv[1] + '/hooks.log', 'w')\n" + \
2453 "caps = sys.argv[3].split(':')\n" + \
2454 "if 'mergeinfo' in caps:\n" + \
2455 " fp.write('yes')\n" + \
2456 "else:\n" + \
2457 " fp.write('no')\n" + \
2458 "fp.close()\n"
2460 start_commit_hook = svntest.main.get_start_commit_hook_path(repos_dir)
2461 svntest.main.create_python_hook_script(start_commit_hook, hook_text)
2463 # Commit something.
2464 iota_path = os.path.join(wc_dir, "iota")
2465 svntest.main.file_append(iota_path, "More stuff in iota")
2466 svntest.actions.run_and_verify_svn(None, [], [], 'ci', '--quiet',
2467 '-m', 'log msg', wc_dir)
2469 # Check that "mergeinfo" was detected.
2470 log_path = os.path.join(repos_dir, "hooks.log")
2471 if os.path.exists(log_path):
2472 data = open(log_path).read()
2473 os.unlink(log_path)
2474 else:
2475 raise svntest.verify.SVNUnexpectedOutput("'%s' not found") % log_path
2476 if data != 'yes':
2477 raise svntest.Failure
2479 def commit_url(sbox):
2480 "'svn commit SOME_URL' should error"
2481 sbox.build()
2482 wc_dir = sbox.wc_dir
2483 repos_url = sbox.repo_url
2485 # Commit directly to a URL
2486 svntest.actions.run_and_verify_commit(None,
2487 None,
2488 None,
2489 "Must give local path",
2490 repos_url)
2493 ########################################################################
2494 # Run the tests
2496 # list all tests here, starting with None:
2497 test_list = [ None,
2498 commit_one_file,
2499 commit_one_new_file,
2500 commit_one_new_binary_file,
2501 commit_multiple_targets,
2502 commit_multiple_targets_2,
2503 commit_inclusive_dir,
2504 commit_top_dir,
2505 commit_unversioned_thing,
2506 nested_dir_replacements,
2507 hudson_part_1,
2508 hudson_part_1_variation_1,
2509 hudson_part_1_variation_2,
2510 hudson_part_2,
2511 hudson_part_2_1,
2512 hook_test,
2513 merge_mixed_revisions,
2514 commit_uri_unsafe,
2515 commit_deleted_edited,
2516 commit_in_dir_scheduled_for_addition,
2517 commit_rmd_and_deleted_file,
2518 commit_add_file_twice,
2519 commit_from_long_dir,
2520 commit_with_lock,
2521 commit_current_dir,
2522 commit_multiple_wc,
2523 commit_nonrecursive,
2524 failed_commit,
2525 commit_out_of_date_deletions,
2526 commit_with_bad_log_message,
2527 from_wc_top_with_bad_editor,
2528 mods_in_schedule_delete,
2529 Skip(tab_test, is_non_posix_os_or_cygwin_platform),
2530 local_mods_are_not_commits,
2531 post_commit_hook_test,
2532 commit_same_folder_in_targets,
2533 commit_inconsistent_eol,
2534 SkipUnless(mkdir_with_revprop, server_has_revprop_commit),
2535 SkipUnless(delete_with_revprop, server_has_revprop_commit),
2536 SkipUnless(commit_with_revprop, server_has_revprop_commit),
2537 SkipUnless(import_with_revprop, server_has_revprop_commit),
2538 SkipUnless(copy_R2R_with_revprop, server_has_revprop_commit),
2539 SkipUnless(copy_WC2R_with_revprop, server_has_revprop_commit),
2540 SkipUnless(move_R2R_with_revprop, server_has_revprop_commit),
2541 SkipUnless(propedit_with_revprop, server_has_revprop_commit),
2542 SkipUnless(set_multiple_props_with_revprop,
2543 server_has_revprop_commit),
2544 SkipUnless(use_empty_value_in_revprop_pair,
2545 server_has_revprop_commit),
2546 SkipUnless(no_equals_in_revprop_pair, server_has_revprop_commit),
2547 SkipUnless(set_invalid_revprops, server_has_revprop_commit),
2548 start_commit_hook_test,
2549 pre_commit_hook_test,
2550 versioned_log_message,
2551 changelist_near_conflict,
2552 commit_out_of_date_file,
2553 SkipUnless(start_commit_detect_capabilities,
2554 server_gets_client_capabilities),
2555 commit_url,
2558 if __name__ == '__main__':
2559 svntest.main.run_tests(test_list)
2560 # NOTREACHED
2563 ### End of file.