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 ######################################################################
20 import stat
, os
, re
, shutil
25 from svntest
.main
import SVN_PROP_MERGEINFO
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."""
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
57 pi_src
= os
.path
.join(wc_dir
, 'A', 'D', 'G', 'pi')
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
)
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,
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
,
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."""
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',
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())
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
,
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
140 pi_src
= os
.path
.join(wc_dir
, 'A', 'D', 'G', 'pi')
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
149 props
= { SVN_PROP_MERGEINFO
: '',
152 props
= { 'phony-prop' : '*'}
154 expected_disk
.tweak('A/D/G/rho',
155 contents
="This is the file 'pi'.\n",
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,
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
,
175 ######################################################################
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
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
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!)
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
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
247 #----------------------------------------------------------------------
249 def basic_copy_and_move_files(sbox
):
250 "basic copy and move commands -- on files only"
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',
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
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
,
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
,
328 # Assure that attempts at local copy and move fail when a log
329 # message is provided.
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"
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
,
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()
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
,
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
429 def resurrect_deleted_dir(sbox
):
430 "resurrect a deleted directory"
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',
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
,
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',
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
,
482 def copy_deleted_dir_into_prefix(sbox
):
483 "copy a deleted dir to a prefix of its old path"
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',
493 expected_output
= svntest
.wc
.State(wc_dir
, {
494 'A/D' : Item(verb
='Deleting'),
497 svntest
.actions
.run_and_verify_commit(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',
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"
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
,
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
,
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
,
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)
561 # File simply missing
562 tau_path
= os
.path
.join(wc_dir
, 'A', 'D', 'G', 'tau')
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"
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',
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
,
610 #----------------------------------------------------------------------
612 # Issue 591, at one point copying a file from URL to WC didn't copy
615 def copy_files_with_properties(sbox
):
616 "copy files with properties"
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
)
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
,
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
,
683 #----------------------------------------------------------------------
686 def copy_delete_commit(sbox
):
687 "copy a tree and delete part of it before commit"
691 B_path
= os
.path
.join(wc_dir
, 'A', 'B')
692 B2_path
= os
.path
.join(wc_dir
, 'A', 'B2')
695 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
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
,
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'))
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
,
734 #----------------------------------------------------------------------
735 def mv_and_revert_directory(sbox
):
736 "move and revert a directory"
738 sbox
.build(read_only
= True)
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',
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',
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"
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
]
791 print "setting svn:executable did not change file's permissions"
792 raise svntest
.Failure
795 svntest
.actions
.run_and_verify_svn(None, None, [], 'ci',
796 '-m', 'create file and set svn:executable',
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
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"
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'),
825 svntest
.actions
.run_and_verify_svn(None, None, [], 'propset', 'foo', 'bar',
829 svntest
.actions
.run_and_verify_svn(None, None, [], '-m', 'fumble file',
830 'copy', beta_path
, beta2_url
)
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")
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
,
874 # check local property was copied
875 svntest
.actions
.run_and_verify_svn(None, ['bar\n'], [],
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"
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)
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 exit_code
, out
, err
= svntest
.main
.run_svn(None, 'diff', pi_path
)
921 raise svntest
.Failure
923 if line
== '+zig\n': # Crude check for diff-like output
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
)
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
)
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)
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'
1013 wc_dir
= sbox
.wc_dir
1015 root
= sbox
.repo_url
1018 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
1022 # Update to HEAD, and check to see if the files really were copied in the
1025 expected_output
= svntest
.wc
.State(wc_dir
, {
1026 'mu': Item(status
='A '),
1029 expected_disk
= svntest
.main
.greek_state
.copy()
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
,
1044 #----------------------------------------------------------------------
1045 def url_copy_parent_into_child(sbox
):
1046 "copy URL URL/subdir"
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'], [],
1058 '-m', 'a can of worms',
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()
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
,
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"
1104 svntest
.main
.safe_rmtree(wc_dir
)
1105 svntest
.actions
.run_and_verify_svn(None, None, [],
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()
1115 svntest
.actions
.run_and_verify_svn(None,
1116 ['\n', 'Committed revision 2.\n'], [],
1118 '-m', 'a larger can',
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('', {
1134 'E/alpha' : Item("This is the file 'alpha'.\n"),
1135 'E/beta' : Item("This is the file 'beta'.\n"),
1137 'lambda' : Item("This is the file 'lambda'.\n"),
1140 'F/B/E/alpha' : Item("This is the file 'alpha'.\n"),
1141 'F/B/E/beta' : Item("This is the file 'beta'.\n"),
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
,
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"
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
,
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
)
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).
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",
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',
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
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()
1277 line_contents
= f
.readlines()
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
1290 def revision_kinds_local_source(sbox
):
1291 "revision-kind keywords with non-URL source"
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,
1304 svntest
.main
.file_append(mu_path
, "New r3 text.\n")
1305 svntest
.actions
.run_and_verify_commit(wc_dir
, expected_output
, None,
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
)
1329 svntest
.actions
.run_and_verify_svn(None, None, [], "copy",
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 exit_code
, output
, errput
= svntest
.main
.run_svn(None, "info", dst_path
)
1339 if line
.rstrip() == "Copied From Rev: " + str(from_rev
):
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.
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
,
1383 #----------------------------------------------------------------------
1384 # Regression test for issue 1634
1386 def repos_to_wc_1634(sbox
):
1387 "copy a deleted directory back from the repos"
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
,
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'
1436 svntest
.actions
.run_and_verify_svn(None, None, [],
1437 'mkdir', '-m', 'mybase',
1440 orig_url
= base_url
+ '/foo%20bar'
1443 svntest
.actions
.run_and_verify_svn(None, None, [],
1444 'mkdir', '-m', 'r1',
1449 new_url
= base_url
+ '/foo_bar'
1450 svntest
.actions
.run_and_verify_svn(None, None, [],
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
)),
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()
1472 wc2_dir
= sbox2
.wc_dir
1474 # Attempt a copy between different repositories.
1475 exit_code
, out
, err
= svntest
.main
.run_svn(1, 'cp',
1476 os
.path
.join(wc2_dir
, 'A'),
1477 os
.path
.join(wc_dir
, 'A', 'B'))
1479 if line
.find("it is not from repository") != -1:
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"
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 exit_code
, out
, err
= svntest
.main
.run_svn(1, 'cp',
1507 os
.path
.join(B_path
, 'E'),
1508 os
.path
.join(B_path
, 'F'))
1510 if line
.find("is scheduled for deletion") != -1:
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
,
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 exit_code
, out
, err
= svntest
.main
.run_svn(1, 'revert', '--recursive',
1546 os
.path
.join(B2_path
, 'F'))
1548 if line
.find("Error restoring text") != -1:
1551 raise svntest
.Failure
1552 exit_code
, out
, err
= svntest
.main
.run_svn(1, 'revert',
1553 os
.path
.join(B2_path
, 'lambda'))
1555 if line
.find("Error restoring text") != -1:
1558 raise svntest
.Failure
1559 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status
)
1561 # Revert the entire copy including the schedule delete bits
1562 svntest
.actions
.run_and_verify_svn(None, None, [], 'revert', '--recursive',
1564 expected_status
.remove('A/B2',
1570 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status
)
1571 svntest
.main
.safe_rmtree(B2_path
)
1573 # Copy again and commit
1574 svntest
.actions
.run_and_verify_svn(None, None, [], 'copy', B_path
, B2_path
)
1575 expected_status
.add({
1576 'A/B2' : Item(status
=' ', wc_rev
=3),
1577 'A/B2/E' : Item(status
=' ', wc_rev
=3),
1578 'A/B2/E/beta' : Item(status
=' ', wc_rev
=3),
1580 expected_output
= svntest
.wc
.State(wc_dir
, {
1581 'A/B2' : Item(verb
='Adding'),
1582 'A/B2/E/alpha' : Item(verb
='Deleting'),
1583 'A/B2/lambda' : Item(verb
='Deleting'),
1584 'A/B2/F' : Item(verb
='Deleting'),
1586 svntest
.actions
.run_and_verify_commit(wc_dir
,
1591 #----------------------------------------------------------------------
1592 # Test for copy into a non-existent URL path
1593 def url_to_non_existent_url_path(sbox
):
1594 "svn cp src-URL non-existent-URL-path"
1596 sbox
.build(create_wc
= False)
1598 dirURL1
= sbox
.repo_url
+ "/A/B/E"
1599 dirURL2
= sbox
.repo_url
+ "/G/C/E/I"
1601 # Look for both possible versions of the error message, as the DAV
1602 # error is worded differently from that of other RA layers.
1603 msg
= ".*: (Path 'G(/C/E)?' not present|.*G(/C/E)?' path not found)"
1605 # Expect failure on 'svn cp SRC DST' where one or more ancestor
1606 # directories of DST do not exist
1607 exit_code
, out
, err
= svntest
.main
.run_svn(1, 'cp', dirURL1
, dirURL2
,
1609 for err_line
in err
:
1610 if re
.match (msg
, err_line
):
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, [],
1633 svntest
.actions
.run_and_verify_svn(None, None, [],
1635 pi_url
+ '@1', new_url
,
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, [],
1654 # Copy a file to where the directory used to be
1655 svntest
.actions
.run_and_verify_svn(None, None, [],
1660 # Try copying a file that was in the deleted directory that is now a
1662 svntest
.actions
.run_and_verify_svn(None, None, [],
1664 pi_url
+ '@1', new_url
,
1669 #----------------------------------------------------------------------
1670 # Test fix for issue 2224 - copying wc dir to itself causes endless
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"
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
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.",
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')
1737 for line
in fp
.readlines():
1738 if re
.match("^Second modification to rho.", line
):
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.*",
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.
1832 wc_dir
= sbox
.wc_dir
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")
1840 expected_file_content
= [ "This is the file 'iota'.\n",
1844 # check for the new content
1845 file_handle
= file(file_path
, "r")
1846 modified_file_content
= file_handle
.readlines()
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",
1855 was_cwd
= os
.getcwd()
1858 svntest
.actions
.run_and_verify_svn(None, move_output
,
1864 # check for the new content
1865 file_handle
= file(os
.path
.join(wc_dir
, "dest"), "r")
1866 modified_file_content
= file_handle
.readlines()
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
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
,
1887 svntest
.actions
.run_and_verify_svn('Cat file', expected_file_content
, [],
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
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
,
1952 def move_copied_file_and_dir(sbox
):
1953 "move a copied file and dir"
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
,
2007 def move_moved_file_and_dir(sbox
):
2008 "move a moved file and dir"
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',
2059 svntest
.actions
.run_and_verify_commit(wc_dir
,
2066 def move_file_within_moved_dir(sbox
):
2067 "move a file twice within a moved dir"
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',
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',
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',
2128 svntest
.actions
.run_and_verify_commit(wc_dir
,
2135 def move_file_out_of_moved_dir(sbox
):
2136 "move a file out of a moved dir"
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',
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',
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',
2196 svntest
.actions
.run_and_verify_commit(wc_dir
,
2203 def move_dir_within_moved_dir(sbox
):
2204 "move a dir twice within a moved dir"
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',
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',
2264 svntest
.actions
.run_and_verify_commit(wc_dir
,
2271 def move_dir_out_of_moved_dir(sbox
):
2272 "move a dir out of a moved dir"
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',
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',
2331 svntest
.actions
.run_and_verify_commit(wc_dir
,
2337 def move_file_back_and_forth(sbox
):
2338 "move a moved file back to original location"
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
,
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
2387 exit_code
, out
, err
= svntest
.actions
.run_and_verify_svn(
2388 None, None, svntest
.verify
.AnyOutput
,
2389 'mv', D_move_path
, D_path
)
2392 if re
.match('.*Cannot copy to .*as it is scheduled for deletion',
2395 raise svntest
.Failure("mv failed but not in the expected way")
2398 def copy_move_added_paths(sbox
):
2399 "copy and move added paths without commits"
2402 wc_dir
= sbox
.wc_dir
2404 # Create a new file and schedule it for addition
2405 upsilon_path
= os
.path
.join(wc_dir
, 'A', 'D', 'upsilon')
2406 svntest
.main
.file_write(upsilon_path
, "This is the file 'upsilon'\n")
2407 svntest
.actions
.run_and_verify_svn(None, None, [], 'add', upsilon_path
)
2409 # Create a dir with children and schedule it for addition
2410 I_path
= os
.path
.join(wc_dir
, 'A', 'D', 'I')
2411 J_path
= os
.path
.join(I_path
, 'J')
2412 eta_path
= os
.path
.join(I_path
, 'eta')
2413 theta_path
= os
.path
.join(I_path
, 'theta')
2414 kappa_path
= os
.path
.join(J_path
, 'kappa')
2417 svntest
.main
.file_write(eta_path
, "This is the file 'eta'\n")
2418 svntest
.main
.file_write(theta_path
, "This is the file 'theta'\n")
2419 svntest
.main
.file_write(kappa_path
, "This is the file 'kappa'\n")
2420 svntest
.actions
.run_and_verify_svn(None, None, [], 'add', I_path
)
2422 # Create another dir and schedule it for addition
2423 K_path
= os
.path
.join(wc_dir
, 'K')
2425 svntest
.actions
.run_and_verify_svn(None, None, [], 'add', K_path
)
2427 # Verify all the adds took place correctly.
2428 expected_status_after_adds
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
2429 expected_status_after_adds
.add({
2430 'A/D/I' : Item(status
='A ', wc_rev
='0'),
2431 'A/D/I/eta' : Item(status
='A ', wc_rev
='0'),
2432 'A/D/I/J' : Item(status
='A ', wc_rev
='0'),
2433 'A/D/I/J/kappa' : Item(status
='A ', wc_rev
='0'),
2434 'A/D/I/theta' : Item(status
='A ', wc_rev
='0'),
2435 'A/D/upsilon' : Item(status
='A ', wc_rev
='0'),
2436 'K' : Item(status
='A ', wc_rev
='0'),
2438 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status_after_adds
)
2440 # Scatter some unversioned paths within the added dir I.
2441 unversioned_path_1
= os
.path
.join(I_path
, 'unversioned1')
2442 unversioned_path_2
= os
.path
.join(J_path
, 'unversioned2')
2443 L_path
= os
.path
.join(I_path
, "L_UNVERSIONED")
2444 unversioned_path_3
= os
.path
.join(L_path
, 'unversioned3')
2445 svntest
.main
.file_write(unversioned_path_1
, "An unversioned file\n")
2446 svntest
.main
.file_write(unversioned_path_2
, "An unversioned file\n")
2448 svntest
.main
.file_write(unversioned_path_3
, "An unversioned file\n")
2450 # Copy added dir A/D/I to added dir K/I
2451 I_copy_path
= os
.path
.join(K_path
, 'I')
2452 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
2453 I_path
, I_copy_path
)
2455 # Copy added file A/D/upsilon into added dir K
2456 upsilon_copy_path
= os
.path
.join(K_path
, 'upsilon')
2457 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
2458 upsilon_path
, upsilon_copy_path
)
2460 # Move added file A/D/upsilon to upsilon,
2461 # then move it again to A/upsilon
2462 upsilon_move_path
= os
.path
.join(wc_dir
, 'upsilon')
2463 upsilon_move_path_2
= os
.path
.join(wc_dir
, 'A', 'upsilon')
2464 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv',
2465 upsilon_path
, upsilon_move_path
)
2466 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv',
2467 upsilon_move_path
, upsilon_move_path_2
)
2469 # Move added dir A/D/I to A/B/I,
2470 # then move it again to A/D/H/I
2471 I_move_path
= os
.path
.join(wc_dir
, 'A', 'B', 'I')
2472 I_move_path_2
= os
.path
.join(wc_dir
, 'A', 'D', 'H', 'I')
2473 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv',
2474 I_path
, I_move_path
)
2475 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv',
2476 I_move_path
, I_move_path_2
)
2478 # Created expected output tree for 'svn ci'
2479 expected_output
= svntest
.wc
.State(wc_dir
, {
2480 'A/D/H/I' : Item(verb
='Adding'),
2481 'A/D/H/I/J' : Item(verb
='Adding'),
2482 'A/D/H/I/J/kappa' : Item(verb
='Adding'),
2483 'A/D/H/I/eta' : Item(verb
='Adding'),
2484 'A/D/H/I/theta' : Item(verb
='Adding'),
2485 'A/upsilon' : Item(verb
='Adding'),
2486 'K' : Item(verb
='Adding'),
2487 'K/I' : Item(verb
='Adding'),
2488 'K/I/J' : Item(verb
='Adding'),
2489 'K/I/J/kappa' : Item(verb
='Adding'),
2490 'K/I/eta' : Item(verb
='Adding'),
2491 'K/I/theta' : Item(verb
='Adding'),
2492 'K/upsilon' : Item(verb
='Adding'),
2495 # Create expected status tree
2496 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
2497 expected_status
.add({
2498 'A/D/H/I' : Item(status
=' ', wc_rev
=2),
2499 'A/D/H/I/J' : Item(status
=' ', wc_rev
=2),
2500 'A/D/H/I/J/kappa' : Item(status
=' ', wc_rev
=2),
2501 'A/D/H/I/eta' : Item(status
=' ', wc_rev
=2),
2502 'A/D/H/I/theta' : Item(status
=' ', wc_rev
=2),
2503 'A/upsilon' : Item(status
=' ', wc_rev
=2),
2504 'K' : Item(status
=' ', wc_rev
=2),
2505 'K/I' : Item(status
=' ', wc_rev
=2),
2506 'K/I/J' : Item(status
=' ', wc_rev
=2),
2507 'K/I/J/kappa' : Item(status
=' ', wc_rev
=2),
2508 'K/I/eta' : Item(status
=' ', wc_rev
=2),
2509 'K/I/theta' : Item(status
=' ', wc_rev
=2),
2510 'K/upsilon' : Item(status
=' ', wc_rev
=2),
2513 svntest
.actions
.run_and_verify_commit(wc_dir
,
2519 # Run_and_verify_commit() doesn't handle status of unversioned paths
2520 # so manually confirm unversioned paths got copied and moved too.
2521 unversioned_paths
= [
2522 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'I', 'unversioned1'),
2523 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'I', 'L_UNVERSIONED'),
2524 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'I', 'L_UNVERSIONED',
2526 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'I', 'J', 'unversioned2'),
2527 os
.path
.join(wc_dir
, 'K', 'I', 'unversioned1'),
2528 os
.path
.join(wc_dir
, 'K', 'I', 'L_UNVERSIONED'),
2529 os
.path
.join(wc_dir
, 'K', 'I', 'L_UNVERSIONED', 'unversioned3'),
2530 os
.path
.join(wc_dir
, 'K', 'I', 'J', 'unversioned2')]
2531 for path
in unversioned_paths
:
2532 if not os
.path
.exists(path
):
2533 raise svntest
.Failure("Unversioned path '%s' not found." % path
)
2535 def copy_added_paths_with_props(sbox
):
2536 "copy added uncommitted paths with props"
2539 wc_dir
= sbox
.wc_dir
2541 # Create a new file, schedule it for addition and set properties
2542 upsilon_path
= os
.path
.join(wc_dir
, 'A', 'D', 'upsilon')
2543 svntest
.main
.file_write(upsilon_path
, "This is the file 'upsilon'\n")
2544 svntest
.actions
.run_and_verify_svn(None, None, [], 'add', upsilon_path
)
2545 svntest
.actions
.run_and_verify_svn(None, None, [], 'propset',
2546 'foo', 'bar', upsilon_path
)
2548 # Create a dir and schedule it for addition and set properties
2549 I_path
= os
.path
.join(wc_dir
, 'A', 'D', 'I')
2551 svntest
.actions
.run_and_verify_svn(None, None, [], 'add', I_path
)
2552 svntest
.actions
.run_and_verify_svn(None, None, [], 'propset',
2553 'foo', 'bar', I_path
)
2555 # Verify all the adds took place correctly.
2556 expected_status_after_adds
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
2557 expected_status_after_adds
.add({
2558 'A/D/upsilon' : Item(status
='A ', wc_rev
='0'),
2559 'A/D/I' : Item(status
='A ', wc_rev
='0'),
2561 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status_after_adds
)
2563 expected_disk
= svntest
.main
.greek_state
.copy()
2565 'A/D/upsilon' : Item(props
={'foo' : 'bar'},
2566 contents
="This is the file 'upsilon'\n"),
2567 'A/D/I' : Item(props
={'foo' : 'bar'}),
2570 # Read disk state with props
2571 actual_disk_tree
= svntest
.tree
.build_tree_from_wc(wc_dir
, 1)
2573 # Compare actual vs. expected disk trees.
2574 svntest
.tree
.compare_trees("disk", actual_disk_tree
,
2575 expected_disk
.old_tree())
2577 # Copy added dir K to dir A/C
2578 I_copy_path
= os
.path
.join(wc_dir
, 'A', 'C', 'I')
2579 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
2580 I_path
, I_copy_path
)
2582 # Copy added file A/upsilon into dir A/C
2583 upsilon_copy_path
= os
.path
.join(wc_dir
, 'A', 'C', 'upsilon')
2584 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
2585 upsilon_path
, upsilon_copy_path
)
2587 # Created expected output tree for 'svn ci'
2588 expected_output
= svntest
.wc
.State(wc_dir
, {
2589 'A/D/upsilon' : Item(verb
='Adding'),
2590 'A/D/I' : Item(verb
='Adding'),
2591 'A/C/upsilon' : Item(verb
='Adding'),
2592 'A/C/I' : Item(verb
='Adding'),
2595 # Create expected status tree
2596 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
2597 expected_status
.add({
2598 'A/D/upsilon' : Item(status
=' ', wc_rev
=2),
2599 'A/D/I' : Item(status
=' ', wc_rev
=2),
2600 'A/C/upsilon' : Item(status
=' ', wc_rev
=2),
2601 'A/C/I' : Item(status
=' ', wc_rev
=2),
2604 # Tweak expected disk tree
2606 'A/C/upsilon' : Item(props
={'foo' : 'bar'},
2607 contents
="This is the file 'upsilon'\n"),
2608 'A/C/I' : Item(props
={'foo' : 'bar'}),
2611 svntest
.actions
.run_and_verify_commit(wc_dir
,
2616 # Read disk state with props
2617 actual_disk_tree
= svntest
.tree
.build_tree_from_wc(wc_dir
, 1)
2619 # Compare actual vs. expected disk trees.
2620 svntest
.tree
.compare_trees("disk", actual_disk_tree
,
2621 expected_disk
.old_tree())
2623 def copy_added_paths_to_URL(sbox
):
2624 "copy added path to URL"
2627 wc_dir
= sbox
.wc_dir
2629 # Create a new file and schedule it for addition
2630 upsilon_path
= os
.path
.join(wc_dir
, 'A', 'D', 'upsilon')
2631 svntest
.main
.file_write(upsilon_path
, "This is the file 'upsilon'\n")
2632 svntest
.actions
.run_and_verify_svn(None, None, [], 'add', upsilon_path
)
2634 # Create a dir with children and schedule it for addition
2635 I_path
= os
.path
.join(wc_dir
, 'A', 'D', 'I')
2636 J_path
= os
.path
.join(I_path
, 'J')
2637 eta_path
= os
.path
.join(I_path
, 'eta')
2638 theta_path
= os
.path
.join(I_path
, 'theta')
2639 kappa_path
= os
.path
.join(J_path
, 'kappa')
2642 svntest
.main
.file_write(eta_path
, "This is the file 'eta'\n")
2643 svntest
.main
.file_write(theta_path
, "This is the file 'theta'\n")
2644 svntest
.main
.file_write(kappa_path
, "This is the file 'kappa'\n")
2645 svntest
.actions
.run_and_verify_svn(None, None, [], 'add', I_path
)
2647 # Verify all the adds took place correctly.
2648 expected_status_after_adds
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
2649 expected_status_after_adds
.add({
2650 'A/D/I' : Item(status
='A ', wc_rev
='0'),
2651 'A/D/I/eta' : Item(status
='A ', wc_rev
='0'),
2652 'A/D/I/J' : Item(status
='A ', wc_rev
='0'),
2653 'A/D/I/J/kappa' : Item(status
='A ', wc_rev
='0'),
2654 'A/D/I/theta' : Item(status
='A ', wc_rev
='0'),
2655 'A/D/upsilon' : Item(status
='A ', wc_rev
='0'),
2657 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status_after_adds
)
2659 # Scatter some unversioned paths within the added dir I.
2660 # These don't get copied in a WC->URL copy obviously.
2661 unversioned_path_1
= os
.path
.join(I_path
, 'unversioned1')
2662 unversioned_path_2
= os
.path
.join(J_path
, 'unversioned2')
2663 L_path
= os
.path
.join(I_path
, "L_UNVERSIONED")
2664 unversioned_path_3
= os
.path
.join(L_path
, 'unversioned3')
2665 svntest
.main
.file_write(unversioned_path_1
, "An unversioned file\n")
2666 svntest
.main
.file_write(unversioned_path_2
, "An unversioned file\n")
2668 svntest
.main
.file_write(unversioned_path_3
, "An unversioned file\n")
2670 # Copy added file A/D/upsilon to URL://A/C/upsilon
2671 upsilon_copy_URL
= sbox
.repo_url
+ '/A/C/upsilon'
2672 svntest
.actions
.run_and_verify_svn(None, None, [],
2674 upsilon_path
, upsilon_copy_URL
)
2676 # Validate the merge info of the copy destination (we expect none).
2677 svntest
.actions
.run_and_verify_svn(None, [], [],
2679 SVN_PROP_MERGEINFO
, upsilon_copy_URL
)
2681 # Copy added dir A/D/I to URL://A/D/G/I
2682 I_copy_URL
= sbox
.repo_url
+ '/A/D/G/I'
2683 svntest
.actions
.run_and_verify_svn(None, None, [],
2687 # Created expected output tree for 'svn ci'
2688 expected_output
= svntest
.wc
.State(wc_dir
, {
2689 'A/D/I' : Item(verb
='Adding'),
2690 'A/D/I/J' : Item(verb
='Adding'),
2691 'A/D/I/J/kappa' : Item(verb
='Adding'),
2692 'A/D/I/eta' : Item(verb
='Adding'),
2693 'A/D/I/theta' : Item(verb
='Adding'),
2694 'A/D/upsilon' : Item(verb
='Adding'),
2697 # Create expected status tree
2698 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
2699 expected_status
.add({
2700 'A/D/I' : Item(status
=' ', wc_rev
=4),
2701 'A/D/I/J' : Item(status
=' ', wc_rev
=4),
2702 'A/D/I/J/kappa' : Item(status
=' ', wc_rev
=4),
2703 'A/D/I/eta' : Item(status
=' ', wc_rev
=4),
2704 'A/D/I/theta' : Item(status
=' ', wc_rev
=4),
2705 'A/D/upsilon' : Item(status
=' ', wc_rev
=4),
2708 svntest
.actions
.run_and_verify_commit(wc_dir
,
2714 # Created expected output for update
2715 expected_output
= svntest
.wc
.State(wc_dir
, {
2716 'A/D/G/I' : Item(status
='A '),
2717 'A/D/G/I/theta' : Item(status
='A '),
2718 'A/D/G/I/J' : Item(status
='A '),
2719 'A/D/G/I/J/kappa' : Item(status
='A '),
2720 'A/D/G/I/eta' : Item(status
='A '),
2721 'A/C/upsilon' : Item(status
='A '),
2724 # Created expected disk for update
2725 expected_disk
= svntest
.main
.greek_state
.copy()
2728 'A/D/G/I/theta' : Item("This is the file 'theta'\n"),
2729 'A/D/G/I/J' : Item(),
2730 'A/D/G/I/J/kappa' : Item("This is the file 'kappa'\n"),
2731 'A/D/G/I/eta' : Item("This is the file 'eta'\n"),
2732 'A/C/upsilon' : Item("This is the file 'upsilon'\n"),
2735 'A/D/I/J/kappa' : Item("This is the file 'kappa'\n"),
2736 'A/D/I/eta' : Item("This is the file 'eta'\n"),
2737 'A/D/I/theta' : Item("This is the file 'theta'\n"),
2738 'A/D/upsilon' : Item("This is the file 'upsilon'\n"),
2739 'A/D/I/L_UNVERSIONED/unversioned3' : Item("An unversioned file\n"),
2740 'A/D/I/L_UNVERSIONED' : Item(),
2741 'A/D/I/unversioned1' : Item("An unversioned file\n"),
2742 'A/D/I/J/unversioned2' : Item("An unversioned file\n"),
2745 # Some more changes to the expected_status to reflect post update WC
2746 expected_status
.tweak(wc_rev
=4)
2747 expected_status
.add({
2748 'A/C' : Item(status
=' ', wc_rev
=4),
2749 'A/C/upsilon' : Item(status
=' ', wc_rev
=4),
2750 'A/D/G' : Item(status
=' ', wc_rev
=4),
2751 'A/D/G/I' : Item(status
=' ', wc_rev
=4),
2752 'A/D/G/I/theta' : Item(status
=' ', wc_rev
=4),
2753 'A/D/G/I/J' : Item(status
=' ', wc_rev
=4),
2754 'A/D/G/I/J/kappa' : Item(status
=' ', wc_rev
=4),
2755 'A/D/G/I/eta' : Item(status
=' ', wc_rev
=4),
2758 # Update WC, the WC->URL copies above should be added
2759 svntest
.actions
.run_and_verify_update(wc_dir
,
2766 def move_to_relative_paths(sbox
):
2767 "move file using relative dst path names"
2770 wc_dir
= sbox
.wc_dir
2771 E_path
= os
.path
.join(wc_dir
, 'A', 'B', 'E')
2772 rel_path
= os
.path
.join('..', '..', '..')
2774 current_dir
= os
.getcwd()
2776 svntest
.main
.run_svn(None, 'mv', 'beta', rel_path
)
2777 os
.chdir(current_dir
)
2779 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
2780 expected_status
.add({
2781 'beta' : Item(status
='A ', copied
='+', wc_rev
='-'),
2782 'A/B/E/beta' : Item(status
='D ', wc_rev
='1')
2784 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status
)
2787 #----------------------------------------------------------------------
2788 def move_from_relative_paths(sbox
):
2789 "move file using relative src path names"
2791 sbox
.build(read_only
= True)
2792 wc_dir
= sbox
.wc_dir
2793 F_path
= os
.path
.join(wc_dir
, 'A', 'B', 'F')
2794 beta_rel_path
= os
.path
.join('..', 'E', 'beta')
2796 current_dir
= os
.getcwd()
2798 svntest
.main
.run_svn(None, 'mv', beta_rel_path
, '.')
2799 os
.chdir(current_dir
)
2801 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
2802 expected_status
.add({
2803 'A/B/F/beta' : Item(status
='A ', copied
='+', wc_rev
='-'),
2804 'A/B/E/beta' : Item(status
='D ', wc_rev
='1')
2806 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status
)
2809 #----------------------------------------------------------------------
2810 def copy_to_relative_paths(sbox
):
2811 "copy file using relative dst path names"
2813 sbox
.build(read_only
= True)
2814 wc_dir
= sbox
.wc_dir
2815 E_path
= os
.path
.join(wc_dir
, 'A', 'B', 'E')
2816 rel_path
= os
.path
.join('..', '..', '..')
2818 current_dir
= os
.getcwd()
2820 svntest
.main
.run_svn(None, 'cp', 'beta', rel_path
)
2821 os
.chdir(current_dir
)
2823 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
2824 expected_status
.add({
2825 'beta' : Item(status
='A ', copied
='+', wc_rev
='-'),
2827 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status
)
2830 #----------------------------------------------------------------------
2831 def copy_from_relative_paths(sbox
):
2832 "copy file using relative src path names"
2834 sbox
.build(read_only
= True)
2835 wc_dir
= sbox
.wc_dir
2836 F_path
= os
.path
.join(wc_dir
, 'A', 'B', 'F')
2837 beta_rel_path
= os
.path
.join('..', 'E', 'beta')
2839 current_dir
= os
.getcwd()
2841 svntest
.main
.run_svn(None, 'cp', beta_rel_path
, '.')
2842 os
.chdir(current_dir
)
2844 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
2845 expected_status
.add({
2846 'A/B/F/beta' : Item(status
='A ', copied
='+', wc_rev
='-'),
2848 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status
)
2851 #----------------------------------------------------------------------
2853 # Test moving multiple files within a wc.
2855 def move_multiple_wc(sbox
):
2856 "svn mv multiple files to a common directory"
2859 wc_dir
= sbox
.wc_dir
2861 chi_path
= os
.path
.join(wc_dir
, 'A', 'D', 'H', 'chi')
2862 psi_path
= os
.path
.join(wc_dir
, 'A', 'D', 'H', 'psi')
2863 omega_path
= os
.path
.join(wc_dir
, 'A', 'D', 'H', 'omega')
2864 E_path
= os
.path
.join(wc_dir
, 'A', 'B', 'E')
2865 C_path
= os
.path
.join(wc_dir
, 'A', 'C')
2867 # Move chi, psi, omega and E to A/C
2868 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv', chi_path
, psi_path
,
2869 omega_path
, E_path
, C_path
)
2871 # Create expected output
2872 expected_output
= svntest
.wc
.State(wc_dir
, {
2873 'A/C/chi' : Item(verb
='Adding'),
2874 'A/C/psi' : Item(verb
='Adding'),
2875 'A/C/omega' : Item(verb
='Adding'),
2876 'A/C/E' : Item(verb
='Adding'),
2877 'A/D/H/chi' : Item(verb
='Deleting'),
2878 'A/D/H/psi' : Item(verb
='Deleting'),
2879 'A/D/H/omega' : Item(verb
='Deleting'),
2880 'A/B/E' : Item(verb
='Deleting'),
2883 # Create expected status tree
2884 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
2886 # Add the moved files
2887 expected_status
.add({
2888 'A/C/chi' : Item(status
=' ', wc_rev
=2),
2889 'A/C/psi' : Item(status
=' ', wc_rev
=2),
2890 'A/C/omega' : Item(status
=' ', wc_rev
=2),
2891 'A/C/E' : Item(status
=' ', wc_rev
=2),
2892 'A/C/E/alpha' : Item(status
=' ', wc_rev
=2),
2893 'A/C/E/beta' : Item(status
=' ', wc_rev
=2),
2896 # Removed the moved files
2897 expected_status
.remove('A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega', 'A/B/E/alpha',
2898 'A/B/E/beta', 'A/B/E')
2900 svntest
.actions
.run_and_verify_commit(wc_dir
,
2906 #----------------------------------------------------------------------
2908 # Test copying multiple files within a wc.
2910 def copy_multiple_wc(sbox
):
2911 "svn cp multiple files to a common directory"
2914 wc_dir
= sbox
.wc_dir
2916 chi_path
= os
.path
.join(wc_dir
, 'A', 'D', 'H', 'chi')
2917 psi_path
= os
.path
.join(wc_dir
, 'A', 'D', 'H', 'psi')
2918 omega_path
= os
.path
.join(wc_dir
, 'A', 'D', 'H', 'omega')
2919 E_path
= os
.path
.join(wc_dir
, 'A', 'B', 'E')
2920 C_path
= os
.path
.join(wc_dir
, 'A', 'C')
2922 # Copy chi, psi, omega and E to A/C
2923 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp', chi_path
, psi_path
,
2924 omega_path
, E_path
, C_path
)
2926 # Create expected output
2927 expected_output
= svntest
.wc
.State(wc_dir
, {
2928 'A/C/chi' : Item(verb
='Adding'),
2929 'A/C/psi' : Item(verb
='Adding'),
2930 'A/C/omega' : Item(verb
='Adding'),
2931 'A/C/E' : Item(verb
='Adding'),
2934 # Create expected status tree
2935 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
2937 # Add the moved files
2938 expected_status
.add({
2939 'A/C/chi' : Item(status
=' ', wc_rev
=2),
2940 'A/C/psi' : Item(status
=' ', wc_rev
=2),
2941 'A/C/omega' : Item(status
=' ', wc_rev
=2),
2942 'A/C/E' : Item(status
=' ', wc_rev
=2),
2943 'A/C/E/alpha' : Item(status
=' ', wc_rev
=2),
2944 'A/C/E/beta' : Item(status
=' ', wc_rev
=2),
2947 svntest
.actions
.run_and_verify_commit(wc_dir
,
2953 #----------------------------------------------------------------------
2955 # Test moving multiple files within a repo.
2957 def move_multiple_repo(sbox
):
2958 "move multiple files within a repo"
2961 wc_dir
= sbox
.wc_dir
2963 chi_url
= sbox
.repo_url
+ '/A/D/H/chi'
2964 psi_url
= sbox
.repo_url
+ '/A/D/H/psi'
2965 omega_url
= sbox
.repo_url
+ '/A/D/H/omega'
2966 E_url
= sbox
.repo_url
+ '/A/B/E'
2967 C_url
= sbox
.repo_url
+ '/A/C'
2969 # Move three files and a directory in the repo to a different location
2971 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv',
2972 chi_url
, psi_url
, omega_url
, E_url
, C_url
,
2975 # Update to HEAD, and check to see if the files really moved in the repo
2977 expected_output
= svntest
.wc
.State(wc_dir
, {
2978 'A/C/chi' : Item(status
='A '),
2979 'A/C/psi' : Item(status
='A '),
2980 'A/C/omega' : Item(status
='A '),
2981 'A/C/E' : Item(status
='A '),
2982 'A/C/E/alpha' : Item(status
='A '),
2983 'A/C/E/beta' : Item(status
='A '),
2984 'A/D/H/chi' : Item(status
='D '),
2985 'A/D/H/psi' : Item(status
='D '),
2986 'A/D/H/omega' : Item(status
='D '),
2987 'A/B/E' : Item(status
='D '),
2990 expected_disk
= svntest
.main
.greek_state
.copy()
2991 expected_disk
.remove('A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega', 'A/B/E/alpha',
2992 'A/B/E/beta', 'A/B/E')
2994 'A/C/chi' : Item(contents
="This is the file 'chi'.\n"),
2995 'A/C/psi' : Item(contents
="This is the file 'psi'.\n"),
2996 'A/C/omega' : Item(contents
="This is the file 'omega'.\n"),
2998 'A/C/E/alpha' : Item(contents
="This is the file 'alpha'.\n"),
2999 'A/C/E/beta' : Item(contents
="This is the file 'beta'.\n"),
3002 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 2)
3003 expected_status
.remove('A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega', 'A/B/E/alpha',
3004 'A/B/E/beta', 'A/B/E')
3005 expected_status
.add({
3006 'A/C/chi' : Item(status
=' ', wc_rev
=2),
3007 'A/C/psi' : Item(status
=' ', wc_rev
=2),
3008 'A/C/omega' : Item(status
=' ', wc_rev
=2),
3009 'A/C/E' : Item(status
=' ', wc_rev
=2),
3010 'A/C/E/alpha' : Item(status
=' ', wc_rev
=2),
3011 'A/C/E/beta' : Item(status
=' ', wc_rev
=2),
3014 svntest
.actions
.run_and_verify_update(wc_dir
,
3019 #----------------------------------------------------------------------
3021 # Test copying multiple files within a repo.
3023 def copy_multiple_repo(sbox
):
3024 "copy multiple files within a repo"
3027 wc_dir
= sbox
.wc_dir
3029 chi_url
= sbox
.repo_url
+ '/A/D/H/chi'
3030 psi_url
= sbox
.repo_url
+ '/A/D/H/psi'
3031 omega_url
= sbox
.repo_url
+ '/A/D/H/omega'
3032 E_url
= sbox
.repo_url
+ '/A/B/E'
3033 C_url
= sbox
.repo_url
+ '/A/C'
3035 # Copy three files and a directory in the repo to a different location
3037 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
3038 chi_url
, psi_url
, omega_url
, E_url
, C_url
,
3041 # Update to HEAD, and check to see if the files really moved in the repo
3043 expected_output
= svntest
.wc
.State(wc_dir
, {
3044 'A/C/chi' : Item(status
='A '),
3045 'A/C/psi' : Item(status
='A '),
3046 'A/C/omega' : Item(status
='A '),
3047 'A/C/E' : Item(status
='A '),
3048 'A/C/E/alpha' : Item(status
='A '),
3049 'A/C/E/beta' : Item(status
='A '),
3052 expected_disk
= svntest
.main
.greek_state
.copy()
3054 'A/C/chi' : Item(contents
="This is the file 'chi'.\n"),
3055 'A/C/psi' : Item(contents
="This is the file 'psi'.\n"),
3056 'A/C/omega' : Item(contents
="This is the file 'omega'.\n"),
3058 'A/C/E/alpha' : Item(contents
="This is the file 'alpha'.\n"),
3059 'A/C/E/beta' : Item(contents
="This is the file 'beta'.\n"),
3062 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 2)
3063 expected_status
.add({
3064 'A/C/chi' : Item(status
=' ', wc_rev
=2),
3065 'A/C/psi' : Item(status
=' ', wc_rev
=2),
3066 'A/C/omega' : Item(status
=' ', wc_rev
=2),
3067 'A/C/E' : Item(status
=' ', wc_rev
=2),
3068 'A/C/E/alpha' : Item(status
=' ', wc_rev
=2),
3069 'A/C/E/beta' : Item(status
=' ', wc_rev
=2),
3072 svntest
.actions
.run_and_verify_update(wc_dir
,
3077 #----------------------------------------------------------------------
3079 # Test moving copying multiple files from a repo to a wc
3081 def copy_multiple_repo_wc(sbox
):
3082 "copy multiple files from a repo to a wc"
3085 wc_dir
= sbox
.wc_dir
3087 chi_url
= sbox
.repo_url
+ '/A/D/H/chi'
3088 psi_url
= sbox
.repo_url
+ '/A/D/H/psi'
3089 omega_with_space_url
= sbox
.repo_url
+ '/A/D/H/omega 2'
3090 E_url
= sbox
.repo_url
+ '/A/B/E'
3091 C_path
= os
.path
.join(wc_dir
, 'A', 'C')
3093 # We need this in order to check that we don't end up with URI-encoded
3094 # paths in the WC (issue #2955)
3095 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv', '-m', 'log_msg',
3096 sbox
.repo_url
+ '/A/D/H/omega',
3097 omega_with_space_url
)
3099 # Perform the copy and check the output
3100 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
3101 chi_url
, psi_url
, omega_with_space_url
,
3104 # Commit the changes, and verify the content actually got copied
3105 expected_output
= svntest
.wc
.State(wc_dir
, {
3106 'A/C/chi' : Item(verb
='Adding'),
3107 'A/C/psi' : Item(verb
='Adding'),
3108 'A/C/omega 2' : Item(verb
='Adding'),
3109 'A/C/E' : Item(verb
='Adding'),
3112 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
3113 expected_status
.add({
3114 'A/C/chi' : Item(status
=' ', wc_rev
=3),
3115 'A/C/psi' : Item(status
=' ', wc_rev
=3),
3116 'A/C/omega 2' : Item(status
=' ', wc_rev
=3),
3117 'A/C/E' : Item(status
=' ', wc_rev
=3),
3118 'A/C/E/alpha' : Item(status
=' ', wc_rev
=3),
3119 'A/C/E/beta' : Item(status
=' ', wc_rev
=3),
3122 svntest
.actions
.run_and_verify_commit(wc_dir
,
3127 #----------------------------------------------------------------------
3129 # Test moving copying multiple files from a wc to a repo
3131 def copy_multiple_wc_repo(sbox
):
3132 "copy multiple files from a wc to a repo"
3135 wc_dir
= sbox
.wc_dir
3137 chi_path
= os
.path
.join(wc_dir
, 'A', 'D', 'H', 'chi')
3138 psi_path
= os
.path
.join(wc_dir
, 'A', 'D', 'H', 'psi')
3139 omega_path
= os
.path
.join(wc_dir
, 'A', 'D', 'H', 'omega')
3140 E_path
= os
.path
.join(wc_dir
, 'A', 'B', 'E')
3141 C_url
= sbox
.repo_url
+ '/A/C'
3143 # Perform the copy and check the output
3144 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
3145 chi_path
, psi_path
, omega_path
, E_path
,
3146 C_url
, '-m', 'logmsg')
3148 # Update to HEAD, and check to see if the files really got copied in the repo
3150 expected_output
= svntest
.wc
.State(wc_dir
, {
3151 'A/C/chi' : Item(status
='A '),
3152 'A/C/psi' : Item(status
='A '),
3153 'A/C/omega' : Item(status
='A '),
3154 'A/C/E' : Item(status
='A '),
3155 'A/C/E/alpha' : Item(status
='A '),
3156 'A/C/E/beta' : Item(status
='A '),
3159 expected_disk
= svntest
.main
.greek_state
.copy()
3161 'A/C/chi': Item(contents
="This is the file 'chi'.\n"),
3162 'A/C/psi': Item(contents
="This is the file 'psi'.\n"),
3163 'A/C/omega': Item(contents
="This is the file 'omega'.\n"),
3165 'A/C/E/alpha' : Item(contents
="This is the file 'alpha'.\n"),
3166 'A/C/E/beta' : Item(contents
="This is the file 'beta'.\n"),
3169 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 2)
3170 expected_status
.add({
3171 'A/C/chi' : Item(status
=' ', wc_rev
=2),
3172 'A/C/psi' : Item(status
=' ', wc_rev
=2),
3173 'A/C/omega' : Item(status
=' ', wc_rev
=2),
3174 'A/C/E' : Item(status
=' ', wc_rev
=2),
3175 'A/C/E/alpha' : Item(status
=' ', wc_rev
=2),
3176 'A/C/E/beta' : Item(status
=' ', wc_rev
=2),
3179 svntest
.actions
.run_and_verify_update(wc_dir
,
3184 #----------------------------------------------------------------------
3186 # Test copying local files using peg revision syntax
3188 def copy_peg_rev_local_files(sbox
):
3189 "copy local files using peg rev syntax"
3192 wc_dir
= sbox
.wc_dir
3194 psi_path
= os
.path
.join(wc_dir
, 'A', 'D', 'H', 'psi')
3195 new_iota_path
= os
.path
.join(wc_dir
, 'new_iota')
3196 iota_path
= os
.path
.join(wc_dir
, 'iota')
3197 sigma_path
= os
.path
.join(wc_dir
, 'sigma')
3199 psi_text
= "This is the file 'psi'.\n"
3200 iota_text
= "This is the file 'iota'.\n"
3202 # Play a shell game with some WC files, then commit the changes back
3203 # to the repository (making r2).
3204 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv',
3205 psi_path
, new_iota_path
)
3206 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv',
3207 iota_path
, psi_path
)
3208 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv',
3209 new_iota_path
, iota_path
)
3211 svntest
.actions
.run_and_verify_svn(None, None, [],
3216 # Copy using a peg rev (remember, the object at iota_path at HEAD
3217 # was at psi_path back at r1).
3218 svntest
.actions
.run_and_verify_svn(None, None, [],
3220 iota_path
+ '@HEAD', '-r', '1',
3223 # Commit and verify disk contents
3224 svntest
.actions
.run_and_verify_svn(None, None, [],
3228 expected_disk
= svntest
.main
.greek_state
.copy()
3229 expected_disk
.tweak('A/D/H/psi', contents
=iota_text
)
3231 'iota' : Item(contents
=psi_text
, props
={SVN_PROP_MERGEINFO
: ''}),
3232 'A/D/H/psi' : Item(contents
=iota_text
, props
={SVN_PROP_MERGEINFO
: ''}),
3233 'sigma' : Item(contents
=psi_text
, props
={}),
3236 actual_disk
= svntest
.tree
.build_tree_from_wc(wc_dir
, 3)
3237 svntest
.tree
.compare_trees("disk", actual_disk
, expected_disk
.old_tree())
3240 #----------------------------------------------------------------------
3242 # Test copying local directories using peg revision syntax
3244 def copy_peg_rev_local_dirs(sbox
):
3245 "copy local dirs using peg rev syntax"
3248 wc_dir
= sbox
.wc_dir
3250 E_path
= os
.path
.join(wc_dir
, 'A', 'B', 'E')
3251 G_path
= os
.path
.join(wc_dir
, 'A', 'D', 'G')
3252 I_path
= os
.path
.join(wc_dir
, 'A', 'D', 'I')
3253 J_path
= os
.path
.join(wc_dir
, 'A', 'J')
3254 alpha_path
= os
.path
.join(E_path
, 'alpha')
3256 # Make some changes to the repository
3257 svntest
.actions
.run_and_verify_svn(None, None, [], 'rm',
3259 svntest
.actions
.run_and_verify_svn(None, None, [],
3263 svntest
.actions
.run_and_verify_svn(None, None, [], 'up', wc_dir
)
3265 svntest
.actions
.run_and_verify_svn(None, None, [],
3268 svntest
.actions
.run_and_verify_svn(None, None, [],
3273 svntest
.actions
.run_and_verify_svn(None, None, [],
3276 svntest
.actions
.run_and_verify_svn(None, None, [],
3281 svntest
.actions
.run_and_verify_svn(None, None, [],
3284 svntest
.actions
.run_and_verify_svn(None, None, [],
3289 # Copy using a peg rev
3290 svntest
.actions
.run_and_verify_svn(None, None, [],
3292 G_path
+ '@HEAD', '-r', '1',
3295 # Commit and verify disk contents
3296 svntest
.actions
.run_and_verify_svn(None, None, [],
3300 expected_disk
= svntest
.main
.greek_state
.copy()
3301 expected_disk
.remove('A/B/E/beta')
3302 expected_disk
.remove('A/B/E/alpha')
3303 expected_disk
.remove('A/D/G/pi')
3304 expected_disk
.remove('A/D/G/rho')
3305 expected_disk
.remove('A/D/G/tau')
3307 'A/B/E' : Item(props
={SVN_PROP_MERGEINFO
: ''}),
3308 'A/B/E/pi' : Item(contents
="This is the file 'pi'.\n"),
3309 'A/B/E/rho' : Item(contents
="This is the file 'rho'.\n"),
3310 'A/B/E/tau' : Item(contents
="This is the file 'tau'.\n"),
3311 'A/D/G' : Item(props
={SVN_PROP_MERGEINFO
: ''}),
3312 'A/D/G/beta' : Item(contents
="This is the file 'beta'.\n"),
3313 'A/J' : Item(props
={}),
3314 'A/J/alpha' : Item(contents
="This is the file 'alpha'.\n"),
3315 'A/J/beta' : Item(contents
="This is the file 'beta'.\n"),
3318 actual_disk
= svntest
.tree
.build_tree_from_wc(wc_dir
, 5)
3319 svntest
.tree
.compare_trees("disk", actual_disk
, expected_disk
.old_tree())
3322 #----------------------------------------------------------------------
3324 # Test copying urls using peg revision syntax
3326 def copy_peg_rev_url(sbox
):
3327 "copy urls using peg rev syntax"
3330 wc_dir
= sbox
.wc_dir
3332 psi_path
= os
.path
.join(wc_dir
, 'A', 'D', 'H', 'psi')
3333 new_iota_path
= os
.path
.join(wc_dir
, 'new_iota')
3334 iota_path
= os
.path
.join(wc_dir
, 'iota')
3335 iota_url
= sbox
.repo_url
+ '/iota'
3336 sigma_url
= sbox
.repo_url
+ '/sigma'
3338 psi_text
= "This is the file 'psi'.\n"
3339 iota_text
= "This is the file 'iota'.\n"
3341 # Make some changes to the repository
3342 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv',
3343 psi_path
, new_iota_path
)
3344 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv',
3345 iota_path
, psi_path
)
3346 svntest
.actions
.run_and_verify_svn(None, None, [], 'mv',
3347 new_iota_path
, iota_path
)
3349 svntest
.actions
.run_and_verify_svn(None, None, [],
3354 # Copy using a peg rev
3355 svntest
.actions
.run_and_verify_svn(None, None, [],
3357 iota_url
+ '@HEAD', '-r', '1',
3358 sigma_url
, '-m', 'rev 3')
3360 # Validate the copy destination's mergeinfo (we expect none).
3361 svntest
.actions
.run_and_verify_svn(None, [], [],
3362 'propget', SVN_PROP_MERGEINFO
, sigma_url
)
3364 # Update to HEAD and verify disk contents
3365 expected_output
= svntest
.wc
.State(wc_dir
, {
3366 'sigma' : Item(status
='A '),
3369 expected_disk
= svntest
.main
.greek_state
.copy()
3370 expected_disk
.tweak('iota', contents
=psi_text
)
3371 expected_disk
.tweak('A/D/H/psi', contents
=iota_text
)
3373 'sigma' : Item(contents
=psi_text
),
3376 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 3)
3377 expected_status
.add({
3378 'sigma' : Item(status
=' ', wc_rev
=3)
3381 svntest
.actions
.run_and_verify_update(wc_dir
,
3386 # Test copying an older revision of a wc directory in the wc.
3387 def old_dir_wc_to_wc(sbox
):
3388 "copy old revision of wc dir to new dir"
3391 wc_dir
= sbox
.wc_dir
3393 E
= os
.path
.join(wc_dir
, 'A', 'B', 'E')
3394 E2
= os
.path
.join(wc_dir
, 'E2')
3395 E_url
= sbox
.repo_url
+ '/A/B/E'
3396 alpha_url
= E_url
+ '/alpha'
3398 # delete E/alpha in r2
3399 svntest
.actions
.run_and_verify_svn(None, None, [],
3400 'rm', '-m', '', alpha_url
)
3403 svntest
.actions
.run_and_verify_svn(None, None, [],
3404 'rm', '-m', '', E_url
)
3406 # Copy an old revision of E into a new path in the WC
3407 svntest
.actions
.run_and_verify_svn(None, None, [],
3410 # Create expected output tree.
3411 expected_output
= svntest
.wc
.State(wc_dir
, {
3412 'E2' : Item(verb
='Adding'),
3415 # Created expected status tree.
3416 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
3417 expected_status
.add({
3418 'E2' : Item(status
=' ', wc_rev
=4),
3419 'E2/alpha' : Item(status
=' ', wc_rev
=4),
3420 'E2/beta' : Item(status
=' ', wc_rev
=4),
3422 # Commit the one file.
3423 svntest
.actions
.run_and_verify_commit(wc_dir
,
3430 #----------------------------------------------------------------------
3431 # Test copying and creating parents in the wc
3433 def copy_make_parents_wc_wc(sbox
):
3434 "svn cp --parents WC_PATH WC_PATH"
3437 wc_dir
= sbox
.wc_dir
3439 iota_path
= os
.path
.join(wc_dir
, 'iota')
3440 new_iota_path
= os
.path
.join(wc_dir
, 'X', 'Y', 'Z', 'iota')
3443 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp', '--parents',
3444 iota_path
, new_iota_path
)
3446 # Create expected output
3447 expected_output
= svntest
.wc
.State(wc_dir
, {
3448 'X' : Item(verb
='Adding'),
3449 'X/Y' : Item(verb
='Adding'),
3450 'X/Y/Z' : Item(verb
='Adding'),
3451 'X/Y/Z/iota' : Item(verb
='Adding'),
3454 # Create expected status tree
3455 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
3457 # Add the moved files
3458 expected_status
.add({
3459 'X' : Item(status
=' ', wc_rev
=2),
3460 'X/Y' : Item(status
=' ', wc_rev
=2),
3461 'X/Y/Z' : Item(status
=' ', wc_rev
=2),
3462 'X/Y/Z/iota' : Item(status
=' ', wc_rev
=2),
3465 svntest
.actions
.run_and_verify_commit(wc_dir
,
3471 #----------------------------------------------------------------------
3472 # Test copying and creating parents from the repo to the wc
3474 def copy_make_parents_repo_wc(sbox
):
3475 "svn cp --parents URL WC_PATH"
3478 wc_dir
= sbox
.wc_dir
3480 iota_url
= sbox
.repo_url
+ '/iota'
3481 new_iota_path
= os
.path
.join(wc_dir
, 'X', 'Y', 'Z', 'iota')
3484 svntest
.actions
.run_and_verify_svn(None, None, [],
3486 iota_url
, new_iota_path
)
3488 # Create expected output
3489 expected_output
= svntest
.wc
.State(wc_dir
, {
3490 'X' : Item(verb
='Adding'),
3491 'X/Y' : Item(verb
='Adding'),
3492 'X/Y/Z' : Item(verb
='Adding'),
3493 'X/Y/Z/iota' : Item(verb
='Adding'),
3496 # Create expected status tree
3497 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
3499 # Add the moved files
3500 expected_status
.add({
3501 'X' : Item(status
=' ', wc_rev
=2),
3502 'X/Y' : Item(status
=' ', wc_rev
=2),
3503 'X/Y/Z' : Item(status
=' ', wc_rev
=2),
3504 'X/Y/Z/iota' : Item(status
=' ', wc_rev
=2),
3507 svntest
.actions
.run_and_verify_commit(wc_dir
,
3514 #----------------------------------------------------------------------
3515 # Test copying and creating parents from the wc to the repo
3517 def copy_make_parents_wc_repo(sbox
):
3518 "svn cp --parents WC_PATH URL"
3521 wc_dir
= sbox
.wc_dir
3523 iota_path
= os
.path
.join(wc_dir
, 'iota')
3524 new_iota_url
= sbox
.repo_url
+ '/X/Y/Z/iota'
3527 svntest
.actions
.run_and_verify_svn(None, None, [],
3530 iota_path
, new_iota_url
)
3532 # Update to HEAD and verify disk contents
3533 expected_output
= svntest
.wc
.State(wc_dir
, {
3534 'X' : Item(status
='A '),
3535 'X/Y' : Item(status
='A '),
3536 'X/Y/Z' : Item(status
='A '),
3537 'X/Y/Z/iota' : Item(status
='A '),
3540 expected_disk
= svntest
.main
.greek_state
.copy()
3545 'X/Y/Z/iota' : Item(contents
="This is the file 'iota'.\n"),
3548 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 2)
3549 expected_status
.add({
3550 'X' : Item(status
=' ', wc_rev
=2),
3551 'X/Y' : Item(status
=' ', wc_rev
=2),
3552 'X/Y/Z' : Item(status
=' ', wc_rev
=2),
3553 'X/Y/Z/iota' : Item(status
=' ', wc_rev
=2),
3556 svntest
.actions
.run_and_verify_update(wc_dir
,
3562 #----------------------------------------------------------------------
3563 # Test copying and creating parents from repo to repo
3565 def copy_make_parents_repo_repo(sbox
):
3566 "svn cp --parents URL URL"
3569 wc_dir
= sbox
.wc_dir
3571 iota_url
= sbox
.repo_url
+ '/iota'
3572 new_iota_url
= sbox
.repo_url
+ '/X/Y/Z/iota'
3575 svntest
.actions
.run_and_verify_svn(None, None, [],
3578 iota_url
, new_iota_url
)
3580 # Update to HEAD and verify disk contents
3581 expected_output
= svntest
.wc
.State(wc_dir
, {
3582 'X' : Item(status
='A '),
3583 'X/Y' : Item(status
='A '),
3584 'X/Y/Z' : Item(status
='A '),
3585 'X/Y/Z/iota' : Item(status
='A '),
3588 expected_disk
= svntest
.main
.greek_state
.copy()
3593 'X/Y/Z/iota' : Item(contents
="This is the file 'iota'.\n"),
3596 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 2)
3597 expected_status
.add({
3598 'X' : Item(status
=' ', wc_rev
=2),
3599 'X/Y' : Item(status
=' ', wc_rev
=2),
3600 'X/Y/Z' : Item(status
=' ', wc_rev
=2),
3601 'X/Y/Z/iota' : Item(status
=' ', wc_rev
=2),
3604 svntest
.actions
.run_and_verify_update(wc_dir
,
3609 # Test for issue #2894
3610 # Can't perform URL to WC copy if URL needs URI encoding.
3611 def URI_encoded_repos_to_wc(sbox
):
3612 "copy a URL that needs URI encoding to WC"
3615 wc_dir
= sbox
.wc_dir
3616 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
3617 expected_disk
= svntest
.main
.greek_state
.copy()
3619 def copy_URL_to_WC(URL_rel_path
, dest_name
, rev
):
3621 "A " + os
.path
.join(wc_dir
, dest_name
, "B") + "\n",
3622 "A " + os
.path
.join(wc_dir
, dest_name
, "B", "lambda") + "\n",
3623 "A " + os
.path
.join(wc_dir
, dest_name
, "B", "E") + "\n",
3624 "A " + os
.path
.join(wc_dir
, dest_name
, "B", "E", "alpha") + "\n",
3625 "A " + os
.path
.join(wc_dir
, dest_name
, "B", "E", "beta") + "\n",
3626 "A " + os
.path
.join(wc_dir
, dest_name
, "B", "F") + "\n",
3627 "A " + os
.path
.join(wc_dir
, dest_name
, "mu") + "\n",
3628 "A " + os
.path
.join(wc_dir
, dest_name
, "C") + "\n",
3629 "A " + os
.path
.join(wc_dir
, dest_name
, "D") + "\n",
3630 "A " + os
.path
.join(wc_dir
, dest_name
, "D", "gamma") + "\n",
3631 "A " + os
.path
.join(wc_dir
, dest_name
, "D", "G") + "\n",
3632 "A " + os
.path
.join(wc_dir
, dest_name
, "D", "G", "pi") + "\n",
3633 "A " + os
.path
.join(wc_dir
, dest_name
, "D", "G", "rho") + "\n",
3634 "A " + os
.path
.join(wc_dir
, dest_name
, "D", "G", "tau") + "\n",
3635 "A " + os
.path
.join(wc_dir
, dest_name
, "D", "H") + "\n",
3636 "A " + os
.path
.join(wc_dir
, dest_name
, "D", "H", "chi") + "\n",
3637 "A " + os
.path
.join(wc_dir
, dest_name
, "D", "H", "omega") + "\n",
3638 "A " + os
.path
.join(wc_dir
, dest_name
, "D", "H", "psi") + "\n",
3639 "Checked out revision " + str(rev
- 1) + ".\n",
3640 "A " + os
.path
.join(wc_dir
, dest_name
) + "\n"]
3641 expected
= svntest
.verify
.UnorderedOutput(lines
)
3642 expected_status
.add({
3643 dest_name
+ "/B" : Item(status
=' ', wc_rev
=rev
),
3644 dest_name
+ "/B/lambda" : Item(status
=' ', wc_rev
=rev
),
3645 dest_name
+ "/B/E" : Item(status
=' ', wc_rev
=rev
),
3646 dest_name
+ "/B/E/alpha" : Item(status
=' ', wc_rev
=rev
),
3647 dest_name
+ "/B/E/beta" : Item(status
=' ', wc_rev
=rev
),
3648 dest_name
+ "/B/F" : Item(status
=' ', wc_rev
=rev
),
3649 dest_name
+ "/mu" : Item(status
=' ', wc_rev
=rev
),
3650 dest_name
+ "/C" : Item(status
=' ', wc_rev
=rev
),
3651 dest_name
+ "/D" : Item(status
=' ', wc_rev
=rev
),
3652 dest_name
+ "/D/gamma" : Item(status
=' ', wc_rev
=rev
),
3653 dest_name
+ "/D/G" : Item(status
=' ', wc_rev
=rev
),
3654 dest_name
+ "/D/G/pi" : Item(status
=' ', wc_rev
=rev
),
3655 dest_name
+ "/D/G/rho" : Item(status
=' ', wc_rev
=rev
),
3656 dest_name
+ "/D/G/tau" : Item(status
=' ', wc_rev
=rev
),
3657 dest_name
+ "/D/H" : Item(status
=' ', wc_rev
=rev
),
3658 dest_name
+ "/D/H/chi" : Item(status
=' ', wc_rev
=rev
),
3659 dest_name
+ "/D/H/omega" : Item(status
=' ', wc_rev
=rev
),
3660 dest_name
+ "/D/H/psi" : Item(status
=' ', wc_rev
=rev
),
3661 dest_name
: Item(status
=' ', wc_rev
=rev
)})
3663 dest_name
: Item(props
={}),
3664 dest_name
+ '/B' : Item(),
3665 dest_name
+ '/B/lambda' : Item("This is the file 'lambda'.\n"),
3666 dest_name
+ '/B/E' : Item(),
3667 dest_name
+ '/B/E/alpha' : Item("This is the file 'alpha'.\n"),
3668 dest_name
+ '/B/E/beta' : Item("This is the file 'beta'.\n"),
3669 dest_name
+ '/B/F' : Item(),
3670 dest_name
+ '/mu' : Item("This is the file 'mu'.\n"),
3671 dest_name
+ '/C' : Item(),
3672 dest_name
+ '/D' : Item(),
3673 dest_name
+ '/D/gamma' : Item("This is the file 'gamma'.\n"),
3674 dest_name
+ '/D/G' : Item(),
3675 dest_name
+ '/D/G/pi' : Item("This is the file 'pi'.\n"),
3676 dest_name
+ '/D/G/rho' : Item("This is the file 'rho'.\n"),
3677 dest_name
+ '/D/G/tau' : Item("This is the file 'tau'.\n"),
3678 dest_name
+ '/D/H' : Item(),
3679 dest_name
+ '/D/H/chi' : Item("This is the file 'chi'.\n"),
3680 dest_name
+ '/D/H/omega' : Item("This is the file 'omega'.\n"),
3681 dest_name
+ '/D/H/psi' : Item("This is the file 'psi'.\n"),
3685 svntest
.actions
.run_and_verify_svn(None, expected
, [],
3687 sbox
.repo_url
+ '/' + URL_rel_path
,
3688 os
.path
.join(wc_dir
,
3691 expected_output
= svntest
.wc
.State(wc_dir
,
3692 {dest_name
: Item(verb
='Adding')})
3693 svntest
.actions
.run_and_verify_commit(wc_dir
,
3698 copy_URL_to_WC('A', 'A COPY', 2)
3699 copy_URL_to_WC('A COPY', 'A_COPY_2', 3)
3701 #----------------------------------------------------------------------
3702 # Issue #3068: copy source parent may be unversioned
3703 def allow_unversioned_parent_for_copy_src(sbox
):
3704 "copy wc in unversioned parent to other wc"
3706 sbox
.build(read_only
= True)
3707 wc_dir
= sbox
.wc_dir
3709 # Make the "other" working copy
3710 wc2_dir
= sbox
.add_wc_path('other')
3711 svntest
.actions
.duplicate_dir(wc_dir
, wc2_dir
)
3712 copy_to_path
= os
.path
.join(wc_dir
, 'A', 'copy_of_wc2')
3714 # Copy the wc-in-unversioned-parent working copy to our original wc.
3715 svntest
.actions
.run_and_verify_svn(None,
3723 #----------------------------------------------------------------------
3725 def replaced_local_source_for_incoming_copy(sbox
):
3726 "update receives copy, but local source is replaced"
3727 sbox
.build(read_only
= True)
3728 wc_dir
= sbox
.wc_dir
3729 other_wc_dir
= wc_dir
+ '-other'
3731 # These paths are for regular content testing.
3732 tau_path
= os
.path
.join(wc_dir
, 'A', 'D', 'G', 'tau')
3733 rho_url
= sbox
.repo_url
+ '/A/D/G/rho'
3734 pi_url
= sbox
.repo_url
+ '/A/D/G/pi'
3735 other_G_path
= os
.path
.join(other_wc_dir
, 'A', 'D', 'G')
3736 other_rho_path
= os
.path
.join(other_G_path
, 'rho')
3738 # These paths are for properties testing.
3739 H_path
= os
.path
.join(wc_dir
, 'A', 'D', 'H')
3740 chi_path
= os
.path
.join(H_path
, 'chi')
3741 psi_path
= os
.path
.join(H_path
, 'psi')
3742 omega_path
= os
.path
.join(H_path
, 'omega')
3743 psi_url
= sbox
.repo_url
+ '/A/D/H/psi'
3744 chi_url
= sbox
.repo_url
+ '/A/D/H/chi'
3745 other_H_path
= os
.path
.join(other_wc_dir
, 'A', 'D', 'H')
3746 other_psi_path
= os
.path
.join(other_H_path
, 'psi')
3747 other_omega_path
= os
.path
.join(other_H_path
, 'omega')
3749 # Prepare for properties testing. If the regular content bug
3750 # reappears, we still want to be able to test for the property bug
3751 # independently. That means making two files have the same content,
3752 # to avoid encountering the checksum error that might reappear in a
3753 # regression. So here we do that, as well as set the marker
3754 # property that we'll check for later. The reason to set the marker
3755 # property in this commit, rather than later, is so that we pass the
3756 # conditional in update_editor.c:locate_copyfrom() that compares the
3758 svntest
.main
.file_write(chi_path
, "Same contents for two files.\n")
3759 svntest
.main
.file_write(psi_path
, "Same contents for two files.\n")
3760 svntest
.actions
.run_and_verify_svn(None, None, [], 'propset',
3761 'chi-prop', 'chi-val', chi_path
)
3762 svntest
.actions
.run_and_verify_svn(None, None, [], 'ci',
3763 '-m', 'identicalize contents', wc_dir
);
3764 svntest
.actions
.run_and_verify_svn(None, None, [], 'up', wc_dir
)
3766 # Make the duplicate working copy.
3767 svntest
.main
.safe_rmtree(other_wc_dir
)
3768 shutil
.copytree(wc_dir
, other_wc_dir
)
3771 ## Test properties. ##
3773 # Commit a replacement from the first working copy.
3774 svntest
.actions
.run_and_verify_svn(None, None, [], 'rm',
3776 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
3777 psi_url
, omega_path
);
3778 svntest
.actions
.run_and_verify_svn(None, None, [], 'ci',
3779 '-m', 'a propset and a copy', wc_dir
);
3781 # Now schedule a replacement in the second working copy, then update
3782 # to receive the replacement from the first working copy, with the
3783 # source being the now-scheduled-replace file.
3784 svntest
.actions
.run_and_verify_svn(None, None, [], 'rm',
3786 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
3787 chi_url
, other_psi_path
);
3788 svntest
.actions
.run_and_verify_svn(None, None, [], 'up',
3790 exit_code
, output
, errput
= svntest
.main
.run_svn(None, 'proplist',
3791 '-v', other_omega_path
)
3793 raise svntest
.Failure("unexpected error output: %s" % errput
)
3795 raise svntest
.Failure("unexpected properties found on '%s': %s"
3796 % (other_omega_path
, output
))
3798 ## Test regular content. ##
3800 # Commit a replacement from the first working copy.
3801 svntest
.actions
.run_and_verify_svn(None, None, [], 'rm',
3803 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
3805 svntest
.actions
.run_and_verify_svn(None, None, [], 'ci',
3806 '-m', 'copy rho to tau', wc_dir
);
3808 # Now schedule a replacement in the second working copy, then update
3809 # to receive the replacement from the first working copy, with the
3810 # source being the now-scheduled-replace file.
3811 svntest
.actions
.run_and_verify_svn(None, None, [], 'rm',
3813 svntest
.actions
.run_and_verify_svn(None, None, [], 'cp',
3814 pi_url
, other_rho_path
);
3815 svntest
.actions
.run_and_verify_svn(None, None, [], 'up',
3819 svntest
.main
.safe_rmtree(other_wc_dir
)
3822 ########################################################################
3826 # list all tests here, starting with None:
3828 basic_copy_and_move_files
,
3829 receive_copy_in_update
,
3830 resurrect_deleted_dir
,
3832 no_wc_copy_overwrites
,
3834 copy_files_with_properties
,
3836 mv_and_revert_directory
,
3837 SkipUnless(copy_preserve_executable_bit
, svntest
.main
.is_posix_os
),
3841 url_copy_parent_into_child
,
3842 wc_copy_parent_into_child
,
3843 resurrect_deleted_file
,
3844 diff_repos_to_wc_copy
,
3845 repos_to_wc_copy_eol_keywords
,
3846 revision_kinds_local_source
,
3847 copy_over_missing_file
,
3849 double_uri_escaping_1814
,
3850 wc_to_wc_copy_between_different_repos
,
3851 wc_to_wc_copy_deleted
,
3852 url_to_non_existent_url_path
,
3853 non_existent_url_to_url
,
3855 wc_copy_dir_to_itself
,
3857 wc_copy_replacement
,
3858 wc_copy_replace_with_props
,
3859 repos_to_wc_copy_replacement
,
3860 repos_to_wc_copy_replace_with_props
,
3861 delete_replaced_file
,
3862 mv_unversioned_file
,
3864 copy_deleted_dir_into_prefix
,
3865 copy_copied_file_and_dir
,
3866 move_copied_file_and_dir
,
3867 move_moved_file_and_dir
,
3868 move_file_within_moved_dir
,
3869 move_file_out_of_moved_dir
,
3870 move_dir_within_moved_dir
,
3871 move_dir_out_of_moved_dir
,
3872 move_file_back_and_forth
,
3873 move_dir_back_and_forth
,
3874 copy_move_added_paths
,
3875 XFail(copy_added_paths_with_props
),
3876 copy_added_paths_to_URL
,
3877 move_to_relative_paths
,
3878 move_from_relative_paths
,
3879 copy_to_relative_paths
,
3880 copy_from_relative_paths
,
3885 copy_multiple_repo_wc
,
3886 copy_multiple_wc_repo
,
3887 copy_peg_rev_local_files
,
3888 copy_peg_rev_local_dirs
,
3891 copy_make_parents_wc_wc
,
3892 copy_make_parents_repo_wc
,
3893 copy_make_parents_wc_repo
,
3894 copy_make_parents_repo_repo
,
3895 URI_encoded_repos_to_wc
,
3896 allow_unversioned_parent_for_copy_src
,
3897 replaced_local_source_for_incoming_copy
,
3900 if __name__
== '__main__':
3901 svntest
.main
.run_tests(test_list
)