Add a little more to the svn_rangelist_intersect test to test the
[svn.git] / subversion / tests / cmdline / copy_tests.py
blob5d5cf1aea382a7bdd1b643fee761cdae878b3dcf
1 #!/usr/bin/env python
3 # copy_tests.py: testing the many uses of 'svn cp' and 'svn mv'
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 stat, os, re
22 # Our testing module
23 import svntest
25 from svntest.main import SVN_PROP_MERGEINFO
27 # (abbreviation)
28 Skip = svntest.testcase.Skip
29 SkipUnless = svntest.testcase.SkipUnless
30 XFail = svntest.testcase.XFail
31 Item = svntest.wc.StateItem
35 #----------------------------------------------------------------------
36 # Helper for wc_copy_replacement and repos_to_wc_copy_replacement
37 def copy_replace(sbox, wc_copy):
38 """Tests for 'R'eplace functionanity for files.
40 Depending on the value of wc_copy either a working copy (when true)
41 or a url (when false) copy source is used."""
43 sbox.build()
44 wc_dir = sbox.wc_dir
46 # File scheduled for deletion
47 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
48 svntest.actions.run_and_verify_svn(None, None, [], 'rm', rho_path)
50 # Status before attempting copies
51 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
52 expected_status.tweak('A/D/G/rho', status='D ')
53 svntest.actions.run_and_verify_status(wc_dir, expected_status)
55 # The copy shouldn't fail
56 if wc_copy:
57 pi_src = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
58 else:
59 pi_src = sbox.repo_url + '/A/D/G/pi'
61 svntest.actions.run_and_verify_svn(None, None, [],
62 'cp', pi_src, rho_path)
64 # Now commit
65 expected_status.tweak('A/D/G/rho', status='R ', copied='+', wc_rev='-')
66 svntest.actions.run_and_verify_status(wc_dir, expected_status)
68 expected_status.tweak('A/D/G/rho', status=' ', copied=None,
69 wc_rev='2')
70 expected_output = svntest.wc.State(wc_dir, {
71 'A/D/G/rho': Item(verb='Replacing'),
73 svntest.actions.run_and_verify_commit(wc_dir,
74 expected_output,
75 expected_status,
76 None, wc_dir)
78 # Helper for wc_copy_replace_with_props and
79 # repos_to_wc_copy_replace_with_props
80 def copy_replace_with_props(sbox, wc_copy):
81 """Tests for 'R'eplace functionanity for files with props.
83 Depending on the value of wc_copy either a working copy (when true) or
84 a url (when false) copy source is used."""
86 sbox.build()
87 wc_dir = sbox.wc_dir
89 # Use a temp file to set properties with wildcards in their values
90 # otherwise Win32/VS2005 will expand them
91 prop_path = os.path.join(wc_dir, 'proptmp')
92 svntest.main.file_append(prop_path, '*')
94 # Set props on file which is copy-source later on
95 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
96 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
97 svntest.actions.run_and_verify_svn(None, None, [],
98 'ps', 'phony-prop', '-F',
99 prop_path, pi_path)
100 os.remove(prop_path)
101 svntest.actions.run_and_verify_svn(None, None, [],
102 'ps', 'svn:eol-style', 'LF', rho_path)
104 # Verify props having been set
105 expected_disk = svntest.main.greek_state.copy()
106 expected_disk.tweak('A/D/G/pi',
107 props={ 'phony-prop': '*' })
108 expected_disk.tweak('A/D/G/rho',
109 props={ 'svn:eol-style': 'LF' })
111 actual_disk = svntest.tree.build_tree_from_wc(wc_dir, 1)
112 svntest.tree.compare_trees("disk", actual_disk, expected_disk.old_tree())
114 # Commit props
115 expected_output = svntest.wc.State(wc_dir, {
116 'A/D/G/pi': Item(verb='Sending'),
117 'A/D/G/rho': Item(verb='Sending'),
119 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
120 expected_status.tweak('A/D/G/pi', wc_rev='2')
121 expected_status.tweak('A/D/G/rho', wc_rev='2')
122 svntest.actions.run_and_verify_commit(wc_dir,
123 expected_output,
124 expected_status,
125 None, wc_dir)
127 # Bring wc into sync
128 svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
130 # File scheduled for deletion
131 svntest.actions.run_and_verify_svn(None, None, [], 'rm', rho_path)
133 # Status before attempting copies
134 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
135 expected_status.tweak('A/D/G/rho', status='D ')
136 svntest.actions.run_and_verify_status(wc_dir, expected_status)
138 # The copy shouldn't fail
139 if wc_copy:
140 pi_src = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
141 else:
142 pi_src = sbox.repo_url + '/A/D/G/pi'
144 svntest.actions.run_and_verify_svn(None, None, [],
145 'cp', pi_src, rho_path)
147 # Verify both content and props have been copied
148 if wc_copy:
149 props = { SVN_PROP_MERGEINFO : '',
150 'phony-prop' : '*'}
151 else:
152 props = { 'phony-prop' : '*'}
154 expected_disk.tweak('A/D/G/rho',
155 contents="This is the file 'pi'.\n",
156 props=props)
157 actual_disk = svntest.tree.build_tree_from_wc(wc_dir, 1)
158 svntest.tree.compare_trees("disk", actual_disk, expected_disk.old_tree())
160 # Now commit and verify
161 expected_status.tweak('A/D/G/rho', status='R ', copied='+', wc_rev='-')
162 svntest.actions.run_and_verify_status(wc_dir, expected_status)
164 expected_status.tweak('A/D/G/rho', status=' ', copied=None,
165 wc_rev='3')
166 expected_output = svntest.wc.State(wc_dir, {
167 'A/D/G/rho': Item(verb='Replacing'),
169 svntest.actions.run_and_verify_commit(wc_dir,
170 expected_output,
171 expected_status,
172 None, wc_dir)
175 ######################################################################
176 # Tests
178 # Each test must return on success or raise on failure.
180 # (Taken from notes/copy-planz.txt:)
182 # We have four use cases for 'svn cp' now.
184 # A. svn cp wc_path1 wc_path2
186 # This duplicates a path in the working copy, and schedules it
187 # for addition with history.
189 # B. svn cp URL [-r rev] wc_path
191 # This "checks out" URL (in REV) into the working copy at
192 # wc_path, integrates it, and schedules it for addition with
193 # history.
195 # C. svn cp wc_path URL
197 # This immediately commits wc_path to URL on the server; the
198 # commit will be an addition with history. The commit will not
199 # change the working copy at all.
201 # D. svn cp URL1 [-r rev] URL2
203 # This causes a server-side copy to happen immediately; no
204 # working copy is required.
208 # TESTS THAT NEED TO BE WRITTEN
210 # Use Cases A & C
212 # -- single files, with/without local mods, as both 'cp' and 'mv'.
213 # (need to verify commit worked by updating a 2nd working copy
214 # to see the local mods)
216 # -- dir copy, has mixed revisions
218 # -- dir copy, has local mods (an edit, an add, a delete, and a replace)
220 # -- dir copy, has mixed revisions AND local mods
222 # -- dir copy, has mixed revisions AND another previously-made copy!
223 # (perhaps done as two nested 'mv' commands!)
225 # Use Case D
228 # By the time the copy setup algorithm is complete, the copy
229 # operation will have four parts: SRC-DIR, SRC-BASENAME, DST-DIR,
230 # DST-BASENAME. In all cases, SRC-DIR/SRC-BASENAME and DST_DIR must
231 # already exist before the operation, but DST_DIR/DST_BASENAME must
232 # NOT exist.
234 # Besides testing things that don't meet the above criteria, we want to
235 # also test valid cases:
237 # - where SRC-DIR/SRC-BASENAME is a file or a dir.
238 # - where SRC-DIR (or SRC-DIR/SRC-BASENAME) is a parent/grandparent
239 # directory of DST-DIR
240 # - where SRC-DIR (or SRC-DIR/SRC-BASENAME) is a child/grandchild
241 # directory of DST-DIR
242 # - where SRC-DIR (or SRC-DIR/SRC-BASENAME) is not in the lineage
243 # of DST-DIR at all
247 #----------------------------------------------------------------------
249 def basic_copy_and_move_files(sbox):
250 "basic copy and move commands -- on files only"
252 sbox.build()
253 wc_dir = sbox.wc_dir
255 mu_path = os.path.join(wc_dir, 'A', 'mu')
256 iota_path = os.path.join(wc_dir, 'iota')
257 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
258 D_path = os.path.join(wc_dir, 'A', 'D')
259 alpha_path = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha')
260 H_path = os.path.join(wc_dir, 'A', 'D', 'H')
261 F_path = os.path.join(wc_dir, 'A', 'B', 'F')
262 alpha2_path = os.path.join(wc_dir, 'A', 'C', 'alpha2')
264 # Make local mods to mu and rho
265 svntest.main.file_append(mu_path, 'appended mu text')
266 svntest.main.file_append(rho_path, 'new appended text for rho')
268 # Copy rho to D -- local mods
269 svntest.actions.run_and_verify_svn(None, None, [], 'cp', rho_path, D_path)
271 # Copy alpha to C -- no local mods, and rename it to 'alpha2' also
272 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
273 alpha_path, alpha2_path)
275 # Move mu to H -- local mods
276 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
277 mu_path, H_path)
279 # Move iota to F -- no local mods
280 svntest.actions.run_and_verify_svn(None, None, [], 'mv', iota_path, F_path)
282 # Created expected output tree for 'svn ci':
283 # We should see four adds, two deletes, and one change in total.
284 expected_output = svntest.wc.State(wc_dir, {
285 'A/D/G/rho' : Item(verb='Sending'),
286 'A/D/rho' : Item(verb='Adding'),
287 'A/C/alpha2' : Item(verb='Adding'),
288 'A/D/H/mu' : Item(verb='Adding'),
289 'A/B/F/iota' : Item(verb='Adding'),
290 'A/mu' : Item(verb='Deleting'),
291 'iota' : Item(verb='Deleting'),
294 # Create expected status tree; all local revisions should be at 1,
295 # but several files should be at revision 2. Also, two files should
296 # be missing.
297 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
298 expected_status.tweak('A/D/G/rho', 'A/mu', wc_rev=2)
300 expected_status.add({
301 'A/D/rho' : Item(status=' ', wc_rev=2),
302 'A/C/alpha2' : Item(status=' ', wc_rev=2),
303 'A/D/H/mu' : Item(status=' ', wc_rev=2),
304 'A/B/F/iota' : Item(status=' ', wc_rev=2),
307 expected_status.remove('A/mu', 'iota')
309 svntest.actions.run_and_verify_commit(wc_dir,
310 expected_output,
311 expected_status,
312 None,
313 wc_dir)
315 # Issue 1091, alpha2 would now have the wrong checksum and so a
316 # subsequent commit would fail
317 svntest.main.file_append(alpha2_path, 'appended alpha2 text')
318 expected_output = svntest.wc.State(wc_dir, {
319 'A/C/alpha2' : Item(verb='Sending'),
321 expected_status.tweak('A/C/alpha2', wc_rev=3)
322 svntest.actions.run_and_verify_commit(wc_dir,
323 expected_output,
324 expected_status,
325 None,
326 wc_dir)
328 # Assure that attempts at local copy and move fail when a log
329 # message is provided.
330 expected_stderr = \
331 ".*Local, non-commit operations do not take a log message"
332 svntest.actions.run_and_verify_svn(None, None, expected_stderr,
333 'cp', '-m', 'op fails', rho_path, D_path)
334 svntest.actions.run_and_verify_svn(None, None, expected_stderr,
335 'mv', '-m', 'op fails', rho_path, D_path)
338 #----------------------------------------------------------------------
340 # This test passes over ra_local certainly; we're adding it because at
341 # one time it failed over ra_neon. Specifically, it failed when
342 # mod_dav_svn first started sending vsn-rsc-urls as "CR/path", and was
343 # sending bogus CR/paths for items within copied subtrees.
345 def receive_copy_in_update(sbox):
346 "receive a copied directory during update"
348 sbox.build()
349 wc_dir = sbox.wc_dir
351 # Make a backup copy of the working copy.
352 wc_backup = sbox.add_wc_path('backup')
353 svntest.actions.duplicate_dir(wc_dir, wc_backup)
355 # Define a zillion paths in both working copies.
356 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
357 newG_path = os.path.join(wc_dir, 'A', 'B', 'newG')
359 # Copy directory A/D to A/B/newG
360 svntest.actions.run_and_verify_svn(None, None, [], 'cp', G_path, newG_path)
362 # Created expected output tree for 'svn ci':
363 expected_output = svntest.wc.State(wc_dir, {
364 'A/B/newG' : Item(verb='Adding'),
367 # Create expected status tree.
368 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
369 expected_status.add({
370 'A/B/newG' : Item(status=' ', wc_rev=2),
371 'A/B/newG/pi' : Item(status=' ', wc_rev=2),
372 'A/B/newG/rho' : Item(status=' ', wc_rev=2),
373 'A/B/newG/tau' : Item(status=' ', wc_rev=2),
376 svntest.actions.run_and_verify_commit(wc_dir,
377 expected_output,
378 expected_status,
379 None,
380 wc_dir)
382 # Now update the other working copy; it should receive a full add of
383 # the newG directory and its contents.
385 # Expected output of update
386 expected_output = svntest.wc.State(wc_backup, {
387 'A/B/newG' : Item(status='A '),
388 'A/B/newG/pi' : Item(status='A '),
389 'A/B/newG/rho' : Item(status='A '),
390 'A/B/newG/tau' : Item(status='A '),
393 # Create expected disk tree for the update.
394 expected_disk = svntest.main.greek_state.copy()
395 expected_disk.add({
396 'A/B/newG' : Item(),
397 'A/B/newG/pi' : Item("This is the file 'pi'.\n"),
398 'A/B/newG/rho' : Item("This is the file 'rho'.\n"),
399 'A/B/newG/tau' : Item("This is the file 'tau'.\n"),
402 # Create expected status tree for the update.
403 expected_status = svntest.actions.get_virginal_state(wc_backup, 2)
404 expected_status.add({
405 'A/B/newG' : Item(status=' ', wc_rev=2),
406 'A/B/newG/pi' : Item(status=' ', wc_rev=2),
407 'A/B/newG/rho' : Item(status=' ', wc_rev=2),
408 'A/B/newG/tau' : Item(status=' ', wc_rev=2),
411 # Do the update and check the results in three ways.
412 svntest.actions.run_and_verify_update(wc_backup,
413 expected_output,
414 expected_disk,
415 expected_status)
418 #----------------------------------------------------------------------
420 # Regression test for issue #683. In particular, this bug prevented
421 # us from running 'svn cp -r N src_URL dst_URL' as a means of
422 # resurrecting a deleted directory. Also, the final 'update' at the
423 # end of this test was uncovering a ghudson 'deleted' edge-case bug.
424 # (In particular, re-adding G to D, when D already had a 'deleted'
425 # entry for G. The entry-merge wasn't overwriting the 'deleted'
426 # attribute, and thus the newly-added G was ending up disconnected
427 # from D.)
429 def resurrect_deleted_dir(sbox):
430 "resurrect a deleted directory"
432 sbox.build()
433 wc_dir = sbox.wc_dir
434 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
436 # Delete directory A/D/G, commit that as r2.
437 svntest.actions.run_and_verify_svn(None, None, [], 'rm', '--force',
438 G_path)
440 expected_output = svntest.wc.State(wc_dir, {
441 'A/D/G' : Item(verb='Deleting'),
444 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
445 expected_status.remove('A/D/G')
446 expected_status.remove('A/D/G/pi')
447 expected_status.remove('A/D/G/rho')
448 expected_status.remove('A/D/G/tau')
450 svntest.actions.run_and_verify_commit(wc_dir,
451 expected_output,
452 expected_status,
453 None,
454 wc_dir)
456 # Use 'svn cp URL@1 URL' to resurrect the deleted directory, where
457 # the two URLs are identical. This used to trigger a failure.
458 url = sbox.repo_url + '/A/D/G'
459 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
460 url + '@1', url,
461 '-m', 'logmsg')
463 # For completeness' sake, update to HEAD, and verify we have a full
464 # greek tree again, all at revision 3.
466 expected_output = svntest.wc.State(wc_dir, {
467 'A/D/G' : Item(status='A '),
468 'A/D/G/pi' : Item(status='A '),
469 'A/D/G/rho' : Item(status='A '),
470 'A/D/G/tau' : Item(status='A '),
473 expected_disk = svntest.main.greek_state.copy()
475 expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
477 svntest.actions.run_and_verify_update(wc_dir,
478 expected_output,
479 expected_disk,
480 expected_status)
482 def copy_deleted_dir_into_prefix(sbox):
483 "copy a deleted dir to a prefix of its old path"
485 sbox.build()
486 wc_dir = sbox.wc_dir
487 D_path = os.path.join(wc_dir, 'A', 'D')
489 # Delete directory A/D, commit that as r2.
490 svntest.actions.run_and_verify_svn(None, None, [], 'rm', '--force',
491 D_path)
493 expected_output = svntest.wc.State(wc_dir, {
494 'A/D' : Item(verb='Deleting'),
497 svntest.actions.run_and_verify_commit(wc_dir,
498 expected_output,
499 None,
500 None,
501 wc_dir)
503 # Ok, copy from a deleted URL into a prefix of that URL, this used to
504 # result in an assert failing.
505 url1 = sbox.repo_url + '/A/D/G'
506 url2 = sbox.repo_url + '/A/D'
507 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
508 url1 + '@1', url2,
509 '-m', 'logmsg')
511 #----------------------------------------------------------------------
513 # Test that we're enforcing proper 'svn cp' overwrite behavior. Note
514 # that svn_fs_copy() will always overwrite its destination if an entry
515 # by the same name already exists. However, libsvn_client should be
516 # doing existence checks to prevent directories from being
517 # overwritten, and files can't be overwritten because the RA layers
518 # are doing out-of-dateness checks during the commit.
521 def no_copy_overwrites(sbox):
522 "svn cp URL URL cannot overwrite destination"
524 sbox.build()
526 wc_dir = sbox.wc_dir
528 fileURL1 = sbox.repo_url + "/A/B/E/alpha"
529 fileURL2 = sbox.repo_url + "/A/B/E/beta"
530 dirURL1 = sbox.repo_url + "/A/D/G"
531 dirURL2 = sbox.repo_url + "/A/D/H"
533 # Expect out-of-date failure if 'svn cp URL URL' tries to overwrite a file
534 svntest.actions.run_and_verify_svn("Whoa, I was able to overwrite a file!",
535 None, svntest.verify.AnyOutput,
536 'cp', fileURL1, fileURL2,
537 '-m', 'fooogle')
539 # Create A/D/H/G by running 'svn cp ...A/D/G .../A/D/H'
540 svntest.actions.run_and_verify_svn(None, None, [],
541 'cp', dirURL1, dirURL2,
542 '-m', 'fooogle')
544 # Repeat the last command. It should *fail* because A/D/H/G already exists.
545 svntest.actions.run_and_verify_svn(
546 "Whoa, I was able to overwrite a directory!",
547 None, svntest.verify.AnyOutput,
548 'cp', dirURL1, dirURL2,
549 '-m', 'fooogle')
551 #----------------------------------------------------------------------
553 # Issue 845. WC -> WC copy should not overwrite base text-base
555 def no_wc_copy_overwrites(sbox):
556 "svn cp PATH PATH cannot overwrite destination"
558 sbox.build(read_only = True)
559 wc_dir = sbox.wc_dir
561 # File simply missing
562 tau_path = os.path.join(wc_dir, 'A', 'D', 'G', 'tau')
563 os.remove(tau_path)
565 # Status before attempting copies
566 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
567 expected_status.tweak('A/D/G/tau', status='! ')
568 svntest.actions.run_and_verify_status(wc_dir, expected_status)
570 # These copies should fail
571 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
572 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
573 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
574 'cp', pi_path, rho_path)
575 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
576 'cp', pi_path, tau_path)
578 # Status after failed copies should not have changed
579 svntest.actions.run_and_verify_status(wc_dir, expected_status)
581 #----------------------------------------------------------------------
583 # Takes out working-copy locks for A/B2 and child A/B2/E. At one stage
584 # during issue 749 the second lock cause an already-locked error.
585 def copy_modify_commit(sbox):
586 "copy a tree and modify before commit"
588 sbox.build()
589 wc_dir = sbox.wc_dir
590 B_path = os.path.join(wc_dir, 'A', 'B')
591 B2_path = os.path.join(wc_dir, 'A', 'B2')
593 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
594 B_path, B2_path)
596 alpha_path = os.path.join(wc_dir, 'A', 'B2', 'E', 'alpha')
597 svntest.main.file_append(alpha_path, "modified alpha")
599 expected_output = svntest.wc.State(wc_dir, {
600 'A/B2' : Item(verb='Adding'),
601 'A/B2/E/alpha' : Item(verb='Sending'),
604 svntest.actions.run_and_verify_commit(wc_dir,
605 expected_output,
606 None,
607 None,
608 wc_dir)
610 #----------------------------------------------------------------------
612 # Issue 591, at one point copying a file from URL to WC didn't copy
613 # properties.
615 def copy_files_with_properties(sbox):
616 "copy files with properties"
618 sbox.build()
619 wc_dir = sbox.wc_dir
621 # Set a property on a file
622 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
623 svntest.actions.run_and_verify_svn(None, None, [],
624 'propset', 'pname', 'pval', rho_path)
626 # and commit it
627 expected_output = svntest.wc.State(wc_dir, {
628 'A/D/G/rho' : Item(verb='Sending'),
630 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
631 expected_status.tweak('A/D/G/rho', status=' ', wc_rev=2)
632 svntest.actions.run_and_verify_commit(wc_dir,
633 expected_output, expected_status,
634 None, wc_dir)
636 # Set another property, but don't commit it yet
637 svntest.actions.run_and_verify_svn(None, None, [],
638 'propset', 'pname2', 'pval2', rho_path)
640 # WC to WC copy of file with committed and uncommitted properties
641 rho_wc_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho_wc')
642 svntest.actions.run_and_verify_svn(None, None, [],
643 'copy', rho_path, rho_wc_path)
645 # REPOS to WC copy of file with properties
646 rho_url_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho_url')
647 rho_url = sbox.repo_url + '/A/D/G/rho'
648 svntest.actions.run_and_verify_svn(None, None, [],
649 'copy', rho_url, rho_url_path)
651 # Properties are not visible in WC status 'A'
652 expected_status.add({
653 'A/D/G/rho' : Item(status=' M', wc_rev='2'),
654 'A/D/G/rho_wc' : Item(status='A ', wc_rev='-', copied='+'),
655 'A/D/G/rho_url' : Item(status='A ', wc_rev='-', copied='+'),
657 svntest.actions.run_and_verify_status(wc_dir, expected_status)
659 # Check properties explicitly
660 svntest.actions.run_and_verify_svn(None, ['pval\n'], [],
661 'propget', 'pname', rho_wc_path)
662 svntest.actions.run_and_verify_svn(None, ['pval2\n'], [],
663 'propget', 'pname2', rho_wc_path)
664 svntest.actions.run_and_verify_svn(None, ['pval\n'], [],
665 'propget', 'pname', rho_url_path)
667 # Commit and properties are visible in status
668 expected_output = svntest.wc.State(wc_dir, {
669 'A/D/G/rho' : Item(verb='Sending'),
670 'A/D/G/rho_wc' : Item(verb='Adding'),
671 'A/D/G/rho_url' : Item(verb='Adding'),
673 expected_status.tweak('A/D/G/rho', status=' ', wc_rev=3)
674 expected_status.remove('A/D/G/rho_wc', 'A/D/G/rho_url')
675 expected_status.add({
676 'A/D/G/rho_wc' : Item(status=' ', wc_rev=3),
677 'A/D/G/rho_url' : Item(status=' ', wc_rev=3),
679 svntest.actions.run_and_verify_commit(wc_dir,
680 expected_output, expected_status,
681 None, wc_dir)
683 #----------------------------------------------------------------------
685 # Issue 918
686 def copy_delete_commit(sbox):
687 "copy a tree and delete part of it before commit"
689 sbox.build()
690 wc_dir = sbox.wc_dir
691 B_path = os.path.join(wc_dir, 'A', 'B')
692 B2_path = os.path.join(wc_dir, 'A', 'B2')
694 # copy a tree
695 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
696 B_path, B2_path)
698 # delete a file
699 alpha_path = os.path.join(wc_dir, 'A', 'B2', 'E', 'alpha')
700 svntest.actions.run_and_verify_svn(None, None, [], 'rm', alpha_path)
702 # commit copied tree containing a deleted file
703 expected_output = svntest.wc.State(wc_dir, {
704 'A/B2' : Item(verb='Adding'),
705 'A/B2/E/alpha' : Item(verb='Deleting'),
707 svntest.actions.run_and_verify_commit(wc_dir,
708 expected_output,
709 None,
710 None,
711 wc_dir)
713 # copy a tree
714 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
715 os.path.join(wc_dir, 'A', 'B'),
716 os.path.join(wc_dir, 'A', 'B3'))
718 # delete a directory
719 E_path = os.path.join(wc_dir, 'A', 'B3', 'E')
720 svntest.actions.run_and_verify_svn(None, None, [], 'rm', E_path)
722 # commit copied tree containing a deleted directory
723 expected_output = svntest.wc.State(wc_dir, {
724 'A/B3' : Item(verb='Adding'),
725 'A/B3/E' : Item(verb='Deleting'),
727 svntest.actions.run_and_verify_commit(wc_dir,
728 expected_output,
729 None,
730 None,
731 wc_dir)
734 #----------------------------------------------------------------------
735 def mv_and_revert_directory(sbox):
736 "move and revert a directory"
738 sbox.build(read_only = True)
739 wc_dir = sbox.wc_dir
740 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
741 F_path = os.path.join(wc_dir, 'A', 'B', 'F')
742 new_E_path = os.path.join(F_path, 'E')
744 # Issue 931: move failed to lock the directory being deleted
745 svntest.actions.run_and_verify_svn(None, None, [], 'move',
746 E_path, F_path)
747 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
748 expected_status.tweak('A/B/E', 'A/B/E/alpha', 'A/B/E/beta', status='D ')
749 expected_status.add({
750 'A/B/F/E' : Item(status='A ', wc_rev='-', copied='+'),
751 'A/B/F/E/alpha' : Item(status=' ', wc_rev='-', copied='+'),
752 'A/B/F/E/beta' : Item(status=' ', wc_rev='-', copied='+'),
754 svntest.actions.run_and_verify_status(wc_dir, expected_status)
756 # Issue 932: revert failed to lock the parent directory
757 svntest.actions.run_and_verify_svn(None, None, [], 'revert', '--recursive',
758 new_E_path)
759 expected_status.remove('A/B/F/E', 'A/B/F/E/alpha', 'A/B/F/E/beta')
760 svntest.actions.run_and_verify_status(wc_dir, expected_status)
763 #----------------------------------------------------------------------
764 # Issue 982. When copying a file with the executable bit set, the copied
765 # file should also have its executable bit set.
766 def copy_preserve_executable_bit(sbox):
767 "executable bit should be preserved when copying"
769 # Bootstrap
770 sbox.build()
771 wc_dir = sbox.wc_dir
773 # Create two paths
774 newpath1 = os.path.join(wc_dir, 'newfile1')
775 newpath2 = os.path.join(wc_dir, 'newfile2')
777 # Create the first file.
778 svntest.main.file_append(newpath1, "a new file")
779 svntest.actions.run_and_verify_svn(None, None, [], 'add', newpath1)
781 mode1 = os.stat(newpath1)[stat.ST_MODE]
783 # Doing this to get the executable bit set on systems that support
784 # that -- the property itself is not the point.
785 svntest.actions.run_and_verify_svn(None, None, [], 'propset',
786 'svn:executable', 'on', newpath1)
788 mode2 = os.stat(newpath1)[stat.ST_MODE]
790 if mode1 == mode2:
791 print "setting svn:executable did not change file's permissions"
792 raise svntest.Failure
794 # Commit the file
795 svntest.actions.run_and_verify_svn(None, None, [], 'ci',
796 '-m', 'create file and set svn:executable',
797 wc_dir)
799 # Copy the file
800 svntest.actions.run_and_verify_svn(None, None, [], 'cp', newpath1, newpath2)
802 mode3 = os.stat(newpath2)[stat.ST_MODE]
804 # The mode on the original and copied file should be identical
805 if mode2 != mode3:
806 print "permissions on the copied file are not identical to original file"
807 raise svntest.Failure
809 #----------------------------------------------------------------------
810 # Issue 1029, copy failed with a "working copy not locked" error
811 def wc_to_repos(sbox):
812 "working-copy to repository copy"
814 sbox.build()
815 wc_dir = sbox.wc_dir
817 beta_path = os.path.join(wc_dir, "A", "B", "E", "beta")
818 beta2_url = sbox.repo_url + "/A/B/E/beta2"
819 H_path = os.path.join(wc_dir, "A", "D", "H")
820 H2_url = sbox.repo_url + "/A/D/H2"
822 # modify some items to be copied
823 svntest.main.file_append(os.path.join(wc_dir, 'A', 'D', 'H', 'omega'),
824 "new otext\n")
825 svntest.actions.run_and_verify_svn(None, None, [], 'propset', 'foo', 'bar',
826 beta_path)
828 # copy a file
829 svntest.actions.run_and_verify_svn(None, None, [], '-m', 'fumble file',
830 'copy', beta_path, beta2_url)
831 # and a directory
832 svntest.actions.run_and_verify_svn(None, None, [], '-m', 'fumble dir',
833 'copy', H_path, H2_url)
834 # copy a file to a directory
835 svntest.actions.run_and_verify_svn(None, None, [], '-m', 'fumble file',
836 'copy', beta_path, H2_url)
838 # update the working copy. post-update mereinfo elision will remove
839 # A/D/H2/beta's mergeinfo, leaving a local mod.
840 expected_output = svntest.wc.State(wc_dir, {
841 'A/B/E/beta2' : Item(status='A '),
842 'A/D/H2' : Item(status='A '),
843 'A/D/H2/chi' : Item(status='A '),
844 'A/D/H2/omega' : Item(status='A '),
845 'A/D/H2/psi' : Item(status='A '),
846 'A/D/H2/beta' : Item(status='A '),
848 expected_disk = svntest.main.greek_state.copy()
849 expected_disk.tweak('A/D/H/omega',
850 contents="This is the file 'omega'.\nnew otext\n")
851 expected_disk.add({
852 'A/B/E/beta2' : Item("This is the file 'beta'.\n"),
853 'A/D/H2/chi' : Item("This is the file 'chi'.\n"),
854 'A/D/H2/omega' : Item("This is the file 'omega'.\nnew otext\n"),
855 'A/D/H2/psi' : Item("This is the file 'psi'.\n"),
856 'A/D/H2/beta' : Item("This is the file 'beta'.\n"),
858 expected_status = svntest.actions.get_virginal_state(wc_dir, 4)
859 expected_status.add({
860 'A/B/E/beta' : Item(status=' M', wc_rev=4),
861 'A/D/H/omega' : Item(status='M ', wc_rev=4),
862 'A/B/E/beta2' : Item(status=' ', wc_rev=4),
863 'A/D/H2' : Item(status=' ', wc_rev=4),
864 'A/D/H2/chi' : Item(status=' ', wc_rev=4),
865 'A/D/H2/omega' : Item(status=' ', wc_rev=4),
866 'A/D/H2/psi' : Item(status=' ', wc_rev=4),
867 'A/D/H2/beta' : Item(status=' ', wc_rev=4),
869 svntest.actions.run_and_verify_update(wc_dir,
870 expected_output,
871 expected_disk,
872 expected_status)
874 # check local property was copied
875 svntest.actions.run_and_verify_svn(None, ['bar\n'], [],
876 'propget', 'foo',
877 beta_path + "2")
879 #----------------------------------------------------------------------
880 # Issue 1090: various use-cases of 'svn cp URL wc' where the
881 # repositories might be different, or be the same repository.
883 def repos_to_wc(sbox):
884 "repository to working-copy copy"
886 sbox.build()
887 wc_dir = sbox.wc_dir
889 # We have a standard repository and working copy. Now we create a
890 # second repository with the same greek tree, but different UUID.
891 repo_dir = sbox.repo_dir
892 other_repo_dir, other_repo_url = sbox.add_repo_path('other')
893 svntest.main.copy_repos(repo_dir, other_repo_dir, 1, 1)
895 # URL->wc copy:
896 # copy a file and a directory from the same repository.
897 # we should get some scheduled additions *with history*.
898 E_url = sbox.repo_url + "/A/B/E"
899 pi_url = sbox.repo_url + "/A/D/G/pi"
900 pi_path = os.path.join(wc_dir, 'pi')
902 svntest.actions.run_and_verify_svn(None, None, [], 'copy', E_url, wc_dir)
903 svntest.actions.run_and_verify_svn(None, None, [], 'copy', pi_url, wc_dir)
905 # Extra test: modify file ASAP to check there was a timestamp sleep
906 svntest.main.file_append(pi_path, 'zig\n')
908 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
909 expected_output.add({
910 'pi' : Item(status='A ', copied='+', wc_rev='-'),
911 'E' : Item(status='A ', copied='+', wc_rev='-'),
912 'E/alpha' : Item(status=' ', copied='+', wc_rev='-'),
913 'E/beta' : Item(status=' ', copied='+', wc_rev='-'),
915 svntest.actions.run_and_verify_status(wc_dir, expected_output)
917 # Modification will only show up if timestamps differ
918 out,err = svntest.main.run_svn(None, 'diff', pi_path)
919 if err or not out:
920 print "diff failed"
921 raise svntest.Failure
922 for line in out:
923 if line == '+zig\n': # Crude check for diff-like output
924 break
925 else:
926 print "diff output incorrect", out
927 raise svntest.Failure
929 # Revert everything and verify.
930 svntest.actions.run_and_verify_svn(None, None, [], 'revert', '-R', wc_dir)
932 svntest.main.safe_rmtree(os.path.join(wc_dir, 'E'))
933 os.unlink(os.path.join(wc_dir, 'pi'))
935 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
936 svntest.actions.run_and_verify_status(wc_dir, expected_output)
938 # URL->wc copy:
939 # Copy an empty directory from the same repository, see issue #1444.
940 C_url = sbox.repo_url + "/A/C"
942 svntest.actions.run_and_verify_svn(None, None, [], 'copy', C_url, wc_dir)
944 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
945 expected_output.add({
946 'C' : Item(status='A ', copied='+', wc_rev='-'),
948 svntest.actions.run_and_verify_status(wc_dir, expected_output)
950 # Revert everything and verify.
951 svntest.actions.run_and_verify_svn(None, None, [], 'revert', '-R', wc_dir)
953 svntest.main.safe_rmtree(os.path.join(wc_dir, 'C'))
955 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
956 svntest.actions.run_and_verify_status(wc_dir, expected_output)
958 # URL->wc copy:
959 # copy a file and a directory from a foreign repository.
960 # we should get some scheduled additions *without history*.
961 E_url = other_repo_url + "/A/B/E"
962 pi_url = other_repo_url + "/A/D/G/pi"
964 # Expect an error in the directory case
965 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
966 'copy', E_url, wc_dir)
968 # But file case should work fine.
969 svntest.actions.run_and_verify_svn(None, None, [], 'copy', pi_url, wc_dir)
971 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
972 expected_output.add({
973 'pi' : Item(status='A ', wc_rev='1'),
975 svntest.actions.run_and_verify_status(wc_dir, expected_output)
977 # Revert everything and verify.
978 svntest.actions.run_and_verify_svn(None, None, [], 'revert', '-R', wc_dir)
979 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
981 # URL->wc copy:
982 # Copy a directory to a pre-existing WC directory.
983 # The source directory should be copied *under* the target directory.
984 B_url = sbox.repo_url + "/A/B"
985 D_dir = os.path.join(wc_dir, 'A', 'D')
987 svntest.actions.run_and_verify_svn(None, None, [],
988 'copy', B_url, D_dir)
990 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
991 expected_output.add({
992 'A/D/B' : Item(status='A ', copied='+', wc_rev='-'),
993 'A/D/B/lambda' : Item(status=' ', copied='+', wc_rev='-'),
994 'A/D/B/E' : Item(status=' ', copied='+', wc_rev='-'),
995 'A/D/B/E/beta' : Item(status=' ', copied='+', wc_rev='-'),
996 'A/D/B/E/alpha' : Item(status=' ', copied='+', wc_rev='-'),
997 'A/D/B/F' : Item(status=' ', copied='+', wc_rev='-'),
999 svntest.actions.run_and_verify_status(wc_dir, expected_output)
1001 # Validate the merge info of the copy destination (we expect none)
1002 svntest.actions.run_and_verify_svn(None, [], [],
1003 'propget', SVN_PROP_MERGEINFO,
1004 os.path.join(D_dir, 'B'))
1006 #----------------------------------------------------------------------
1007 # Issue 1084: ra_svn move/copy bug
1009 def copy_to_root(sbox):
1010 'copy item to root of repository'
1012 sbox.build()
1013 wc_dir = sbox.wc_dir
1015 root = sbox.repo_url
1016 mu = root + '/A/mu'
1018 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1019 '-m', '',
1020 mu, root)
1022 # Update to HEAD, and check to see if the files really were copied in the
1023 # repo
1025 expected_output = svntest.wc.State(wc_dir, {
1026 'mu': Item(status='A '),
1029 expected_disk = svntest.main.greek_state.copy()
1030 expected_disk.add({
1031 'mu': Item(contents="This is the file 'mu'.\n")
1034 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
1035 expected_status.add({
1036 'mu': Item(status=' ', wc_rev=2),
1039 svntest.actions.run_and_verify_update(wc_dir,
1040 expected_output,
1041 expected_disk,
1042 expected_status)
1044 #----------------------------------------------------------------------
1045 def url_copy_parent_into_child(sbox):
1046 "copy URL URL/subdir"
1048 sbox.build()
1049 wc_dir = sbox.wc_dir
1051 B_url = sbox.repo_url + "/A/B"
1052 F_url = sbox.repo_url + "/A/B/F"
1054 # Issue 1367 parent/child URL-to-URL was rejected.
1055 svntest.actions.run_and_verify_svn(None,
1056 ['\n', 'Committed revision 2.\n'], [],
1057 'cp',
1058 '-m', 'a can of worms',
1059 B_url, F_url)
1061 # Do an update to verify the copy worked
1062 expected_output = svntest.wc.State(wc_dir, {
1063 'A/B/F/B' : Item(status='A '),
1064 'A/B/F/B/E' : Item(status='A '),
1065 'A/B/F/B/E/alpha' : Item(status='A '),
1066 'A/B/F/B/E/beta' : Item(status='A '),
1067 'A/B/F/B/F' : Item(status='A '),
1068 'A/B/F/B/lambda' : Item(status='A '),
1070 expected_disk = svntest.main.greek_state.copy()
1071 expected_disk.add({
1072 'A/B/F/B' : Item(),
1073 'A/B/F/B/E' : Item(),
1074 'A/B/F/B/E/alpha' : Item("This is the file 'alpha'.\n"),
1075 'A/B/F/B/E/beta' : Item("This is the file 'beta'.\n"),
1076 'A/B/F/B/F' : Item(),
1077 'A/B/F/B/lambda' : Item("This is the file 'lambda'.\n"),
1079 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
1080 expected_status.add({
1081 'A/B/F/B' : Item(status=' ', wc_rev=2),
1082 'A/B/F/B/E' : Item(status=' ', wc_rev=2),
1083 'A/B/F/B/E/alpha' : Item(status=' ', wc_rev=2),
1084 'A/B/F/B/E/beta' : Item(status=' ', wc_rev=2),
1085 'A/B/F/B/F' : Item(status=' ', wc_rev=2),
1086 'A/B/F/B/lambda' : Item(status=' ', wc_rev=2),
1088 svntest.actions.run_and_verify_update(wc_dir,
1089 expected_output,
1090 expected_disk,
1091 expected_status)
1093 #----------------------------------------------------------------------
1094 def wc_copy_parent_into_child(sbox):
1095 "copy WC URL/subdir"
1097 sbox.build(create_wc = False)
1098 wc_dir = sbox.wc_dir
1100 B_url = sbox.repo_url + "/A/B"
1101 F_B_url = sbox.repo_url + "/A/B/F/B"
1103 # Want a smaller WC
1104 svntest.main.safe_rmtree(wc_dir)
1105 svntest.actions.run_and_verify_svn(None, None, [],
1106 'checkout',
1107 B_url, wc_dir)
1109 # Issue 1367: A) copying '.' to URL failed with a parent/child
1110 # error, and also B) copying root of a working copy attempted to
1111 # lock the non-working copy parent directory.
1112 was_cwd = os.getcwd()
1113 os.chdir(wc_dir)
1115 svntest.actions.run_and_verify_svn(None,
1116 ['\n', 'Committed revision 2.\n'], [],
1117 'cp',
1118 '-m', 'a larger can',
1119 '.', F_B_url)
1121 os.chdir(was_cwd)
1123 # Do an update to verify the copy worked
1124 expected_output = svntest.wc.State(wc_dir, {
1125 'F/B' : Item(status='A '),
1126 'F/B/E' : Item(status='A '),
1127 'F/B/E/alpha' : Item(status='A '),
1128 'F/B/E/beta' : Item(status='A '),
1129 'F/B/F' : Item(status='A '),
1130 'F/B/lambda' : Item(status='A '),
1132 expected_disk = svntest.wc.State('', {
1133 'E' : Item(),
1134 'E/alpha' : Item("This is the file 'alpha'.\n"),
1135 'E/beta' : Item("This is the file 'beta'.\n"),
1136 'F' : Item(),
1137 'lambda' : Item("This is the file 'lambda'.\n"),
1138 'F/B' : Item(),
1139 'F/B/E' : Item(),
1140 'F/B/E/alpha' : Item("This is the file 'alpha'.\n"),
1141 'F/B/E/beta' : Item("This is the file 'beta'.\n"),
1142 'F/B/F' : Item(),
1143 'F/B/lambda' : Item("This is the file 'lambda'.\n"),
1145 expected_status = svntest.wc.State(wc_dir, {
1146 '' : Item(status=' ', wc_rev=2),
1147 'E' : Item(status=' ', wc_rev=2),
1148 'E/alpha' : Item(status=' ', wc_rev=2),
1149 'E/beta' : Item(status=' ', wc_rev=2),
1150 'F' : Item(status=' ', wc_rev=2),
1151 'lambda' : Item(status=' ', wc_rev=2),
1152 'F/B' : Item(status=' ', wc_rev=2),
1153 'F/B/E' : Item(status=' ', wc_rev=2),
1154 'F/B/E/alpha' : Item(status=' ', wc_rev=2),
1155 'F/B/E/beta' : Item(status=' ', wc_rev=2),
1156 'F/B/F' : Item(status=' ', wc_rev=2),
1157 'F/B/lambda' : Item(status=' ', wc_rev=2),
1159 svntest.actions.run_and_verify_update(wc_dir,
1160 expected_output,
1161 expected_disk,
1162 expected_status)
1164 #----------------------------------------------------------------------
1165 # Issue 1419: at one point ra_neon->get_uuid() was failing on a
1166 # non-existent public URL, which prevented us from resurrecting files
1167 # (svn cp -rOLD URL wc).
1169 def resurrect_deleted_file(sbox):
1170 "resurrect a deleted file"
1172 sbox.build()
1173 wc_dir = sbox.wc_dir
1175 # Delete a file in the repository via immediate commit
1176 rho_url = sbox.repo_url + '/A/D/G/rho'
1177 svntest.actions.run_and_verify_svn(None, None, [],
1178 'rm', rho_url, '-m', 'rev 2')
1180 # Update the wc to HEAD (r2)
1181 expected_output = svntest.wc.State(wc_dir, {
1182 'A/D/G/rho' : Item(status='D '),
1184 expected_disk = svntest.main.greek_state.copy()
1185 expected_disk.remove('A/D/G/rho')
1186 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
1187 expected_status.remove('A/D/G/rho')
1188 svntest.actions.run_and_verify_update(wc_dir,
1189 expected_output,
1190 expected_disk,
1191 expected_status)
1193 # repos->wc copy, to resurrect deleted file.
1194 svntest.actions.run_and_verify_svn("Copy error:", None, [],
1195 'cp', rho_url + '@1', wc_dir)
1197 # status should now show the file scheduled for addition-with-history
1198 expected_status.add({
1199 'rho' : Item(status='A ', copied='+', wc_rev='-'),
1201 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1203 #-------------------------------------------------------------
1204 # Regression tests for Issue #1297:
1205 # svn diff failed after a repository to WC copy of a single file
1206 # This test checks just that.
1208 def diff_repos_to_wc_copy(sbox):
1209 "copy file from repos to working copy and run diff"
1211 sbox.build(read_only = True)
1212 wc_dir = sbox.wc_dir
1214 iota_repos_path = sbox.repo_url + '/iota'
1215 target_wc_path = os.path.join(wc_dir, 'new_file')
1217 # Copy a file from the repository to the working copy.
1218 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1219 iota_repos_path, target_wc_path)
1221 # Run diff.
1222 svntest.actions.run_and_verify_svn(None, None, [], 'diff', wc_dir)
1225 #-------------------------------------------------------------
1227 def repos_to_wc_copy_eol_keywords(sbox):
1228 "repos->WC copy with keyword or eol property set"
1230 # See issue #1473: repos->wc copy would seg fault if svn:keywords or
1231 # svn:eol were set on the copied file, because we'd be querying an
1232 # entry for keyword values when the entry was still null (because
1233 # not yet been fully installed in the wc).
1235 sbox.build()
1236 wc_dir = sbox.wc_dir
1238 iota_repos_path = sbox.repo_url + '/iota'
1239 iota_wc_path = os.path.join(wc_dir, 'iota')
1240 target_wc_path = os.path.join(wc_dir, 'new_file')
1242 # Modify iota to make it checkworthy.
1243 svntest.main.file_write(iota_wc_path,
1244 "Hello\nSubversion\n$LastChangedRevision$\n",
1245 "ab")
1247 svntest.actions.run_and_verify_svn(None, None, [],
1248 'propset', 'svn:eol-style',
1249 'CRLF', iota_wc_path)
1251 svntest.actions.run_and_verify_svn(None, None, [],
1252 'propset', 'svn:keywords',
1253 'Rev', iota_wc_path)
1255 svntest.actions.run_and_verify_svn(None, None, [],
1256 'commit', '-m', 'log msg',
1257 wc_dir)
1259 # Copy a file from the repository to the working copy.
1260 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1261 iota_repos_path, target_wc_path)
1263 # The original bug was that the copy would seg fault. So we test
1264 # that the copy target exists now; if it doesn't, it's probably
1265 # because of the segfault. Note that the crash would be independent
1266 # of whether there are actually any line breaks or keywords in the
1267 # file's contents -- the mere existence of the property would
1268 # trigger the bug.
1269 if not os.path.exists(target_wc_path):
1270 raise svntest.Failure
1272 # Okay, if we got this far, we might as well make sure that the
1273 # translations/substitutions were done correctly:
1274 f = open(target_wc_path, "rb")
1275 raw_contents = f.read()
1276 f.seek(0, 0)
1277 line_contents = f.readlines()
1278 f.close()
1280 if re.match('[^\\r]\\n', raw_contents):
1281 raise svntest.Failure
1283 if not re.match('.*\$LastChangedRevision:\s*\d+\s*\$', line_contents[3]):
1284 raise svntest.Failure
1286 #-------------------------------------------------------------
1287 # Regression test for revision 7331, with commented-out parts for a further
1288 # similar bug.
1290 def revision_kinds_local_source(sbox):
1291 "revision-kind keywords with non-URL source"
1293 sbox.build()
1294 wc_dir = sbox.wc_dir
1296 mu_path = os.path.join(wc_dir, 'A', 'mu')
1298 # Make a file with different content in each revision and WC; BASE != HEAD.
1299 expected_output = svntest.wc.State(wc_dir, {
1300 'A/mu' : Item(verb='Sending'), })
1301 svntest.main.file_append(mu_path, "New r2 text.\n")
1302 svntest.actions.run_and_verify_commit(wc_dir, expected_output, None,
1303 None, wc_dir)
1304 svntest.main.file_append(mu_path, "New r3 text.\n")
1305 svntest.actions.run_and_verify_commit(wc_dir, expected_output, None,
1306 None, wc_dir)
1307 svntest.actions.run_and_verify_svn(None, None, [], 'up', '-r2', mu_path)
1308 svntest.main.file_append(mu_path, "Working copy.\n")
1310 r1 = "This is the file 'mu'.\n"
1311 r2 = r1 + "New r2 text.\n"
1312 r3 = r2 + "New r3 text.\n"
1313 rWC = r2 + "Working copy.\n"
1315 expected_disk = svntest.main.greek_state.copy()
1316 expected_disk.tweak('A/mu', contents=rWC)
1318 # Test the various revision-kind keywords, and none.
1319 sub_tests = [ ('file0', 2, rWC, None),
1320 ('file1', 3, r3, 'HEAD'),
1321 ('file2', 2, r2, 'BASE'),
1322 # ('file3', 2, r2, 'COMMITTED'),
1323 # ('file4', 1, r1, 'PREV'),
1326 for dst, from_rev, text, peg_rev in sub_tests:
1327 dst_path = os.path.join(wc_dir, dst)
1328 if peg_rev is None:
1329 svntest.actions.run_and_verify_svn(None, None, [], "copy",
1330 mu_path, dst_path)
1331 else:
1332 svntest.actions.run_and_verify_svn(None, None, [], "copy",
1333 mu_path + "@" + peg_rev, dst_path)
1334 expected_disk.add({ dst: Item(contents=text) })
1336 # Check that the copied-from revision == from_rev.
1337 output, errput = svntest.main.run_svn(None, "info", dst_path)
1338 for line in output:
1339 if line.rstrip() == "Copied From Rev: " + str(from_rev):
1340 break
1341 else:
1342 print dst, "should have been copied from revision", from_rev
1343 raise svntest.Failure
1345 # Check that the new files have the right contents
1346 actual_disk = svntest.tree.build_tree_from_wc(wc_dir)
1347 svntest.tree.compare_trees("disk", actual_disk, expected_disk.old_tree())
1350 #-------------------------------------------------------------
1351 # Regression test for issue 1581.
1353 def copy_over_missing_file(sbox):
1354 "copy over a missing file"
1355 sbox.build(read_only = True)
1356 wc_dir = sbox.wc_dir
1358 mu_path = os.path.join(wc_dir, 'A', 'mu')
1359 iota_path = os.path.join(wc_dir, 'iota')
1360 iota_url = sbox.repo_url + "/iota"
1362 # Make the target missing.
1363 os.remove(mu_path)
1365 # Try both wc->wc copy and repos->wc copy, expect failures:
1366 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
1367 'cp', iota_path, mu_path)
1369 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
1370 'cp', iota_url, mu_path)
1372 # Make sure that the working copy is not corrupted:
1373 expected_disk = svntest.main.greek_state.copy()
1374 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1375 expected_output = svntest.wc.State(wc_dir, {'A/mu' : Item(verb='Restored')})
1376 svntest.actions.run_and_verify_update(wc_dir,
1377 expected_output,
1378 expected_disk,
1379 expected_status)
1383 #----------------------------------------------------------------------
1384 # Regression test for issue 1634
1386 def repos_to_wc_1634(sbox):
1387 "copy a deleted directory back from the repos"
1389 sbox.build()
1390 wc_dir = sbox.wc_dir
1392 # First delete a subdirectory and commit.
1393 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
1394 svntest.actions.run_and_verify_svn(None, None, [], 'delete', E_path)
1395 expected_output = svntest.wc.State(wc_dir, {
1396 'A/B/E' : Item(verb='Deleting'),
1398 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1399 expected_status.remove('A/B/E', 'A/B/E/alpha', 'A/B/E/beta')
1400 svntest.actions.run_and_verify_commit(wc_dir,
1401 expected_output,
1402 expected_status,
1403 None, wc_dir)
1405 # Now copy the directory back.
1406 E_url = sbox.repo_url + "/A/B/E@1"
1407 svntest.actions.run_and_verify_svn(None, None, [],
1408 'copy', E_url, E_path)
1409 expected_status.add({
1410 'A/B/E' : Item(status='A ', copied='+', wc_rev='-'),
1411 'A/B/E/alpha' : Item(status=' ', copied='+', wc_rev='-'),
1412 'A/B/E/beta' : Item(status=' ', copied='+', wc_rev='-'),
1414 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1416 svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
1417 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
1418 expected_status.add({
1419 'A/B/E' : Item(status='A ', copied='+', wc_rev='-'),
1420 'A/B/E/alpha' : Item(status=' ', copied='+', wc_rev='-'),
1421 'A/B/E/beta' : Item(status=' ', copied='+', wc_rev='-'),
1423 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1425 #----------------------------------------------------------------------
1426 # Regression test for issue 1814
1428 def double_uri_escaping_1814(sbox):
1429 "check for double URI escaping in svn ls -R"
1431 sbox.build(create_wc = False)
1433 base_url = sbox.repo_url + '/base'
1435 # rev. 2
1436 svntest.actions.run_and_verify_svn(None, None, [],
1437 'mkdir', '-m', 'mybase',
1438 base_url)
1440 orig_url = base_url + '/foo%20bar'
1442 # rev. 3
1443 svntest.actions.run_and_verify_svn(None, None, [],
1444 'mkdir', '-m', 'r1',
1445 orig_url)
1446 orig_rev = 3
1448 # rev. 4
1449 new_url = base_url + '/foo_bar'
1450 svntest.actions.run_and_verify_svn(None, None, [],
1451 'mv', '-m', 'r2',
1452 orig_url, new_url)
1454 # This had failed with ra_neon because "foo bar" would be double-encoded
1455 # "foo bar" ==> "foo%20bar" ==> "foo%2520bar"
1456 svntest.actions.run_and_verify_svn(None, None, [],
1457 'ls', ('-r'+str(orig_rev)),
1458 '-R', base_url)
1461 #----------------------------------------------------------------------
1462 # Regression test for issues 2404
1464 def wc_to_wc_copy_between_different_repos(sbox):
1465 "wc to wc copy attempts between different repos"
1467 sbox.build(read_only = True)
1468 wc_dir = sbox.wc_dir
1470 sbox2 = sbox.clone_dependent()
1471 sbox2.build()
1472 wc2_dir = sbox2.wc_dir
1474 # Attempt a copy between different repositories.
1475 out, err = svntest.main.run_svn(1, 'cp',
1476 os.path.join(wc2_dir, 'A'),
1477 os.path.join(wc_dir, 'A', 'B'))
1478 for line in err:
1479 if line.find("it is not from repository") != -1:
1480 break
1481 else:
1482 raise svntest.Failure
1484 #----------------------------------------------------------------------
1485 # Regression test for issues 2101 and 2020
1487 def wc_to_wc_copy_deleted(sbox):
1488 "wc to wc copy with deleted=true items"
1490 sbox.build()
1491 wc_dir = sbox.wc_dir
1493 B_path = os.path.join(wc_dir, 'A', 'B')
1494 B2_path = os.path.join(wc_dir, 'A', 'B2')
1496 # Schedule for delete
1497 svntest.actions.run_and_verify_svn(None, None, [], 'rm',
1498 os.path.join(B_path, 'E', 'alpha'),
1499 os.path.join(B_path, 'lambda'),
1500 os.path.join(B_path, 'F'))
1501 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1502 expected_status.tweak('A/B/E/alpha', 'A/B/lambda', 'A/B/F', status='D ')
1503 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1505 # Copy to schedule=delete fails
1506 out, err = svntest.main.run_svn(1, 'cp',
1507 os.path.join(B_path, 'E'),
1508 os.path.join(B_path, 'F'))
1509 for line in err:
1510 if line.find("is scheduled for deletion") != -1:
1511 break
1512 else:
1513 raise svntest.Failure
1514 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1517 # Commit to get state deleted
1518 expected_status.remove('A/B/E/alpha', 'A/B/lambda', 'A/B/F')
1519 expected_output = svntest.wc.State(wc_dir, {
1520 'A/B/E/alpha' : Item(verb='Deleting'),
1521 'A/B/lambda' : Item(verb='Deleting'),
1522 'A/B/F' : Item(verb='Deleting'),
1524 svntest.actions.run_and_verify_commit(wc_dir,
1525 expected_output,
1526 expected_status,
1527 None, wc_dir)
1529 # Copy including stuff in state deleted=true
1530 svntest.actions.run_and_verify_svn(None, None, [], 'copy', B_path, B2_path)
1531 expected_status.add({
1532 'A/B2' : Item(status='A ', wc_rev='-', copied='+'),
1533 'A/B2/E' : Item(status=' ', wc_rev='-', copied='+'),
1534 'A/B2/E/beta' : Item(status=' ', wc_rev='-', copied='+'),
1535 'A/B2/E/alpha' : Item(status='D ', wc_rev='-', copied='+'),
1536 'A/B2/lambda' : Item(status='D ', wc_rev='-', copied='+'),
1537 'A/B2/F' : Item(status='D ', wc_rev='-', copied='+'),
1539 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1541 # Stuff copied from state deleted=true is now schedule=delete.
1542 # Attempts to revert the schedule=delete will fail, but should not
1543 # break the wc. It's very important that the directory revert fails
1544 # since it's a placeholder rather than a full hierarchy
1545 out, err = svntest.main.run_svn(1, 'revert', '--recursive',
1546 os.path.join(B2_path, 'F'))
1547 for line in err:
1548 if line.find("Error restoring text") != -1:
1549 break
1550 else:
1551 raise svntest.Failure
1552 out, err = svntest.main.run_svn(1, 'revert', os.path.join(B2_path, 'lambda'))
1553 for line in err:
1554 if line.find("Error restoring text") != -1:
1555 break
1556 else:
1557 raise svntest.Failure
1558 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1560 # Revert the entire copy including the schedule delete bits
1561 svntest.actions.run_and_verify_svn(None, None, [], 'revert', '--recursive',
1562 B2_path)
1563 expected_status.remove('A/B2',
1564 'A/B2/E',
1565 'A/B2/E/beta',
1566 'A/B2/E/alpha',
1567 'A/B2/lambda',
1568 'A/B2/F')
1569 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1570 svntest.main.safe_rmtree(B2_path)
1572 # Copy again and commit
1573 svntest.actions.run_and_verify_svn(None, None, [], 'copy', B_path, B2_path)
1574 expected_status.add({
1575 'A/B2' : Item(status=' ', wc_rev=3),
1576 'A/B2/E' : Item(status=' ', wc_rev=3),
1577 'A/B2/E/beta' : Item(status=' ', wc_rev=3),
1579 expected_output = svntest.wc.State(wc_dir, {
1580 'A/B2' : Item(verb='Adding'),
1581 'A/B2/E/alpha' : Item(verb='Deleting'),
1582 'A/B2/lambda' : Item(verb='Deleting'),
1583 'A/B2/F' : Item(verb='Deleting'),
1585 svntest.actions.run_and_verify_commit(wc_dir,
1586 expected_output,
1587 expected_status,
1588 None, wc_dir)
1590 #----------------------------------------------------------------------
1591 # Test for copy into a non-existent URL path
1592 def url_to_non_existent_url_path(sbox):
1593 "svn cp src-URL non-existent-URL-path"
1595 sbox.build(create_wc = False)
1597 dirURL1 = sbox.repo_url + "/A/B/E"
1598 dirURL2 = sbox.repo_url + "/G/C/E/I"
1600 # Look for both possible versions of the error message, as the DAV
1601 # error is worded differently from that of other RA layers.
1602 msg = ".*: (Path 'G(/C/E)?' not present|.*G(/C/E)?' path not found)"
1604 # Expect failure on 'svn cp SRC DST' where one or more ancestor
1605 # directories of DST do not exist
1606 out, err = svntest.main.run_svn(1,
1607 'cp', dirURL1, dirURL2,
1608 '-m', 'fooogle')
1609 for err_line in err:
1610 if re.match (msg, err_line):
1611 break
1612 else:
1613 print "message \"" + msg + "\" not found in error output: ", err
1614 raise svntest.Failure
1617 #----------------------------------------------------------------------
1618 # Test for a copying (URL to URL) an old rev of a deleted file in a
1619 # deleted directory.
1620 def non_existent_url_to_url(sbox):
1621 "svn cp oldrev-of-deleted-URL URL"
1623 sbox.build(create_wc = False)
1625 adg_url = sbox.repo_url + '/A/D/G'
1626 pi_url = sbox.repo_url + '/A/D/G/pi'
1627 new_url = sbox.repo_url + '/newfile'
1629 svntest.actions.run_and_verify_svn(None, None, [],
1630 'delete',
1631 adg_url, '-m', '')
1633 svntest.actions.run_and_verify_svn(None, None, [],
1634 'copy',
1635 pi_url + '@1', new_url,
1636 '-m', '')
1638 #----------------------------------------------------------------------
1639 def old_dir_url_to_url(sbox):
1640 "test URL to URL copying edge case"
1642 sbox.build(create_wc = False)
1644 adg_url = sbox.repo_url + '/A/D/G'
1645 pi_url = sbox.repo_url + '/A/D/G/pi'
1646 iota_url = sbox.repo_url + '/iota'
1647 new_url = sbox.repo_url + '/newfile'
1649 # Delete a directory
1650 svntest.actions.run_and_verify_svn(None, None, [],
1651 'delete',
1652 adg_url, '-m', '')
1654 # Copy a file to where the directory used to be
1655 svntest.actions.run_and_verify_svn(None, None, [],
1656 'copy',
1657 iota_url, adg_url,
1658 '-m', '')
1660 # Try copying a file that was in the deleted directory that is now a
1661 # file
1662 svntest.actions.run_and_verify_svn(None, None, [],
1663 'copy',
1664 pi_url + '@1', new_url,
1665 '-m', '')
1669 #----------------------------------------------------------------------
1670 # Test fix for issue 2224 - copying wc dir to itself causes endless
1671 # recursion
1672 def wc_copy_dir_to_itself(sbox):
1673 "copy wc dir to itself"
1675 sbox.build(read_only = True)
1676 wc_dir = sbox.wc_dir
1677 dnames = ['A','A/B']
1679 for dirname in dnames:
1680 dir_path = os.path.join(wc_dir, dirname)
1682 # try to copy dir to itself
1683 svntest.actions.run_and_verify_svn(None, [],
1684 '.*Cannot copy .* into its own child.*',
1685 'copy', dir_path, dir_path)
1688 #----------------------------------------------------------------------
1690 def mixed_wc_to_url(sbox):
1691 "copy a complex mixed-rev wc"
1693 # For issue 2153.
1695 # Copy a mixed-revision wc (that also has some uncommitted local
1696 # mods, and an entry marked as 'deleted') to a URL. Make sure the
1697 # copy gets the uncommitted mods, and does not contain the deleted
1698 # file.
1700 sbox.build()
1702 wc_dir = sbox.wc_dir
1703 Z_url = sbox.repo_url + '/A/D/Z'
1704 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
1705 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
1706 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
1708 # Remove A/D/G/pi, then commit that removal.
1709 svntest.actions.run_and_verify_svn(None, None, [], 'rm', pi_path)
1710 svntest.actions.run_and_verify_svn(None, None, [],
1711 'ci', '-m', "Delete pi.", wc_dir)
1713 # Make a modification to A/D/G/rho, then commit that modification.
1714 svntest.main.file_append(rho_path, "\nFirst modification to rho.\n")
1715 svntest.actions.run_and_verify_svn(None, None, [],
1716 'ci', '-m', "Modify rho.", wc_dir)
1718 # Make another modification to A/D/G/rho, but don't commit it.
1719 svntest.main.file_append(rho_path, "Second modification to rho.\n")
1721 # Now copy local A/D/G to create new directory A/D/Z the repository.
1722 svntest.actions.run_and_verify_svn(None, None, [],
1723 'cp', '-m', "Make a copy.",
1724 G_path, Z_url)
1726 # Check out A/D/Z. If it has pi, that's a bug; or if its rho does
1727 # not have the second local mod, that's also a bug.
1728 svntest.main.safe_rmtree(wc_dir)
1729 svntest.actions.run_and_verify_svn(None, None, [],
1730 'co', Z_url, wc_dir)
1732 if os.path.exists(os.path.join(wc_dir, 'pi')):
1733 raise svntest.Failure
1735 fp = open(os.path.join(wc_dir, 'rho'), 'r')
1736 found_it = 0
1737 for line in fp.readlines():
1738 if re.match("^Second modification to rho.", line):
1739 found_it = 1
1740 if not found_it:
1741 raise svntest.Failure
1744 #----------------------------------------------------------------------
1746 # Issue 845 and 1516: WC replacement of files requires
1747 # a second text-base and prop-base
1749 def wc_copy_replacement(sbox):
1750 "svn cp PATH PATH replace file"
1752 copy_replace(sbox, 1)
1754 def wc_copy_replace_with_props(sbox):
1755 "svn cp PATH PATH replace file with props"
1757 copy_replace_with_props(sbox, 1)
1760 def repos_to_wc_copy_replacement(sbox):
1761 "svn cp URL PATH replace file"
1763 copy_replace(sbox, 0)
1765 def repos_to_wc_copy_replace_with_props(sbox):
1766 "svn cp URL PATH replace file with props"
1768 copy_replace_with_props(sbox, 0)
1770 def delete_replaced_file(sbox):
1771 "delete file scheduled for replace"
1773 sbox.build(read_only = True)
1774 wc_dir = sbox.wc_dir
1776 # File scheduled for deletion.
1777 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
1778 svntest.actions.run_and_verify_svn(None, None, [], 'rm', rho_path)
1780 # Status before attempting copies
1781 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1782 expected_status.tweak('A/D/G/rho', status='D ')
1783 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1785 # Copy 'pi' over 'rho' with history.
1786 pi_src = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
1787 svntest.actions.run_and_verify_svn(None, None, [], 'cp', pi_src, rho_path)
1789 # Check that file copied.
1790 expected_status.tweak('A/D/G/rho', status='R ', copied='+', wc_rev='-')
1791 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1793 # Now delete replaced file.
1794 svntest.actions.run_and_verify_svn(None, None, [], 'rm',
1795 '--force', rho_path)
1797 # Verify status after deletion.
1798 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1799 expected_status.tweak('A/D/G/rho', status='D ')
1800 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1803 def mv_unversioned_file(sbox):
1804 "move an unversioned file"
1805 # Issue #2436: Attempting to move an unversioned file would seg fault.
1806 sbox.build(read_only = True)
1807 wc_dir = sbox.wc_dir
1809 unver_path_1 = os.path.join(wc_dir, 'unversioned1')
1810 dest_path_1 = os.path.join(wc_dir, 'dest')
1811 svntest.main.file_append(unver_path_1, "an unversioned file")
1813 unver_path_2 = os.path.join(wc_dir, 'A', 'unversioned2')
1814 dest_path_2 = os.path.join(wc_dir, 'A', 'dest_forced')
1815 svntest.main.file_append(unver_path_2, "another unversioned file")
1817 # Try to move an unversioned file.
1818 svntest.actions.run_and_verify_svn(None, None,
1819 ".*unversioned1.* is not under version control.*",
1820 'mv', unver_path_1, dest_path_1)
1822 # Try to forcibly move an unversioned file.
1823 svntest.actions.run_and_verify_svn(None, None,
1824 ".*unversioned2.* is not under version control.*",
1825 'mv',
1826 unver_path_2, dest_path_2)
1828 def force_move(sbox):
1829 "'move' should not lose local mods"
1830 # Issue #2435: 'svn move' / 'svn mv' can lose local modifications.
1831 sbox.build()
1832 wc_dir = sbox.wc_dir
1833 file_name = "iota"
1834 file_path = os.path.join(wc_dir, file_name)
1836 # modify the content
1837 file_handle = file(file_path, "a")
1838 file_handle.write("Added contents\n")
1839 file_handle.close()
1840 expected_file_content = [ "This is the file 'iota'.\n",
1841 "Added contents\n",
1844 # check for the new content
1845 file_handle = file(file_path, "r")
1846 modified_file_content = file_handle.readlines()
1847 file_handle.close()
1848 if modified_file_content != expected_file_content:
1849 raise svntest.Failure("Test setup failed. Incorrect file contents.")
1851 # force move the file
1852 move_output = [ "A dest\n",
1853 "D iota\n",
1855 was_cwd = os.getcwd()
1856 os.chdir(wc_dir)
1858 svntest.actions.run_and_verify_svn(None, move_output,
1860 'move',
1861 file_name, "dest")
1862 os.chdir(was_cwd)
1864 # check for the new content
1865 file_handle = file(os.path.join(wc_dir, "dest"), "r")
1866 modified_file_content = file_handle.readlines()
1867 file_handle.close()
1868 # Error if we dont find the modified contents...
1869 if modified_file_content != expected_file_content:
1870 raise svntest.Failure("File modifications were lost on 'move'")
1872 # Commit the move and make sure the new content actually reaches
1873 # the repository.
1874 expected_output = svntest.wc.State(wc_dir, {
1875 'iota': Item(verb='Deleting'),
1876 'dest': Item(verb='Adding'),
1878 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1879 expected_status.remove("iota")
1880 expected_status.add({
1881 'dest': Item(status=' ', wc_rev='2'),
1883 svntest.actions.run_and_verify_commit(wc_dir,
1884 expected_output,
1885 expected_status,
1886 None, wc_dir)
1887 svntest.actions.run_and_verify_svn('Cat file', expected_file_content, [],
1888 'cat',
1889 sbox.repo_url + '/dest')
1892 def copy_copied_file_and_dir(sbox):
1893 "copy a copied file and dir"
1894 # Improve support for copy and move
1895 # Allow copy of copied items without a commit between
1897 sbox.build()
1898 wc_dir = sbox.wc_dir
1900 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
1901 rho_copy_path_1 = os.path.join(wc_dir, 'A', 'D', 'rho_copy_1')
1902 rho_copy_path_2 = os.path.join(wc_dir, 'A', 'B', 'F', 'rho_copy_2')
1904 # Copy A/D/G/rho to A/D/rho_copy_1
1905 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1906 rho_path, rho_copy_path_1)
1908 # Copy the copied file: A/D/rho_copy_1 to A/B/F/rho_copy_2
1909 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1910 rho_copy_path_1, rho_copy_path_2)
1912 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
1913 E_path_copy_1 = os.path.join(wc_dir, 'A', 'B', 'F', 'E_copy_1')
1914 E_path_copy_2 = os.path.join(wc_dir, 'A', 'D', 'G', 'E_copy_2')
1916 # Copy A/B/E to A/B/F/E_copy_1
1917 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1918 E_path, E_path_copy_1)
1920 # Copy the copied dir: A/B/F/E_copy_1 to A/D/G/E_copy_2
1921 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1922 E_path_copy_1, E_path_copy_2)
1924 # Created expected output tree for 'svn ci':
1925 expected_output = svntest.wc.State(wc_dir, {
1926 'A/D/rho_copy_1' : Item(verb='Adding'),
1927 'A/B/F/rho_copy_2' : Item(verb='Adding'),
1928 'A/B/F/E_copy_1/' : Item(verb='Adding'),
1929 'A/D/G/E_copy_2/' : Item(verb='Adding'),
1932 # Create expected status tree
1933 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1934 expected_status.add({
1935 'A/D/rho_copy_1' : Item(status=' ', wc_rev=2),
1936 'A/B/F/rho_copy_2' : Item(status=' ', wc_rev=2),
1937 'A/B/F/E_copy_1' : Item(status=' ', wc_rev=2),
1938 'A/B/F/E_copy_1/alpha' : Item(status=' ', wc_rev=2),
1939 'A/B/F/E_copy_1/beta' : Item(status=' ', wc_rev=2),
1940 'A/D/G/E_copy_2' : Item(status=' ', wc_rev=2),
1941 'A/D/G/E_copy_2/alpha' : Item(status=' ', wc_rev=2),
1942 'A/D/G/E_copy_2/beta' : Item(status=' ', wc_rev=2),
1945 svntest.actions.run_and_verify_commit(wc_dir,
1946 expected_output,
1947 expected_status,
1948 None,
1949 wc_dir)
1952 def move_copied_file_and_dir(sbox):
1953 "move a copied file and dir"
1955 sbox.build()
1956 wc_dir = sbox.wc_dir
1958 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
1959 rho_copy_path = os.path.join(wc_dir, 'A', 'D', 'rho_copy')
1960 rho_copy_move_path = os.path.join(wc_dir, 'A', 'B', 'F', 'rho_copy_moved')
1962 # Copy A/D/G/rho to A/D/rho_copy
1963 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1964 rho_path, rho_copy_path)
1966 # Move the copied file: A/D/rho_copy to A/B/F/rho_copy_moved
1967 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
1968 rho_copy_path, rho_copy_move_path)
1970 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
1971 E_path_copy = os.path.join(wc_dir, 'A', 'B', 'F', 'E_copy')
1972 E_path_copy_move = os.path.join(wc_dir, 'A', 'D', 'G', 'E_copy_moved')
1974 # Copy A/B/E to A/B/F/E_copy
1975 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1976 E_path, E_path_copy)
1978 # Move the copied file: A/B/F/E_copy to A/D/G/E_copy_moved
1979 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
1980 E_path_copy, E_path_copy_move)
1982 # Created expected output tree for 'svn ci':
1983 # Since we are moving items that were only *scheduled* for addition
1984 # we expect only to additions when checking in, rather than a
1985 # deletion/addition pair.
1986 expected_output = svntest.wc.State(wc_dir, {
1987 'A/B/F/rho_copy_moved' : Item(verb='Adding'),
1988 'A/D/G/E_copy_moved/' : Item(verb='Adding'),
1991 # Create expected status tree
1992 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1993 expected_status.add({
1994 'A/B/F/rho_copy_moved' : Item(status=' ', wc_rev=2),
1995 'A/D/G/E_copy_moved' : Item(status=' ', wc_rev=2),
1996 'A/D/G/E_copy_moved/alpha' : Item(status=' ', wc_rev=2),
1997 'A/D/G/E_copy_moved/beta' : Item(status=' ', wc_rev=2),
2000 svntest.actions.run_and_verify_commit(wc_dir,
2001 expected_output,
2002 expected_status,
2003 None,
2004 wc_dir)
2007 def move_moved_file_and_dir(sbox):
2008 "move a moved file and dir"
2010 sbox.build()
2011 wc_dir = sbox.wc_dir
2013 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
2014 rho_move_path = os.path.join(wc_dir, 'A', 'D', 'rho_moved')
2015 rho_move_moved_path = os.path.join(wc_dir, 'A', 'B', 'F', 'rho_move_moved')
2017 # Move A/D/G/rho to A/D/rho_moved
2018 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2019 rho_path, rho_move_path)
2021 # Move the moved file: A/D/rho_moved to A/B/F/rho_move_moved
2022 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2023 rho_move_path, rho_move_moved_path)
2025 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
2026 E_path_moved = os.path.join(wc_dir, 'A', 'B', 'F', 'E_moved')
2027 E_path_move_moved = os.path.join(wc_dir, 'A', 'D', 'G', 'E_move_moved')
2029 # Copy A/B/E to A/B/F/E_moved
2030 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2031 E_path, E_path_moved)
2033 # Move the moved file: A/B/F/E_moved to A/D/G/E_move_moved
2034 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2035 E_path_moved, E_path_move_moved)
2037 # Created expected output tree for 'svn ci':
2038 expected_output = svntest.wc.State(wc_dir, {
2039 'A/B/E' : Item(verb='Deleting'),
2040 'A/D/G/E_move_moved/' : Item(verb='Adding'),
2041 'A/D/G/rho' : Item(verb='Deleting'),
2042 'A/B/F/rho_move_moved' : Item(verb='Adding'),
2045 # Create expected status tree
2046 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2047 expected_status.add({
2048 'A/D/G/E_move_moved/' : Item(status=' ', wc_rev=2),
2049 'A/D/G/E_move_moved/alpha' : Item(status=' ', wc_rev=2),
2050 'A/D/G/E_move_moved/beta' : Item(status=' ', wc_rev=2),
2051 'A/B/F/rho_move_moved' : Item(status=' ', wc_rev=2),
2054 expected_status.remove('A/B/E',
2055 'A/B/E/alpha',
2056 'A/B/E/beta',
2057 'A/D/G/rho')
2059 svntest.actions.run_and_verify_commit(wc_dir,
2060 expected_output,
2061 expected_status,
2062 None,
2063 wc_dir)
2066 def move_file_within_moved_dir(sbox):
2067 "move a file twice within a moved dir"
2069 sbox.build()
2070 wc_dir = sbox.wc_dir
2072 D_path = os.path.join(wc_dir, 'A', 'D')
2073 D_path_moved = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved')
2075 # Move A/B/D to A/B/F/D_moved
2076 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2077 D_path, D_path_moved)
2079 chi_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved', 'H', 'chi')
2080 chi_moved_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved',
2081 'H', 'chi_moved')
2082 chi_moved_again_path = os.path.join(wc_dir, 'A', 'B', 'F',
2083 'D_moved', 'H', 'chi_moved_again')
2085 # Move A/B/F/D_moved/H/chi to A/B/F/D_moved/H/chi_moved
2086 # then move that to A/B/F/D_moved/H/chi_moved_again
2087 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2088 chi_path, chi_moved_path)
2089 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2090 chi_moved_path,
2091 chi_moved_again_path)
2093 # Created expected output tree for 'svn ci':
2094 expected_output = svntest.wc.State(wc_dir, {
2095 'A/B/F/D_moved/' : Item(verb='Adding'),
2096 'A/B/F/D_moved/H/chi' : Item(verb='Deleting'),
2097 'A/B/F/D_moved/H/chi_moved_again' : Item(verb='Adding'),
2098 'A/D' : Item(verb='Deleting'),
2101 # Create expected status tree
2102 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2103 expected_status.add({
2104 'A/B/F/D_moved' : Item(status=' ', wc_rev=2),
2105 'A/B/F/D_moved/gamma' : Item(status=' ', wc_rev=2),
2106 'A/B/F/D_moved/G' : Item(status=' ', wc_rev=2),
2107 'A/B/F/D_moved/G/pi' : Item(status=' ', wc_rev=2),
2108 'A/B/F/D_moved/G/rho' : Item(status=' ', wc_rev=2),
2109 'A/B/F/D_moved/G/tau' : Item(status=' ', wc_rev=2),
2110 'A/B/F/D_moved/H' : Item(status=' ', wc_rev=2),
2111 'A/B/F/D_moved/H/omega' : Item(status=' ', wc_rev=2),
2112 'A/B/F/D_moved/H/psi' : Item(status=' ', wc_rev=2),
2113 'A/B/F/D_moved/H/chi_moved_again' : Item(status=' ', wc_rev=2),
2116 expected_status.remove('A/D',
2117 'A/D/gamma',
2118 'A/D/G',
2119 'A/D/G/pi',
2120 'A/D/G/rho',
2121 'A/D/G/tau',
2122 'A/D/H',
2123 'A/D/H/chi',
2124 'A/D/H/omega',
2125 'A/D/H/psi',
2128 svntest.actions.run_and_verify_commit(wc_dir,
2129 expected_output,
2130 expected_status,
2131 None,
2132 wc_dir)
2135 def move_file_out_of_moved_dir(sbox):
2136 "move a file out of a moved dir"
2138 sbox.build()
2139 wc_dir = sbox.wc_dir
2141 D_path = os.path.join(wc_dir, 'A', 'D')
2142 D_path_moved = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved')
2144 # Move A/B/D to A/B/F/D_moved
2145 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2146 D_path, D_path_moved)
2148 chi_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved', 'H', 'chi')
2149 chi_moved_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved',
2150 'H', 'chi_moved')
2151 chi_moved_again_path = os.path.join(wc_dir, 'A', 'C', 'chi_moved_again')
2153 # Move A/B/F/D_moved/H/chi to A/B/F/D_moved/H/chi_moved
2154 # then move that to A/C/chi_moved_again
2155 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2156 chi_path, chi_moved_path)
2157 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2158 chi_moved_path,
2159 chi_moved_again_path)
2161 # Created expected output tree for 'svn ci':
2162 expected_output = svntest.wc.State(wc_dir, {
2163 'A/B/F/D_moved/' : Item(verb='Adding'),
2164 'A/B/F/D_moved/H/chi' : Item(verb='Deleting'),
2165 'A/C/chi_moved_again' : Item(verb='Adding'),
2166 'A/D' : Item(verb='Deleting'),
2169 # Create expected status tree
2170 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2171 expected_status.add({
2172 'A/B/F/D_moved' : Item(status=' ', wc_rev=2),
2173 'A/B/F/D_moved/gamma' : Item(status=' ', wc_rev=2),
2174 'A/B/F/D_moved/G' : Item(status=' ', wc_rev=2),
2175 'A/B/F/D_moved/G/pi' : Item(status=' ', wc_rev=2),
2176 'A/B/F/D_moved/G/rho' : Item(status=' ', wc_rev=2),
2177 'A/B/F/D_moved/G/tau' : Item(status=' ', wc_rev=2),
2178 'A/B/F/D_moved/H' : Item(status=' ', wc_rev=2),
2179 'A/B/F/D_moved/H/omega' : Item(status=' ', wc_rev=2),
2180 'A/B/F/D_moved/H/psi' : Item(status=' ', wc_rev=2),
2181 'A/C/chi_moved_again' : Item(status=' ', wc_rev=2),
2184 expected_status.remove('A/D',
2185 'A/D/gamma',
2186 'A/D/G',
2187 'A/D/G/pi',
2188 'A/D/G/rho',
2189 'A/D/G/tau',
2190 'A/D/H',
2191 'A/D/H/chi',
2192 'A/D/H/omega',
2193 'A/D/H/psi',
2196 svntest.actions.run_and_verify_commit(wc_dir,
2197 expected_output,
2198 expected_status,
2199 None,
2200 wc_dir)
2203 def move_dir_within_moved_dir(sbox):
2204 "move a dir twice within a moved dir"
2206 sbox.build()
2207 wc_dir = sbox.wc_dir
2209 D_path = os.path.join(wc_dir, 'A', 'D')
2210 D_path_moved = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved')
2212 # Move A/D to A/B/F/D_moved
2213 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2214 D_path, D_path_moved)
2216 H_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved', 'H')
2217 H_moved_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved', 'H_moved')
2218 H_moved_again_path = os.path.join(wc_dir, 'A', 'B', 'F',
2219 'D_moved', 'H_moved_again')
2221 # Move A/B/F/D_moved/H to A/B/F/D_moved/H_moved
2222 # then move that to A/B/F/D_moved/H_moved_again
2223 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2224 H_path, H_moved_path)
2225 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2226 H_moved_path,
2227 H_moved_again_path)
2229 # Created expected output tree for 'svn ci':
2230 expected_output = svntest.wc.State(wc_dir, {
2231 'A/D' : Item(verb='Deleting'),
2232 'A/B/F/D_moved' : Item(verb='Adding'),
2233 'A/B/F/D_moved/H' : Item(verb='Deleting'),
2234 'A/B/F/D_moved/H_moved_again' : Item(verb='Adding'),
2237 # Create expected status tree
2238 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2239 expected_status.add({
2240 'A/B/F/D_moved' : Item(status=' ', wc_rev=2),
2241 'A/B/F/D_moved/gamma' : Item(status=' ', wc_rev=2),
2242 'A/B/F/D_moved/G' : Item(status=' ', wc_rev=2),
2243 'A/B/F/D_moved/G/pi' : Item(status=' ', wc_rev=2),
2244 'A/B/F/D_moved/G/rho' : Item(status=' ', wc_rev=2),
2245 'A/B/F/D_moved/G/tau' : Item(status=' ', wc_rev=2),
2246 'A/B/F/D_moved/H_moved_again' : Item(status=' ', wc_rev=2),
2247 'A/B/F/D_moved/H_moved_again/omega' : Item(status=' ', wc_rev=2),
2248 'A/B/F/D_moved/H_moved_again/psi' : Item(status=' ', wc_rev=2),
2249 'A/B/F/D_moved/H_moved_again/chi' : Item(status=' ', wc_rev=2),
2252 expected_status.remove('A/D',
2253 'A/D/gamma',
2254 'A/D/G',
2255 'A/D/G/pi',
2256 'A/D/G/rho',
2257 'A/D/G/tau',
2258 'A/D/H',
2259 'A/D/H/chi',
2260 'A/D/H/omega',
2261 'A/D/H/psi',
2264 svntest.actions.run_and_verify_commit(wc_dir,
2265 expected_output,
2266 expected_status,
2267 None,
2268 wc_dir)
2271 def move_dir_out_of_moved_dir(sbox):
2272 "move a dir out of a moved dir"
2274 sbox.build()
2275 wc_dir = sbox.wc_dir
2277 D_path = os.path.join(wc_dir, 'A', 'D')
2278 D_path_moved = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved')
2280 # Move A/D to A/B/F/D_moved
2281 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2282 D_path, D_path_moved)
2284 H_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved', 'H')
2285 H_moved_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved', 'H_moved')
2286 H_moved_again_path = os.path.join(wc_dir, 'A', 'C', 'H_moved_again')
2288 # Move A/B/F/D_moved/H to A/B/F/D_moved/H_moved
2289 # then move that to A/C/H_moved_again
2290 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2291 H_path, H_moved_path)
2292 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2293 H_moved_path,
2294 H_moved_again_path)
2296 # Created expected output tree for 'svn ci':
2297 expected_output = svntest.wc.State(wc_dir, {
2298 'A/D' : Item(verb='Deleting'),
2299 'A/B/F/D_moved' : Item(verb='Adding'),
2300 'A/B/F/D_moved/H' : Item(verb='Deleting'),
2301 'A/C/H_moved_again' : Item(verb='Adding'),
2304 # Create expected status tree
2305 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2306 expected_status.add({
2307 'A/B/F/D_moved' : Item(status=' ', wc_rev=2),
2308 'A/B/F/D_moved/gamma' : Item(status=' ', wc_rev=2),
2309 'A/B/F/D_moved/G' : Item(status=' ', wc_rev=2),
2310 'A/B/F/D_moved/G/pi' : Item(status=' ', wc_rev=2),
2311 'A/B/F/D_moved/G/rho' : Item(status=' ', wc_rev=2),
2312 'A/B/F/D_moved/G/tau' : Item(status=' ', wc_rev=2),
2313 'A/C/H_moved_again' : Item(status=' ', wc_rev=2),
2314 'A/C/H_moved_again/omega' : Item(status=' ', wc_rev=2),
2315 'A/C/H_moved_again/psi' : Item(status=' ', wc_rev=2),
2316 'A/C/H_moved_again/chi' : Item(status=' ', wc_rev=2),
2319 expected_status.remove('A/D',
2320 'A/D/gamma',
2321 'A/D/G',
2322 'A/D/G/pi',
2323 'A/D/G/rho',
2324 'A/D/G/tau',
2325 'A/D/H',
2326 'A/D/H/chi',
2327 'A/D/H/omega',
2328 'A/D/H/psi',
2331 svntest.actions.run_and_verify_commit(wc_dir,
2332 expected_output,
2333 expected_status,
2334 None,
2335 wc_dir)
2337 def move_file_back_and_forth(sbox):
2338 "move a moved file back to original location"
2340 sbox.build()
2341 wc_dir = sbox.wc_dir
2343 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
2344 rho_move_path = os.path.join(wc_dir, 'A', 'D', 'rho_moved')
2346 # Move A/D/G/rho to A/D/rho_moved
2347 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2348 rho_path, rho_move_path)
2350 # Move the moved file: A/D/rho_moved to A/B/F/rho_move_moved
2351 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2352 rho_move_path, rho_path)
2354 # Created expected output tree for 'svn ci':
2355 expected_output = svntest.wc.State(wc_dir, {
2356 'A/D/G/rho' : Item(verb='Replacing'),
2359 # Create expected status tree
2360 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2361 expected_status.add({
2362 'A/D/G/rho' : Item(status=' ', wc_rev=2),
2365 svntest.actions.run_and_verify_commit(wc_dir,
2366 expected_output,
2367 expected_status,
2368 None,
2369 wc_dir)
2372 def move_dir_back_and_forth(sbox):
2373 "move a moved dir back to original location"
2375 sbox.build(read_only = True)
2376 wc_dir = sbox.wc_dir
2378 D_path = os.path.join(wc_dir, 'A', 'D')
2379 D_move_path = os.path.join(wc_dir, 'D_moved')
2381 # Move A/D to D_moved
2382 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2383 D_path, D_move_path)
2385 # Move the moved dir: D_moved back to its starting
2386 # location at A/D.
2387 out, err = svntest.actions.run_and_verify_svn(None, None,
2388 svntest.verify.AnyOutput,
2389 'mv', D_move_path,
2390 D_path)
2392 for line in err:
2393 if re.match('.*Cannot copy to .*as it is scheduled for deletion',
2394 line, ):
2395 return
2396 raise svntest.Failure("mv failed but not in the expected way")
2399 def copy_move_added_paths(sbox):
2400 "copy and move added paths without commits"
2402 sbox.build()
2403 wc_dir = sbox.wc_dir
2405 # Create a new file and schedule it for addition
2406 upsilon_path = os.path.join(wc_dir, 'A', 'D', 'upsilon')
2407 svntest.main.file_write(upsilon_path, "This is the file 'upsilon'\n")
2408 svntest.actions.run_and_verify_svn(None, None, [], 'add', upsilon_path)
2410 # Create a dir with children and schedule it for addition
2411 I_path = os.path.join(wc_dir, 'A', 'D', 'I')
2412 J_path = os.path.join(I_path, 'J')
2413 eta_path = os.path.join(I_path, 'eta')
2414 theta_path = os.path.join(I_path, 'theta')
2415 kappa_path = os.path.join(J_path, 'kappa')
2416 os.mkdir(I_path)
2417 os.mkdir(J_path)
2418 svntest.main.file_write(eta_path, "This is the file 'eta'\n")
2419 svntest.main.file_write(theta_path, "This is the file 'theta'\n")
2420 svntest.main.file_write(kappa_path, "This is the file 'kappa'\n")
2421 svntest.actions.run_and_verify_svn(None, None, [], 'add', I_path)
2423 # Create another dir and schedule it for addition
2424 K_path = os.path.join(wc_dir, 'K')
2425 os.mkdir(K_path)
2426 svntest.actions.run_and_verify_svn(None, None, [], 'add', K_path)
2428 # Verify all the adds took place correctly.
2429 expected_status_after_adds = svntest.actions.get_virginal_state(wc_dir, 1)
2430 expected_status_after_adds.add({
2431 'A/D/I' : Item(status='A ', wc_rev='0'),
2432 'A/D/I/eta' : Item(status='A ', wc_rev='0'),
2433 'A/D/I/J' : Item(status='A ', wc_rev='0'),
2434 'A/D/I/J/kappa' : Item(status='A ', wc_rev='0'),
2435 'A/D/I/theta' : Item(status='A ', wc_rev='0'),
2436 'A/D/upsilon' : Item(status='A ', wc_rev='0'),
2437 'K' : Item(status='A ', wc_rev='0'),
2439 svntest.actions.run_and_verify_status(wc_dir, expected_status_after_adds)
2441 # Scatter some unversioned paths within the added dir I.
2442 unversioned_path_1 = os.path.join(I_path, 'unversioned1')
2443 unversioned_path_2 = os.path.join(J_path, 'unversioned2')
2444 L_path = os.path.join(I_path, "L_UNVERSIONED")
2445 unversioned_path_3 = os.path.join(L_path, 'unversioned3')
2446 svntest.main.file_write(unversioned_path_1, "An unversioned file\n")
2447 svntest.main.file_write(unversioned_path_2, "An unversioned file\n")
2448 os.mkdir(L_path)
2449 svntest.main.file_write(unversioned_path_3, "An unversioned file\n")
2451 # Copy added dir A/D/I to added dir K/I
2452 I_copy_path = os.path.join(K_path, 'I')
2453 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
2454 I_path, I_copy_path)
2456 # Copy added file A/D/upsilon into added dir K
2457 upsilon_copy_path = os.path.join(K_path, 'upsilon')
2458 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
2459 upsilon_path, upsilon_copy_path)
2461 # Move added file A/D/upsilon to upsilon,
2462 # then move it again to A/upsilon
2463 upsilon_move_path = os.path.join(wc_dir, 'upsilon')
2464 upsilon_move_path_2 = os.path.join(wc_dir, 'A', 'upsilon')
2465 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2466 upsilon_path, upsilon_move_path)
2467 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2468 upsilon_move_path, upsilon_move_path_2)
2470 # Move added dir A/D/I to A/B/I,
2471 # then move it again to A/D/H/I
2472 I_move_path = os.path.join(wc_dir, 'A', 'B', 'I')
2473 I_move_path_2 = os.path.join(wc_dir, 'A', 'D', 'H', 'I')
2474 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2475 I_path, I_move_path)
2476 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2477 I_move_path, I_move_path_2)
2479 # Created expected output tree for 'svn ci'
2480 expected_output = svntest.wc.State(wc_dir, {
2481 'A/D/H/I' : Item(verb='Adding'),
2482 'A/D/H/I/J' : Item(verb='Adding'),
2483 'A/D/H/I/J/kappa' : Item(verb='Adding'),
2484 'A/D/H/I/eta' : Item(verb='Adding'),
2485 'A/D/H/I/theta' : Item(verb='Adding'),
2486 'A/upsilon' : Item(verb='Adding'),
2487 'K' : Item(verb='Adding'),
2488 'K/I' : Item(verb='Adding'),
2489 'K/I/J' : Item(verb='Adding'),
2490 'K/I/J/kappa' : Item(verb='Adding'),
2491 'K/I/eta' : Item(verb='Adding'),
2492 'K/I/theta' : Item(verb='Adding'),
2493 'K/upsilon' : Item(verb='Adding'),
2496 # Create expected status tree
2497 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2498 expected_status.add({
2499 'A/D/H/I' : Item(status=' ', wc_rev=2),
2500 'A/D/H/I/J' : Item(status=' ', wc_rev=2),
2501 'A/D/H/I/J/kappa' : Item(status=' ', wc_rev=2),
2502 'A/D/H/I/eta' : Item(status=' ', wc_rev=2),
2503 'A/D/H/I/theta' : Item(status=' ', wc_rev=2),
2504 'A/upsilon' : Item(status=' ', wc_rev=2),
2505 'K' : Item(status=' ', wc_rev=2),
2506 'K/I' : Item(status=' ', wc_rev=2),
2507 'K/I/J' : Item(status=' ', wc_rev=2),
2508 'K/I/J/kappa' : Item(status=' ', wc_rev=2),
2509 'K/I/eta' : Item(status=' ', wc_rev=2),
2510 'K/I/theta' : Item(status=' ', wc_rev=2),
2511 'K/upsilon' : Item(status=' ', wc_rev=2),
2514 svntest.actions.run_and_verify_commit(wc_dir,
2515 expected_output,
2516 expected_status,
2517 None,
2518 wc_dir)
2520 # Run_and_verify_commit() doesn't handle status of unversioned paths
2521 # so manually confirm unversioned paths got copied and moved too.
2522 unversioned_paths = [
2523 os.path.join(wc_dir, 'A', 'D', 'H', 'I', 'unversioned1'),
2524 os.path.join(wc_dir, 'A', 'D', 'H', 'I', 'L_UNVERSIONED'),
2525 os.path.join(wc_dir, 'A', 'D', 'H', 'I', 'L_UNVERSIONED',
2526 'unversioned3'),
2527 os.path.join(wc_dir, 'A', 'D', 'H', 'I', 'J', 'unversioned2'),
2528 os.path.join(wc_dir, 'K', 'I', 'unversioned1'),
2529 os.path.join(wc_dir, 'K', 'I', 'L_UNVERSIONED'),
2530 os.path.join(wc_dir, 'K', 'I', 'L_UNVERSIONED', 'unversioned3'),
2531 os.path.join(wc_dir, 'K', 'I', 'J', 'unversioned2')]
2532 for path in unversioned_paths:
2533 if not os.path.exists(path):
2534 raise svntest.Failure("Unversioned path '%s' not found." % path)
2536 def copy_added_paths_with_props(sbox):
2537 "copy added uncommitted paths with props"
2539 sbox.build()
2540 wc_dir = sbox.wc_dir
2542 # Create a new file, schedule it for addition and set properties
2543 upsilon_path = os.path.join(wc_dir, 'A', 'D', 'upsilon')
2544 svntest.main.file_write(upsilon_path, "This is the file 'upsilon'\n")
2545 svntest.actions.run_and_verify_svn(None, None, [], 'add', upsilon_path)
2546 svntest.actions.run_and_verify_svn(None, None, [], 'propset',
2547 'foo', 'bar', upsilon_path)
2549 # Create a dir and schedule it for addition and set properties
2550 I_path = os.path.join(wc_dir, 'A', 'D', 'I')
2551 os.mkdir(I_path)
2552 svntest.actions.run_and_verify_svn(None, None, [], 'add', I_path)
2553 svntest.actions.run_and_verify_svn(None, None, [], 'propset',
2554 'foo', 'bar', I_path)
2556 # Verify all the adds took place correctly.
2557 expected_status_after_adds = svntest.actions.get_virginal_state(wc_dir, 1)
2558 expected_status_after_adds.add({
2559 'A/D/upsilon' : Item(status='A ', wc_rev='0'),
2560 'A/D/I' : Item(status='A ', wc_rev='0'),
2562 svntest.actions.run_and_verify_status(wc_dir, expected_status_after_adds)
2564 expected_disk = svntest.main.greek_state.copy()
2565 expected_disk.add({
2566 'A/D/upsilon' : Item(props={'foo' : 'bar'},
2567 contents="This is the file 'upsilon'\n"),
2568 'A/D/I' : Item(props={'foo' : 'bar'}),
2571 # Read disk state with props
2572 actual_disk_tree = svntest.tree.build_tree_from_wc(wc_dir, 1)
2574 # Compare actual vs. expected disk trees.
2575 svntest.tree.compare_trees("disk", actual_disk_tree,
2576 expected_disk.old_tree())
2578 # Copy added dir K to dir A/C
2579 I_copy_path = os.path.join(wc_dir, 'A', 'C', 'I')
2580 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
2581 I_path, I_copy_path)
2583 # Copy added file A/upsilon into dir A/C
2584 upsilon_copy_path = os.path.join(wc_dir, 'A', 'C', 'upsilon')
2585 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
2586 upsilon_path, upsilon_copy_path)
2588 # Created expected output tree for 'svn ci'
2589 expected_output = svntest.wc.State(wc_dir, {
2590 'A/D/upsilon' : Item(verb='Adding'),
2591 'A/D/I' : Item(verb='Adding'),
2592 'A/C/upsilon' : Item(verb='Adding'),
2593 'A/C/I' : Item(verb='Adding'),
2596 # Create expected status tree
2597 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2598 expected_status.add({
2599 'A/D/upsilon' : Item(status=' ', wc_rev=2),
2600 'A/D/I' : Item(status=' ', wc_rev=2),
2601 'A/C/upsilon' : Item(status=' ', wc_rev=2),
2602 'A/C/I' : Item(status=' ', wc_rev=2),
2605 # Tweak expected disk tree
2606 expected_disk.add({
2607 'A/C/upsilon' : Item(props={'foo' : 'bar'},
2608 contents="This is the file 'upsilon'\n"),
2609 'A/C/I' : Item(props={'foo' : 'bar'}),
2612 svntest.actions.run_and_verify_commit(wc_dir,
2613 expected_output,
2614 expected_status,
2615 None,
2616 wc_dir)
2617 # Read disk state with props
2618 actual_disk_tree = svntest.tree.build_tree_from_wc(wc_dir, 1)
2620 # Compare actual vs. expected disk trees.
2621 svntest.tree.compare_trees("disk", actual_disk_tree,
2622 expected_disk.old_tree())
2624 def copy_added_paths_to_URL(sbox):
2625 "copy added path to URL"
2627 sbox.build()
2628 wc_dir = sbox.wc_dir
2630 # Create a new file and schedule it for addition
2631 upsilon_path = os.path.join(wc_dir, 'A', 'D', 'upsilon')
2632 svntest.main.file_write(upsilon_path, "This is the file 'upsilon'\n")
2633 svntest.actions.run_and_verify_svn(None, None, [], 'add', upsilon_path)
2635 # Create a dir with children and schedule it for addition
2636 I_path = os.path.join(wc_dir, 'A', 'D', 'I')
2637 J_path = os.path.join(I_path, 'J')
2638 eta_path = os.path.join(I_path, 'eta')
2639 theta_path = os.path.join(I_path, 'theta')
2640 kappa_path = os.path.join(J_path, 'kappa')
2641 os.mkdir(I_path)
2642 os.mkdir(J_path)
2643 svntest.main.file_write(eta_path, "This is the file 'eta'\n")
2644 svntest.main.file_write(theta_path, "This is the file 'theta'\n")
2645 svntest.main.file_write(kappa_path, "This is the file 'kappa'\n")
2646 svntest.actions.run_and_verify_svn(None, None, [], 'add', I_path)
2648 # Verify all the adds took place correctly.
2649 expected_status_after_adds = svntest.actions.get_virginal_state(wc_dir, 1)
2650 expected_status_after_adds.add({
2651 'A/D/I' : Item(status='A ', wc_rev='0'),
2652 'A/D/I/eta' : Item(status='A ', wc_rev='0'),
2653 'A/D/I/J' : Item(status='A ', wc_rev='0'),
2654 'A/D/I/J/kappa' : Item(status='A ', wc_rev='0'),
2655 'A/D/I/theta' : Item(status='A ', wc_rev='0'),
2656 'A/D/upsilon' : Item(status='A ', wc_rev='0'),
2658 svntest.actions.run_and_verify_status(wc_dir, expected_status_after_adds)
2660 # Scatter some unversioned paths within the added dir I.
2661 # These don't get copied in a WC->URL copy obviously.
2662 unversioned_path_1 = os.path.join(I_path, 'unversioned1')
2663 unversioned_path_2 = os.path.join(J_path, 'unversioned2')
2664 L_path = os.path.join(I_path, "L_UNVERSIONED")
2665 unversioned_path_3 = os.path.join(L_path, 'unversioned3')
2666 svntest.main.file_write(unversioned_path_1, "An unversioned file\n")
2667 svntest.main.file_write(unversioned_path_2, "An unversioned file\n")
2668 os.mkdir(L_path)
2669 svntest.main.file_write(unversioned_path_3, "An unversioned file\n")
2671 # Copy added file A/D/upsilon to URL://A/C/upsilon
2672 upsilon_copy_URL = sbox.repo_url + '/A/C/upsilon'
2673 svntest.actions.run_and_verify_svn(None, None, [],
2674 'cp', '-m', '',
2675 upsilon_path, upsilon_copy_URL)
2677 # Validate the merge info of the copy destination (we expect none).
2678 svntest.actions.run_and_verify_svn(None, [], [],
2679 'propget',
2680 SVN_PROP_MERGEINFO, upsilon_copy_URL)
2682 # Copy added dir A/D/I to URL://A/D/G/I
2683 I_copy_URL = sbox.repo_url + '/A/D/G/I'
2684 svntest.actions.run_and_verify_svn(None, None, [],
2685 'cp', '-m', '',
2686 I_path, I_copy_URL)
2688 # Created expected output tree for 'svn ci'
2689 expected_output = svntest.wc.State(wc_dir, {
2690 'A/D/I' : Item(verb='Adding'),
2691 'A/D/I/J' : Item(verb='Adding'),
2692 'A/D/I/J/kappa' : Item(verb='Adding'),
2693 'A/D/I/eta' : Item(verb='Adding'),
2694 'A/D/I/theta' : Item(verb='Adding'),
2695 'A/D/upsilon' : Item(verb='Adding'),
2698 # Create expected status tree
2699 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2700 expected_status.add({
2701 'A/D/I' : Item(status=' ', wc_rev=4),
2702 'A/D/I/J' : Item(status=' ', wc_rev=4),
2703 'A/D/I/J/kappa' : Item(status=' ', wc_rev=4),
2704 'A/D/I/eta' : Item(status=' ', wc_rev=4),
2705 'A/D/I/theta' : Item(status=' ', wc_rev=4),
2706 'A/D/upsilon' : Item(status=' ', wc_rev=4),
2709 svntest.actions.run_and_verify_commit(wc_dir,
2710 expected_output,
2711 expected_status,
2712 None,
2713 wc_dir)
2715 # Created expected output for update
2716 expected_output = svntest.wc.State(wc_dir, {
2717 'A/D/G/I' : Item(status='A '),
2718 'A/D/G/I/theta' : Item(status='A '),
2719 'A/D/G/I/J' : Item(status='A '),
2720 'A/D/G/I/J/kappa' : Item(status='A '),
2721 'A/D/G/I/eta' : Item(status='A '),
2722 'A/C/upsilon' : Item(status='A '),
2725 # Created expected disk for update
2726 expected_disk = svntest.main.greek_state.copy()
2727 expected_disk.add({
2728 'A/D/G/I' : Item(),
2729 'A/D/G/I/theta' : Item("This is the file 'theta'\n"),
2730 'A/D/G/I/J' : Item(),
2731 'A/D/G/I/J/kappa' : Item("This is the file 'kappa'\n"),
2732 'A/D/G/I/eta' : Item("This is the file 'eta'\n"),
2733 'A/C/upsilon' : Item("This is the file 'upsilon'\n"),
2734 'A/D/I' : Item(),
2735 'A/D/I/J' : Item(),
2736 'A/D/I/J/kappa' : Item("This is the file 'kappa'\n"),
2737 'A/D/I/eta' : Item("This is the file 'eta'\n"),
2738 'A/D/I/theta' : Item("This is the file 'theta'\n"),
2739 'A/D/upsilon' : Item("This is the file 'upsilon'\n"),
2740 'A/D/I/L_UNVERSIONED/unversioned3' : Item("An unversioned file\n"),
2741 'A/D/I/L_UNVERSIONED' : Item(),
2742 'A/D/I/unversioned1' : Item("An unversioned file\n"),
2743 'A/D/I/J/unversioned2' : Item("An unversioned file\n"),
2746 # Some more changes to the expected_status to reflect post update WC
2747 expected_status.tweak(wc_rev=4)
2748 expected_status.add({
2749 'A/C' : Item(status=' ', wc_rev=4),
2750 'A/C/upsilon' : Item(status=' ', wc_rev=4),
2751 'A/D/G' : Item(status=' ', wc_rev=4),
2752 'A/D/G/I' : Item(status=' ', wc_rev=4),
2753 'A/D/G/I/theta' : Item(status=' ', wc_rev=4),
2754 'A/D/G/I/J' : Item(status=' ', wc_rev=4),
2755 'A/D/G/I/J/kappa' : Item(status=' ', wc_rev=4),
2756 'A/D/G/I/eta' : Item(status=' ', wc_rev=4),
2759 # Update WC, the WC->URL copies above should be added
2760 svntest.actions.run_and_verify_update(wc_dir,
2761 expected_output,
2762 expected_disk,
2763 expected_status)
2766 # Issue #1869.
2767 def move_to_relative_paths(sbox):
2768 "move file using relative dst path names"
2770 sbox.build()
2771 wc_dir = sbox.wc_dir
2772 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
2773 rel_path = os.path.join('..', '..', '..')
2775 current_dir = os.getcwd()
2776 os.chdir(E_path)
2777 svntest.main.run_svn(None, 'mv', 'beta', rel_path)
2778 os.chdir(current_dir)
2780 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2781 expected_status.add({
2782 'beta' : Item(status='A ', copied='+', wc_rev='-'),
2783 'A/B/E/beta' : Item(status='D ', wc_rev='1')
2785 svntest.actions.run_and_verify_status(wc_dir, expected_status)
2788 #----------------------------------------------------------------------
2789 def move_from_relative_paths(sbox):
2790 "move file using relative src path names"
2792 sbox.build(read_only = True)
2793 wc_dir = sbox.wc_dir
2794 F_path = os.path.join(wc_dir, 'A', 'B', 'F')
2795 beta_rel_path = os.path.join('..', 'E', 'beta')
2797 current_dir = os.getcwd()
2798 os.chdir(F_path)
2799 svntest.main.run_svn(None, 'mv', beta_rel_path, '.')
2800 os.chdir(current_dir)
2802 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2803 expected_status.add({
2804 'A/B/F/beta' : Item(status='A ', copied='+', wc_rev='-'),
2805 'A/B/E/beta' : Item(status='D ', wc_rev='1')
2807 svntest.actions.run_and_verify_status(wc_dir, expected_status)
2810 #----------------------------------------------------------------------
2811 def copy_to_relative_paths(sbox):
2812 "copy file using relative dst path names"
2814 sbox.build(read_only = True)
2815 wc_dir = sbox.wc_dir
2816 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
2817 rel_path = os.path.join('..', '..', '..')
2819 current_dir = os.getcwd()
2820 os.chdir(E_path)
2821 svntest.main.run_svn(None, 'cp', 'beta', rel_path)
2822 os.chdir(current_dir)
2824 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2825 expected_status.add({
2826 'beta' : Item(status='A ', copied='+', wc_rev='-'),
2828 svntest.actions.run_and_verify_status(wc_dir, expected_status)
2831 #----------------------------------------------------------------------
2832 def copy_from_relative_paths(sbox):
2833 "copy file using relative src path names"
2835 sbox.build(read_only = True)
2836 wc_dir = sbox.wc_dir
2837 F_path = os.path.join(wc_dir, 'A', 'B', 'F')
2838 beta_rel_path = os.path.join('..', 'E', 'beta')
2840 current_dir = os.getcwd()
2841 os.chdir(F_path)
2842 svntest.main.run_svn(None, 'cp', beta_rel_path, '.')
2843 os.chdir(current_dir)
2845 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2846 expected_status.add({
2847 'A/B/F/beta' : Item(status='A ', copied='+', wc_rev='-'),
2849 svntest.actions.run_and_verify_status(wc_dir, expected_status)
2852 #----------------------------------------------------------------------
2854 # Test moving multiple files within a wc.
2856 def move_multiple_wc(sbox):
2857 "svn mv multiple files to a common directory"
2859 sbox.build()
2860 wc_dir = sbox.wc_dir
2862 chi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'chi')
2863 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
2864 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
2865 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
2866 C_path = os.path.join(wc_dir, 'A', 'C')
2868 # Move chi, psi, omega and E to A/C
2869 svntest.actions.run_and_verify_svn(None, None, [], 'mv', chi_path, psi_path,
2870 omega_path, E_path, C_path)
2872 # Create expected output
2873 expected_output = svntest.wc.State(wc_dir, {
2874 'A/C/chi' : Item(verb='Adding'),
2875 'A/C/psi' : Item(verb='Adding'),
2876 'A/C/omega' : Item(verb='Adding'),
2877 'A/C/E' : Item(verb='Adding'),
2878 'A/D/H/chi' : Item(verb='Deleting'),
2879 'A/D/H/psi' : Item(verb='Deleting'),
2880 'A/D/H/omega' : Item(verb='Deleting'),
2881 'A/B/E' : Item(verb='Deleting'),
2884 # Create expected status tree
2885 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2887 # Add the moved files
2888 expected_status.add({
2889 'A/C/chi' : Item(status=' ', wc_rev=2),
2890 'A/C/psi' : Item(status=' ', wc_rev=2),
2891 'A/C/omega' : Item(status=' ', wc_rev=2),
2892 'A/C/E' : Item(status=' ', wc_rev=2),
2893 'A/C/E/alpha' : Item(status=' ', wc_rev=2),
2894 'A/C/E/beta' : Item(status=' ', wc_rev=2),
2897 # Removed the moved files
2898 expected_status.remove('A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega', 'A/B/E/alpha',
2899 'A/B/E/beta', 'A/B/E')
2901 svntest.actions.run_and_verify_commit(wc_dir,
2902 expected_output,
2903 expected_status,
2904 None,
2905 wc_dir)
2907 #----------------------------------------------------------------------
2909 # Test copying multiple files within a wc.
2911 def copy_multiple_wc(sbox):
2912 "svn cp multiple files to a common directory"
2914 sbox.build()
2915 wc_dir = sbox.wc_dir
2917 chi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'chi')
2918 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
2919 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
2920 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
2921 C_path = os.path.join(wc_dir, 'A', 'C')
2923 # Copy chi, psi, omega and E to A/C
2924 svntest.actions.run_and_verify_svn(None, None, [], 'cp', chi_path, psi_path,
2925 omega_path, E_path, C_path)
2927 # Create expected output
2928 expected_output = svntest.wc.State(wc_dir, {
2929 'A/C/chi' : Item(verb='Adding'),
2930 'A/C/psi' : Item(verb='Adding'),
2931 'A/C/omega' : Item(verb='Adding'),
2932 'A/C/E' : Item(verb='Adding'),
2935 # Create expected status tree
2936 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2938 # Add the moved files
2939 expected_status.add({
2940 'A/C/chi' : Item(status=' ', wc_rev=2),
2941 'A/C/psi' : Item(status=' ', wc_rev=2),
2942 'A/C/omega' : Item(status=' ', wc_rev=2),
2943 'A/C/E' : Item(status=' ', wc_rev=2),
2944 'A/C/E/alpha' : Item(status=' ', wc_rev=2),
2945 'A/C/E/beta' : Item(status=' ', wc_rev=2),
2948 svntest.actions.run_and_verify_commit(wc_dir,
2949 expected_output,
2950 expected_status,
2951 None,
2952 wc_dir)
2954 #----------------------------------------------------------------------
2956 # Test moving multiple files within a repo.
2958 def move_multiple_repo(sbox):
2959 "move multiple files within a repo"
2961 sbox.build()
2962 wc_dir = sbox.wc_dir
2964 chi_url = sbox.repo_url + '/A/D/H/chi'
2965 psi_url = sbox.repo_url + '/A/D/H/psi'
2966 omega_url = sbox.repo_url + '/A/D/H/omega'
2967 E_url = sbox.repo_url + '/A/B/E'
2968 C_url = sbox.repo_url + '/A/C'
2970 # Move three files and a directory in the repo to a different location
2971 # in the repo
2972 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2973 chi_url, psi_url, omega_url, E_url, C_url,
2974 '-m', 'logmsg')
2976 # Update to HEAD, and check to see if the files really moved in the repo
2978 expected_output = svntest.wc.State(wc_dir, {
2979 'A/C/chi' : Item(status='A '),
2980 'A/C/psi' : Item(status='A '),
2981 'A/C/omega' : Item(status='A '),
2982 'A/C/E' : Item(status='A '),
2983 'A/C/E/alpha' : Item(status='A '),
2984 'A/C/E/beta' : Item(status='A '),
2985 'A/D/H/chi' : Item(status='D '),
2986 'A/D/H/psi' : Item(status='D '),
2987 'A/D/H/omega' : Item(status='D '),
2988 'A/B/E' : Item(status='D '),
2991 expected_disk = svntest.main.greek_state.copy()
2992 expected_disk.remove('A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega', 'A/B/E/alpha',
2993 'A/B/E/beta', 'A/B/E')
2994 expected_disk.add({
2995 'A/C/chi' : Item(contents="This is the file 'chi'.\n"),
2996 'A/C/psi' : Item(contents="This is the file 'psi'.\n"),
2997 'A/C/omega' : Item(contents="This is the file 'omega'.\n"),
2998 'A/C/E' : Item(),
2999 'A/C/E/alpha' : Item(contents="This is the file 'alpha'.\n"),
3000 'A/C/E/beta' : Item(contents="This is the file 'beta'.\n"),
3003 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
3004 expected_status.remove('A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega', 'A/B/E/alpha',
3005 'A/B/E/beta', 'A/B/E')
3006 expected_status.add({
3007 'A/C/chi' : Item(status=' ', wc_rev=2),
3008 'A/C/psi' : Item(status=' ', wc_rev=2),
3009 'A/C/omega' : Item(status=' ', wc_rev=2),
3010 'A/C/E' : Item(status=' ', wc_rev=2),
3011 'A/C/E/alpha' : Item(status=' ', wc_rev=2),
3012 'A/C/E/beta' : Item(status=' ', wc_rev=2),
3015 svntest.actions.run_and_verify_update(wc_dir,
3016 expected_output,
3017 expected_disk,
3018 expected_status)
3020 #----------------------------------------------------------------------
3022 # Test copying multiple files within a repo.
3024 def copy_multiple_repo(sbox):
3025 "copy multiple files within a repo"
3027 sbox.build()
3028 wc_dir = sbox.wc_dir
3030 chi_url = sbox.repo_url + '/A/D/H/chi'
3031 psi_url = sbox.repo_url + '/A/D/H/psi'
3032 omega_url = sbox.repo_url + '/A/D/H/omega'
3033 E_url = sbox.repo_url + '/A/B/E'
3034 C_url = sbox.repo_url + '/A/C'
3036 # Copy three files and a directory in the repo to a different location
3037 # in the repo
3038 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
3039 chi_url, psi_url, omega_url, E_url, C_url,
3040 '-m', 'logmsg')
3042 # Update to HEAD, and check to see if the files really moved in the repo
3044 expected_output = svntest.wc.State(wc_dir, {
3045 'A/C/chi' : Item(status='A '),
3046 'A/C/psi' : Item(status='A '),
3047 'A/C/omega' : Item(status='A '),
3048 'A/C/E' : Item(status='A '),
3049 'A/C/E/alpha' : Item(status='A '),
3050 'A/C/E/beta' : Item(status='A '),
3053 expected_disk = svntest.main.greek_state.copy()
3054 expected_disk.add({
3055 'A/C/chi' : Item(contents="This is the file 'chi'.\n"),
3056 'A/C/psi' : Item(contents="This is the file 'psi'.\n"),
3057 'A/C/omega' : Item(contents="This is the file 'omega'.\n"),
3058 'A/C/E' : Item(),
3059 'A/C/E/alpha' : Item(contents="This is the file 'alpha'.\n"),
3060 'A/C/E/beta' : Item(contents="This is the file 'beta'.\n"),
3063 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
3064 expected_status.add({
3065 'A/C/chi' : Item(status=' ', wc_rev=2),
3066 'A/C/psi' : Item(status=' ', wc_rev=2),
3067 'A/C/omega' : Item(status=' ', wc_rev=2),
3068 'A/C/E' : Item(status=' ', wc_rev=2),
3069 'A/C/E/alpha' : Item(status=' ', wc_rev=2),
3070 'A/C/E/beta' : Item(status=' ', wc_rev=2),
3073 svntest.actions.run_and_verify_update(wc_dir,
3074 expected_output,
3075 expected_disk,
3076 expected_status)
3078 #----------------------------------------------------------------------
3080 # Test moving copying multiple files from a repo to a wc
3082 def copy_multiple_repo_wc(sbox):
3083 "copy multiple files from a repo to a wc"
3085 sbox.build()
3086 wc_dir = sbox.wc_dir
3088 chi_url = sbox.repo_url + '/A/D/H/chi'
3089 psi_url = sbox.repo_url + '/A/D/H/psi'
3090 omega_with_space_url = sbox.repo_url + '/A/D/H/omega 2'
3091 E_url = sbox.repo_url + '/A/B/E'
3092 C_path = os.path.join(wc_dir, 'A', 'C')
3094 # We need this in order to check that we don't end up with URI-encoded
3095 # paths in the WC (issue #2955)
3096 svntest.actions.run_and_verify_svn(None, None, [], 'mv', '-m', 'log_msg',
3097 sbox.repo_url + '/A/D/H/omega',
3098 omega_with_space_url)
3100 # Perform the copy and check the output
3101 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
3102 chi_url, psi_url, omega_with_space_url,
3103 E_url, C_path)
3105 # Commit the changes, and verify the content actually got copied
3106 expected_output = svntest.wc.State(wc_dir, {
3107 'A/C/chi' : Item(verb='Adding'),
3108 'A/C/psi' : Item(verb='Adding'),
3109 'A/C/omega 2' : Item(verb='Adding'),
3110 'A/C/E' : Item(verb='Adding'),
3113 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
3114 expected_status.add({
3115 'A/C/chi' : Item(status=' ', wc_rev=3),
3116 'A/C/psi' : Item(status=' ', wc_rev=3),
3117 'A/C/omega 2' : Item(status=' ', wc_rev=3),
3118 'A/C/E' : Item(status=' ', wc_rev=3),
3119 'A/C/E/alpha' : Item(status=' ', wc_rev=3),
3120 'A/C/E/beta' : Item(status=' ', wc_rev=3),
3123 svntest.actions.run_and_verify_commit(wc_dir,
3124 expected_output,
3125 expected_status,
3126 None, wc_dir)
3128 #----------------------------------------------------------------------
3130 # Test moving copying multiple files from a wc to a repo
3132 def copy_multiple_wc_repo(sbox):
3133 "copy multiple files from a wc to a repo"
3135 sbox.build()
3136 wc_dir = sbox.wc_dir
3138 chi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'chi')
3139 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
3140 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
3141 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
3142 C_url = sbox.repo_url + '/A/C'
3144 # Perform the copy and check the output
3145 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
3146 chi_path, psi_path, omega_path, E_path,
3147 C_url, '-m', 'logmsg')
3149 # Update to HEAD, and check to see if the files really got copied in the repo
3151 expected_output = svntest.wc.State(wc_dir, {
3152 'A/C/chi' : Item(status='A '),
3153 'A/C/psi' : Item(status='A '),
3154 'A/C/omega' : Item(status='A '),
3155 'A/C/E' : Item(status='A '),
3156 'A/C/E/alpha' : Item(status='A '),
3157 'A/C/E/beta' : Item(status='A '),
3160 expected_disk = svntest.main.greek_state.copy()
3161 expected_disk.add({
3162 'A/C/chi': Item(contents="This is the file 'chi'.\n"),
3163 'A/C/psi': Item(contents="This is the file 'psi'.\n"),
3164 'A/C/omega': Item(contents="This is the file 'omega'.\n"),
3165 'A/C/E' : Item(),
3166 'A/C/E/alpha' : Item(contents="This is the file 'alpha'.\n"),
3167 'A/C/E/beta' : Item(contents="This is the file 'beta'.\n"),
3170 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
3171 expected_status.add({
3172 'A/C/chi' : Item(status=' ', wc_rev=2),
3173 'A/C/psi' : Item(status=' ', wc_rev=2),
3174 'A/C/omega' : Item(status=' ', wc_rev=2),
3175 'A/C/E' : Item(status=' ', wc_rev=2),
3176 'A/C/E/alpha' : Item(status=' ', wc_rev=2),
3177 'A/C/E/beta' : Item(status=' ', wc_rev=2),
3180 svntest.actions.run_and_verify_update(wc_dir,
3181 expected_output,
3182 expected_disk,
3183 expected_status)
3185 #----------------------------------------------------------------------
3187 # Test copying local files using peg revision syntax
3188 # (Issue 2546)
3189 def copy_peg_rev_local_files(sbox):
3190 "copy local files using peg rev syntax"
3192 sbox.build()
3193 wc_dir = sbox.wc_dir
3195 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
3196 new_iota_path = os.path.join(wc_dir, 'new_iota')
3197 iota_path = os.path.join(wc_dir, 'iota')
3198 sigma_path = os.path.join(wc_dir, 'sigma')
3200 psi_text = "This is the file 'psi'.\n"
3201 iota_text = "This is the file 'iota'.\n"
3203 # Play a shell game with some WC files, then commit the changes back
3204 # to the repository (making r2).
3205 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3206 psi_path, new_iota_path)
3207 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3208 iota_path, psi_path)
3209 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3210 new_iota_path, iota_path)
3212 svntest.actions.run_and_verify_svn(None, None, [],
3213 'ci',
3214 '-m', 'rev 2',
3215 wc_dir)
3217 # Copy using a peg rev (remember, the object at iota_path at HEAD
3218 # was at psi_path back at r1).
3219 svntest.actions.run_and_verify_svn(None, None, [],
3220 'cp',
3221 iota_path + '@HEAD', '-r', '1',
3222 sigma_path)
3224 # Commit and verify disk contents
3225 svntest.actions.run_and_verify_svn(None, None, [],
3226 'ci', wc_dir,
3227 '-m', 'rev 3')
3229 expected_disk = svntest.main.greek_state.copy()
3230 expected_disk.tweak('A/D/H/psi', contents=iota_text)
3231 expected_disk.add({
3232 'iota' : Item(contents=psi_text, props={SVN_PROP_MERGEINFO : ''}),
3233 'A/D/H/psi' : Item(contents=iota_text, props={SVN_PROP_MERGEINFO : ''}),
3234 'sigma' : Item(contents=psi_text, props={}),
3237 actual_disk = svntest.tree.build_tree_from_wc(wc_dir, 3)
3238 svntest.tree.compare_trees("disk", actual_disk, expected_disk.old_tree())
3241 #----------------------------------------------------------------------
3243 # Test copying local directories using peg revision syntax
3244 # (Issue 2546)
3245 def copy_peg_rev_local_dirs(sbox):
3246 "copy local dirs using peg rev syntax"
3248 sbox.build()
3249 wc_dir = sbox.wc_dir
3251 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
3252 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
3253 I_path = os.path.join(wc_dir, 'A', 'D', 'I')
3254 J_path = os.path.join(wc_dir, 'A', 'J')
3255 alpha_path = os.path.join(E_path, 'alpha')
3257 # Make some changes to the repository
3258 svntest.actions.run_and_verify_svn(None, None, [], 'rm',
3259 alpha_path)
3260 svntest.actions.run_and_verify_svn(None, None, [],
3261 'ci',
3262 '-m', 'rev 2',
3263 wc_dir)
3264 svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
3266 svntest.actions.run_and_verify_svn(None, None, [],
3267 'mv',
3268 E_path, I_path)
3269 svntest.actions.run_and_verify_svn(None, None, [],
3270 'ci',
3271 '-m', 'rev 3',
3272 wc_dir)
3274 svntest.actions.run_and_verify_svn(None, None, [],
3275 'mv',
3276 G_path, E_path)
3277 svntest.actions.run_and_verify_svn(None, None, [],
3278 'ci',
3279 '-m', 'rev 4',
3280 wc_dir)
3282 svntest.actions.run_and_verify_svn(None, None, [],
3283 'mv',
3284 I_path, G_path)
3285 svntest.actions.run_and_verify_svn(None, None, [],
3286 'ci',
3287 '-m', 'rev 5',
3288 wc_dir)
3290 # Copy using a peg rev
3291 svntest.actions.run_and_verify_svn(None, None, [],
3292 'cp',
3293 G_path + '@HEAD', '-r', '1',
3294 J_path)
3296 # Commit and verify disk contents
3297 svntest.actions.run_and_verify_svn(None, None, [],
3298 'ci', wc_dir,
3299 '-m', 'rev 6')
3301 expected_disk = svntest.main.greek_state.copy()
3302 expected_disk.remove('A/B/E/beta')
3303 expected_disk.remove('A/B/E/alpha')
3304 expected_disk.remove('A/D/G/pi')
3305 expected_disk.remove('A/D/G/rho')
3306 expected_disk.remove('A/D/G/tau')
3307 expected_disk.add({
3308 'A/B/E' : Item(props={SVN_PROP_MERGEINFO : ''}),
3309 'A/B/E/pi' : Item(contents="This is the file 'pi'.\n"),
3310 'A/B/E/rho' : Item(contents="This is the file 'rho'.\n"),
3311 'A/B/E/tau' : Item(contents="This is the file 'tau'.\n"),
3312 'A/D/G' : Item(props={SVN_PROP_MERGEINFO : ''}),
3313 'A/D/G/beta' : Item(contents="This is the file 'beta'.\n"),
3314 'A/J' : Item(props={}),
3315 'A/J/alpha' : Item(contents="This is the file 'alpha'.\n"),
3316 'A/J/beta' : Item(contents="This is the file 'beta'.\n"),
3319 actual_disk = svntest.tree.build_tree_from_wc(wc_dir, 5)
3320 svntest.tree.compare_trees("disk", actual_disk, expected_disk.old_tree())
3323 #----------------------------------------------------------------------
3325 # Test copying urls using peg revision syntax
3326 # (Issue 2546)
3327 def copy_peg_rev_url(sbox):
3328 "copy urls using peg rev syntax"
3330 sbox.build()
3331 wc_dir = sbox.wc_dir
3333 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
3334 new_iota_path = os.path.join(wc_dir, 'new_iota')
3335 iota_path = os.path.join(wc_dir, 'iota')
3336 iota_url = sbox.repo_url + '/iota'
3337 sigma_url = sbox.repo_url + '/sigma'
3339 psi_text = "This is the file 'psi'.\n"
3340 iota_text = "This is the file 'iota'.\n"
3342 # Make some changes to the repository
3343 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3344 psi_path, new_iota_path)
3345 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3346 iota_path, psi_path)
3347 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3348 new_iota_path, iota_path)
3350 svntest.actions.run_and_verify_svn(None, None, [],
3351 'ci',
3352 '-m', 'rev 2',
3353 wc_dir)
3355 # Copy using a peg rev
3356 svntest.actions.run_and_verify_svn(None, None, [],
3357 'cp',
3358 iota_url + '@HEAD', '-r', '1',
3359 sigma_url, '-m', 'rev 3')
3361 # Validate the copy destination's mergeinfo (we expect none).
3362 svntest.actions.run_and_verify_svn(None, [], [],
3363 'propget', SVN_PROP_MERGEINFO, sigma_url)
3365 # Update to HEAD and verify disk contents
3366 expected_output = svntest.wc.State(wc_dir, {
3367 'sigma' : Item(status='A '),
3370 expected_disk = svntest.main.greek_state.copy()
3371 expected_disk.tweak('iota', contents=psi_text)
3372 expected_disk.tweak('A/D/H/psi', contents=iota_text)
3373 expected_disk.add({
3374 'sigma' : Item(contents=psi_text),
3377 expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
3378 expected_status.add({
3379 'sigma' : Item(status=' ', wc_rev=3)
3382 svntest.actions.run_and_verify_update(wc_dir,
3383 expected_output,
3384 expected_disk,
3385 expected_status)
3387 # Test copying an older revision of a wc directory in the wc.
3388 def old_dir_wc_to_wc(sbox):
3389 "copy old revision of wc dir to new dir"
3391 sbox.build()
3392 wc_dir = sbox.wc_dir
3394 E = os.path.join(wc_dir, 'A', 'B', 'E')
3395 E2 = os.path.join(wc_dir, 'E2')
3396 E_url = sbox.repo_url + '/A/B/E'
3397 alpha_url = E_url + '/alpha'
3399 # delete E/alpha in r2
3400 svntest.actions.run_and_verify_svn(None, None, [],
3401 'rm', '-m', '', alpha_url)
3403 # delete E in r3
3404 svntest.actions.run_and_verify_svn(None, None, [],
3405 'rm', '-m', '', E_url)
3407 # Copy an old revision of E into a new path in the WC
3408 svntest.actions.run_and_verify_svn(None, None, [],
3409 'cp', '-r1', E, E2)
3411 # Create expected output tree.
3412 expected_output = svntest.wc.State(wc_dir, {
3413 'E2' : Item(verb='Adding'),
3416 # Created expected status tree.
3417 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
3418 expected_status.add({
3419 'E2' : Item(status=' ', wc_rev=4),
3420 'E2/alpha' : Item(status=' ', wc_rev=4),
3421 'E2/beta' : Item(status=' ', wc_rev=4),
3423 # Commit the one file.
3424 svntest.actions.run_and_verify_commit(wc_dir,
3425 expected_output,
3426 expected_status,
3427 None,
3428 wc_dir)
3431 #----------------------------------------------------------------------
3432 # Test copying and creating parents in the wc
3434 def copy_make_parents_wc_wc(sbox):
3435 "svn cp --parents WC_PATH WC_PATH"
3437 sbox.build()
3438 wc_dir = sbox.wc_dir
3440 iota_path = os.path.join(wc_dir, 'iota')
3441 new_iota_path = os.path.join(wc_dir, 'X', 'Y', 'Z', 'iota')
3443 # Copy iota
3444 svntest.actions.run_and_verify_svn(None, None, [], 'cp', '--parents',
3445 iota_path, new_iota_path)
3447 # Create expected output
3448 expected_output = svntest.wc.State(wc_dir, {
3449 'X' : Item(verb='Adding'),
3450 'X/Y' : Item(verb='Adding'),
3451 'X/Y/Z' : Item(verb='Adding'),
3452 'X/Y/Z/iota' : Item(verb='Adding'),
3455 # Create expected status tree
3456 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
3458 # Add the moved files
3459 expected_status.add({
3460 'X' : Item(status=' ', wc_rev=2),
3461 'X/Y' : Item(status=' ', wc_rev=2),
3462 'X/Y/Z' : Item(status=' ', wc_rev=2),
3463 'X/Y/Z/iota' : Item(status=' ', wc_rev=2),
3466 svntest.actions.run_and_verify_commit(wc_dir,
3467 expected_output,
3468 expected_status,
3469 None,
3470 wc_dir)
3472 #----------------------------------------------------------------------
3473 # Test copying and creating parents from the repo to the wc
3475 def copy_make_parents_repo_wc(sbox):
3476 "svn cp --parents URL WC_PATH"
3478 sbox.build()
3479 wc_dir = sbox.wc_dir
3481 iota_url = sbox.repo_url + '/iota'
3482 new_iota_path = os.path.join(wc_dir, 'X', 'Y', 'Z', 'iota')
3484 # Copy iota
3485 svntest.actions.run_and_verify_svn(None, None, [],
3486 'cp', '--parents',
3487 iota_url, new_iota_path)
3489 # Create expected output
3490 expected_output = svntest.wc.State(wc_dir, {
3491 'X' : Item(verb='Adding'),
3492 'X/Y' : Item(verb='Adding'),
3493 'X/Y/Z' : Item(verb='Adding'),
3494 'X/Y/Z/iota' : Item(verb='Adding'),
3497 # Create expected status tree
3498 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
3500 # Add the moved files
3501 expected_status.add({
3502 'X' : Item(status=' ', wc_rev=2),
3503 'X/Y' : Item(status=' ', wc_rev=2),
3504 'X/Y/Z' : Item(status=' ', wc_rev=2),
3505 'X/Y/Z/iota' : Item(status=' ', wc_rev=2),
3508 svntest.actions.run_and_verify_commit(wc_dir,
3509 expected_output,
3510 expected_status,
3511 None,
3512 wc_dir)
3515 #----------------------------------------------------------------------
3516 # Test copying and creating parents from the wc to the repo
3518 def copy_make_parents_wc_repo(sbox):
3519 "svn cp --parents WC_PATH URL"
3521 sbox.build()
3522 wc_dir = sbox.wc_dir
3524 iota_path = os.path.join(wc_dir, 'iota')
3525 new_iota_url = sbox.repo_url + '/X/Y/Z/iota'
3527 # Copy iota
3528 svntest.actions.run_and_verify_svn(None, None, [],
3529 'cp', '--parents',
3530 '-m', 'log msg',
3531 iota_path, new_iota_url)
3533 # Update to HEAD and verify disk contents
3534 expected_output = svntest.wc.State(wc_dir, {
3535 'X' : Item(status='A '),
3536 'X/Y' : Item(status='A '),
3537 'X/Y/Z' : Item(status='A '),
3538 'X/Y/Z/iota' : Item(status='A '),
3541 expected_disk = svntest.main.greek_state.copy()
3542 expected_disk.add({
3543 'X' : Item(),
3544 'X/Y' : Item(),
3545 'X/Y/Z' : Item(),
3546 'X/Y/Z/iota' : Item(contents="This is the file 'iota'.\n"),
3549 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
3550 expected_status.add({
3551 'X' : Item(status=' ', wc_rev=2),
3552 'X/Y' : Item(status=' ', wc_rev=2),
3553 'X/Y/Z' : Item(status=' ', wc_rev=2),
3554 'X/Y/Z/iota' : Item(status=' ', wc_rev=2),
3557 svntest.actions.run_and_verify_update(wc_dir,
3558 expected_output,
3559 expected_disk,
3560 expected_status)
3563 #----------------------------------------------------------------------
3564 # Test copying and creating parents from repo to repo
3566 def copy_make_parents_repo_repo(sbox):
3567 "svn cp --parents URL URL"
3569 sbox.build()
3570 wc_dir = sbox.wc_dir
3572 iota_url = sbox.repo_url + '/iota'
3573 new_iota_url = sbox.repo_url + '/X/Y/Z/iota'
3575 # Copy iota
3576 svntest.actions.run_and_verify_svn(None, None, [],
3577 'cp', '--parents',
3578 '-m', 'log msg',
3579 iota_url, new_iota_url)
3581 # Update to HEAD and verify disk contents
3582 expected_output = svntest.wc.State(wc_dir, {
3583 'X' : Item(status='A '),
3584 'X/Y' : Item(status='A '),
3585 'X/Y/Z' : Item(status='A '),
3586 'X/Y/Z/iota' : Item(status='A '),
3589 expected_disk = svntest.main.greek_state.copy()
3590 expected_disk.add({
3591 'X' : Item(),
3592 'X/Y' : Item(),
3593 'X/Y/Z' : Item(),
3594 'X/Y/Z/iota' : Item(contents="This is the file 'iota'.\n"),
3597 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
3598 expected_status.add({
3599 'X' : Item(status=' ', wc_rev=2),
3600 'X/Y' : Item(status=' ', wc_rev=2),
3601 'X/Y/Z' : Item(status=' ', wc_rev=2),
3602 'X/Y/Z/iota' : Item(status=' ', wc_rev=2),
3605 svntest.actions.run_and_verify_update(wc_dir,
3606 expected_output,
3607 expected_disk,
3608 expected_status)
3610 # Test for issue #2894
3611 # Can't perform URL to WC copy if URL needs URI encoding.
3612 def URI_encoded_repos_to_wc(sbox):
3613 "copy a URL that needs URI encoding to WC"
3615 sbox.build()
3616 wc_dir = sbox.wc_dir
3617 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
3618 expected_disk = svntest.main.greek_state.copy()
3620 def copy_URL_to_WC(URL_rel_path, dest_name, rev):
3621 lines = [
3622 "A " + os.path.join(wc_dir, dest_name, "B") + "\n",
3623 "A " + os.path.join(wc_dir, dest_name, "B", "lambda") + "\n",
3624 "A " + os.path.join(wc_dir, dest_name, "B", "E") + "\n",
3625 "A " + os.path.join(wc_dir, dest_name, "B", "E", "alpha") + "\n",
3626 "A " + os.path.join(wc_dir, dest_name, "B", "E", "beta") + "\n",
3627 "A " + os.path.join(wc_dir, dest_name, "B", "F") + "\n",
3628 "A " + os.path.join(wc_dir, dest_name, "mu") + "\n",
3629 "A " + os.path.join(wc_dir, dest_name, "C") + "\n",
3630 "A " + os.path.join(wc_dir, dest_name, "D") + "\n",
3631 "A " + os.path.join(wc_dir, dest_name, "D", "gamma") + "\n",
3632 "A " + os.path.join(wc_dir, dest_name, "D", "G") + "\n",
3633 "A " + os.path.join(wc_dir, dest_name, "D", "G", "pi") + "\n",
3634 "A " + os.path.join(wc_dir, dest_name, "D", "G", "rho") + "\n",
3635 "A " + os.path.join(wc_dir, dest_name, "D", "G", "tau") + "\n",
3636 "A " + os.path.join(wc_dir, dest_name, "D", "H") + "\n",
3637 "A " + os.path.join(wc_dir, dest_name, "D", "H", "chi") + "\n",
3638 "A " + os.path.join(wc_dir, dest_name, "D", "H", "omega") + "\n",
3639 "A " + os.path.join(wc_dir, dest_name, "D", "H", "psi") + "\n",
3640 "Checked out revision " + str(rev - 1) + ".\n",
3641 "A " + os.path.join(wc_dir, dest_name) + "\n"]
3642 expected = svntest.verify.UnorderedOutput(lines)
3643 expected_status.add({
3644 dest_name + "/B" : Item(status=' ', wc_rev=rev),
3645 dest_name + "/B/lambda" : Item(status=' ', wc_rev=rev),
3646 dest_name + "/B/E" : Item(status=' ', wc_rev=rev),
3647 dest_name + "/B/E/alpha" : Item(status=' ', wc_rev=rev),
3648 dest_name + "/B/E/beta" : Item(status=' ', wc_rev=rev),
3649 dest_name + "/B/F" : Item(status=' ', wc_rev=rev),
3650 dest_name + "/mu" : Item(status=' ', wc_rev=rev),
3651 dest_name + "/C" : Item(status=' ', wc_rev=rev),
3652 dest_name + "/D" : Item(status=' ', wc_rev=rev),
3653 dest_name + "/D/gamma" : Item(status=' ', wc_rev=rev),
3654 dest_name + "/D/G" : Item(status=' ', wc_rev=rev),
3655 dest_name + "/D/G/pi" : Item(status=' ', wc_rev=rev),
3656 dest_name + "/D/G/rho" : Item(status=' ', wc_rev=rev),
3657 dest_name + "/D/G/tau" : Item(status=' ', wc_rev=rev),
3658 dest_name + "/D/H" : Item(status=' ', wc_rev=rev),
3659 dest_name + "/D/H/chi" : Item(status=' ', wc_rev=rev),
3660 dest_name + "/D/H/omega" : Item(status=' ', wc_rev=rev),
3661 dest_name + "/D/H/psi" : Item(status=' ', wc_rev=rev),
3662 dest_name : Item(status=' ', wc_rev=rev)})
3663 expected_disk.add({
3664 dest_name : Item(props={}),
3665 dest_name + '/B' : Item(),
3666 dest_name + '/B/lambda' : Item("This is the file 'lambda'.\n"),
3667 dest_name + '/B/E' : Item(),
3668 dest_name + '/B/E/alpha' : Item("This is the file 'alpha'.\n"),
3669 dest_name + '/B/E/beta' : Item("This is the file 'beta'.\n"),
3670 dest_name + '/B/F' : Item(),
3671 dest_name + '/mu' : Item("This is the file 'mu'.\n"),
3672 dest_name + '/C' : Item(),
3673 dest_name + '/D' : Item(),
3674 dest_name + '/D/gamma' : Item("This is the file 'gamma'.\n"),
3675 dest_name + '/D/G' : Item(),
3676 dest_name + '/D/G/pi' : Item("This is the file 'pi'.\n"),
3677 dest_name + '/D/G/rho' : Item("This is the file 'rho'.\n"),
3678 dest_name + '/D/G/tau' : Item("This is the file 'tau'.\n"),
3679 dest_name + '/D/H' : Item(),
3680 dest_name + '/D/H/chi' : Item("This is the file 'chi'.\n"),
3681 dest_name + '/D/H/omega' : Item("This is the file 'omega'.\n"),
3682 dest_name + '/D/H/psi' : Item("This is the file 'psi'.\n"),
3685 # Make a copy
3686 svntest.actions.run_and_verify_svn(None, expected, [],
3687 'copy',
3688 sbox.repo_url + '/' + URL_rel_path,
3689 os.path.join(wc_dir,
3690 dest_name))
3692 expected_output = svntest.wc.State(wc_dir,
3693 {dest_name : Item(verb='Adding')})
3694 svntest.actions.run_and_verify_commit(wc_dir,
3695 expected_output,
3696 expected_status,
3697 None, wc_dir)
3699 copy_URL_to_WC('A', 'A COPY', 2)
3700 copy_URL_to_WC('A COPY', 'A_COPY_2', 3)
3702 #----------------------------------------------------------------------
3703 # Issue #3068: copy source parent may be unversioned
3704 def allow_unversioned_parent_for_copy_src(sbox):
3705 "copy wc in unversioned parent to other wc"
3707 sbox.build(read_only = True)
3708 wc_dir = sbox.wc_dir
3710 # Make the "other" working copy
3711 wc2_dir = sbox.add_wc_path('other')
3712 svntest.actions.duplicate_dir(wc_dir, wc2_dir)
3713 copy_to_path = os.path.join(wc_dir, 'A', 'copy_of_wc2')
3715 # Copy the wc-in-unversioned-parent working copy to our original wc.
3716 svntest.actions.run_and_verify_svn(None,
3717 None,
3719 'cp',
3720 wc2_dir,
3721 copy_to_path)
3724 ########################################################################
3725 # Run the tests
3728 # list all tests here, starting with None:
3729 test_list = [ None,
3730 basic_copy_and_move_files,
3731 receive_copy_in_update,
3732 resurrect_deleted_dir,
3733 no_copy_overwrites,
3734 no_wc_copy_overwrites,
3735 copy_modify_commit,
3736 copy_files_with_properties,
3737 copy_delete_commit,
3738 mv_and_revert_directory,
3739 SkipUnless(copy_preserve_executable_bit, svntest.main.is_posix_os),
3740 wc_to_repos,
3741 repos_to_wc,
3742 copy_to_root,
3743 url_copy_parent_into_child,
3744 wc_copy_parent_into_child,
3745 resurrect_deleted_file,
3746 diff_repos_to_wc_copy,
3747 repos_to_wc_copy_eol_keywords,
3748 revision_kinds_local_source,
3749 copy_over_missing_file,
3750 repos_to_wc_1634,
3751 double_uri_escaping_1814,
3752 wc_to_wc_copy_between_different_repos,
3753 wc_to_wc_copy_deleted,
3754 url_to_non_existent_url_path,
3755 non_existent_url_to_url,
3756 old_dir_url_to_url,
3757 wc_copy_dir_to_itself,
3758 mixed_wc_to_url,
3759 wc_copy_replacement,
3760 wc_copy_replace_with_props,
3761 repos_to_wc_copy_replacement,
3762 repos_to_wc_copy_replace_with_props,
3763 delete_replaced_file,
3764 mv_unversioned_file,
3765 force_move,
3766 copy_deleted_dir_into_prefix,
3767 copy_copied_file_and_dir,
3768 move_copied_file_and_dir,
3769 move_moved_file_and_dir,
3770 move_file_within_moved_dir,
3771 move_file_out_of_moved_dir,
3772 move_dir_within_moved_dir,
3773 move_dir_out_of_moved_dir,
3774 move_file_back_and_forth,
3775 move_dir_back_and_forth,
3776 copy_move_added_paths,
3777 XFail(copy_added_paths_with_props),
3778 copy_added_paths_to_URL,
3779 move_to_relative_paths,
3780 move_from_relative_paths,
3781 copy_to_relative_paths,
3782 copy_from_relative_paths,
3783 move_multiple_wc,
3784 copy_multiple_wc,
3785 move_multiple_repo,
3786 copy_multiple_repo,
3787 copy_multiple_repo_wc,
3788 copy_multiple_wc_repo,
3789 copy_peg_rev_local_files,
3790 copy_peg_rev_local_dirs,
3791 copy_peg_rev_url,
3792 old_dir_wc_to_wc,
3793 copy_make_parents_wc_wc,
3794 copy_make_parents_repo_wc,
3795 copy_make_parents_wc_repo,
3796 copy_make_parents_repo_repo,
3797 URI_encoded_repos_to_wc,
3798 allow_unversioned_parent_for_copy_src,
3801 if __name__ == '__main__':
3802 svntest.main.run_tests(test_list)
3803 # NOTREACHED
3806 ### End of file.