In the command-line client, forbid
[svn.git] / subversion / tests / cmdline / commit_tests.py
blob81331782d30a0e9e09ed83eb23bdd37d0297d0e1
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 from svntest.actions import inject_conflict_into_wc
34 ######################################################################
35 # Utilities
38 def is_non_posix_os_or_cygwin_platform():
39 return (not svntest.main.is_posix_os()) or sys.platform == 'cygwin'
41 def get_standard_state(wc_dir):
42 """Return a status list reflecting the local mods made by
43 make_standard_slew_of_changes()."""
45 state = svntest.actions.get_virginal_state(wc_dir, 1)
47 state.tweak('', 'A/D', 'A/D/G/pi', status=' M')
48 state.tweak('A/B/lambda', status='M ')
49 state.tweak('A/B/E', 'A/D/H/chi', status='R ')
50 state.tweak('A/B/E/alpha', 'A/B/E/beta', 'A/C', 'A/D/gamma',
51 'A/D/G/rho', status='D ')
52 state.tweak('A/D/H/omega', status='MM')
54 # New things
55 state.add({
56 'Q' : Item(status='A ', wc_rev=0),
57 'Q/floo' : Item(status='A ', wc_rev=0),
58 'A/D/H/gloo' : Item(status='A ', wc_rev=0),
59 'A/B/E/bloo' : Item(status='A ', wc_rev=0),
62 return state
65 def make_standard_slew_of_changes(wc_dir):
66 """Make a specific set of local mods to WC_DIR. These will be used
67 by every commit-test. Verify the 'svn status' output, and return the
68 (pre-commit) status tree."""
70 # Cache current working directory, move into wc_dir
71 was_cwd = os.getcwd()
72 os.chdir(wc_dir)
74 # Add a directory
75 os.mkdir('Q')
76 svntest.main.run_svn(None, 'add', 'Q')
78 # Remove two directories
79 svntest.main.run_svn(None, 'rm', os.path.join('A', 'B', 'E'))
80 svntest.main.run_svn(None, 'rm', os.path.join('A', 'C'))
82 # Replace one of the removed directories
83 svntest.main.run_svn(None, 'add', os.path.join('A', 'B', 'E'))
85 # Make property mods to two directories
86 svntest.main.run_svn(None, 'propset', 'foo', 'bar', os.curdir)
87 svntest.main.run_svn(None, 'propset', 'foo2', 'bar2', os.path.join('A', 'D'))
89 # Add three files
90 svntest.main.file_append(os.path.join('A', 'B', 'E', 'bloo'), "hi")
91 svntest.main.file_append(os.path.join('A', 'D', 'H', 'gloo'), "hello")
92 svntest.main.file_append(os.path.join('Q', 'floo'), "yo")
93 svntest.main.run_svn(None, 'add', os.path.join('A', 'B', 'E', 'bloo'))
94 svntest.main.run_svn(None, 'add', os.path.join('A', 'D', 'H', 'gloo'))
95 svntest.main.run_svn(None, 'add', os.path.join('Q', 'floo'))
97 # Remove three files
98 svntest.main.run_svn(None, 'rm', os.path.join('A', 'D', 'G', 'rho'))
99 svntest.main.run_svn(None, 'rm', os.path.join('A', 'D', 'H', 'chi'))
100 svntest.main.run_svn(None, 'rm', os.path.join('A', 'D', 'gamma'))
102 # Replace one of the removed files
103 svntest.main.file_append(os.path.join('A', 'D', 'H', 'chi'), "chi")
104 svntest.main.run_svn(None, 'add', os.path.join('A', 'D', 'H', 'chi'))
106 # Make textual mods to two files
107 svntest.main.file_append(os.path.join('A', 'B', 'lambda'), "new ltext")
108 svntest.main.file_append(os.path.join('A', 'D', 'H', 'omega'), "new otext")
110 # Make property mods to three files
111 svntest.main.run_svn(None, 'propset', 'blue', 'azul',
112 os.path.join('A', 'D', 'H', 'omega'))
113 svntest.main.run_svn(None, 'propset', 'green', 'verde',
114 os.path.join('Q', 'floo'))
115 svntest.main.run_svn(None, 'propset', 'red', 'rojo',
116 os.path.join('A', 'D', 'G', 'pi'))
118 # Restore the CWD.
119 os.chdir(was_cwd)
121 # Build an expected status tree.
122 expected_status = get_standard_state(wc_dir)
124 # Verify status -- all local mods should be present.
125 svntest.actions.run_and_verify_status(wc_dir, expected_status)
127 return expected_status
130 ######################################################################
131 # Tests
133 # Each test must return on success or raise on failure.
136 #----------------------------------------------------------------------
138 def commit_one_file(sbox):
139 "commit one file"
141 sbox.build()
142 wc_dir = sbox.wc_dir
144 expected_status = make_standard_slew_of_changes(wc_dir)
146 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
148 # Create expected state.
149 expected_output = svntest.wc.State(wc_dir, {
150 'A/D/H/omega' : Item(verb='Sending'),
152 expected_status.tweak('A/D/H/omega', wc_rev=2, status=' ')
154 # Commit the one file.
155 svntest.actions.run_and_verify_commit(wc_dir,
156 expected_output,
157 expected_status,
158 None,
159 None, None,
160 None, None,
161 omega_path)
164 #----------------------------------------------------------------------
166 def commit_one_new_file(sbox):
167 "commit one newly added file"
169 sbox.build()
170 wc_dir = sbox.wc_dir
172 expected_status = make_standard_slew_of_changes(wc_dir)
174 gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo')
176 # Create expected state.
177 expected_output = svntest.wc.State(wc_dir, {
178 'A/D/H/gloo' : Item(verb='Adding'),
180 expected_status.tweak('A/D/H/gloo', wc_rev=2, status=' ')
182 # Commit the one file.
183 svntest.actions.run_and_verify_commit(wc_dir,
184 expected_output,
185 expected_status,
186 None,
187 None, None,
188 None, None,
189 gloo_path)
192 #----------------------------------------------------------------------
194 def commit_one_new_binary_file(sbox):
195 "commit one newly added binary file"
197 sbox.build()
198 wc_dir = sbox.wc_dir
200 expected_status = make_standard_slew_of_changes(wc_dir)
202 gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo')
203 svntest.main.run_svn(None, 'propset', 'svn:mime-type',
204 'application/octet-stream', gloo_path)
206 # Create expected state.
207 expected_output = svntest.wc.State(wc_dir, {
208 'A/D/H/gloo' : Item(verb='Adding (bin)'),
210 expected_status.tweak('A/D/H/gloo', wc_rev=2, status=' ')
212 # Commit the one file.
213 svntest.actions.run_and_verify_commit(wc_dir,
214 expected_output,
215 expected_status,
216 None,
217 None, None,
218 None, None,
219 gloo_path)
222 #----------------------------------------------------------------------
224 def commit_multiple_targets(sbox):
225 "commit multiple targets"
227 sbox.build()
228 wc_dir = sbox.wc_dir
230 # This test will commit three targets: psi, B, and pi. In that order.
232 # Make local mods to many files.
233 AB_path = os.path.join(wc_dir, 'A', 'B')
234 lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
235 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
236 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
237 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
238 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
239 svntest.main.file_append(lambda_path, 'new appended text for lambda')
240 svntest.main.file_append(rho_path, 'new appended text for rho')
241 svntest.main.file_append(pi_path, 'new appended text for pi')
242 svntest.main.file_append(omega_path, 'new appended text for omega')
243 svntest.main.file_append(psi_path, 'new appended text for psi')
245 # Just for kicks, add a property to A/D/G as well. We'll make sure
246 # that it *doesn't* get committed.
247 ADG_path = os.path.join(wc_dir, 'A', 'D', 'G')
248 svntest.main.run_svn(None, 'propset', 'foo', 'bar', ADG_path)
250 # Create expected output tree for 'svn ci'. We should see changes
251 # only on these three targets, no others.
252 expected_output = svntest.wc.State(wc_dir, {
253 'A/D/H/psi' : Item(verb='Sending'),
254 'A/B/lambda' : Item(verb='Sending'),
255 'A/D/G/pi' : Item(verb='Sending'),
258 # Create expected status tree; all local revisions should be at 1,
259 # but our three targets should be at 2.
260 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
261 expected_status.tweak('A/D/H/psi', 'A/B/lambda', 'A/D/G/pi', wc_rev=2)
263 # rho and omega should still display as locally modified:
264 expected_status.tweak('A/D/G/rho', 'A/D/H/omega', status='M ')
266 # A/D/G should still have a local property set, too.
267 expected_status.tweak('A/D/G', status=' M')
269 svntest.actions.run_and_verify_commit(wc_dir,
270 expected_output,
271 expected_status,
272 None,
273 None, None,
274 None, None,
275 psi_path, AB_path, pi_path)
277 #----------------------------------------------------------------------
280 def commit_multiple_targets_2(sbox):
281 "commit multiple targets, 2nd variation"
283 sbox.build()
284 wc_dir = sbox.wc_dir
286 # This test will commit four targets: psi, B, omega and pi. In that order.
288 # Make local mods to many files.
289 AB_path = os.path.join(wc_dir, 'A', 'B')
290 lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
291 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
292 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
293 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
294 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
295 svntest.main.file_append(lambda_path, 'new appended text for lambda')
296 svntest.main.file_append(rho_path, 'new appended text for rho')
297 svntest.main.file_append(pi_path, 'new appended text for pi')
298 svntest.main.file_append(omega_path, 'new appended text for omega')
299 svntest.main.file_append(psi_path, 'new appended text for psi')
301 # Just for kicks, add a property to A/D/G as well. We'll make sure
302 # that it *doesn't* get committed.
303 ADG_path = os.path.join(wc_dir, 'A', 'D', 'G')
304 svntest.main.run_svn(None, 'propset', 'foo', 'bar', ADG_path)
306 # Created expected output tree for 'svn ci'. We should see changes
307 # only on these three targets, no others.
308 expected_output = svntest.wc.State(wc_dir, {
309 'A/D/H/psi' : Item(verb='Sending'),
310 'A/B/lambda' : Item(verb='Sending'),
311 'A/D/H/omega' : Item(verb='Sending'),
312 'A/D/G/pi' : Item(verb='Sending'),
315 # Create expected status tree; all local revisions should be at 1,
316 # but our four targets should be at 2.
317 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
318 expected_status.tweak('A/D/H/psi', 'A/B/lambda', 'A/D/G/pi', 'A/D/H/omega',
319 wc_rev=2)
321 # rho should still display as locally modified:
322 expected_status.tweak('A/D/G/rho', status='M ')
324 # A/D/G should still have a local property set, too.
325 expected_status.tweak('A/D/G', status=' M')
327 svntest.actions.run_and_verify_commit(wc_dir,
328 expected_output,
329 expected_status,
330 None,
331 None, None,
332 None, None,
333 psi_path, AB_path,
334 omega_path, pi_path)
336 #----------------------------------------------------------------------
338 def commit_inclusive_dir(sbox):
339 "commit wc_dir/A/D -- includes D. (anchor=A, tgt=D)"
341 sbox.build()
342 wc_dir = sbox.wc_dir
344 expected_status = make_standard_slew_of_changes(wc_dir)
346 D_path = os.path.join(wc_dir, 'A', 'D')
348 # Create expected state.
349 expected_output = svntest.wc.State(wc_dir, {
350 'A/D' : Item(verb='Sending'),
351 'A/D/G/pi' : Item(verb='Sending'),
352 'A/D/G/rho' : Item(verb='Deleting'),
353 'A/D/H/gloo' : Item(verb='Adding'),
354 'A/D/H/chi' : Item(verb='Replacing'),
355 'A/D/H/omega' : Item(verb='Sending'),
356 'A/D/gamma' : Item(verb='Deleting'),
359 expected_status.remove('A/D/G/rho', 'A/D/gamma')
360 expected_status.tweak('A/D', 'A/D/G/pi', 'A/D/H/omega',
361 wc_rev=2, status=' ')
362 expected_status.tweak('A/D/H/chi', 'A/D/H/gloo', wc_rev=2, status=' ')
364 # Commit the one file.
365 svntest.actions.run_and_verify_commit(wc_dir,
366 expected_output,
367 expected_status,
368 None,
369 None, None,
370 None, None,
371 D_path)
373 #----------------------------------------------------------------------
375 def commit_top_dir(sbox):
376 "commit wc_dir -- (anchor=wc_dir, tgt={})"
378 sbox.build()
379 wc_dir = sbox.wc_dir
381 expected_status = make_standard_slew_of_changes(wc_dir)
383 # Create expected state.
384 expected_output = svntest.wc.State(wc_dir, {
385 '' : Item(verb='Sending'),
386 'Q' : Item(verb='Adding'),
387 'Q/floo' : Item(verb='Adding'),
388 'A/B/E' : Item(verb='Replacing'),
389 'A/B/E/bloo' : Item(verb='Adding'),
390 'A/B/lambda' : Item(verb='Sending'),
391 'A/C' : Item(verb='Deleting'),
392 'A/D' : Item(verb='Sending'),
393 'A/D/G/pi' : Item(verb='Sending'),
394 'A/D/G/rho' : Item(verb='Deleting'),
395 'A/D/H/gloo' : Item(verb='Adding'),
396 'A/D/H/chi' : Item(verb='Replacing'),
397 'A/D/H/omega' : Item(verb='Sending'),
398 'A/D/gamma' : Item(verb='Deleting'),
401 expected_status.remove('A/D/G/rho', 'A/D/gamma', 'A/C',
402 'A/B/E/alpha', 'A/B/E/beta')
403 expected_status.tweak('A/D', 'A/D/G/pi', 'A/D/H/omega', 'Q/floo', '',
404 wc_rev=2, status=' ')
405 expected_status.tweak('A/D/H/chi', 'Q', 'A/B/E', 'A/B/E/bloo', 'A/B/lambda',
406 'A/D/H/gloo', wc_rev=2, status=' ')
408 # Commit the one file.
409 svntest.actions.run_and_verify_commit(wc_dir,
410 expected_output,
411 expected_status,
412 None,
413 None, None,
414 None, None,
415 wc_dir)
417 #----------------------------------------------------------------------
419 # Regression test for bug reported by Jon Trowbridge:
421 # From: Jon Trowbridge <trow@ximian.com>
422 # Subject: svn segfaults if you commit a file that hasn't been added
423 # To: dev@subversion.tigris.org
424 # Date: 17 Jul 2001 03:20:55 -0500
425 # Message-Id: <995358055.16975.5.camel@morimoto>
427 # The problem is that report_single_mod in libsvn_wc/adm_crawler.c is
428 # called with its entry parameter as NULL, but the code doesn't
429 # check that entry is non-NULL before trying to dereference it.
431 # This bug never had an issue number.
433 def commit_unversioned_thing(sbox):
434 "committing unversioned object produces error"
436 sbox.build()
437 wc_dir = sbox.wc_dir
439 # Create an unversioned file in the wc.
440 svntest.main.file_append(os.path.join(wc_dir, 'blorg'), "nothing to see")
442 # Commit a non-existent file and *expect* failure:
443 svntest.actions.run_and_verify_commit(wc_dir,
444 None,
445 None,
446 "is not under version control",
447 None, None,
448 None, None,
449 os.path.join(wc_dir,'blorg'))
451 #----------------------------------------------------------------------
453 # regression test for bug #391
455 def nested_dir_replacements(sbox):
456 "replace two nested dirs, verify empty contents"
458 sbox.build()
459 wc_dir = sbox.wc_dir
461 # Delete and re-add A/D (a replacement), and A/D/H (another replace).
462 svntest.main.run_svn(None, 'rm', os.path.join(wc_dir, 'A', 'D'))
463 svntest.main.run_svn(None, 'add', '--depth=empty',
464 os.path.join(wc_dir, 'A', 'D'))
465 svntest.main.run_svn(None, 'add', '--depth=empty',
466 os.path.join(wc_dir, 'A', 'D', 'H'))
468 # For kicks, add new file A/D/bloo.
469 svntest.main.file_append(os.path.join(wc_dir, 'A', 'D', 'bloo'), "hi")
470 svntest.main.run_svn(None, 'add', os.path.join(wc_dir, 'A', 'D', 'bloo'))
472 # Verify pre-commit status:
474 # - A/D and A/D/H should both be scheduled as "R" at rev 1
475 # (rev 1 because they both existed before at rev 1)
477 # - A/D/bloo scheduled as "A" at rev 0
478 # (rev 0 because it did not exist before)
480 # - ALL other children of A/D scheduled as "D" at rev 1
482 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
483 expected_status.tweak('A/D', 'A/D/H', status='R ', wc_rev=1)
484 expected_status.add({
485 'A/D/bloo' : Item(status='A ', wc_rev=0),
487 expected_status.tweak('A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau',
488 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi', 'A/D/gamma',
489 status='D ')
491 svntest.actions.run_and_verify_status(wc_dir, expected_status)
493 # Build expected post-commit trees:
495 # Create expected output tree.
496 expected_output = svntest.wc.State(wc_dir, {
497 'A/D' : Item(verb='Replacing'),
498 'A/D/H' : Item(verb='Adding'),
499 'A/D/bloo' : Item(verb='Adding'),
502 # Created expected status tree.
503 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
504 expected_status.tweak('A/D', 'A/D/H', wc_rev=2)
505 expected_status.add({
506 'A/D/bloo' : Item(status=' ', wc_rev=2),
508 expected_status.remove('A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau',
509 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi', 'A/D/gamma')
511 # Commit from the top of the working copy and verify output & status.
512 svntest.actions.run_and_verify_commit(wc_dir,
513 expected_output,
514 expected_status,
515 None,
516 None, None,
517 None, None,
518 wc_dir)
520 #----------------------------------------------------------------------
522 # Testing part 1 of the "Greg Hudson" problem -- specifically, that
523 # our use of the "existence=deleted" flag is working properly in cases
524 # where the parent directory's revision lags behind a deleted child's
525 # revision.
527 def hudson_part_1(sbox):
528 "hudson prob 1.0: delete file, commit, update"
530 sbox.build()
531 wc_dir = sbox.wc_dir
533 # Remove gamma from the working copy.
534 gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
535 svntest.main.run_svn(None, 'rm', gamma_path)
537 # Create expected commit output.
538 expected_output = svntest.wc.State(wc_dir, {
539 'A/D/gamma' : Item(verb='Deleting'),
542 # After committing, status should show no sign of gamma.
543 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
544 expected_status.remove('A/D/gamma')
546 # Commit the deletion of gamma and verify.
547 svntest.actions.run_and_verify_commit(wc_dir,
548 expected_output,
549 expected_status,
550 None, None, None, None, None,
551 wc_dir)
553 # Now gamma should be marked as `deleted' under the hood. When we
554 # update, we should no output, and a perfect, virginal status list
555 # at revision 2. (The `deleted' entry should be removed.)
557 # Expected output of update: nothing.
558 expected_output = svntest.wc.State(wc_dir, {})
560 # Expected disk tree: everything but gamma
561 expected_disk = svntest.main.greek_state.copy()
562 expected_disk.remove('A/D/gamma')
564 # Expected status after update: totally clean revision 2, minus gamma.
565 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
566 expected_status.remove('A/D/gamma')
568 svntest.actions.run_and_verify_update(wc_dir,
569 expected_output,
570 expected_disk,
571 expected_status)
574 #----------------------------------------------------------------------
576 # Testing part 1 of the "Greg Hudson" problem -- variation on previous
577 # test, removing a directory instead of a file this time.
579 def hudson_part_1_variation_1(sbox):
580 "hudson prob 1.1: delete dir, commit, update"
582 sbox.build()
583 wc_dir = sbox.wc_dir
585 # Remove H from the working copy.
586 H_path = os.path.join(wc_dir, 'A', 'D', 'H')
587 svntest.main.run_svn(None, 'rm', H_path)
589 # Create expected commit output.
590 expected_output = svntest.wc.State(wc_dir, {
591 'A/D/H' : Item(verb='Deleting'),
594 # After committing, status should show no sign of H or its contents
595 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
596 expected_status.remove('A/D/H', 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi')
598 # Commit the deletion of H and verify.
599 svntest.actions.run_and_verify_commit(wc_dir,
600 expected_output,
601 expected_status,
602 None, None, None, None, None,
603 wc_dir)
605 # Now H should be marked as `deleted' under the hood. When we
606 # update, we should no see output, and a perfect, virginal status
607 # list at revision 2. (The `deleted' entry should be removed.)
609 # Expected output of update: H gets a no-op deletion.
610 expected_output = svntest.wc.State(wc_dir, {})
612 # Expected disk tree: everything except files in H
613 expected_disk = svntest.main.greek_state.copy()
614 expected_disk.remove('A/D/H', 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi')
616 # Expected status after update: totally clean revision 2, minus H.
617 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
618 expected_status.remove('A/D/H', 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi')
620 svntest.actions.run_and_verify_update(wc_dir,
621 expected_output,
622 expected_disk,
623 expected_status)
625 #----------------------------------------------------------------------
627 # Testing part 1 of the "Greg Hudson" problem -- variation 2. In this
628 # test, we make sure that a file that is BOTH `deleted' and scheduled
629 # for addition can be correctly committed & merged.
631 def hudson_part_1_variation_2(sbox):
632 "hudson prob 1.2: delete, commit, re-add, commit"
634 sbox.build()
635 wc_dir = sbox.wc_dir
637 # Remove gamma from the working copy.
638 gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
639 svntest.main.run_svn(None, 'rm', gamma_path)
641 # Create expected commit output.
642 expected_output = svntest.wc.State(wc_dir, {
643 'A/D/gamma' : Item(verb='Deleting'),
646 # After committing, status should show no sign of gamma.
647 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
648 expected_status.remove('A/D/gamma')
650 # Commit the deletion of gamma and verify.
651 svntest.actions.run_and_verify_commit(wc_dir,
652 expected_output,
653 expected_status,
654 None, None, None, None, None,
655 wc_dir)
657 # Now gamma should be marked as `deleted' under the hood.
658 # Go ahead and re-add gamma, so that is *also* scheduled for addition.
659 svntest.main.file_append(gamma_path, "added gamma")
660 svntest.main.run_svn(None, 'add', gamma_path)
662 # For sanity, examine status: it should show a revision 2 tree with
663 # gamma scheduled for addition.
664 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
665 expected_status.tweak('A/D/gamma', wc_rev=0, status='A ')
667 svntest.actions.run_and_verify_status(wc_dir, expected_status)
669 # Create expected commit output.
670 expected_output = svntest.wc.State(wc_dir, {
671 'A/D/gamma' : Item(verb='Adding'),
674 # After committing, status should show only gamma at revision 3.
675 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
676 expected_status.tweak('A/D/gamma', wc_rev=3)
678 svntest.actions.run_and_verify_commit(wc_dir,
679 expected_output,
680 expected_status,
681 None, None, None, None, None,
682 wc_dir)
685 #----------------------------------------------------------------------
687 # Testing part 2 of the "Greg Hudson" problem.
689 # In this test, we make sure that we're UNABLE to commit a propchange
690 # on an out-of-date directory.
692 def hudson_part_2(sbox):
693 "hudson prob 2.0: prop commit on old dir fails"
695 sbox.build()
696 wc_dir = sbox.wc_dir
698 # Remove gamma from the working copy.
699 D_path = os.path.join(wc_dir, 'A', 'D')
700 gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
701 svntest.main.run_svn(None, 'rm', gamma_path)
703 # Create expected commit output.
704 expected_output = svntest.wc.State(wc_dir, {
705 'A/D/gamma' : Item(verb='Deleting'),
708 # After committing, status should show no sign of gamma.
709 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
710 expected_status.remove('A/D/gamma')
712 # Commit the deletion of gamma and verify.
713 svntest.actions.run_and_verify_commit(wc_dir,
714 expected_output,
715 expected_status,
716 None, None, None, None, None,
717 wc_dir)
719 # Now gamma should be marked as `deleted' under the hood, at
720 # revision 2. Meanwhile, A/D is still lagging at revision 1.
722 # Make a propchange on A/D
723 svntest.main.run_svn(None, 'ps', 'foo', 'bar', D_path)
725 # Commit and *expect* a repository Merge failure:
726 svntest.actions.run_and_verify_commit(wc_dir,
727 None,
728 None,
729 "[Oo]ut.of.date",
730 None, None,
731 None, None,
732 wc_dir)
734 #----------------------------------------------------------------------
736 # Test a possible regression in our 'deleted' post-commit handling.
738 # This test moves files from one subdir to another, commits, then
739 # updates the empty directory. Nothing should be printed, assuming
740 # all the moved files are properly marked as 'deleted' and reported to
741 # the server.
743 def hudson_part_2_1(sbox):
744 "hudson prob 2.1: move files, update empty dir"
746 sbox.build()
747 wc_dir = sbox.wc_dir
749 # Move all the files in H to G
750 H_path = os.path.join(wc_dir, 'A', 'D', 'H')
751 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
752 chi_path = os.path.join(H_path, 'chi')
753 psi_path = os.path.join(H_path, 'psi')
754 omega_path = os.path.join(H_path, 'omega')
756 svntest.main.run_svn(None, 'mv', chi_path, G_path)
757 svntest.main.run_svn(None, 'mv', psi_path, G_path)
758 svntest.main.run_svn(None, 'mv', omega_path, G_path)
760 # Create expected commit output.
761 expected_output = svntest.wc.State(wc_dir, {
762 'A/D/H/chi' : Item(verb='Deleting'),
763 'A/D/H/omega' : Item(verb='Deleting'),
764 'A/D/H/psi' : Item(verb='Deleting'),
765 'A/D/G/chi' : Item(verb='Adding'),
766 'A/D/G/omega' : Item(verb='Adding'),
767 'A/D/G/psi' : Item(verb='Adding'),
770 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
771 expected_status.remove('A/D/H/chi')
772 expected_status.remove('A/D/H/omega')
773 expected_status.remove('A/D/H/psi')
774 expected_status.add({ 'A/D/G/chi' :
775 Item(wc_rev=2, status=' ') })
776 expected_status.add({ 'A/D/G/omega' :
777 Item(wc_rev=2, status=' ') })
778 expected_status.add({ 'A/D/G/psi' :
779 Item(wc_rev=2, status=' ') })
781 svntest.actions.run_and_verify_commit(wc_dir,
782 expected_output,
783 expected_status,
784 None, None, None, None, None,
785 wc_dir)
787 # Now, assuming all three files in H are marked as 'deleted', an
788 # update of H should print absolutely nothing.
789 expected_output = svntest.wc.State(wc_dir, { })
791 # Reuse expected_status
792 expected_status.tweak(wc_rev=2)
794 expected_disk = svntest.main.greek_state.copy()
795 expected_disk.remove('A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi')
796 expected_disk.add({
797 'A/D/G/chi' : Item("This is the file 'chi'.\n"),
799 expected_disk.add({
800 'A/D/G/omega' : Item("This is the file 'omega'.\n"),
802 expected_disk.add({
803 'A/D/G/psi' : Item("This is the file 'psi'.\n"),
806 svntest.actions.run_and_verify_update(wc_dir,
807 expected_output,
808 expected_disk,
809 expected_status)
811 #----------------------------------------------------------------------
813 def hook_test(sbox):
814 "hook testing"
816 sbox.build()
818 # Get paths to the working copy and repository
819 wc_dir = sbox.wc_dir
820 repo_dir = sbox.repo_dir
822 # Create a hook that appends its name to a log file.
823 hook_format = """import sys
824 fp = open(sys.argv[1] + '/hooks.log', 'a')
825 fp.write("%s\\n")
826 fp.close()"""
828 # Setup the hook configs to log data to a file
829 start_commit_hook = svntest.main.get_start_commit_hook_path(repo_dir)
830 svntest.main.create_python_hook_script(start_commit_hook,
831 hook_format % "start_commit_hook")
833 pre_commit_hook = svntest.main.get_pre_commit_hook_path(repo_dir)
834 svntest.main.create_python_hook_script(pre_commit_hook,
835 hook_format % "pre_commit_hook")
837 post_commit_hook = svntest.main.get_post_commit_hook_path(repo_dir)
838 svntest.main.create_python_hook_script(post_commit_hook,
839 hook_format % "post_commit_hook")
841 # Modify iota just so there is something to commit.
842 iota_path = os.path.join(wc_dir, "iota")
843 svntest.main.file_append(iota_path, "More stuff in iota")
845 # Commit, no output expected.
846 svntest.actions.run_and_verify_svn(None, [], [],
847 'ci', '--quiet',
848 '-m', 'log msg', wc_dir)
850 # Now check the logfile
851 expected_data = [ 'start_commit_hook\n', 'pre_commit_hook\n', 'post_commit_hook\n' ]
853 logfilename = os.path.join(repo_dir, "hooks.log")
854 if os.path.exists(logfilename):
855 fp = open(logfilename)
856 else:
857 raise svntest.verify.SVNUnexpectedOutput("hook logfile %s not found")\
858 % logfilename
860 actual_data = fp.readlines()
861 fp.close()
862 os.unlink(logfilename)
863 svntest.verify.compare_and_display_lines('wrong hook logfile content',
864 'STDERR',
865 expected_data, actual_data)
867 #----------------------------------------------------------------------
869 # Regression test for bug #469, whereby merge() was once reporting
870 # erroneous conflicts due to Ancestor < Target < Source, in terms of
871 # node-rev-id parentage.
873 def merge_mixed_revisions(sbox):
874 "commit mixed-rev wc (no erroneous merge error)"
876 sbox.build()
877 wc_dir = sbox.wc_dir
879 # Make some convenient paths.
880 iota_path = os.path.join(wc_dir, 'iota')
881 H_path = os.path.join(wc_dir, 'A', 'D', 'H')
882 chi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'chi')
883 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
885 # Here's the reproduction formula, in 5 parts.
886 # Hoo, what a buildup of state!
888 # 1. echo "moo" >> iota; echo "moo" >> A/D/H/chi; svn ci
889 svntest.main.file_append(iota_path, "moo")
890 svntest.main.file_append(chi_path, "moo")
892 expected_output = svntest.wc.State(wc_dir, {
893 'iota' : Item(verb='Sending'),
894 'A/D/H/chi' : Item(verb='Sending'),
897 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
898 expected_status.tweak('iota', 'A/D/H/chi', wc_rev=2)
900 svntest.actions.run_and_verify_commit(wc_dir,
901 expected_output,
902 expected_status,
903 None, None, None, None, None,
904 wc_dir)
907 # 2. svn up A/D/H
908 expected_status = svntest.wc.State(wc_dir, {
909 'A/D/H' : Item(status=' ', wc_rev=2),
910 'A/D/H/chi' : Item(status=' ', wc_rev=2),
911 'A/D/H/omega' : Item(status=' ', wc_rev=2),
912 'A/D/H/psi' : Item(status=' ', wc_rev=2),
914 expected_disk = svntest.wc.State('', {
915 'omega' : Item("This is the file 'omega'.\n"),
916 'chi' : Item("This is the file 'chi'.\nmoo"),
917 'psi' : Item("This is the file 'psi'.\n"),
919 expected_output = svntest.wc.State(wc_dir, { })
920 svntest.actions.run_and_verify_update(H_path,
921 expected_output,
922 expected_disk,
923 expected_status)
926 # 3. echo "moo" >> iota; svn ci iota
927 svntest.main.file_append(iota_path, "moo2")
928 expected_output = svntest.wc.State(wc_dir, {
929 'iota' : Item(verb='Sending'),
931 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
932 expected_status.tweak('A/D/H', 'A/D/H/omega', 'A/D/H/chi', 'A/D/H/psi',
933 wc_rev=2)
934 expected_status.tweak('iota', wc_rev=3)
936 svntest.actions.run_and_verify_commit(wc_dir,
937 expected_output,
938 expected_status,
939 None, None, None, None, None,
940 wc_dir)
943 # 4. echo "moo" >> A/D/H/chi; svn ci A/D/H/chi
944 svntest.main.file_append(chi_path, "moo3")
945 expected_output = svntest.wc.State(wc_dir, {
946 'A/D/H/chi' : Item(verb='Sending'),
948 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
949 expected_status.tweak('A/D/H/chi', wc_rev=4)
950 expected_status.tweak('A/D/H', 'A/D/H/omega', 'A/D/H/psi', wc_rev=2)
951 expected_status.tweak('iota', wc_rev=3)
952 svntest.actions.run_and_verify_commit(wc_dir,
953 expected_output,
954 expected_status,
955 None, None, None, None, None,
956 wc_dir)
958 # 5. echo "moo" >> iota; svn ci iota
959 svntest.main.file_append(iota_path, "moomoo")
960 expected_output = svntest.wc.State(wc_dir, {
961 'iota' : Item(verb='Sending'),
963 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
964 expected_status.tweak('A/D/H', 'A/D/H/omega', 'A/D/H/psi', wc_rev=2)
965 expected_status.tweak('A/D/H/chi', wc_rev=4)
966 expected_status.tweak('iota', wc_rev=5)
967 svntest.actions.run_and_verify_commit(wc_dir,
968 expected_output,
969 expected_status,
970 None, None, None, None, None,
971 wc_dir)
973 # At this point, here is what our tree should look like:
974 # _ 1 ( 5) working_copies/commit_tests-10
975 # _ 1 ( 5) working_copies/commit_tests-10/A
976 # _ 1 ( 5) working_copies/commit_tests-10/A/B
977 # _ 1 ( 5) working_copies/commit_tests-10/A/B/E
978 # _ 1 ( 5) working_copies/commit_tests-10/A/B/E/alpha
979 # _ 1 ( 5) working_copies/commit_tests-10/A/B/E/beta
980 # _ 1 ( 5) working_copies/commit_tests-10/A/B/F
981 # _ 1 ( 5) working_copies/commit_tests-10/A/B/lambda
982 # _ 1 ( 5) working_copies/commit_tests-10/A/C
983 # _ 1 ( 5) working_copies/commit_tests-10/A/D
984 # _ 1 ( 5) working_copies/commit_tests-10/A/D/G
985 # _ 1 ( 5) working_copies/commit_tests-10/A/D/G/pi
986 # _ 1 ( 5) working_copies/commit_tests-10/A/D/G/rho
987 # _ 1 ( 5) working_copies/commit_tests-10/A/D/G/tau
988 # _ 2 ( 5) working_copies/commit_tests-10/A/D/H
989 # _ 4 ( 5) working_copies/commit_tests-10/A/D/H/chi
990 # _ 2 ( 5) working_copies/commit_tests-10/A/D/H/omega
991 # _ 2 ( 5) working_copies/commit_tests-10/A/D/H/psi
992 # _ 1 ( 5) working_copies/commit_tests-10/A/D/gamma
993 # _ 1 ( 5) working_copies/commit_tests-10/A/mu
994 # _ 5 ( 5) working_copies/commit_tests-10/iota
996 # At this point, we're ready to modify omega and iota, and commit
997 # from the top. We should *not* get a conflict!
999 svntest.main.file_append(iota_path, "finalmoo")
1000 svntest.main.file_append(omega_path, "finalmoo")
1002 expected_output = svntest.wc.State(wc_dir, {
1003 'iota' : Item(verb='Sending'),
1004 'A/D/H/omega' : Item(verb='Sending'),
1006 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1007 expected_status.tweak('iota', 'A/D/H/omega', wc_rev=6)
1008 expected_status.tweak('A/D/H', 'A/D/H/psi', wc_rev=2)
1009 expected_status.tweak('A/D/H/chi', wc_rev=4)
1010 svntest.actions.run_and_verify_commit(wc_dir,
1011 expected_output,
1012 expected_status,
1013 None, None, None, None, None,
1014 wc_dir)
1016 #----------------------------------------------------------------------
1018 def commit_uri_unsafe(sbox):
1019 "commit files and dirs with URI-unsafe characters"
1021 sbox.build()
1022 wc_dir = sbox.wc_dir
1024 # Note: on Windows, files can't have angle brackets in them, so we
1025 # don't tests that case.
1026 if svntest.main.windows or sys.platform == 'cygwin':
1027 angle_name = '_angle_'
1028 nasty_name = '#![]{}()__%'
1029 else:
1030 angle_name = '<angle>'
1031 nasty_name = '#![]{}()<>%'
1033 # Make some convenient paths.
1034 hash_dir = os.path.join(wc_dir, '#hash#')
1035 nasty_dir = os.path.join(wc_dir, nasty_name)
1036 space_path = os.path.join(wc_dir, 'A', 'D', 'space path')
1037 bang_path = os.path.join(wc_dir, 'A', 'D', 'H', 'bang!')
1038 bracket_path = os.path.join(wc_dir, 'A', 'D', 'H', 'bra[ket')
1039 brace_path = os.path.join(wc_dir, 'A', 'D', 'H', 'bra{e')
1040 angle_path = os.path.join(wc_dir, 'A', 'D', 'H', angle_name)
1041 paren_path = os.path.join(wc_dir, 'A', 'D', 'pare)(theses')
1042 percent_path = os.path.join(wc_dir, '#hash#', 'percen%')
1043 nasty_path = os.path.join(wc_dir, 'A', nasty_name)
1045 os.mkdir(hash_dir)
1046 os.mkdir(nasty_dir)
1047 svntest.main.file_append(space_path, "This path has a space in it.")
1048 svntest.main.file_append(bang_path, "This path has a bang in it.")
1049 svntest.main.file_append(bracket_path, "This path has a bracket in it.")
1050 svntest.main.file_append(brace_path, "This path has a brace in it.")
1051 svntest.main.file_append(angle_path, "This path has angle brackets in it.")
1052 svntest.main.file_append(paren_path, "This path has parentheses in it.")
1053 svntest.main.file_append(percent_path, "This path has a percent in it.")
1054 svntest.main.file_append(nasty_path, "This path has all sorts of ick in it.")
1056 add_list = [hash_dir,
1057 nasty_dir, # not xml-safe
1058 space_path,
1059 bang_path,
1060 bracket_path,
1061 brace_path,
1062 angle_path, # not xml-safe
1063 paren_path,
1064 percent_path,
1065 nasty_path, # not xml-safe
1067 for item in add_list:
1068 svntest.main.run_svn(None, 'add', '--depth=empty', item)
1070 expected_output = svntest.wc.State(wc_dir, {
1071 '#hash#' : Item(verb='Adding'),
1072 nasty_name : Item(verb='Adding'),
1073 'A/D/space path' : Item(verb='Adding'),
1074 'A/D/H/bang!' : Item(verb='Adding'),
1075 'A/D/H/bra[ket' : Item(verb='Adding'),
1076 'A/D/H/bra{e' : Item(verb='Adding'),
1077 'A/D/H/' + angle_name : Item(verb='Adding'),
1078 'A/D/pare)(theses' : Item(verb='Adding'),
1079 '#hash#/percen%' : Item(verb='Adding'),
1080 'A/' + nasty_name : Item(verb='Adding'),
1083 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1085 # Items in our add list will be at rev 2
1086 for item in expected_output.desc.keys():
1087 expected_status.add({ item : Item(wc_rev=2, status=' ') })
1089 svntest.actions.run_and_verify_commit(wc_dir,
1090 expected_output,
1091 expected_status,
1092 None, None, None, None, None,
1093 wc_dir)
1096 #----------------------------------------------------------------------
1098 def commit_deleted_edited(sbox):
1099 "commit deleted yet edited files"
1101 sbox.build()
1102 wc_dir = sbox.wc_dir
1104 # Make some convenient paths.
1105 iota_path = os.path.join(wc_dir, 'iota')
1106 mu_path = os.path.join(wc_dir, 'A', 'mu')
1108 # Edit the files.
1109 svntest.main.file_append(iota_path, "This file has been edited.")
1110 svntest.main.file_append(mu_path, "This file has been edited.")
1112 # Schedule the files for removal.
1113 svntest.main.run_svn(None, 'remove', '--force', iota_path)
1114 svntest.main.run_svn(None, 'remove', '--force', mu_path)
1116 # Make our output list
1117 expected_output = svntest.wc.State(wc_dir, {
1118 'iota' : Item(verb='Deleting'),
1119 'A/mu' : Item(verb='Deleting'),
1122 # Items in the status list are all at rev 1, except the two things
1123 # we changed...but then, they don't exist at all.
1124 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1125 expected_status.remove('iota', 'A/mu')
1127 svntest.actions.run_and_verify_commit(wc_dir,
1128 expected_output,
1129 expected_status,
1130 None, None, None, None, None,
1131 wc_dir)
1133 #----------------------------------------------------------------------
1135 def commit_in_dir_scheduled_for_addition(sbox):
1136 "commit a file inside dir scheduled for addition"
1138 sbox.build()
1139 wc_dir = sbox.wc_dir
1141 A_path = os.path.join(wc_dir, 'A')
1142 Z_path = os.path.join(wc_dir, 'Z')
1143 mu_path = os.path.join(wc_dir, 'Z', 'mu')
1145 svntest.main.run_svn(None, 'move', A_path, Z_path)
1147 # Commit a copied thing inside an added-with-history directory,
1148 # expecting a specific error to occur!
1149 svntest.actions.run_and_verify_commit(wc_dir,
1150 None,
1151 None,
1152 "unversioned",
1153 None, None,
1154 None, None,
1155 mu_path)
1157 Q_path = os.path.join(wc_dir, 'Q')
1158 bloo_path = os.path.join(Q_path, 'bloo')
1160 os.mkdir(Q_path)
1161 svntest.main.file_append(bloo_path, "New contents.")
1162 svntest.main.run_svn(None, 'add', Q_path)
1164 # Commit a regular added thing inside an added directory,
1165 # expecting a specific error to occur!
1166 svntest.actions.run_and_verify_commit(wc_dir,
1167 None,
1168 None,
1169 "not under version control",
1170 None, None,
1171 None, None,
1172 bloo_path)
1174 #----------------------------------------------------------------------
1176 # Does this make sense now that deleted files are always removed from the wc?
1177 def commit_rmd_and_deleted_file(sbox):
1178 "commit deleted (and missing) file"
1180 sbox.build()
1181 wc_dir = sbox.wc_dir
1182 mu_path = os.path.join(wc_dir, 'A', 'mu')
1184 # 'svn remove' mu
1185 svntest.main.run_svn(None, 'rm', mu_path)
1187 # Commit, hoping to see no errors
1188 svntest.actions.run_and_verify_svn("Output on stderr where none expected",
1189 svntest.verify.AnyOutput, [],
1190 'commit', '-m', 'logmsg', mu_path)
1192 #----------------------------------------------------------------------
1194 # Issue #644 which failed over ra_neon.
1195 def commit_add_file_twice(sbox):
1196 "issue 644 attempt to add a file twice"
1198 sbox.build()
1199 wc_dir = sbox.wc_dir
1201 # Create a file
1202 gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo')
1203 svntest.main.file_append(gloo_path, "hello")
1204 svntest.main.run_svn(None, 'add', gloo_path)
1206 # Create expected output tree.
1207 expected_output = svntest.wc.State(wc_dir, {
1208 'A/D/H/gloo' : Item(verb='Adding'),
1211 # Created expected status tree.
1212 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1213 expected_status.add({
1214 'A/D/H/gloo' : Item(status=' ', wc_rev=2),
1217 # Commit should succeed
1218 svntest.actions.run_and_verify_commit(wc_dir,
1219 expected_output,
1220 expected_status,
1221 None,
1222 None, None,
1223 None, None,
1224 wc_dir)
1226 # Update to state before commit
1227 svntest.main.run_svn(None, 'up', '-r', '1', wc_dir)
1229 # Create the file again
1230 svntest.main.file_append(gloo_path, "hello")
1231 svntest.main.run_svn(None, 'add', gloo_path)
1233 # Commit and *expect* a failure:
1234 svntest.actions.run_and_verify_commit(wc_dir,
1235 None,
1236 None,
1237 "already exists",
1238 None, None,
1239 None, None,
1240 wc_dir)
1242 #----------------------------------------------------------------------
1244 # There was a problem that committing from a directory that had a
1245 # longer name than the working copy directory caused the commit notify
1246 # messages to display truncated/random filenames.
1248 def commit_from_long_dir(sbox):
1249 "commit from a dir with a longer name than the wc"
1251 sbox.build()
1252 wc_dir = sbox.wc_dir
1254 was_dir = os.getcwd()
1255 abs_wc_dir = os.path.realpath(os.path.join(was_dir, wc_dir))
1257 # something to commit
1258 svntest.main.file_append(os.path.join(wc_dir, 'iota'), "modified iota")
1260 # Create expected output tree.
1261 expected_output = svntest.wc.State('', {
1262 'iota' : Item(verb='Sending'),
1265 # Any length name was enough to provoke the original bug, but
1266 # keeping its length less than that of the filename 'iota' avoided
1267 # random behaviour, but still caused the test to fail
1268 extra_name = 'xx'
1270 os.chdir(wc_dir)
1271 os.mkdir(extra_name)
1272 os.chdir(extra_name)
1274 svntest.actions.run_and_verify_commit(abs_wc_dir,
1275 expected_output,
1276 None,
1277 None,
1278 None, None,
1279 None, None,
1280 abs_wc_dir)
1282 #----------------------------------------------------------------------
1284 def commit_with_lock(sbox):
1285 "try to commit when directory is locked"
1287 sbox.build()
1288 # modify gamma and lock its directory
1289 wc_dir = sbox.wc_dir
1291 D_path = os.path.join(wc_dir, 'A', 'D')
1292 gamma_path = os.path.join(D_path, 'gamma')
1293 svntest.main.file_append(gamma_path, "modified gamma")
1294 svntest.actions.lock_admin_dir(D_path)
1296 # this commit should fail
1297 svntest.actions.run_and_verify_commit(wc_dir,
1298 None,
1299 None,
1300 'svn: Working copy \'.*\' locked',
1301 None, None,
1302 None, None,
1303 wc_dir)
1305 # unlock directory
1306 svntest.actions.run_and_verify_svn("Output on stderr where none expected",
1307 [], [],
1308 'cleanup', D_path)
1310 # this commit should succeed
1311 expected_output = svntest.wc.State(wc_dir, {
1312 'A/D/gamma' : Item(verb='Sending'),
1314 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1315 expected_status.tweak('A/D/gamma', wc_rev=2)
1316 svntest.actions.run_and_verify_commit(wc_dir,
1317 expected_output,
1318 expected_status,
1319 None,
1320 None, None,
1321 None, None,
1322 wc_dir)
1324 #----------------------------------------------------------------------
1326 # Explicitly commit the current directory. This did at one point fail
1327 # in post-commit processing due to a path canonicalization problem.
1329 def commit_current_dir(sbox):
1330 "commit the current directory"
1332 sbox.build()
1334 wc_dir = sbox.wc_dir
1335 svntest.main.run_svn(None, 'propset', 'pname', 'pval', wc_dir)
1337 was_cwd = os.getcwd()
1339 os.chdir(wc_dir)
1341 expected_output = svntest.wc.State('.', {
1342 '.' : Item(verb='Sending'),
1344 svntest.actions.run_and_verify_commit('.',
1345 expected_output,
1346 None,
1347 None,
1348 None, None,
1349 None, None,
1350 '.')
1351 os.chdir(was_cwd)
1353 # I can't get the status check to work as part of run_and_verify_commit.
1354 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1355 expected_status.tweak('', wc_rev=2, status=' ')
1356 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1358 #----------------------------------------------------------------------
1360 # Check that the pending txn gets removed from the repository after
1361 # a failed commit.
1363 def failed_commit(sbox):
1364 "commit with conflicts and check txn in repo"
1366 sbox.build()
1367 wc_dir = sbox.wc_dir
1369 # Make the other working copy
1370 other_wc_dir = sbox.add_wc_path('other')
1371 svntest.actions.duplicate_dir(wc_dir, other_wc_dir)
1373 # Make different changes in the two working copies
1374 iota_path = os.path.join(wc_dir, "iota")
1375 svntest.main.file_append(iota_path, "More stuff in iota")
1377 other_iota_path = os.path.join(other_wc_dir, "iota")
1378 svntest.main.file_append(other_iota_path, "More different stuff in iota")
1380 # Commit both working copies. The second commit should fail.
1381 svntest.actions.run_and_verify_svn("Output on stderr where none expected",
1382 svntest.verify.AnyOutput, [],
1383 'commit', '-m', 'log', wc_dir)
1385 svntest.actions.run_and_verify_svn("Output on stderr expected",
1386 None, svntest.verify.AnyOutput,
1387 'commit', '-m', 'log', other_wc_dir)
1389 # Now list the txns in the repo. The list should be empty.
1390 output, errput = svntest.main.run_svnadmin('lstxns', sbox.repo_dir)
1391 svntest.verify.compare_and_display_lines(
1392 "Error running 'svnadmin lstxns'.",
1393 'STDERR', [], errput)
1394 svntest.verify.compare_and_display_lines(
1395 "Output of 'svnadmin lstxns' is unexpected.",
1396 'STDOUT', [], output)
1398 #----------------------------------------------------------------------
1400 # Commit from multiple working copies is not yet supported. At
1401 # present an error is generated and none of the working copies change.
1402 # Related to issue 959, this test here doesn't use svn:externals but the
1403 # behaviour needs to be considered.
1405 def commit_multiple_wc(sbox):
1406 "attempted commit from multiple wc fails"
1408 sbox.build()
1409 wc_dir = sbox.wc_dir
1411 # Checkout a second working copy
1412 wc2_dir = os.path.join(wc_dir, 'A', 'wc2')
1413 url = sbox.repo_url
1414 svntest.actions.run_and_verify_svn("Output on stderr where none expected",
1415 svntest.verify.AnyOutput, [],
1416 'checkout',
1417 url, wc2_dir)
1419 # Modify both working copies
1420 mu_path = os.path.join(wc_dir, 'A', 'mu')
1421 svntest.main.file_append(mu_path, 'appended mu text')
1422 lambda2_path = os.path.join(wc2_dir, 'A', 'B', 'lambda')
1423 svntest.main.file_append(lambda2_path, 'appended lambda2 text')
1425 # Verify modified status
1426 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1427 expected_status.tweak('A/mu', status='M ')
1428 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1429 expected_status2 = svntest.actions.get_virginal_state(wc2_dir, 1)
1430 expected_status2.tweak('A/B/lambda', status='M ')
1431 svntest.actions.run_and_verify_status(wc2_dir, expected_status2)
1433 # Commit should fail, even though one target is a "child" of the other.
1434 svntest.actions.run_and_verify_svn("Unexpectedly not locked",
1435 None, svntest.verify.AnyOutput,
1436 'commit', '-m', 'log',
1437 wc_dir, wc2_dir)
1439 # Verify status unchanged
1440 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1441 svntest.actions.run_and_verify_status(wc2_dir, expected_status2)
1444 def commit_nonrecursive(sbox):
1445 "commit named targets with -N (issues #1195, #1239)"
1447 sbox.build()
1448 wc_dir = sbox.wc_dir
1450 ### Note: the original recipes used 'add -N'. These days, we use
1451 ### --depth={empty,files}, and both the code and the comments below
1452 ### have been adjusted to reflect this.
1454 #####################################################
1455 ### Issue #1195:
1457 ### 1. Create these directories and files:
1459 ### file1
1460 ### dir1
1461 ### dir1/file2
1462 ### dir1/file3
1463 ### dir1/dir2
1464 ### dir1/dir2/file4
1466 ### 2. run 'svn add --depth=empty <all of the above>'
1468 ### 3. run 'svn ci -N <all of the above>'
1470 ### (The bug was that only 4 entities would get committed, when it
1471 ### should be 6: dir2/ and file4 were left out.)
1473 # These paths are relative to the top of the test's working copy.
1474 file1_path = 'file1'
1475 dir1_path = 'dir1'
1476 file2_path = os.path.join('dir1', 'file2')
1477 file3_path = os.path.join('dir1', 'file3')
1478 dir2_path = os.path.join('dir1', 'dir2')
1479 file4_path = os.path.join('dir1', 'dir2', 'file4')
1481 # Create the new files and directories.
1482 svntest.main.file_append(os.path.join(wc_dir, file1_path), 'this is file1')
1483 os.mkdir(os.path.join(wc_dir, dir1_path))
1484 svntest.main.file_append(os.path.join(wc_dir, file2_path), 'this is file2')
1485 svntest.main.file_append(os.path.join(wc_dir, file3_path), 'this is file3')
1486 os.mkdir(os.path.join(wc_dir, dir2_path))
1487 svntest.main.file_append(os.path.join(wc_dir, file4_path), 'this is file4')
1489 # Add them to version control.
1490 svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [],
1491 'add', '--depth=empty',
1492 os.path.join(wc_dir, file1_path),
1493 os.path.join(wc_dir, dir1_path),
1494 os.path.join(wc_dir, file2_path),
1495 os.path.join(wc_dir, file3_path),
1496 os.path.join(wc_dir, dir2_path),
1497 os.path.join(wc_dir, file4_path))
1499 # Commit. We should see all 6 items (2 dirs, 4 files) get sent.
1500 expected_output = svntest.wc.State(
1501 wc_dir,
1502 { file1_path : Item(verb='Adding'),
1503 dir1_path : Item(verb='Adding'),
1504 file2_path : Item(verb='Adding'),
1505 file3_path : Item(verb='Adding'),
1506 dir2_path : Item(verb='Adding'),
1507 file4_path : Item(verb='Adding'),
1511 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1512 expected_status.add({
1513 file1_path : Item(status=' ', wc_rev=2),
1514 dir1_path : Item(status=' ', wc_rev=2),
1515 file2_path : Item(status=' ', wc_rev=2),
1516 file3_path : Item(status=' ', wc_rev=2),
1517 dir2_path : Item(status=' ', wc_rev=2),
1518 file4_path : Item(status=' ', wc_rev=2),
1521 svntest.actions.run_and_verify_commit(wc_dir,
1522 expected_output,
1523 expected_status,
1524 None,
1525 None, None,
1526 None, None,
1527 '-N',
1528 os.path.join(wc_dir, file1_path),
1529 os.path.join(wc_dir, dir1_path),
1530 os.path.join(wc_dir, file2_path),
1531 os.path.join(wc_dir, file3_path),
1532 os.path.join(wc_dir, dir2_path),
1533 os.path.join(wc_dir, file4_path))
1535 #######################################################################
1537 ### There's some complex history here; please bear with me.
1539 ### First there was issue #1239, which had the following recipe:
1541 ### 1. Create these directories and files:
1543 ### dirA
1544 ### dirA/fileA
1545 ### dirA/fileB
1546 ### dirA/dirB
1547 ### dirA/dirB/fileC
1548 ### dirA/dirB/nocommit
1550 ### 2. run 'svn add --depth=empty <all of the above>'
1552 ### 3. run 'svn ci -N <all but nocommit>'
1554 ### (In this recipe, 'add -N' has been changed to 'add --depth...',
1555 ### but 'ci -N' has been left as-is, for reasons explained below.)
1557 ### Issue #1239 claimed a two-part bug: that step 3 would try to
1558 ### commit the file `nocommit' when it shouldn't, and that it would
1559 ### get an error anyway:
1561 ### Adding wc/dirA
1562 ### Adding wc/dirA/fileA
1563 ### Adding wc/dirA/fileB
1564 ### Adding wc/dirA/dirB
1565 ### Adding wc/dirA/dirB/nocommit
1566 ### Adding wc/dirA/dirB/fileC
1567 ### Transmitting file data ....svn: A problem occurred; \
1568 ### see later errors for details
1569 ### svn: Commit succeeded, but other errors follow:
1570 ### svn: Problem running log
1571 ### svn: Error bumping revisions post-commit (details follow):
1572 ### svn: in directory
1573 ### 'F:/Programmation/Projets/subversion/svnant/test/wc/dirA'
1574 ### svn: start_handler: error processing command 'committed' in
1575 ### 'F:/Programmation/Projets/subversion/svnant/test/wc/dirA'
1576 ### svn: Working copy not locked
1577 ### svn: directory not locked
1578 ### (F:/Programmation/Projets/subversion/svnant/test/wc)
1580 ### However, this was all in the days before --depth, and depended
1581 ### on an idiosyncratic interpretation of -N, one which required
1582 ### commit to behave differently from other commands taking -N.
1584 ### These days, -N should be equivalent to --depth=files in almost
1585 ### all cases. There are some exceptions (e.g., status), but commit
1586 ### is not an exception. Thus, the above recipe is now incorrect,
1587 ### because "wc/dirA/dirB" was given as an explicit target, and
1588 ### therefore the file "wc/dirA/dirB/nocommit" *should* have been
1589 ### committed after all, since it's a file child of a named target
1590 ### and -N means --depth=files.
1592 ### So we really need two tests: one for commit -N (--depth=files),
1593 ### and another for --depth=empty. I've changed this test to cover
1594 ### the -N case, and added 'commit_propmods_with_depth_empty' to
1595 ### depth_tests.py to cover the --depth=empty case.
1597 # Now add these directories and files, except the last:
1598 dirA_path = 'dirA'
1599 fileA_path = os.path.join('dirA', 'fileA')
1600 fileB_path = os.path.join('dirA', 'fileB')
1601 dirB_path = os.path.join('dirA', 'dirB')
1602 nope_1_path = os.path.join(dirB_path, 'nope_1')
1603 nope_2_path = os.path.join(dirB_path, 'nope_2')
1605 # Create the new files and directories.
1606 os.mkdir(os.path.join(wc_dir, dirA_path))
1607 svntest.main.file_append(os.path.join(wc_dir, fileA_path), 'fileA')
1608 svntest.main.file_append(os.path.join(wc_dir, fileB_path), 'fileB')
1609 os.mkdir(os.path.join(wc_dir, dirB_path))
1610 svntest.main.file_append(os.path.join(wc_dir, nope_1_path), 'nope_1')
1611 svntest.main.file_append(os.path.join(wc_dir, nope_2_path), 'nope_2')
1613 # Add them to version control.
1614 svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [],
1615 'add', '--depth=empty',
1616 os.path.join(wc_dir, dirA_path),
1617 os.path.join(wc_dir, fileA_path),
1618 os.path.join(wc_dir, fileB_path),
1619 os.path.join(wc_dir, dirB_path),
1620 os.path.join(wc_dir, nope_1_path),
1621 os.path.join(wc_dir, nope_2_path))
1623 expected_output = svntest.wc.State(
1624 wc_dir,
1625 { dirA_path : Item(verb='Adding'),
1626 fileA_path : Item(verb='Adding'),
1627 fileB_path : Item(verb='Adding'),
1631 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1633 # Expect the leftovers from the first part of the test.
1634 expected_status.add({
1635 file1_path : Item(status=' ', wc_rev=2),
1636 dir1_path : Item(status=' ', wc_rev=2),
1637 file2_path : Item(status=' ', wc_rev=2),
1638 file3_path : Item(status=' ', wc_rev=2),
1639 dir2_path : Item(status=' ', wc_rev=2),
1640 file4_path : Item(status=' ', wc_rev=2),
1643 # Expect some commits and some non-commits from this part of the test.
1644 expected_status.add({
1645 dirA_path : Item(status=' ', wc_rev=3),
1646 fileA_path : Item(status=' ', wc_rev=3),
1647 fileB_path : Item(status=' ', wc_rev=3),
1648 dirB_path : Item(status='A ', wc_rev=0),
1649 nope_1_path : Item(status='A ', wc_rev=0),
1650 nope_2_path : Item(status='A ', wc_rev=0)
1653 svntest.actions.run_and_verify_commit(wc_dir,
1654 expected_output,
1655 expected_status,
1656 None,
1657 None, None,
1658 None, None,
1659 '-N', os.path.join(wc_dir, dirA_path))
1661 #----------------------------------------------------------------------
1662 # Regression for #1017: ra_neon was allowing the deletion of out-of-date
1663 # files or dirs, which majorly violates Subversion's semantics.
1666 def commit_out_of_date_deletions(sbox):
1667 "commit deletion of out-of-date file or dir"
1669 sbox.build()
1670 wc_dir = sbox.wc_dir
1672 # Make a backup copy of the working copy
1673 wc_backup = sbox.add_wc_path('backup')
1674 svntest.actions.duplicate_dir(wc_dir, wc_backup)
1676 # Change omega's text, and make a propchange to A/C directory
1677 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
1678 C_path = os.path.join(wc_dir, 'A', 'C')
1679 svntest.main.file_append(omega_path, 'appended omega text')
1680 svntest.main.run_svn(None, 'propset', 'fooprop', 'foopropval', C_path)
1682 # Commit revision 2.
1683 expected_output = svntest.wc.State(wc_dir, {
1684 'A/D/H/omega' : Item(verb='Sending'),
1685 'A/C' : Item(verb='Sending'),
1687 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1688 expected_status.tweak('A/D/H/omega', 'A/C', wc_rev=2, status=' ')
1690 svntest.actions.run_and_verify_commit(wc_dir,
1691 expected_output,
1692 expected_status,
1693 None,
1694 None, None,
1695 None, None,
1696 wc_dir)
1698 # Now, in the second working copy, schedule both omega and C for deletion.
1699 omega_path = os.path.join(wc_backup, 'A', 'D', 'H', 'omega')
1700 C_path = os.path.join(wc_backup, 'A', 'C')
1701 svntest.main.run_svn(None, 'rm', omega_path, C_path)
1703 # Attempt to delete omega. This should return an (expected)
1704 # out-of-dateness error.
1705 outlines, errlines = svntest.main.run_svn(1, 'commit', '-m', 'blah',
1706 omega_path)
1707 for line in errlines:
1708 if re.match(".*[Oo]ut.of.date.*", line):
1709 break
1710 else:
1711 raise svntest.Failure
1713 # Attempt to delete directory C. This should return an (expected)
1714 # out-of-dateness error.
1715 outlines, errlines = svntest.main.run_svn(1, 'commit', '-m', 'blah', C_path)
1716 for line in errlines:
1717 if re.match(".*[Oo]ut.of.date.*", line):
1718 break
1719 else:
1720 raise svntest.Failure
1722 def commit_with_bad_log_message(sbox):
1723 "commit with a log message containing bad data"
1725 sbox.build()
1726 wc_dir = sbox.wc_dir
1728 iota_path = os.path.join(wc_dir, 'iota')
1729 log_msg_path = os.path.join(wc_dir, 'log-message')
1731 # Make a random change, so there's something to commit.
1732 svntest.main.file_append(iota_path, 'fish')
1734 # Create a log message containing a zero-byte.
1735 svntest.main.file_append(log_msg_path, '\x00')
1737 # Commit and expect an error.
1738 svntest.actions.run_and_verify_commit(wc_dir,
1739 None, None,
1740 "contains a zero byte",
1741 None, None,
1742 None, None,
1743 '-F', log_msg_path,
1744 iota_path)
1746 def from_wc_top_with_bad_editor(sbox):
1747 "commit with invalid external editor cmd"
1749 # Shortly after revision 5407, Vladimir Prus posted this bug recipe:
1751 # #!/bin/bash
1752 # cd /tmp
1753 # rm -rf repo wc
1754 # svnadmin create repo
1755 # svn mkdir file:///tmp/repo/foo -m ""
1756 # svn co file:///tmp/repo/foo wc
1757 # cd wc
1758 # svn ps svn:externals "lib http://something.org/lib" .
1759 # svn ci
1761 # The final 'svn ci' would seg fault because of a problem in
1762 # calculating the paths to insert in the initial log message that
1763 # gets passed to the editor.
1765 # So this regression test is primarily about making sure the seg
1766 # fault is gone, and only secondarily about testing that we get the
1767 # expected error from passing a bad editor cmd to Subversion.
1769 sbox.build()
1770 wc_dir = sbox.wc_dir
1772 svntest.actions.run_and_verify_svn("Unexpected failure from propset.",
1773 svntest.verify.AnyOutput, [],
1774 'pset', 'fish', 'food', wc_dir)
1775 os.chdir(wc_dir)
1776 out, err = svntest.actions.run_and_verify_svn(
1777 "Commit succeeded when should have failed.",
1778 None, svntest.verify.AnyOutput,
1779 'ci', '--editor-cmd', 'no_such-editor')
1781 err = string.join(map(string.strip, err), ' ')
1782 if not (re.match(".*no_such-editor.*", err)
1783 and re.match(".*Commit failed.*", err)):
1784 print "Commit failed, but not in the way expected."
1785 raise svntest.Failure
1788 def mods_in_schedule_delete(sbox):
1789 "commit with mods in schedule delete"
1791 sbox.build()
1792 wc_dir = sbox.wc_dir
1794 # Schedule a delete, then put in local mods
1795 C_path = os.path.join(wc_dir, 'A', 'C')
1796 svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [],
1797 'rm', C_path)
1798 foo_path = os.path.join(C_path, 'foo')
1799 foo_contents = 'zig\nzag\n'
1800 svntest.main.file_append(foo_path, foo_contents)
1802 # Commit should succeed
1803 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1804 expected_status.remove('A/C')
1805 expected_output = svntest.wc.State(wc_dir, {
1806 'A/C' : Item(verb='Deleting'),
1808 svntest.actions.run_and_verify_commit(wc_dir,
1809 expected_output, expected_status,
1810 None, None, None, None, None, wc_dir)
1812 # Unversioned file still exists
1813 actual_contents = svntest.main.file_read(foo_path)
1814 if actual_contents != foo_contents:
1815 raise svntest.Failure
1818 #----------------------------------------------------------------------
1820 def tab_test(sbox):
1821 "tabs in paths"
1822 # For issue #1954.
1824 sbox.build()
1825 wc_dir = sbox.wc_dir
1827 tab_file = os.path.join(wc_dir, 'A', "tab\tfile")
1828 tab_dir = os.path.join(wc_dir, 'A', "tab\tdir")
1829 source_url = sbox.repo_url + "/source_dir"
1830 tab_url = sbox.repo_url + "/tab%09dir"
1832 svntest.main.file_append(tab_file, "This file has a tab in it.")
1833 os.mkdir(tab_dir)
1835 def match_bad_tab_path(path, errlines):
1836 match_re = ".*: Invalid control character '0x09' in path .*"
1837 for line in errlines:
1838 if re.match (match_re, line):
1839 break
1840 else:
1841 raise svntest.Failure("Failed to find match_re in " + str(errlines))
1843 # add file to wc
1844 outlines, errlines = svntest.main.run_svn(1, 'add', tab_file)
1845 match_bad_tab_path(tab_file, errlines)
1847 # add dir to wc
1848 outlines, errlines = svntest.main.run_svn(1, 'add', tab_dir)
1849 match_bad_tab_path(tab_dir, errlines)
1851 # mkdir URL
1852 outlines, errlines = svntest.main.run_svn(1,
1853 'mkdir', '-m', 'msg', tab_url)
1854 match_bad_tab_path(tab_dir, errlines)
1856 # copy URL
1857 svntest.main.run_svn(1,
1858 'mkdir', '-m', 'msg', source_url)
1859 outlines, errlines = svntest.main.run_svn(1,
1860 'copy', '-m', 'msg',
1861 source_url, tab_url)
1862 match_bad_tab_path(tab_dir, errlines)
1864 # mv URL
1865 outlines, errlines = svntest.main.run_svn(1, 'mv', '-m', 'msg',
1866 source_url, tab_url)
1867 match_bad_tab_path(tab_dir, errlines)
1869 #----------------------------------------------------------------------
1871 def local_mods_are_not_commits(sbox):
1872 "local ops should not be treated like commits"
1874 # For issue #2285.
1876 # Some commands can run on either a URL or a local path. These
1877 # commands take a log message, intended for the URL case.
1878 # Therefore, they should make sure that getting a log message for
1879 # a local operation errors (because not committing).
1881 # This is in commit_tests.py because the unifying theme is that
1882 # commits are *not* happening. And because there was no better
1883 # place to put it :-).
1885 sbox.build()
1886 wc_dir = sbox.wc_dir
1887 expected_error = '.*Local, non-commit operations do not take a log message.*'
1889 # copy wc->wc
1890 svntest.actions.run_and_verify_svn(None, None, expected_error,
1891 'cp', '-m', 'log msg',
1892 os.path.join(wc_dir, 'iota'),
1893 os.path.join(wc_dir, 'iota2'))
1895 # copy repos->wc
1896 svntest.actions.run_and_verify_svn(None, None, expected_error,
1897 'cp', '-m', 'log msg',
1898 sbox.repo_url + "/iota",
1899 os.path.join(wc_dir, 'iota2'))
1901 # delete
1902 svntest.actions.run_and_verify_svn(None, None, expected_error,
1903 'rm', '-m', 'log msg',
1904 os.path.join(wc_dir, 'A', 'D', 'gamma'))
1906 # mkdir
1907 svntest.actions.run_and_verify_svn(None, None, expected_error,
1908 'mkdir', '-m', 'log msg',
1909 os.path.join(wc_dir, 'newdir'))
1911 # rename
1912 svntest.actions.run_and_verify_svn(None, None, expected_error,
1913 'cp', '-m', 'log msg',
1914 os.path.join(wc_dir, 'A', 'mu'),
1915 os.path.join(wc_dir, 'A', 'yu'))
1917 # Helper for hook tests: returns the "hook failed" line, with precise
1918 # wording that changed with Subversion 1.5.
1919 def hook_failure_message(hookname):
1920 if svntest.main.server_minor_version < 5:
1921 return "'%s' hook failed with error output:\n" % hookname
1922 else:
1923 return "'%s' hook failed (exited with a " \
1924 "non-zero exitcode of 1). The following error output " \
1925 "was produced by the hook:\n" % hookname
1928 #----------------------------------------------------------------------
1929 # Test if the post-commit error message is returned back to the svn
1930 # client and is displayed as a warning.
1932 def post_commit_hook_test(sbox):
1933 "post commit hook failure case testing"
1935 sbox.build()
1937 # Get paths to the working copy and repository
1938 wc_dir = sbox.wc_dir
1939 repo_dir = sbox.repo_dir
1941 # Disable commits
1942 svntest.actions.create_failing_post_commit_hook(repo_dir)
1944 # Modify iota just so there is something to commit.
1945 iota_path = os.path.join(wc_dir, "iota")
1946 svntest.main.file_append(iota_path, "lakalakalakalaka")
1948 # Now, commit and examine the output (we happen to know that the
1949 # filesystem will report an absolute path because that's the way the
1950 # filesystem is created by this test suite.
1951 expected_output = [ "Sending "+ iota_path + "\n",
1952 "Transmitting file data .\n",
1953 "Committed revision 2.\n",
1954 "\n",
1955 "Warning: " + hook_failure_message('post-commit'),
1956 "Post-commit hook failed\n",
1959 svntest.actions.run_and_verify_svn(None, expected_output, [],
1960 'ci', '-m', 'log msg', iota_path)
1962 #----------------------------------------------------------------------
1963 # Commit two targets non-recursively, but both targets should be the
1964 # same folder (in multiple variations). Test that svn handles this correctly.
1965 def commit_same_folder_in_targets(sbox):
1966 "commit two targets, both the same folder"
1968 sbox.build()
1969 wc_dir = sbox.wc_dir
1971 iota_path = os.path.join(wc_dir, 'iota')
1973 svntest.main.file_append(iota_path, "added extra line to file iota")
1975 # Create expected output tree.
1976 expected_output = svntest.wc.State(wc_dir, {
1977 'iota' : Item(verb='Sending'),
1980 # Created expected status tree.
1981 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1982 expected_status.tweak('iota', wc_rev=2)
1984 # Commit the wc_dir and iota.
1985 svntest.actions.run_and_verify_commit(wc_dir,
1986 expected_output,
1987 expected_status,
1988 None,
1989 None, None,
1990 None, None,
1991 '-N',
1992 wc_dir,
1993 iota_path)
1995 #----------------------------------------------------------------------
1996 # test for issue 2459: verify that commit fails when a file with mixed
1997 # eol-styles is included, and show an error message which includes the
1998 # filename.
1999 def commit_inconsistent_eol(sbox):
2000 "commit files with inconsistent eol should fail"
2002 sbox.build()
2003 wc_dir = sbox.wc_dir
2005 iota_path = os.path.join(wc_dir, 'iota')
2006 mu_path = os.path.join(wc_dir, 'A', 'mu')
2008 svntest.main.run_svn(None, 'propset', 'svn:eol-style', 'native', iota_path)
2009 svntest.main.file_append_binary(iota_path,
2010 "added extra line to file iota\012"
2011 "added extra line to file iota\015")
2012 svntest.main.file_append(mu_path, "added extra line to file mu\n"
2013 "added extra line to file mu\n")
2015 expected_err = ".*iota.*"
2017 svntest.actions.run_and_verify_svn(None, None, expected_err,
2018 'commit', '-m', 'log message',
2019 wc_dir)
2022 def mkdir_with_revprop(sbox):
2023 "set revision props during remote mkdir"
2025 sbox.build()
2026 remote_dir = sbox.repo_url + "/dir"
2028 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2029 '--with-revprop', 'bug=42', remote_dir)
2031 expected = svntest.verify.UnorderedOutput(
2032 ['Unversioned properties on revision 2:\n',
2033 ' svn:author\n',' svn:date\n', ' svn:log\n',
2034 ' bug\n'])
2035 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2036 '--revprop', '-r', 2, sbox.repo_url)
2037 svntest.actions.run_and_verify_svn(None, '42', [], 'propget', 'bug',
2038 '--revprop', '-r', 2, sbox.repo_url)
2041 def delete_with_revprop(sbox):
2042 "set revision props during remote delete"
2044 sbox.build()
2045 remote_dir = sbox.repo_url + "/dir"
2046 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2047 remote_dir)
2049 svntest.actions.run_and_verify_svn(None, None, [], 'delete', '-m', 'msg',
2050 '--with-revprop', 'bug=52', remote_dir)
2052 expected = svntest.verify.UnorderedOutput(
2053 ['Unversioned properties on revision 3:\n',
2054 ' svn:author\n',' svn:date\n', ' svn:log\n',
2055 ' bug\n'])
2056 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2057 '--revprop', '-r', 3, sbox.repo_url)
2058 svntest.actions.run_and_verify_svn(None, '52', [], 'propget', 'bug',
2059 '--revprop', '-r', 3, sbox.repo_url)
2062 def commit_with_revprop(sbox):
2063 "set revision props during commit"
2065 sbox.build()
2066 wc_dir = sbox.wc_dir
2067 expected_status = make_standard_slew_of_changes(wc_dir)
2069 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
2070 gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo')
2071 expected_output = svntest.wc.State(wc_dir, {
2072 'A/D/H/omega' : Item(verb='Sending'),
2073 'A/D/H/gloo' : Item(verb='Adding'),
2076 expected_status.tweak('A/D/H/omega', wc_rev=2, status=' ')
2077 expected_status.tweak('A/D/H/gloo', wc_rev=2, status=' ')
2079 svntest.actions.run_and_verify_commit(wc_dir,
2080 expected_output,
2081 expected_status,
2082 None, None, None, None, None,
2083 '-m', 'msg',
2084 '--with-revprop', 'bug=62',
2085 omega_path, gloo_path)
2087 expected = svntest.verify.UnorderedOutput(
2088 ['Unversioned properties on revision 2:\n',
2089 ' svn:author\n',' svn:date\n', ' svn:log\n',
2090 ' bug\n'])
2091 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2092 '--revprop', '-r', 2, sbox.repo_url)
2093 svntest.actions.run_and_verify_svn(None, '62', [], 'propget', 'bug',
2094 '--revprop', '-r', 2, sbox.repo_url)
2097 def import_with_revprop(sbox):
2098 "set revision props during import"
2100 sbox.build()
2101 local_dir = os.path.join(sbox.wc_dir, 'folder')
2102 local_file = os.path.join(sbox.wc_dir, 'folder', 'file')
2103 os.mkdir(local_dir)
2104 svntest.main.file_write(local_file, "xxxx")
2106 svntest.actions.run_and_verify_svn(None, None, [], 'import', '-m', 'msg',
2107 '--with-revprop', 'bug=72', local_dir,
2108 sbox.repo_url)
2110 expected = svntest.verify.UnorderedOutput(
2111 ['Unversioned properties on revision 2:\n',
2112 ' svn:author\n',' svn:date\n', ' svn:log\n',
2113 ' bug\n'])
2114 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2115 '--revprop', '-r', 2, sbox.repo_url)
2116 svntest.actions.run_and_verify_svn(None, '72', [], 'propget', 'bug',
2117 '--revprop', '-r', 2, sbox.repo_url)
2120 def copy_R2R_with_revprop(sbox):
2121 "set revision props during repos-to-repos copy"
2123 sbox.build()
2124 remote_dir1 = sbox.repo_url + "/dir1"
2125 remote_dir2 = sbox.repo_url + "/dir2"
2126 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2127 remote_dir1)
2129 svntest.actions.run_and_verify_svn(None, None, [], 'copy', '-m', 'msg',
2130 '--with-revprop', 'bug=82', remote_dir1,
2131 remote_dir2)
2133 expected = svntest.verify.UnorderedOutput(
2134 ['Unversioned properties on revision 3:\n',
2135 ' svn:author\n',' svn:date\n', ' svn:log\n',
2136 ' bug\n'])
2137 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2138 '--revprop', '-r', 3, sbox.repo_url)
2139 svntest.actions.run_and_verify_svn(None, '82', [], 'propget', 'bug',
2140 '--revprop', '-r', 3, sbox.repo_url)
2143 def copy_WC2R_with_revprop(sbox):
2144 "set revision props during wc-to-repos copy"
2146 sbox.build()
2147 remote_dir = sbox.repo_url + "/dir"
2148 local_dir = os.path.join(sbox.wc_dir, 'folder')
2149 svntest.actions.run_and_verify_svn(None, None, [],
2150 'mkdir', local_dir)
2152 svntest.actions.run_and_verify_svn(None, None, [], 'copy', '-m', 'msg',
2153 '--with-revprop', 'bug=92', local_dir,
2154 remote_dir)
2156 expected = svntest.verify.UnorderedOutput(
2157 ['Unversioned properties on revision 2:\n',
2158 ' svn:author\n',' svn:date\n', ' svn:log\n',
2159 ' bug\n'])
2160 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2161 '--revprop', '-r', 2, sbox.repo_url)
2162 svntest.actions.run_and_verify_svn(None, '92', [], 'propget', 'bug',
2163 '--revprop', '-r', 2, sbox.repo_url)
2166 def move_R2R_with_revprop(sbox):
2167 "set revision props during repos-to-repos move"
2169 sbox.build()
2170 remote_dir1 = sbox.repo_url + "/dir1"
2171 remote_dir2 = sbox.repo_url + "/dir2"
2172 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2173 remote_dir1)
2175 svntest.actions.run_and_verify_svn(None, None, [], 'move', '-m', 'msg',
2176 '--with-revprop', 'bug=102', remote_dir1,
2177 remote_dir2)
2179 expected = svntest.verify.UnorderedOutput(
2180 ['Unversioned properties on revision 3:\n',
2181 ' svn:author\n',' svn:date\n', ' svn:log\n',
2182 ' bug\n'])
2183 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2184 '--revprop', '-r', 3, sbox.repo_url)
2185 svntest.actions.run_and_verify_svn(None, '102', [], 'propget', 'bug',
2186 '--revprop', '-r', 3, sbox.repo_url)
2189 def propedit_with_revprop(sbox):
2190 "set revision props during remote property edit"
2192 sbox.build()
2193 svntest.main.use_editor('append_foo')
2195 svntest.actions.run_and_verify_svn(None, None, [], 'propedit', '-m', 'msg',
2196 '--with-revprop', 'bug=112', 'prop',
2197 sbox.repo_url)
2199 expected = svntest.verify.UnorderedOutput(
2200 ['Unversioned properties on revision 2:\n',
2201 ' svn:author\n',' svn:date\n', ' svn:log\n',
2202 ' bug\n'])
2203 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2204 '--revprop', '-r', 2, sbox.repo_url)
2205 svntest.actions.run_and_verify_svn(None, '112', [], 'propget', 'bug',
2206 '--revprop', '-r', 2, sbox.repo_url)
2209 def set_multiple_props_with_revprop(sbox):
2210 "set multiple revision props during remote mkdir"
2212 sbox.build()
2213 remote_dir = sbox.repo_url + "/dir"
2215 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2216 '--with-revprop', 'bug=32',
2217 '--with-revprop', 'ref=22', remote_dir)
2219 expected = svntest.verify.UnorderedOutput(
2220 ['Unversioned properties on revision 2:\n',
2221 ' svn:author\n',' svn:date\n', ' svn:log\n',
2222 ' bug\n', ' ref\n'])
2223 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2224 '--revprop', '-r', 2, sbox.repo_url)
2225 svntest.actions.run_and_verify_svn(None, '32', [], 'propget', 'bug',
2226 '--revprop', '-r', 2, sbox.repo_url)
2227 svntest.actions.run_and_verify_svn(None, '22', [], 'propget', 'ref',
2228 '--revprop', '-r', 2, sbox.repo_url)
2231 def use_empty_value_in_revprop_pair(sbox):
2232 "set revprop without value ('') during remote mkdir"
2234 sbox.build()
2235 remote_dir = sbox.repo_url + "/dir"
2237 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2238 '--with-revprop', 'bug=',
2239 '--with-revprop', 'ref=', remote_dir)
2241 expected = svntest.verify.UnorderedOutput(
2242 ['Unversioned properties on revision 2:\n',
2243 ' svn:author\n',' svn:date\n', ' svn:log\n',
2244 ' bug\n', ' ref\n'])
2245 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2246 '--revprop', '-r', 2, sbox.repo_url)
2247 svntest.actions.run_and_verify_svn(None, '', [], 'propget', 'bug',
2248 '--revprop', '-r', 2, sbox.repo_url)
2249 svntest.actions.run_and_verify_svn(None, '', [], 'propget', 'ref',
2250 '--revprop', '-r', 2, sbox.repo_url)
2253 def no_equals_in_revprop_pair(sbox):
2254 "set revprop without '=' during remote mkdir"
2256 sbox.build()
2257 remote_dir = sbox.repo_url + "/dir"
2258 svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', '-m', 'msg',
2259 '--with-revprop', 'bug',
2260 '--with-revprop', 'ref', remote_dir)
2262 expected = svntest.verify.UnorderedOutput(
2263 ['Unversioned properties on revision 2:\n',
2264 ' svn:author\n',' svn:date\n', ' svn:log\n',
2265 ' bug\n', ' ref\n'])
2266 svntest.actions.run_and_verify_svn(None, expected, [], 'proplist',
2267 '--revprop', '-r', 2, sbox.repo_url)
2268 svntest.actions.run_and_verify_svn(None, '', [], 'propget', 'bug',
2269 '--revprop', '-r', 2, sbox.repo_url)
2270 svntest.actions.run_and_verify_svn(None, '', [], 'propget', 'ref',
2271 '--revprop', '-r', 2, sbox.repo_url)
2274 def set_invalid_revprops(sbox):
2275 "set invalid revision props during remote mkdir"
2277 sbox.build()
2278 remote_dir = sbox.repo_url + "/dir"
2279 # Try to set svn: revprops.
2280 expected = '.*Standard properties can\'t.*'
2281 svntest.actions.run_and_verify_svn(None, [], expected, 'mkdir', '-m', 'msg',
2282 '--with-revprop', 'svn:author=42', remote_dir)
2283 svntest.actions.run_and_verify_svn(None, [], expected, 'mkdir', '-m', 'msg',
2284 '--with-revprop', 'svn:log=42', remote_dir)
2285 svntest.actions.run_and_verify_svn(None, [], expected, 'mkdir', '-m', 'msg',
2286 '--with-revprop', 'svn:date=42', remote_dir)
2287 svntest.actions.run_and_verify_svn(None, [], expected, 'mkdir', '-m', 'msg',
2288 '--with-revprop', 'svn:foo=bar', remote_dir)
2290 # Empty revprop pair.
2291 svntest.actions.run_and_verify_svn(None, [],
2292 'svn: Revision property pair is empty',
2293 'mkdir', '-m', 'msg',
2294 '--with-revprop', '',
2295 remote_dir)
2297 #----------------------------------------------------------------------
2299 def start_commit_hook_test(sbox):
2300 "start-commit hook failure case testing"
2302 sbox.build()
2304 # Get paths to the working copy and repository
2305 wc_dir = sbox.wc_dir
2306 repo_dir = sbox.repo_dir
2308 # Create a hook that outputs a message to stderr and returns exit code 1
2309 hook_code = """import sys
2310 sys.stderr.write("Start-commit hook failed")
2311 sys.exit(1)"""
2313 # Setup the hook configs to log data to a file
2314 start_commit_hook = svntest.main.get_start_commit_hook_path(repo_dir)
2315 svntest.main.create_python_hook_script(start_commit_hook, hook_code)
2317 # Modify iota just so there is something to commit.
2318 iota_path = os.path.join(wc_dir, "iota")
2319 svntest.main.file_append(iota_path, "More stuff in iota")
2321 # Commit, expect error code 1
2322 actual_stdout, actual_stderr = svntest.main.run_svn(1,
2323 'ci', '--quiet',
2324 '-m', 'log msg', wc_dir)
2326 # No stdout expected
2327 svntest.verify.compare_and_display_lines('Start-commit hook test',
2328 'STDOUT', [], actual_stdout)
2330 # Compare only the last two lines of stderr since the preceding ones
2331 # contain source code file and line numbers.
2332 if len(actual_stderr) > 2:
2333 actual_stderr = actual_stderr[-2:]
2334 expected_stderr = [ "svn: " + hook_failure_message('start-commit'),
2335 "Start-commit hook failed\n"
2337 svntest.verify.compare_and_display_lines('Start-commit hook test',
2338 'STDERR',
2339 expected_stderr, actual_stderr)
2341 #----------------------------------------------------------------------
2343 def pre_commit_hook_test(sbox):
2344 "pre-commit hook failure case testing"
2346 sbox.build()
2348 # Get paths to the working copy and repository
2349 wc_dir = sbox.wc_dir
2350 repo_dir = sbox.repo_dir
2352 # Create a hook that outputs a message to stderr and returns exit code 1
2353 hook_code = """import sys
2354 sys.stderr.write("Pre-commit hook failed")
2355 sys.exit(1)"""
2357 # Setup the hook configs to log data to a file
2358 pre_commit_hook = svntest.main.get_pre_commit_hook_path(repo_dir)
2359 svntest.main.create_python_hook_script(pre_commit_hook, hook_code)
2361 # Modify iota just so there is something to commit.
2362 iota_path = os.path.join(wc_dir, "iota")
2363 svntest.main.file_append(iota_path, "More stuff in iota")
2365 # Commit, expect error code 1
2366 actual_stdout, actual_stderr = svntest.main.run_svn(1,
2367 'ci', '--quiet',
2368 '-m', 'log msg', wc_dir)
2370 # No stdout expected
2371 svntest.verify.compare_and_display_lines('Pre-commit hook test',
2372 'STDOUT', [], actual_stdout)
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('pre-commit'),
2379 "Pre-commit hook failed\n"
2381 svntest.verify.compare_and_display_lines('Pre-commit hook test',
2382 'STDERR',
2383 expected_stderr, actual_stderr)
2385 #----------------------------------------------------------------------
2387 def versioned_log_message(sbox):
2388 "'svn commit -F foo' when foo is a versioned file"
2390 sbox.build()
2392 os.chdir(sbox.wc_dir)
2394 iota_path = os.path.join('iota')
2395 mu_path = os.path.join('A', 'mu')
2396 log_path = os.path.join('A', 'D', 'H', 'omega')
2398 svntest.main.file_append(iota_path, "2")
2400 # try to check in a change using a versioned file as your log entry.
2401 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
2402 'ci', '-F', log_path)
2404 # force it. should not produce any errors.
2405 svntest.actions.run_and_verify_svn(None, None, [],
2406 'ci', '-F', log_path, '--force-log')
2408 svntest.main.file_append(mu_path, "2")
2410 # try the same thing, but specifying the file to commit explicitly.
2411 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
2412 'ci', '-F', log_path, mu_path)
2414 # force it... should succeed.
2415 svntest.actions.run_and_verify_svn(None, None, [],
2416 'ci',
2417 '-F', log_path,
2418 '--force-log', mu_path)
2420 #----------------------------------------------------------------------
2422 def changelist_near_conflict(sbox):
2423 "'svn commit --changelist=foo' above a conflict"
2425 sbox.build()
2427 wc_dir = sbox.wc_dir
2428 iota_path = os.path.join(wc_dir, "iota")
2429 mu_path = os.path.join(wc_dir, "A", "mu")
2430 gloo_path = os.path.join(wc_dir, "A", "D", "H", "gloo")
2432 expected_status = make_standard_slew_of_changes(wc_dir)
2434 # Create a changelist.
2435 changelist_name = "logical-changeset"
2436 svntest.actions.run_and_verify_svn(None, None, [],
2437 "changelist", changelist_name,
2438 mu_path, gloo_path)
2440 # Create a conflict (making r2 in the process).
2441 inject_conflict_into_wc(sbox, 'iota', iota_path,
2442 None, expected_status, 2)
2444 # Commit the changelist.
2445 expected_output = svntest.wc.State(wc_dir, {
2446 "A/D/H/gloo" : Item(verb='Adding'),
2448 expected_status.tweak("A/D/H/gloo", wc_rev=3, status=" ")
2449 svntest.actions.run_and_verify_commit(wc_dir,
2450 expected_output,
2451 expected_status,
2452 None, None, None, None, None,
2453 "--changelist=" + changelist_name,
2454 "-m", "msg", wc_dir)
2457 #----------------------------------------------------------------------
2459 def no_such_changelist(sbox):
2460 "'svn commit --changelist=not-found' should warn"
2462 sbox.build()
2463 wc_dir = sbox.wc_dir
2465 # Attempt to commit a non-existent changelist.
2466 expected_output = svntest.wc.State(wc_dir, {})
2467 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2468 svntest.actions.run_and_verify_svn("Attempt to commit a changelist with no "
2469 "relevant paths should warn",
2470 None, ".*Unknown changelist 'not-found'",
2471 "commit", "--changelist=not-found",
2472 "-m", "msg", wc_dir)
2474 def commit_out_of_date_file(sbox):
2475 "try to commit a file that is out-of-date"
2477 sbox.build()
2478 wc_dir = sbox.wc_dir
2480 # Make a backup copy of the working copy
2481 wc_backup = sbox.add_wc_path('backup')
2482 svntest.actions.duplicate_dir(wc_dir, wc_backup)
2484 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
2485 backup_pi_path = os.path.join(wc_backup, 'A', 'D', 'G', 'pi')
2487 svntest.main.file_append(pi_path, "new line\n")
2488 expected_output = svntest.wc.State(wc_dir, {
2489 "A/D/G/pi" : Item(verb='Sending'),
2491 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2492 expected_status.tweak("A/D/G/pi", wc_rev=2, status=" ")
2493 svntest.actions.run_and_verify_commit(wc_dir,
2494 expected_output,
2495 expected_status,
2496 None, None, None, None, None,
2497 "-m", "log message", wc_dir)
2499 svntest.main.file_append(backup_pi_path, "hello")
2500 expected_err = ".*(pi.*out of date|Out of date.*pi).*"
2501 svntest.actions.run_and_verify_svn(None, None, expected_err,
2502 'commit', '-m', 'log message',
2503 wc_backup)
2505 def start_commit_detect_capabilities(sbox):
2506 "start-commit hook sees client capabilities" # Issue #2991
2507 sbox.build()
2508 wc_dir = sbox.wc_dir
2509 repos_dir = sbox.repo_dir
2511 # Create a start-commit hook that detects the "mergeinfo" capability.
2512 hook_text = "import sys\n" + \
2513 "fp = open(sys.argv[1] + '/hooks.log', 'w')\n" + \
2514 "caps = sys.argv[3].split(':')\n" + \
2515 "if 'mergeinfo' in caps:\n" + \
2516 " fp.write('yes')\n" + \
2517 "else:\n" + \
2518 " fp.write('no')\n" + \
2519 "fp.close()\n"
2521 start_commit_hook = svntest.main.get_start_commit_hook_path(repos_dir)
2522 svntest.main.create_python_hook_script(start_commit_hook, hook_text)
2524 # Commit something.
2525 iota_path = os.path.join(wc_dir, "iota")
2526 svntest.main.file_append(iota_path, "More stuff in iota")
2527 svntest.actions.run_and_verify_svn(None, [], [], 'ci', '--quiet',
2528 '-m', 'log msg', wc_dir)
2530 # Check that "mergeinfo" was detected.
2531 log_path = os.path.join(repos_dir, "hooks.log")
2532 if os.path.exists(log_path):
2533 data = open(log_path).read()
2534 os.unlink(log_path)
2535 else:
2536 raise svntest.verify.SVNUnexpectedOutput("'%s' not found") % log_path
2537 if data != 'yes':
2538 raise svntest.Failure
2541 ########################################################################
2542 # Run the tests
2544 # list all tests here, starting with None:
2545 test_list = [ None,
2546 commit_one_file,
2547 commit_one_new_file,
2548 commit_one_new_binary_file,
2549 commit_multiple_targets,
2550 commit_multiple_targets_2,
2551 commit_inclusive_dir,
2552 commit_top_dir,
2553 commit_unversioned_thing,
2554 nested_dir_replacements,
2555 hudson_part_1,
2556 hudson_part_1_variation_1,
2557 hudson_part_1_variation_2,
2558 hudson_part_2,
2559 hudson_part_2_1,
2560 hook_test,
2561 merge_mixed_revisions,
2562 commit_uri_unsafe,
2563 commit_deleted_edited,
2564 commit_in_dir_scheduled_for_addition,
2565 commit_rmd_and_deleted_file,
2566 commit_add_file_twice,
2567 commit_from_long_dir,
2568 commit_with_lock,
2569 commit_current_dir,
2570 commit_multiple_wc,
2571 commit_nonrecursive,
2572 failed_commit,
2573 commit_out_of_date_deletions,
2574 commit_with_bad_log_message,
2575 from_wc_top_with_bad_editor,
2576 mods_in_schedule_delete,
2577 Skip(tab_test, is_non_posix_os_or_cygwin_platform),
2578 local_mods_are_not_commits,
2579 post_commit_hook_test,
2580 commit_same_folder_in_targets,
2581 commit_inconsistent_eol,
2582 SkipUnless(mkdir_with_revprop, server_has_revprop_commit),
2583 SkipUnless(delete_with_revprop, server_has_revprop_commit),
2584 SkipUnless(commit_with_revprop, server_has_revprop_commit),
2585 SkipUnless(import_with_revprop, server_has_revprop_commit),
2586 SkipUnless(copy_R2R_with_revprop, server_has_revprop_commit),
2587 SkipUnless(copy_WC2R_with_revprop, server_has_revprop_commit),
2588 SkipUnless(move_R2R_with_revprop, server_has_revprop_commit),
2589 SkipUnless(propedit_with_revprop, server_has_revprop_commit),
2590 SkipUnless(set_multiple_props_with_revprop,
2591 server_has_revprop_commit),
2592 SkipUnless(use_empty_value_in_revprop_pair,
2593 server_has_revprop_commit),
2594 SkipUnless(no_equals_in_revprop_pair, server_has_revprop_commit),
2595 SkipUnless(set_invalid_revprops, server_has_revprop_commit),
2596 start_commit_hook_test,
2597 pre_commit_hook_test,
2598 versioned_log_message,
2599 changelist_near_conflict,
2600 no_such_changelist,
2601 commit_out_of_date_file,
2602 start_commit_detect_capabilities,
2605 if __name__ == '__main__':
2606 svntest.main.run_tests(test_list)
2607 # NOTREACHED
2610 ### End of file.