In the command-line client, forbid
[svn.git] / subversion / tests / cmdline / copy_tests.py
blobf11b851df4f09ca6a38c0223ac2f3873b9666545
1 #!/usr/bin/env python
3 # copy_tests.py: testing the many uses of 'svn cp' and 'svn mv'
5 # Subversion is a tool for revision control.
6 # See http://subversion.tigris.org for more information.
8 # ====================================================================
9 # Copyright (c) 2000-2007 CollabNet. All rights reserved.
11 # This software is licensed as described in the file COPYING, which
12 # you should have received as part of this distribution. The terms
13 # are also available at http://subversion.tigris.org/license-1.html.
14 # If newer versions of this license are posted there, you may use a
15 # newer version instead, at your option.
17 ######################################################################
19 # General modules
20 import stat, os, re
22 # Our testing module
23 import svntest
25 from svntest.main import SVN_PROP_MERGE_INFO
27 # (abbreviation)
28 Skip = svntest.testcase.Skip
29 SkipUnless = svntest.testcase.SkipUnless
30 XFail = svntest.testcase.XFail
31 Item = svntest.wc.StateItem
35 #----------------------------------------------------------------------
36 # Helper for wc_copy_replacement and repos_to_wc_copy_replacement
37 def copy_replace(sbox, wc_copy):
38 """Tests for 'R'eplace functionanity for files.
40 Depending on the value of wc_copy either a working copy (when true)
41 or a url (when false) copy source is used."""
43 sbox.build()
44 wc_dir = sbox.wc_dir
46 # File scheduled for deletion
47 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
48 svntest.actions.run_and_verify_svn(None, None, [], 'rm', rho_path)
50 # Status before attempting copies
51 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
52 expected_status.tweak('A/D/G/rho', status='D ')
53 svntest.actions.run_and_verify_status(wc_dir, expected_status)
55 # The copy shouldn't fail
56 if wc_copy:
57 pi_src = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
58 else:
59 pi_src = sbox.repo_url + '/A/D/G/pi'
61 svntest.actions.run_and_verify_svn(None, None, [],
62 'cp', pi_src, rho_path)
64 # Now commit
65 expected_status.tweak('A/D/G/rho', status='R ', copied='+', wc_rev='-')
66 svntest.actions.run_and_verify_status(wc_dir, expected_status)
68 expected_status.tweak('A/D/G/rho', status=' ', copied=None,
69 wc_rev='2')
70 expected_output = svntest.wc.State(wc_dir, {
71 'A/D/G/rho': Item(verb='Replacing'),
73 svntest.actions.run_and_verify_commit(wc_dir,
74 expected_output,
75 expected_status,
76 None, None, None, None, None,
77 wc_dir)
79 # Helper for wc_copy_replace_with_props and
80 # repos_to_wc_copy_replace_with_props
81 def copy_replace_with_props(sbox, wc_copy):
82 """Tests for 'R'eplace functionanity for files with props.
84 Depending on the value of wc_copy either a working copy (when true) or
85 a url (when false) copy source is used."""
87 sbox.build()
88 wc_dir = sbox.wc_dir
90 # Use a temp file to set properties with wildcards in their values
91 # otherwise Win32/VS2005 will expand them
92 prop_path = os.path.join(wc_dir, 'proptmp')
93 svntest.main.file_append(prop_path, '*')
95 # Set props on file which is copy-source later on
96 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
97 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
98 svntest.actions.run_and_verify_svn(None, None, [],
99 'ps', 'phony-prop', '-F',
100 prop_path, pi_path)
101 os.remove(prop_path)
102 svntest.actions.run_and_verify_svn(None, None, [],
103 'ps', 'svn:eol-style', 'LF', rho_path)
105 # Verify props having been set
106 expected_disk = svntest.main.greek_state.copy()
107 expected_disk.tweak('A/D/G/pi',
108 props={ 'phony-prop': '*' })
109 expected_disk.tweak('A/D/G/rho',
110 props={ 'svn:eol-style': 'LF' })
112 actual_disk = svntest.tree.build_tree_from_wc(wc_dir, 1)
113 svntest.tree.compare_trees(actual_disk, expected_disk.old_tree())
115 # Commit props
116 expected_output = svntest.wc.State(wc_dir, {
117 'A/D/G/pi': Item(verb='Sending'),
118 'A/D/G/rho': Item(verb='Sending'),
120 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
121 expected_status.tweak('A/D/G/pi', wc_rev='2')
122 expected_status.tweak('A/D/G/rho', wc_rev='2')
123 svntest.actions.run_and_verify_commit(wc_dir,
124 expected_output,
125 expected_status,
126 None, None, None, None, None,
127 wc_dir)
129 # Bring wc into sync
130 svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
132 # File scheduled for deletion
133 svntest.actions.run_and_verify_svn(None, None, [], 'rm', rho_path)
135 # Status before attempting copies
136 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
137 expected_status.tweak('A/D/G/rho', status='D ')
138 svntest.actions.run_and_verify_status(wc_dir, expected_status)
140 # The copy shouldn't fail
141 if wc_copy:
142 pi_src = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
143 else:
144 pi_src = sbox.repo_url + '/A/D/G/pi'
146 svntest.actions.run_and_verify_svn(None, None, [],
147 'cp', pi_src, rho_path)
149 # Verify both content and props have been copied
150 expected_disk.tweak('A/D/G/rho',
151 contents="This is the file 'pi'.\n",
152 props={ 'phony-prop' : '*',
153 SVN_PROP_MERGE_INFO : '' })
154 actual_disk = svntest.tree.build_tree_from_wc(wc_dir, 1)
155 svntest.tree.compare_trees(actual_disk, expected_disk.old_tree())
157 # Now commit and verify
158 expected_status.tweak('A/D/G/rho', status='R ', copied='+', wc_rev='-')
159 svntest.actions.run_and_verify_status(wc_dir, expected_status)
161 expected_status.tweak('A/D/G/rho', status=' ', copied=None,
162 wc_rev='3')
163 expected_output = svntest.wc.State(wc_dir, {
164 'A/D/G/rho': Item(verb='Replacing'),
166 svntest.actions.run_and_verify_commit(wc_dir,
167 expected_output,
168 expected_status,
169 None, None, None, None, None,
170 wc_dir)
173 ######################################################################
174 # Tests
176 # Each test must return on success or raise on failure.
178 # (Taken from notes/copy-planz.txt:)
180 # We have four use cases for 'svn cp' now.
182 # A. svn cp wc_path1 wc_path2
184 # This duplicates a path in the working copy, and schedules it
185 # for addition with history.
187 # B. svn cp URL [-r rev] wc_path
189 # This "checks out" URL (in REV) into the working copy at
190 # wc_path, integrates it, and schedules it for addition with
191 # history.
193 # C. svn cp wc_path URL
195 # This immediately commits wc_path to URL on the server; the
196 # commit will be an addition with history. The commit will not
197 # change the working copy at all.
199 # D. svn cp URL1 [-r rev] URL2
201 # This causes a server-side copy to happen immediately; no
202 # working copy is required.
206 # TESTS THAT NEED TO BE WRITTEN
208 # Use Cases A & C
210 # -- single files, with/without local mods, as both 'cp' and 'mv'.
211 # (need to verify commit worked by updating a 2nd working copy
212 # to see the local mods)
214 # -- dir copy, has mixed revisions
216 # -- dir copy, has local mods (an edit, an add, a delete, and a replace)
218 # -- dir copy, has mixed revisions AND local mods
220 # -- dir copy, has mixed revisions AND another previously-made copy!
221 # (perhaps done as two nested 'mv' commands!)
223 # Use Case D
226 # By the time the copy setup algorithm is complete, the copy
227 # operation will have four parts: SRC-DIR, SRC-BASENAME, DST-DIR,
228 # DST-BASENAME. In all cases, SRC-DIR/SRC-BASENAME and DST_DIR must
229 # already exist before the operation, but DST_DIR/DST_BASENAME must
230 # NOT exist.
232 # Besides testing things that don't meet the above criteria, we want to
233 # also test valid cases:
235 # - where SRC-DIR/SRC-BASENAME is a file or a dir.
236 # - where SRC-DIR (or SRC-DIR/SRC-BASENAME) is a parent/grandparent
237 # directory of DST-DIR
238 # - where SRC-DIR (or SRC-DIR/SRC-BASENAME) is a child/grandchild
239 # directory of DST-DIR
240 # - where SRC-DIR (or SRC-DIR/SRC-BASENAME) is not in the lineage
241 # of DST-DIR at all
245 #----------------------------------------------------------------------
247 def basic_copy_and_move_files(sbox):
248 "basic copy and move commands -- on files only"
250 sbox.build()
251 wc_dir = sbox.wc_dir
253 mu_path = os.path.join(wc_dir, 'A', 'mu')
254 iota_path = os.path.join(wc_dir, 'iota')
255 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
256 D_path = os.path.join(wc_dir, 'A', 'D')
257 alpha_path = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha')
258 H_path = os.path.join(wc_dir, 'A', 'D', 'H')
259 F_path = os.path.join(wc_dir, 'A', 'B', 'F')
260 alpha2_path = os.path.join(wc_dir, 'A', 'C', 'alpha2')
262 # Make local mods to mu and rho
263 svntest.main.file_append(mu_path, 'appended mu text')
264 svntest.main.file_append(rho_path, 'new appended text for rho')
266 # Copy rho to D -- local mods
267 svntest.actions.run_and_verify_svn(None, None, [], 'cp', rho_path, D_path)
269 # Copy alpha to C -- no local mods, and rename it to 'alpha2' also
270 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
271 alpha_path, alpha2_path)
273 # Move mu to H -- local mods
274 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
275 mu_path, H_path)
277 # Move iota to F -- no local mods
278 svntest.actions.run_and_verify_svn(None, None, [], 'mv', iota_path, F_path)
280 # Created expected output tree for 'svn ci':
281 # We should see four adds, two deletes, and one change in total.
282 expected_output = svntest.wc.State(wc_dir, {
283 'A/D/G/rho' : Item(verb='Sending'),
284 'A/D/rho' : Item(verb='Adding'),
285 'A/C/alpha2' : Item(verb='Adding'),
286 'A/D/H/mu' : Item(verb='Adding'),
287 'A/B/F/iota' : Item(verb='Adding'),
288 'A/mu' : Item(verb='Deleting'),
289 'iota' : Item(verb='Deleting'),
292 # Create expected status tree; all local revisions should be at 1,
293 # but several files should be at revision 2. Also, two files should
294 # be missing.
295 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
296 expected_status.tweak('A/D/G/rho', 'A/mu', wc_rev=2)
298 expected_status.add({
299 'A/D/rho' : Item(status=' ', wc_rev=2),
300 'A/C/alpha2' : Item(status=' ', wc_rev=2),
301 'A/D/H/mu' : Item(status=' ', wc_rev=2),
302 'A/B/F/iota' : Item(status=' ', wc_rev=2),
305 expected_status.remove('A/mu', 'iota')
307 svntest.actions.run_and_verify_commit(wc_dir,
308 expected_output,
309 expected_status,
310 None,
311 None, None,
312 None, None,
313 wc_dir)
315 # Issue 1091, alpha2 would now have the wrong checksum and so a
316 # subsequent commit would fail
317 svntest.main.file_append(alpha2_path, 'appended alpha2 text')
318 expected_output = svntest.wc.State(wc_dir, {
319 'A/C/alpha2' : Item(verb='Sending'),
321 expected_status.tweak('A/C/alpha2', wc_rev=3)
322 svntest.actions.run_and_verify_commit(wc_dir,
323 expected_output,
324 expected_status,
325 None,
326 None, None,
327 None, None,
328 wc_dir)
330 # Assure that attempts at local copy and move fail when a log
331 # message is provided.
332 expected_stderr = \
333 ".*Local, non-commit operations do not take a log message"
334 svntest.actions.run_and_verify_svn(None, None, expected_stderr,
335 'cp', '-m', 'op fails', rho_path, D_path)
336 svntest.actions.run_and_verify_svn(None, None, expected_stderr,
337 'mv', '-m', 'op fails', rho_path, D_path)
340 #----------------------------------------------------------------------
342 # This test passes over ra_local certainly; we're adding it because at
343 # one time it failed over ra_neon. Specifically, it failed when
344 # mod_dav_svn first started sending vsn-rsc-urls as "CR/path", and was
345 # sending bogus CR/paths for items within copied subtrees.
347 def receive_copy_in_update(sbox):
348 "receive a copied directory during update"
350 sbox.build()
351 wc_dir = sbox.wc_dir
353 # Make a backup copy of the working copy.
354 wc_backup = sbox.add_wc_path('backup')
355 svntest.actions.duplicate_dir(wc_dir, wc_backup)
357 # Define a zillion paths in both working copies.
358 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
359 newG_path = os.path.join(wc_dir, 'A', 'B', 'newG')
361 # Copy directory A/D to A/B/newG
362 svntest.actions.run_and_verify_svn(None, None, [], 'cp', G_path, newG_path)
364 # Created expected output tree for 'svn ci':
365 expected_output = svntest.wc.State(wc_dir, {
366 'A/B/newG' : Item(verb='Adding'),
369 # Create expected status tree.
370 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
371 expected_status.add({
372 'A/B/newG' : Item(status=' ', wc_rev=2),
373 'A/B/newG/pi' : Item(status=' ', wc_rev=2),
374 'A/B/newG/rho' : Item(status=' ', wc_rev=2),
375 'A/B/newG/tau' : Item(status=' ', wc_rev=2),
378 svntest.actions.run_and_verify_commit(wc_dir,
379 expected_output,
380 expected_status,
381 None,
382 None, None,
383 None, None,
384 wc_dir)
386 # Now update the other working copy; it should receive a full add of
387 # the newG directory and its contents.
389 # Expected output of update
390 expected_output = svntest.wc.State(wc_backup, {
391 'A/B/newG' : Item(status='A '),
392 'A/B/newG/pi' : Item(status='A '),
393 'A/B/newG/rho' : Item(status='A '),
394 'A/B/newG/tau' : Item(status='A '),
397 # Create expected disk tree for the update.
398 expected_disk = svntest.main.greek_state.copy()
399 expected_disk.add({
400 'A/B/newG' : Item(),
401 'A/B/newG/pi' : Item("This is the file 'pi'.\n"),
402 'A/B/newG/rho' : Item("This is the file 'rho'.\n"),
403 'A/B/newG/tau' : Item("This is the file 'tau'.\n"),
406 # Create expected status tree for the update.
407 expected_status = svntest.actions.get_virginal_state(wc_backup, 2)
408 expected_status.add({
409 'A/B/newG' : Item(status=' ', wc_rev=2),
410 'A/B/newG/pi' : Item(status=' ', wc_rev=2),
411 'A/B/newG/rho' : Item(status=' ', wc_rev=2),
412 'A/B/newG/tau' : Item(status=' ', wc_rev=2),
415 # Do the update and check the results in three ways.
416 svntest.actions.run_and_verify_update(wc_backup,
417 expected_output,
418 expected_disk,
419 expected_status)
422 #----------------------------------------------------------------------
424 # Regression test for issue #683. In particular, this bug prevented
425 # us from running 'svn cp -r N src_URL dst_URL' as a means of
426 # resurrecting a deleted directory. Also, the final 'update' at the
427 # end of this test was uncovering a ghudson 'deleted' edge-case bug.
428 # (In particular, re-adding G to D, when D already had a 'deleted'
429 # entry for G. The entry-merge wasn't overwriting the 'deleted'
430 # attribute, and thus the newly-added G was ending up disconnected
431 # from D.)
433 def resurrect_deleted_dir(sbox):
434 "resurrect a deleted directory"
436 sbox.build()
437 wc_dir = sbox.wc_dir
438 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
440 # Delete directory A/D/G, commit that as r2.
441 svntest.actions.run_and_verify_svn(None, None, [], 'rm', '--force',
442 G_path)
444 expected_output = svntest.wc.State(wc_dir, {
445 'A/D/G' : Item(verb='Deleting'),
448 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
449 expected_status.remove('A/D/G')
450 expected_status.remove('A/D/G/pi')
451 expected_status.remove('A/D/G/rho')
452 expected_status.remove('A/D/G/tau')
454 svntest.actions.run_and_verify_commit(wc_dir,
455 expected_output,
456 expected_status,
457 None,
458 None, None,
459 None, None,
460 wc_dir)
462 # Use 'svn cp URL@1 URL' to resurrect the deleted directory, where
463 # the two URLs are identical. This used to trigger a failure.
464 url = sbox.repo_url + '/A/D/G'
465 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
466 url + '@1', url,
467 '-m', 'logmsg')
469 # For completeness' sake, update to HEAD, and verify we have a full
470 # greek tree again, all at revision 3.
472 expected_output = svntest.wc.State(wc_dir, {
473 'A/D/G' : Item(status='A '),
474 'A/D/G/pi' : Item(status='A '),
475 'A/D/G/rho' : Item(status='A '),
476 'A/D/G/tau' : Item(status='A '),
479 expected_disk = svntest.main.greek_state.copy()
481 expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
483 svntest.actions.run_and_verify_update(wc_dir,
484 expected_output,
485 expected_disk,
486 expected_status)
488 def copy_deleted_dir_into_prefix(sbox):
489 "copy a deleted dir to a prefix of its old path"
491 sbox.build()
492 wc_dir = sbox.wc_dir
493 D_path = os.path.join(wc_dir, 'A', 'D')
495 # Delete directory A/D, commit that as r2.
496 svntest.actions.run_and_verify_svn(None, None, [], 'rm', '--force',
497 D_path)
499 expected_output = svntest.wc.State(wc_dir, {
500 'A/D' : Item(verb='Deleting'),
503 svntest.actions.run_and_verify_commit(wc_dir,
504 expected_output,
505 None,
506 None,
507 None, None,
508 None, None,
509 wc_dir)
511 # Ok, copy from a deleted URL into a prefix of that URL, this used to
512 # result in an assert failing.
513 url1 = sbox.repo_url + '/A/D/G'
514 url2 = sbox.repo_url + '/A/D'
515 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
516 url1 + '@1', url2,
517 '-m', 'logmsg')
519 #----------------------------------------------------------------------
521 # Test that we're enforcing proper 'svn cp' overwrite behavior. Note
522 # that svn_fs_copy() will always overwrite its destination if an entry
523 # by the same name already exists. However, libsvn_client should be
524 # doing existence checks to prevent directories from being
525 # overwritten, and files can't be overwritten because the RA layers
526 # are doing out-of-dateness checks during the commit.
529 def no_copy_overwrites(sbox):
530 "svn cp URL URL cannot overwrite destination"
532 sbox.build()
534 wc_dir = sbox.wc_dir
536 fileURL1 = sbox.repo_url + "/A/B/E/alpha"
537 fileURL2 = sbox.repo_url + "/A/B/E/beta"
538 dirURL1 = sbox.repo_url + "/A/D/G"
539 dirURL2 = sbox.repo_url + "/A/D/H"
541 # Expect out-of-date failure if 'svn cp URL URL' tries to overwrite a file
542 svntest.actions.run_and_verify_svn("Whoa, I was able to overwrite a file!",
543 None, svntest.verify.AnyOutput,
544 'cp', fileURL1, fileURL2,
545 '-m', 'fooogle')
547 # Create A/D/H/G by running 'svn cp ...A/D/G .../A/D/H'
548 svntest.actions.run_and_verify_svn(None, None, [],
549 'cp', dirURL1, dirURL2,
550 '-m', 'fooogle')
552 # Repeat the last command. It should *fail* because A/D/H/G already exists.
553 svntest.actions.run_and_verify_svn(
554 "Whoa, I was able to overwrite a directory!",
555 None, svntest.verify.AnyOutput,
556 'cp', dirURL1, dirURL2,
557 '-m', 'fooogle')
559 #----------------------------------------------------------------------
561 # Issue 845. WC -> WC copy should not overwrite base text-base
563 def no_wc_copy_overwrites(sbox):
564 "svn cp PATH PATH cannot overwrite destination"
566 sbox.build()
567 wc_dir = sbox.wc_dir
569 # File simply missing
570 tau_path = os.path.join(wc_dir, 'A', 'D', 'G', 'tau')
571 os.remove(tau_path)
573 # Status before attempting copies
574 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
575 expected_status.tweak('A/D/G/tau', status='! ')
576 svntest.actions.run_and_verify_status(wc_dir, expected_status)
578 # These copies should fail
579 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
580 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
581 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
582 'cp', pi_path, rho_path)
583 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
584 'cp', pi_path, tau_path)
586 # Status after failed copies should not have changed
587 svntest.actions.run_and_verify_status(wc_dir, expected_status)
589 #----------------------------------------------------------------------
591 # Takes out working-copy locks for A/B2 and child A/B2/E. At one stage
592 # during issue 749 the second lock cause an already-locked error.
593 def copy_modify_commit(sbox):
594 "copy a tree and modify before commit"
596 sbox.build()
597 wc_dir = sbox.wc_dir
598 B_path = os.path.join(wc_dir, 'A', 'B')
599 B2_path = os.path.join(wc_dir, 'A', 'B2')
601 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
602 B_path, B2_path)
604 alpha_path = os.path.join(wc_dir, 'A', 'B2', 'E', 'alpha')
605 svntest.main.file_append(alpha_path, "modified alpha")
607 expected_output = svntest.wc.State(wc_dir, {
608 'A/B2' : Item(verb='Adding'),
609 'A/B2/E/alpha' : Item(verb='Sending'),
612 svntest.actions.run_and_verify_commit(wc_dir,
613 expected_output,
614 None,
615 None,
616 None, None,
617 None, None,
618 wc_dir)
620 #----------------------------------------------------------------------
622 # Issue 591, at one point copying a file from URL to WC didn't copy
623 # properties.
625 def copy_files_with_properties(sbox):
626 "copy files with properties"
628 sbox.build()
629 wc_dir = sbox.wc_dir
631 # Set a property on a file
632 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
633 svntest.actions.run_and_verify_svn(None, None, [],
634 'propset', 'pname', 'pval', rho_path)
636 # and commit it
637 expected_output = svntest.wc.State(wc_dir, {
638 'A/D/G/rho' : Item(verb='Sending'),
640 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
641 expected_status.tweak('A/D/G/rho', status=' ', wc_rev=2)
642 svntest.actions.run_and_verify_commit(wc_dir,
643 expected_output, expected_status,
644 None, None, None, None, None,
645 wc_dir)
647 # Set another property, but don't commit it yet
648 svntest.actions.run_and_verify_svn(None, None, [],
649 'propset', 'pname2', 'pval2', rho_path)
651 # WC to WC copy of file with committed and uncommitted properties
652 rho_wc_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho_wc')
653 svntest.actions.run_and_verify_svn(None, None, [],
654 'copy', rho_path, rho_wc_path)
656 # REPOS to WC copy of file with properties
657 rho_url_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho_url')
658 rho_url = sbox.repo_url + '/A/D/G/rho'
659 svntest.actions.run_and_verify_svn(None, None, [],
660 'copy', rho_url, rho_url_path)
662 # Properties are not visible in WC status 'A'
663 expected_status.add({
664 'A/D/G/rho' : Item(status=' M', wc_rev='2'),
665 'A/D/G/rho_wc' : Item(status='A ', wc_rev='-', copied='+'),
666 'A/D/G/rho_url' : Item(status='A ', wc_rev='-', copied='+'),
668 svntest.actions.run_and_verify_status(wc_dir, expected_status)
670 # Check properties explicitly
671 svntest.actions.run_and_verify_svn(None, ['pval\n'], [],
672 'propget', 'pname', rho_wc_path)
673 svntest.actions.run_and_verify_svn(None, ['pval2\n'], [],
674 'propget', 'pname2', rho_wc_path)
675 svntest.actions.run_and_verify_svn(None, ['pval\n'], [],
676 'propget', 'pname', rho_url_path)
678 # Commit and properties are visible in status
679 expected_output = svntest.wc.State(wc_dir, {
680 'A/D/G/rho' : Item(verb='Sending'),
681 'A/D/G/rho_wc' : Item(verb='Adding'),
682 'A/D/G/rho_url' : Item(verb='Adding'),
684 expected_status.tweak('A/D/G/rho', status=' ', wc_rev=3)
685 expected_status.remove('A/D/G/rho_wc', 'A/D/G/rho_url')
686 expected_status.add({
687 'A/D/G/rho_wc' : Item(status=' ', wc_rev=3),
688 'A/D/G/rho_url' : Item(status=' ', wc_rev=3),
690 svntest.actions.run_and_verify_commit(wc_dir,
691 expected_output, expected_status,
692 None, None, None, None, None,
693 wc_dir)
695 #----------------------------------------------------------------------
697 # Issue 918
698 def copy_delete_commit(sbox):
699 "copy a tree and delete part of it before commit"
701 sbox.build()
702 wc_dir = sbox.wc_dir
703 B_path = os.path.join(wc_dir, 'A', 'B')
704 B2_path = os.path.join(wc_dir, 'A', 'B2')
706 # copy a tree
707 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
708 B_path, B2_path)
710 # delete a file
711 alpha_path = os.path.join(wc_dir, 'A', 'B2', 'E', 'alpha')
712 svntest.actions.run_and_verify_svn(None, None, [], 'rm', alpha_path)
714 # commit copied tree containing a deleted file
715 expected_output = svntest.wc.State(wc_dir, {
716 'A/B2' : Item(verb='Adding'),
717 'A/B2/E/alpha' : Item(verb='Deleting'),
719 svntest.actions.run_and_verify_commit(wc_dir,
720 expected_output,
721 None,
722 None,
723 None, None,
724 None, None,
725 wc_dir)
727 # copy a tree
728 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
729 os.path.join(wc_dir, 'A', 'B'),
730 os.path.join(wc_dir, 'A', 'B3'))
732 # delete a directory
733 E_path = os.path.join(wc_dir, 'A', 'B3', 'E')
734 svntest.actions.run_and_verify_svn(None, None, [], 'rm', E_path)
736 # commit copied tree containing a deleted directory
737 expected_output = svntest.wc.State(wc_dir, {
738 'A/B3' : Item(verb='Adding'),
739 'A/B3/E' : Item(verb='Deleting'),
741 svntest.actions.run_and_verify_commit(wc_dir,
742 expected_output,
743 None,
744 None,
745 None, None,
746 None, None,
747 wc_dir)
750 #----------------------------------------------------------------------
751 def mv_and_revert_directory(sbox):
752 "move and revert a directory"
754 sbox.build()
755 wc_dir = sbox.wc_dir
756 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
757 F_path = os.path.join(wc_dir, 'A', 'B', 'F')
758 new_E_path = os.path.join(F_path, 'E')
760 # Issue 931: move failed to lock the directory being deleted
761 svntest.actions.run_and_verify_svn(None, None, [], 'move',
762 E_path, F_path)
763 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
764 expected_status.tweak('A/B/E', 'A/B/E/alpha', 'A/B/E/beta', status='D ')
765 expected_status.add({
766 'A/B/F/E' : Item(status='A ', wc_rev='-', copied='+'),
767 'A/B/F/E/alpha' : Item(status=' ', wc_rev='-', copied='+'),
768 'A/B/F/E/beta' : Item(status=' ', wc_rev='-', copied='+'),
770 svntest.actions.run_and_verify_status(wc_dir, expected_status)
772 # Issue 932: revert failed to lock the parent directory
773 svntest.actions.run_and_verify_svn(None, None, [], 'revert', '--recursive',
774 new_E_path)
775 expected_status.remove('A/B/F/E', 'A/B/F/E/alpha', 'A/B/F/E/beta')
776 svntest.actions.run_and_verify_status(wc_dir, expected_status)
779 #----------------------------------------------------------------------
780 # Issue 982. When copying a file with the executable bit set, the copied
781 # file should also have its executable bit set.
782 def copy_preserve_executable_bit(sbox):
783 "executable bit should be preserved when copying"
785 # Bootstrap
786 sbox.build()
787 wc_dir = sbox.wc_dir
789 # Create two paths
790 newpath1 = os.path.join(wc_dir, 'newfile1')
791 newpath2 = os.path.join(wc_dir, 'newfile2')
793 # Create the first file.
794 svntest.main.file_append(newpath1, "a new file")
795 svntest.actions.run_and_verify_svn(None, None, [], 'add', newpath1)
797 mode1 = os.stat(newpath1)[stat.ST_MODE]
799 # Doing this to get the executable bit set on systems that support
800 # that -- the property itself is not the point.
801 svntest.actions.run_and_verify_svn(None, None, [], 'propset',
802 'svn:executable', 'on', newpath1)
804 mode2 = os.stat(newpath1)[stat.ST_MODE]
806 if mode1 == mode2:
807 print "setting svn:executable did not change file's permissions"
808 raise svntest.Failure
810 # Commit the file
811 svntest.actions.run_and_verify_svn(None, None, [], 'ci',
812 '-m', 'create file and set svn:executable',
813 wc_dir)
815 # Copy the file
816 svntest.actions.run_and_verify_svn(None, None, [], 'cp', newpath1, newpath2)
818 mode3 = os.stat(newpath2)[stat.ST_MODE]
820 # The mode on the original and copied file should be identical
821 if mode2 != mode3:
822 print "permissions on the copied file are not identical to original file"
823 raise svntest.Failure
825 #----------------------------------------------------------------------
826 # Issue 1029, copy failed with a "working copy not locked" error
827 def wc_to_repos(sbox):
828 "working-copy to repository copy"
830 sbox.build()
831 wc_dir = sbox.wc_dir
833 beta_path = os.path.join(wc_dir, "A", "B", "E", "beta")
834 beta2_url = sbox.repo_url + "/A/B/E/beta2"
835 H_path = os.path.join(wc_dir, "A", "D", "H")
836 H2_url = sbox.repo_url + "/A/D/H2"
838 # modify some items to be copied
839 svntest.main.file_append(os.path.join(wc_dir, 'A', 'D', 'H', 'omega'),
840 "new otext\n")
841 svntest.actions.run_and_verify_svn(None, None, [], 'propset', 'foo', 'bar',
842 beta_path)
844 # copy a file
845 svntest.actions.run_and_verify_svn(None, None, [], '-m', 'fumble file',
846 'copy', beta_path, beta2_url)
847 # and a directory
848 svntest.actions.run_and_verify_svn(None, None, [], '-m', 'fumble dir',
849 'copy', H_path, H2_url)
850 # copy a file to a directory
851 svntest.actions.run_and_verify_svn(None, None, [], '-m', 'fumble file',
852 'copy', beta_path, H2_url)
854 # update the working copy. post-update mereinfo elision will remove
855 # A/D/H2/beta's mergeinfo, leaving a local mod.
856 expected_output = svntest.wc.State(wc_dir, {
857 'A/B/E/beta2' : Item(status='A '),
858 'A/D/H2' : Item(status='A '),
859 'A/D/H2/chi' : Item(status='A '),
860 'A/D/H2/omega' : Item(status='A '),
861 'A/D/H2/psi' : Item(status='A '),
862 'A/D/H2/beta' : Item(status='A '),
864 expected_disk = svntest.main.greek_state.copy()
865 expected_disk.tweak('A/D/H/omega',
866 contents="This is the file 'omega'.\nnew otext\n")
867 expected_disk.add({
868 'A/B/E/beta2' : Item("This is the file 'beta'.\n"),
869 'A/D/H2/chi' : Item("This is the file 'chi'.\n"),
870 'A/D/H2/omega' : Item("This is the file 'omega'.\nnew otext\n"),
871 'A/D/H2/psi' : Item("This is the file 'psi'.\n"),
872 'A/D/H2/beta' : Item("This is the file 'beta'.\n"),
874 expected_status = svntest.actions.get_virginal_state(wc_dir, 4)
875 expected_status.add({
876 'A/B/E/beta' : Item(status=' M', wc_rev=4),
877 'A/D/H/omega' : Item(status='M ', wc_rev=4),
878 'A/B/E/beta2' : Item(status=' ', wc_rev=4),
879 'A/D/H2' : Item(status=' ', wc_rev=4),
880 'A/D/H2/chi' : Item(status=' ', wc_rev=4),
881 'A/D/H2/omega' : Item(status=' ', wc_rev=4),
882 'A/D/H2/psi' : Item(status=' ', wc_rev=4),
883 'A/D/H2/beta' : Item(status=' ', wc_rev=4),
885 svntest.actions.run_and_verify_update(wc_dir,
886 expected_output,
887 expected_disk,
888 expected_status)
890 # check local property was copied
891 svntest.actions.run_and_verify_svn(None, ['bar\n'], [],
892 'propget', 'foo',
893 beta_path + "2")
895 #----------------------------------------------------------------------
896 # Issue 1090: various use-cases of 'svn cp URL wc' where the
897 # repositories might be different, or be the same repository.
899 def repos_to_wc(sbox):
900 "repository to working-copy copy"
902 sbox.build()
903 wc_dir = sbox.wc_dir
905 # We have a standard repository and working copy. Now we create a
906 # second repository with the same greek tree, but different UUID.
907 repo_dir = sbox.repo_dir
908 other_repo_dir, other_repo_url = sbox.add_repo_path('other')
909 svntest.main.copy_repos(repo_dir, other_repo_dir, 1, 1)
911 # URL->wc copy:
912 # copy a file and a directory from the same repository.
913 # we should get some scheduled additions *with history*.
914 E_url = sbox.repo_url + "/A/B/E"
915 pi_url = sbox.repo_url + "/A/D/G/pi"
916 pi_path = os.path.join(wc_dir, 'pi')
918 svntest.actions.run_and_verify_svn(None, None, [], 'copy', E_url, wc_dir)
919 svntest.actions.run_and_verify_svn(None, None, [], 'copy', pi_url, wc_dir)
921 # Extra test: modify file ASAP to check there was a timestamp sleep
922 svntest.main.file_append(pi_path, 'zig\n')
924 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
925 expected_output.add({
926 'pi' : Item(status='A ', copied='+', wc_rev='-'),
927 'E' : Item(status='A ', copied='+', wc_rev='-'),
928 'E/alpha' : Item(status=' ', copied='+', wc_rev='-'),
929 'E/beta' : Item(status=' ', copied='+', wc_rev='-'),
931 svntest.actions.run_and_verify_status(wc_dir, expected_output)
933 # Modification will only show up if timestamps differ
934 out,err = svntest.main.run_svn(None, 'diff', pi_path)
935 if err or not out:
936 print "diff failed"
937 raise svntest.Failure
938 for line in out:
939 if line == '+zig\n': # Crude check for diff-like output
940 break
941 else:
942 print "diff output incorrect", out
943 raise svntest.Failure
945 # Revert everything and verify.
946 svntest.actions.run_and_verify_svn(None, None, [], 'revert', '-R', wc_dir)
948 svntest.main.safe_rmtree(os.path.join(wc_dir, 'E'))
949 os.unlink(os.path.join(wc_dir, 'pi'))
951 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
952 svntest.actions.run_and_verify_status(wc_dir, expected_output)
954 # URL->wc copy:
955 # Copy an empty directory from the same repository, see issue #1444.
956 C_url = sbox.repo_url + "/A/C"
958 svntest.actions.run_and_verify_svn(None, None, [], 'copy', C_url, wc_dir)
960 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
961 expected_output.add({
962 'C' : Item(status='A ', copied='+', wc_rev='-'),
964 svntest.actions.run_and_verify_status(wc_dir, expected_output)
966 # Revert everything and verify.
967 svntest.actions.run_and_verify_svn(None, None, [], 'revert', '-R', wc_dir)
969 svntest.main.safe_rmtree(os.path.join(wc_dir, 'C'))
971 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
972 svntest.actions.run_and_verify_status(wc_dir, expected_output)
974 # URL->wc copy:
975 # copy a file and a directory from a foreign repository.
976 # we should get some scheduled additions *without history*.
977 E_url = other_repo_url + "/A/B/E"
978 pi_url = other_repo_url + "/A/D/G/pi"
980 # Expect an error in the directory case
981 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
982 'copy', E_url, wc_dir)
984 # But file case should work fine.
985 svntest.actions.run_and_verify_svn(None, None, [], 'copy', pi_url, wc_dir)
987 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
988 expected_output.add({
989 'pi' : Item(status='A ', wc_rev='1'),
991 svntest.actions.run_and_verify_status(wc_dir, expected_output)
993 # Revert everything and verify.
994 svntest.actions.run_and_verify_svn(None, None, [], 'revert', '-R', wc_dir)
995 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
997 # URL->wc copy:
998 # Copy a directory to a pre-existing WC directory.
999 # The source directory should be copied *under* the target directory.
1000 B_url = sbox.repo_url + "/A/B"
1001 D_dir = os.path.join(wc_dir, 'A', 'D')
1003 svntest.actions.run_and_verify_svn(None, None, [],
1004 'copy', B_url, D_dir)
1006 expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
1007 expected_output.add({
1008 'A/D/B' : Item(status='A ', copied='+', wc_rev='-'),
1009 'A/D/B/lambda' : Item(status=' ', copied='+', wc_rev='-'),
1010 'A/D/B/E' : Item(status=' ', copied='+', wc_rev='-'),
1011 'A/D/B/E/beta' : Item(status=' ', copied='+', wc_rev='-'),
1012 'A/D/B/E/alpha' : Item(status=' ', copied='+', wc_rev='-'),
1013 'A/D/B/F' : Item(status=' ', copied='+', wc_rev='-'),
1015 svntest.actions.run_and_verify_status(wc_dir, expected_output)
1017 # Validate that the merge info of the copy destination has been initialized.
1018 svntest.actions.run_and_verify_svn(None, ['\n'], [],
1019 'propget', SVN_PROP_MERGE_INFO,
1020 os.path.join(D_dir, 'B'))
1022 #----------------------------------------------------------------------
1023 # Issue 1084: ra_svn move/copy bug
1025 def copy_to_root(sbox):
1026 'copy item to root of repository'
1028 sbox.build()
1029 wc_dir = sbox.wc_dir
1031 root = sbox.repo_url
1032 mu = root + '/A/mu'
1034 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1035 '-m', '',
1036 mu, root)
1038 # Update to HEAD, and check to see if the files really were copied in the
1039 # repo
1041 expected_output = svntest.wc.State(wc_dir, {
1042 'mu': Item(status='A '),
1045 expected_disk = svntest.main.greek_state.copy()
1046 expected_disk.add({
1047 'mu': Item(contents="This is the file 'mu'.\n")
1050 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
1051 expected_status.add({
1052 'mu': Item(status=' ', wc_rev=2),
1055 svntest.actions.run_and_verify_update(wc_dir,
1056 expected_output,
1057 expected_disk,
1058 expected_status)
1060 #----------------------------------------------------------------------
1061 def url_copy_parent_into_child(sbox):
1062 "copy URL URL/subdir"
1064 sbox.build()
1065 wc_dir = sbox.wc_dir
1067 B_url = sbox.repo_url + "/A/B"
1068 F_url = sbox.repo_url + "/A/B/F"
1070 # Issue 1367 parent/child URL-to-URL was rejected.
1071 svntest.actions.run_and_verify_svn(None,
1072 ['\n', 'Committed revision 2.\n'], [],
1073 'cp',
1074 '-m', 'a can of worms',
1075 B_url, F_url)
1077 # Do an update to verify the copy worked
1078 expected_output = svntest.wc.State(wc_dir, {
1079 'A/B/F/B' : Item(status='A '),
1080 'A/B/F/B/E' : Item(status='A '),
1081 'A/B/F/B/E/alpha' : Item(status='A '),
1082 'A/B/F/B/E/beta' : Item(status='A '),
1083 'A/B/F/B/F' : Item(status='A '),
1084 'A/B/F/B/lambda' : Item(status='A '),
1086 expected_disk = svntest.main.greek_state.copy()
1087 expected_disk.add({
1088 'A/B/F/B' : Item(),
1089 'A/B/F/B/E' : Item(),
1090 'A/B/F/B/E/alpha' : Item("This is the file 'alpha'.\n"),
1091 'A/B/F/B/E/beta' : Item("This is the file 'beta'.\n"),
1092 'A/B/F/B/F' : Item(),
1093 'A/B/F/B/lambda' : Item("This is the file 'lambda'.\n"),
1095 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
1096 expected_status.add({
1097 'A/B/F/B' : Item(status=' ', wc_rev=2),
1098 'A/B/F/B/E' : Item(status=' ', wc_rev=2),
1099 'A/B/F/B/E/alpha' : Item(status=' ', wc_rev=2),
1100 'A/B/F/B/E/beta' : Item(status=' ', wc_rev=2),
1101 'A/B/F/B/F' : Item(status=' ', wc_rev=2),
1102 'A/B/F/B/lambda' : Item(status=' ', wc_rev=2),
1104 svntest.actions.run_and_verify_update(wc_dir,
1105 expected_output,
1106 expected_disk,
1107 expected_status)
1109 #----------------------------------------------------------------------
1110 def wc_copy_parent_into_child(sbox):
1111 "copy WC URL/subdir"
1113 sbox.build(create_wc = False)
1114 wc_dir = sbox.wc_dir
1116 B_url = sbox.repo_url + "/A/B"
1117 F_B_url = sbox.repo_url + "/A/B/F/B"
1119 # Want a smaller WC
1120 svntest.main.safe_rmtree(wc_dir)
1121 svntest.actions.run_and_verify_svn(None, None, [],
1122 'checkout',
1123 B_url, wc_dir)
1125 # Issue 1367: A) copying '.' to URL failed with a parent/child
1126 # error, and also B) copying root of a working copy attempted to
1127 # lock the non-working copy parent directory.
1128 was_cwd = os.getcwd()
1129 os.chdir(wc_dir)
1131 svntest.actions.run_and_verify_svn(None,
1132 ['\n', 'Committed revision 2.\n'], [],
1133 'cp',
1134 '-m', 'a larger can',
1135 '.', F_B_url)
1137 os.chdir(was_cwd)
1139 # Do an update to verify the copy worked
1140 expected_output = svntest.wc.State(wc_dir, {
1141 'F/B' : Item(status='A '),
1142 'F/B/E' : Item(status='A '),
1143 'F/B/E/alpha' : Item(status='A '),
1144 'F/B/E/beta' : Item(status='A '),
1145 'F/B/F' : Item(status='A '),
1146 'F/B/lambda' : Item(status='A '),
1148 expected_disk = svntest.wc.State('', {
1149 'E' : Item(),
1150 'E/alpha' : Item("This is the file 'alpha'.\n"),
1151 'E/beta' : Item("This is the file 'beta'.\n"),
1152 'F' : Item(),
1153 'lambda' : Item("This is the file 'lambda'.\n"),
1154 'F/B' : Item(),
1155 'F/B/E' : Item(),
1156 'F/B/E/alpha' : Item("This is the file 'alpha'.\n"),
1157 'F/B/E/beta' : Item("This is the file 'beta'.\n"),
1158 'F/B/F' : Item(),
1159 'F/B/lambda' : Item("This is the file 'lambda'.\n"),
1161 expected_status = svntest.wc.State(wc_dir, {
1162 '' : Item(status=' ', wc_rev=2),
1163 'E' : Item(status=' ', wc_rev=2),
1164 'E/alpha' : Item(status=' ', wc_rev=2),
1165 'E/beta' : Item(status=' ', wc_rev=2),
1166 'F' : Item(status=' ', wc_rev=2),
1167 'lambda' : Item(status=' ', wc_rev=2),
1168 'F/B' : Item(status=' ', wc_rev=2),
1169 'F/B/E' : Item(status=' ', wc_rev=2),
1170 'F/B/E/alpha' : Item(status=' ', wc_rev=2),
1171 'F/B/E/beta' : Item(status=' ', wc_rev=2),
1172 'F/B/F' : Item(status=' ', wc_rev=2),
1173 'F/B/lambda' : Item(status=' ', wc_rev=2),
1175 svntest.actions.run_and_verify_update(wc_dir,
1176 expected_output,
1177 expected_disk,
1178 expected_status)
1180 #----------------------------------------------------------------------
1181 # Issue 1419: at one point ra_neon->get_uuid() was failing on a
1182 # non-existent public URL, which prevented us from resurrecting files
1183 # (svn cp -rOLD URL wc).
1185 def resurrect_deleted_file(sbox):
1186 "resurrect a deleted file"
1188 sbox.build()
1189 wc_dir = sbox.wc_dir
1191 # Delete a file in the repository via immediate commit
1192 rho_url = sbox.repo_url + '/A/D/G/rho'
1193 svntest.actions.run_and_verify_svn(None, None, [],
1194 'rm', rho_url, '-m', 'rev 2')
1196 # Update the wc to HEAD (r2)
1197 expected_output = svntest.wc.State(wc_dir, {
1198 'A/D/G/rho' : Item(status='D '),
1200 expected_disk = svntest.main.greek_state.copy()
1201 expected_disk.remove('A/D/G/rho')
1202 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
1203 expected_status.remove('A/D/G/rho')
1204 svntest.actions.run_and_verify_update(wc_dir,
1205 expected_output,
1206 expected_disk,
1207 expected_status)
1209 # repos->wc copy, to resurrect deleted file.
1210 svntest.actions.run_and_verify_svn("Copy error:", None, [],
1211 'cp', rho_url + '@1', wc_dir)
1213 # status should now show the file scheduled for addition-with-history
1214 expected_status.add({
1215 'rho' : Item(status='A ', copied='+', wc_rev='-'),
1217 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1219 #-------------------------------------------------------------
1220 # Regression tests for Issue #1297:
1221 # svn diff failed after a repository to WC copy of a single file
1222 # This test checks just that.
1224 def diff_repos_to_wc_copy(sbox):
1225 "copy file from repos to working copy and run diff"
1227 sbox.build()
1228 wc_dir = sbox.wc_dir
1230 iota_repos_path = sbox.repo_url + '/iota'
1231 target_wc_path = os.path.join(wc_dir, 'new_file')
1233 # Copy a file from the repository to the working copy.
1234 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1235 iota_repos_path, target_wc_path)
1237 # Run diff.
1238 svntest.actions.run_and_verify_svn(None, None, [], 'diff', wc_dir)
1241 #-------------------------------------------------------------
1243 def repos_to_wc_copy_eol_keywords(sbox):
1244 "repos->WC copy with keyword or eol property set"
1246 # See issue #1473: repos->wc copy would seg fault if svn:keywords or
1247 # svn:eol were set on the copied file, because we'd be querying an
1248 # entry for keyword values when the entry was still null (because
1249 # not yet been fully installed in the wc).
1251 sbox.build()
1252 wc_dir = sbox.wc_dir
1254 iota_repos_path = sbox.repo_url + '/iota'
1255 iota_wc_path = os.path.join(wc_dir, 'iota')
1256 target_wc_path = os.path.join(wc_dir, 'new_file')
1258 # Modify iota to make it checkworthy.
1259 svntest.main.file_write(iota_wc_path,
1260 "Hello\nSubversion\n$LastChangedRevision$\n",
1261 "ab")
1263 svntest.actions.run_and_verify_svn(None, None, [],
1264 'propset', 'svn:eol-style',
1265 'CRLF', iota_wc_path)
1267 svntest.actions.run_and_verify_svn(None, None, [],
1268 'propset', 'svn:keywords',
1269 'Rev', iota_wc_path)
1271 svntest.actions.run_and_verify_svn(None, None, [],
1272 'commit', '-m', 'log msg',
1273 wc_dir)
1275 # Copy a file from the repository to the working copy.
1276 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1277 iota_repos_path, target_wc_path)
1279 # The original bug was that the copy would seg fault. So we test
1280 # that the copy target exists now; if it doesn't, it's probably
1281 # because of the segfault. Note that the crash would be independent
1282 # of whether there are actually any line breaks or keywords in the
1283 # file's contents -- the mere existence of the property would
1284 # trigger the bug.
1285 if not os.path.exists(target_wc_path):
1286 raise svntest.Failure
1288 # Okay, if we got this far, we might as well make sure that the
1289 # translations/substitutions were done correctly:
1290 f = open(target_wc_path, "rb")
1291 raw_contents = f.read()
1292 f.seek(0, 0)
1293 line_contents = f.readlines()
1294 f.close()
1296 if re.match('[^\\r]\\n', raw_contents):
1297 raise svntest.Failure
1299 if not re.match('.*\$LastChangedRevision:\s*\d+\s*\$', line_contents[3]):
1300 raise svntest.Failure
1302 #-------------------------------------------------------------
1303 # Regression test for revision 7331, with commented-out parts for a further
1304 # similar bug.
1306 def revision_kinds_local_source(sbox):
1307 "revision-kind keywords with non-URL source"
1309 sbox.build()
1310 wc_dir = sbox.wc_dir
1312 mu_path = os.path.join(wc_dir, 'A', 'mu')
1314 # Make a file with different content in each revision and WC; BASE != HEAD.
1315 expected_output = svntest.wc.State(wc_dir, {
1316 'A/mu' : Item(verb='Sending'), })
1317 svntest.main.file_append(mu_path, "New r2 text.\n")
1318 svntest.actions.run_and_verify_commit(wc_dir, expected_output, None,
1319 None, None, None, None, None, wc_dir)
1320 svntest.main.file_append(mu_path, "New r3 text.\n")
1321 svntest.actions.run_and_verify_commit(wc_dir, expected_output, None,
1322 None, None, None, None, None, wc_dir)
1323 svntest.actions.run_and_verify_svn(None, None, [], 'up', '-r2', mu_path)
1324 svntest.main.file_append(mu_path, "Working copy.\n")
1326 r1 = "This is the file 'mu'.\n"
1327 r2 = r1 + "New r2 text.\n"
1328 r3 = r2 + "New r3 text.\n"
1329 rWC = r2 + "Working copy.\n"
1331 expected_disk = svntest.main.greek_state.copy()
1332 expected_disk.tweak('A/mu', contents=rWC)
1334 # Test the various revision-kind keywords, and none.
1335 sub_tests = [ ('file0', 2, rWC, None),
1336 ('file1', 3, r3, 'HEAD'),
1337 ('file2', 2, r2, 'BASE'),
1338 # ('file3', 2, r2, 'COMMITTED'),
1339 # ('file4', 1, r1, 'PREV'),
1342 for dst, from_rev, text, peg_rev in sub_tests:
1343 dst_path = os.path.join(wc_dir, dst)
1344 if peg_rev is None:
1345 svntest.actions.run_and_verify_svn(None, None, [], "copy",
1346 mu_path, dst_path)
1347 else:
1348 svntest.actions.run_and_verify_svn(None, None, [], "copy",
1349 mu_path + "@" + peg_rev, dst_path)
1350 expected_disk.add({ dst: Item(contents=text) })
1352 # Check that the copied-from revision == from_rev.
1353 output, errput = svntest.main.run_svn(None, "info", dst_path)
1354 for line in output:
1355 if line.rstrip() == "Copied From Rev: " + str(from_rev):
1356 break
1357 else:
1358 print dst, "should have been copied from revision", from_rev
1359 raise svntest.Failure
1361 # Check that the new files have the right contents
1362 actual_disk = svntest.tree.build_tree_from_wc(wc_dir)
1363 svntest.tree.compare_trees(actual_disk, expected_disk.old_tree())
1366 #-------------------------------------------------------------
1367 # Regression test for issue 1581.
1369 def copy_over_missing_file(sbox):
1370 "copy over a missing file"
1371 sbox.build()
1372 wc_dir = sbox.wc_dir
1374 mu_path = os.path.join(wc_dir, 'A', 'mu')
1375 iota_path = os.path.join(wc_dir, 'iota')
1376 iota_url = sbox.repo_url + "/iota"
1378 # Make the target missing.
1379 os.remove(mu_path)
1381 # Try both wc->wc copy and repos->wc copy, expect failures:
1382 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
1383 'cp', iota_path, mu_path)
1385 svntest.actions.run_and_verify_svn(None, None, svntest.verify.AnyOutput,
1386 'cp', iota_url, mu_path)
1388 # Make sure that the working copy is not corrupted:
1389 expected_disk = svntest.main.greek_state.copy()
1390 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1391 expected_output = svntest.wc.State(wc_dir, {'A/mu' : Item(verb='Restored')})
1392 svntest.actions.run_and_verify_update(wc_dir,
1393 expected_output,
1394 expected_disk,
1395 expected_status)
1399 #----------------------------------------------------------------------
1400 # Regression test for issue 1634
1402 def repos_to_wc_1634(sbox):
1403 "copy a deleted directory back from the repos"
1405 sbox.build()
1406 wc_dir = sbox.wc_dir
1408 # First delete a subdirectory and commit.
1409 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
1410 svntest.actions.run_and_verify_svn(None, None, [], 'delete', E_path)
1411 expected_output = svntest.wc.State(wc_dir, {
1412 'A/B/E' : Item(verb='Deleting'),
1414 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1415 expected_status.remove('A/B/E', 'A/B/E/alpha', 'A/B/E/beta')
1416 svntest.actions.run_and_verify_commit(wc_dir,
1417 expected_output,
1418 expected_status,
1419 None, None, None, None, None,
1420 wc_dir)
1422 # Now copy the directory back.
1423 E_url = sbox.repo_url + "/A/B/E@1"
1424 svntest.actions.run_and_verify_svn(None, None, [],
1425 'copy', E_url, E_path)
1426 expected_status.add({
1427 'A/B/E' : Item(status='A ', copied='+', wc_rev='-'),
1428 'A/B/E/alpha' : Item(status=' ', copied='+', wc_rev='-'),
1429 'A/B/E/beta' : Item(status=' ', copied='+', wc_rev='-'),
1431 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1433 svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
1434 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
1435 expected_status.add({
1436 'A/B/E' : Item(status='A ', copied='+', wc_rev='-'),
1437 'A/B/E/alpha' : Item(status=' ', copied='+', wc_rev='-'),
1438 'A/B/E/beta' : Item(status=' ', copied='+', wc_rev='-'),
1440 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1442 #----------------------------------------------------------------------
1443 # Regression test for issue 1814
1445 def double_uri_escaping_1814(sbox):
1446 "check for double URI escaping in svn ls -R"
1448 sbox.build(create_wc = False)
1450 base_url = sbox.repo_url + '/base'
1452 # rev. 2
1453 svntest.actions.run_and_verify_svn(None, None, [],
1454 'mkdir', '-m', 'mybase',
1455 base_url)
1457 orig_url = base_url + '/foo%20bar'
1459 # rev. 3
1460 svntest.actions.run_and_verify_svn(None, None, [],
1461 'mkdir', '-m', 'r1',
1462 orig_url)
1463 orig_rev = 3
1465 # rev. 4
1466 new_url = base_url + '/foo_bar'
1467 svntest.actions.run_and_verify_svn(None, None, [],
1468 'mv', '-m', 'r2',
1469 orig_url, new_url)
1471 # This had failed with ra_neon because "foo bar" would be double-encoded
1472 # "foo bar" ==> "foo%20bar" ==> "foo%2520bar"
1473 svntest.actions.run_and_verify_svn(None, None, [],
1474 'ls', ('-r'+str(orig_rev)),
1475 '-R', base_url)
1478 #----------------------------------------------------------------------
1479 # Regression test for issues 2404
1481 def wc_to_wc_copy_between_different_repos(sbox):
1482 "wc to wc copy attempts between different repos"
1484 sbox.build()
1485 wc_dir = sbox.wc_dir
1487 sbox2 = sbox.clone_dependent()
1488 sbox2.build()
1489 wc2_dir = sbox2.wc_dir
1491 # Attempt a copy between different repositories.
1492 out, err = svntest.main.run_svn(1, 'cp',
1493 os.path.join(wc2_dir, 'A'),
1494 os.path.join(wc_dir, 'A', 'B'))
1495 for line in err:
1496 if line.find("it is not from repository") != -1:
1497 break
1498 else:
1499 raise svntest.Failure
1501 #----------------------------------------------------------------------
1502 # Regression test for issues 2101 and 2020
1504 def wc_to_wc_copy_deleted(sbox):
1505 "wc to wc copy with deleted=true items"
1507 sbox.build()
1508 wc_dir = sbox.wc_dir
1510 B_path = os.path.join(wc_dir, 'A', 'B')
1511 B2_path = os.path.join(wc_dir, 'A', 'B2')
1513 # Schedule for delete
1514 svntest.actions.run_and_verify_svn(None, None, [], 'rm',
1515 os.path.join(B_path, 'E', 'alpha'),
1516 os.path.join(B_path, 'lambda'),
1517 os.path.join(B_path, 'F'))
1518 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1519 expected_status.tweak('A/B/E/alpha', 'A/B/lambda', 'A/B/F', status='D ')
1520 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1522 # Copy to schedule=delete fails
1523 out, err = svntest.main.run_svn(1, 'cp',
1524 os.path.join(B_path, 'E'),
1525 os.path.join(B_path, 'F'))
1526 for line in err:
1527 if line.find("is scheduled for deletion") != -1:
1528 break
1529 else:
1530 raise svntest.Failure
1531 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1534 # Commit to get state deleted
1535 expected_status.remove('A/B/E/alpha', 'A/B/lambda', 'A/B/F')
1536 expected_output = svntest.wc.State(wc_dir, {
1537 'A/B/E/alpha' : Item(verb='Deleting'),
1538 'A/B/lambda' : Item(verb='Deleting'),
1539 'A/B/F' : Item(verb='Deleting'),
1541 svntest.actions.run_and_verify_commit(wc_dir,
1542 expected_output,
1543 expected_status,
1544 None, None, None, None, None,
1545 wc_dir)
1547 # Copy including stuff in state deleted=true
1548 svntest.actions.run_and_verify_svn(None, None, [], 'copy', B_path, B2_path)
1549 expected_status.add({
1550 'A/B2' : Item(status='A ', wc_rev='-', copied='+'),
1551 'A/B2/E' : Item(status=' ', wc_rev='-', copied='+'),
1552 'A/B2/E/beta' : Item(status=' ', wc_rev='-', copied='+'),
1553 'A/B2/E/alpha' : Item(status='D ', wc_rev='-', copied='+'),
1554 'A/B2/lambda' : Item(status='D ', wc_rev='-', copied='+'),
1555 'A/B2/F' : Item(status='D ', wc_rev='-', copied='+'),
1557 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1559 # Stuff copied from state deleted=true is now schedule=delete.
1560 # Attempts to revert the schedule=delete will fail, but should not
1561 # break the wc. It's very important that the directory revert fails
1562 # since it's a placeholder rather than a full hierarchy
1563 out, err = svntest.main.run_svn(1, 'revert', '--recursive',
1564 os.path.join(B2_path, 'F'))
1565 for line in err:
1566 if line.find("Error restoring text") != -1:
1567 break
1568 else:
1569 raise svntest.Failure
1570 out, err = svntest.main.run_svn(1, 'revert', os.path.join(B2_path, 'lambda'))
1571 for line in err:
1572 if line.find("Error restoring text") != -1:
1573 break
1574 else:
1575 raise svntest.Failure
1576 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1578 # Revert the entire copy including the schedule delete bits
1579 svntest.actions.run_and_verify_svn(None, None, [], 'revert', '--recursive',
1580 B2_path)
1581 expected_status.remove('A/B2',
1582 'A/B2/E',
1583 'A/B2/E/beta',
1584 'A/B2/E/alpha',
1585 'A/B2/lambda',
1586 'A/B2/F')
1587 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1588 svntest.main.safe_rmtree(B2_path)
1590 # Copy again and commit
1591 svntest.actions.run_and_verify_svn(None, None, [], 'copy', B_path, B2_path)
1592 expected_status.add({
1593 'A/B2' : Item(status=' ', wc_rev=3),
1594 'A/B2/E' : Item(status=' ', wc_rev=3),
1595 'A/B2/E/beta' : Item(status=' ', wc_rev=3),
1597 expected_output = svntest.wc.State(wc_dir, {
1598 'A/B2' : Item(verb='Adding'),
1599 'A/B2/E/alpha' : Item(verb='Deleting'),
1600 'A/B2/lambda' : Item(verb='Deleting'),
1601 'A/B2/F' : Item(verb='Deleting'),
1603 svntest.actions.run_and_verify_commit(wc_dir,
1604 expected_output,
1605 expected_status,
1606 None, None, None, None, None,
1607 wc_dir)
1609 #----------------------------------------------------------------------
1610 # Test for copy into a non-existent URL path
1611 def url_to_non_existent_url_path(sbox):
1612 "svn cp src-URL non-existent-URL-path"
1614 sbox.build(create_wc = False)
1616 dirURL1 = sbox.repo_url + "/A/B/E"
1617 dirURL2 = sbox.repo_url + "/G/C/E/I"
1619 # Look for both possible versions of the error message, as the DAV
1620 # error is worded differently from that of other RA layers.
1621 msg = ".*: (Path 'G(/C/E)?' not present|.*G(/C/E)?' path not found)"
1623 # Expect failure on 'svn cp SRC DST' where one or more ancestor
1624 # directories of DST do not exist
1625 out, err = svntest.main.run_svn(1,
1626 'cp', dirURL1, dirURL2,
1627 '-m', 'fooogle')
1628 for err_line in err:
1629 if re.match (msg, err_line):
1630 break
1631 else:
1632 print "message \"" + msg + "\" not found in error output: ", err
1633 raise svntest.Failure
1636 #----------------------------------------------------------------------
1637 # Test for a copying (URL to URL) an old rev of a deleted file in a
1638 # deleted directory.
1639 def non_existent_url_to_url(sbox):
1640 "svn cp oldrev-of-deleted-URL URL"
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 new_url = sbox.repo_url + '/newfile'
1648 svntest.actions.run_and_verify_svn(None, None, [],
1649 'delete',
1650 adg_url, '-m', '')
1652 svntest.actions.run_and_verify_svn(None, None, [],
1653 'copy',
1654 pi_url + '@1', new_url,
1655 '-m', '')
1657 #----------------------------------------------------------------------
1658 def old_dir_url_to_url(sbox):
1659 "test URL to URL copying edge case"
1661 sbox.build(create_wc = False)
1663 adg_url = sbox.repo_url + '/A/D/G'
1664 pi_url = sbox.repo_url + '/A/D/G/pi'
1665 iota_url = sbox.repo_url + '/iota'
1666 new_url = sbox.repo_url + '/newfile'
1668 # Delete a directory
1669 svntest.actions.run_and_verify_svn(None, None, [],
1670 'delete',
1671 adg_url, '-m', '')
1673 # Copy a file to where the directory used to be
1674 svntest.actions.run_and_verify_svn(None, None, [],
1675 'copy',
1676 iota_url, adg_url,
1677 '-m', '')
1679 # Try copying a file that was in the deleted directory that is now a
1680 # file
1681 svntest.actions.run_and_verify_svn(None, None, [],
1682 'copy',
1683 pi_url + '@1', new_url,
1684 '-m', '')
1688 #----------------------------------------------------------------------
1689 # Test fix for issue 2224 - copying wc dir to itself causes endless
1690 # recursion
1691 def wc_copy_dir_to_itself(sbox):
1692 "copy wc dir to itself"
1694 sbox.build()
1695 wc_dir = sbox.wc_dir
1696 dnames = ['A','A/B']
1698 for dirname in dnames:
1699 dir_path = os.path.join(wc_dir, dirname)
1701 # try to copy dir to itself
1702 svntest.actions.run_and_verify_svn(None, [],
1703 '.*Cannot copy .* into its own child.*',
1704 'copy', dir_path, dir_path)
1707 #----------------------------------------------------------------------
1709 def mixed_wc_to_url(sbox):
1710 "copy a complex mixed-rev wc"
1712 # For issue 2153.
1714 # Copy a mixed-revision wc (that also has some uncommitted local
1715 # mods, and an entry marked as 'deleted') to a URL. Make sure the
1716 # copy gets the uncommitted mods, and does not contain the deleted
1717 # file.
1719 sbox.build()
1721 wc_dir = sbox.wc_dir
1722 Z_url = sbox.repo_url + '/A/D/Z'
1723 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
1724 pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
1725 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
1727 # Remove A/D/G/pi, then commit that removal.
1728 svntest.actions.run_and_verify_svn(None, None, [], 'rm', pi_path)
1729 svntest.actions.run_and_verify_svn(None, None, [],
1730 'ci', '-m', "Delete pi.", wc_dir)
1732 # Make a modification to A/D/G/rho, then commit that modification.
1733 svntest.main.file_append(rho_path, "\nFirst modification to rho.\n")
1734 svntest.actions.run_and_verify_svn(None, None, [],
1735 'ci', '-m', "Modify rho.", wc_dir)
1737 # Make another modification to A/D/G/rho, but don't commit it.
1738 svntest.main.file_append(rho_path, "Second modification to rho.\n")
1740 # Now copy local A/D/G to create new directory A/D/Z the repository.
1741 svntest.actions.run_and_verify_svn(None, None, [],
1742 'cp', '-m', "Make a copy.",
1743 G_path, Z_url)
1745 # Check out A/D/Z. If it has pi, that's a bug; or if its rho does
1746 # not have the second local mod, that's also a bug.
1747 svntest.main.safe_rmtree(wc_dir)
1748 svntest.actions.run_and_verify_svn(None, None, [],
1749 'co', Z_url, wc_dir)
1751 if os.path.exists(os.path.join(wc_dir, 'pi')):
1752 raise svntest.Failure
1754 fp = open(os.path.join(wc_dir, 'rho'), 'r')
1755 found_it = 0
1756 for line in fp.readlines():
1757 if re.match("^Second modification to rho.", line):
1758 found_it = 1
1759 if not found_it:
1760 raise svntest.Failure
1763 #----------------------------------------------------------------------
1765 # Issue 845 and 1516: WC replacement of files requires
1766 # a second text-base and prop-base
1768 def wc_copy_replacement(sbox):
1769 "svn cp PATH PATH replace file"
1771 copy_replace(sbox, 1)
1773 def wc_copy_replace_with_props(sbox):
1774 "svn cp PATH PATH replace file with props"
1776 copy_replace_with_props(sbox, 1)
1779 def repos_to_wc_copy_replacement(sbox):
1780 "svn cp URL PATH replace file"
1782 copy_replace(sbox, 0)
1784 def repos_to_wc_copy_replace_with_props(sbox):
1785 "svn cp URL PATH replace file with props"
1787 copy_replace_with_props(sbox, 0)
1789 def delete_replaced_file(sbox):
1790 "delete file scheduled for replace"
1792 sbox.build()
1793 wc_dir = sbox.wc_dir
1795 # File scheduled for deletion.
1796 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
1797 svntest.actions.run_and_verify_svn(None, None, [], 'rm', rho_path)
1799 # Status before attempting copies
1800 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1801 expected_status.tweak('A/D/G/rho', status='D ')
1802 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1804 # Copy 'pi' over 'rho' with history.
1805 pi_src = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
1806 svntest.actions.run_and_verify_svn(None, None, [], 'cp', pi_src, rho_path)
1808 # Check that file copied.
1809 expected_status.tweak('A/D/G/rho', status='R ', copied='+', wc_rev='-')
1810 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1812 # Now delete replaced file.
1813 svntest.actions.run_and_verify_svn(None, None, [], 'rm',
1814 '--force', rho_path)
1816 # Verify status after deletion.
1817 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1818 expected_status.tweak('A/D/G/rho', status='D ')
1819 svntest.actions.run_and_verify_status(wc_dir, expected_status)
1822 def mv_unversioned_file(sbox):
1823 "move an unversioned file"
1824 # Issue #2436: Attempting to move an unversioned file would seg fault.
1825 sbox.build()
1826 wc_dir = sbox.wc_dir
1828 unver_path_1 = os.path.join(wc_dir, 'unversioned1')
1829 dest_path_1 = os.path.join(wc_dir, 'dest')
1830 svntest.main.file_append(unver_path_1, "an unversioned file")
1832 unver_path_2 = os.path.join(wc_dir, 'A', 'unversioned2')
1833 dest_path_2 = os.path.join(wc_dir, 'A', 'dest_forced')
1834 svntest.main.file_append(unver_path_2, "another unversioned file")
1836 # Try to move an unversioned file.
1837 svntest.actions.run_and_verify_svn(None, None,
1838 ".*unversioned1.* is not under version control.*",
1839 'mv', unver_path_1, dest_path_1)
1841 # Try to forcibly move an unversioned file.
1842 svntest.actions.run_and_verify_svn(None, None,
1843 ".*unversioned2.* is not under version control.*",
1844 'mv',
1845 unver_path_2, dest_path_2)
1847 def force_move(sbox):
1848 "'move' should not lose local mods"
1849 # Issue #2435: 'svn move' / 'svn mv' can lose local modifications.
1850 sbox.build()
1851 wc_dir = sbox.wc_dir
1852 file_name = "iota"
1853 file_path = os.path.join(wc_dir, file_name)
1855 # modify the content
1856 file_handle = file(file_path, "a")
1857 file_handle.write("Added contents\n")
1858 file_handle.close()
1859 expected_file_content = [ "This is the file 'iota'.\n",
1860 "Added contents\n",
1863 # check for the new content
1864 file_handle = file(file_path, "r")
1865 modified_file_content = file_handle.readlines()
1866 file_handle.close()
1867 if modified_file_content != expected_file_content:
1868 raise svntest.Failure("Test setup failed. Incorrect file contents.")
1870 # force move the file
1871 move_output = [ "A dest\n",
1872 "D iota\n",
1874 was_cwd = os.getcwd()
1875 os.chdir(wc_dir)
1877 svntest.actions.run_and_verify_svn(None, move_output,
1879 'move',
1880 file_name, "dest")
1881 os.chdir(was_cwd)
1883 # check for the new content
1884 file_handle = file(os.path.join(wc_dir, "dest"), "r")
1885 modified_file_content = file_handle.readlines()
1886 file_handle.close()
1887 # Error if we dont find the modified contents...
1888 if modified_file_content != expected_file_content:
1889 raise svntest.Failure("File modifications were lost on 'move'")
1891 # Commit the move and make sure the new content actually reaches
1892 # the repository.
1893 expected_output = svntest.wc.State(wc_dir, {
1894 'iota': Item(verb='Deleting'),
1895 'dest': Item(verb='Adding'),
1897 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1898 expected_status.remove("iota")
1899 expected_status.add({
1900 'dest': Item(status=' ', wc_rev='2'),
1902 svntest.actions.run_and_verify_commit(wc_dir,
1903 expected_output,
1904 expected_status,
1905 None, None, None, None, None,
1906 wc_dir)
1907 svntest.actions.run_and_verify_svn('Cat file', expected_file_content, [],
1908 'cat',
1909 sbox.repo_url + '/dest')
1912 def copy_copied_file_and_dir(sbox):
1913 "copy a copied file and dir"
1914 # Improve support for copy and move
1915 # Allow copy of copied items without a commit between
1917 sbox.build()
1918 wc_dir = sbox.wc_dir
1920 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
1921 rho_copy_path_1 = os.path.join(wc_dir, 'A', 'D', 'rho_copy_1')
1922 rho_copy_path_2 = os.path.join(wc_dir, 'A', 'B', 'F', 'rho_copy_2')
1924 # Copy A/D/G/rho to A/D/rho_copy_1
1925 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1926 rho_path, rho_copy_path_1)
1928 # Copy the copied file: A/D/rho_copy_1 to A/B/F/rho_copy_2
1929 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1930 rho_copy_path_1, rho_copy_path_2)
1932 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
1933 E_path_copy_1 = os.path.join(wc_dir, 'A', 'B', 'F', 'E_copy_1')
1934 E_path_copy_2 = os.path.join(wc_dir, 'A', 'D', 'G', 'E_copy_2')
1936 # Copy A/B/E to A/B/F/E_copy_1
1937 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1938 E_path, E_path_copy_1)
1940 # Copy the copied dir: A/B/F/E_copy_1 to A/D/G/E_copy_2
1941 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1942 E_path_copy_1, E_path_copy_2)
1944 # Created expected output tree for 'svn ci':
1945 expected_output = svntest.wc.State(wc_dir, {
1946 'A/D/rho_copy_1' : Item(verb='Adding'),
1947 'A/B/F/rho_copy_2' : Item(verb='Adding'),
1948 'A/B/F/E_copy_1/' : Item(verb='Adding'),
1949 'A/D/G/E_copy_2/' : Item(verb='Adding'),
1952 # Create expected status tree
1953 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1954 expected_status.add({
1955 'A/D/rho_copy_1' : Item(status=' ', wc_rev=2),
1956 'A/B/F/rho_copy_2' : Item(status=' ', wc_rev=2),
1957 'A/B/F/E_copy_1' : Item(status=' ', wc_rev=2),
1958 'A/B/F/E_copy_1/alpha' : Item(status=' ', wc_rev=2),
1959 'A/B/F/E_copy_1/beta' : Item(status=' ', wc_rev=2),
1960 'A/D/G/E_copy_2' : Item(status=' ', wc_rev=2),
1961 'A/D/G/E_copy_2/alpha' : Item(status=' ', wc_rev=2),
1962 'A/D/G/E_copy_2/beta' : Item(status=' ', wc_rev=2),
1965 svntest.actions.run_and_verify_commit(wc_dir,
1966 expected_output,
1967 expected_status,
1968 None,
1969 None, None,
1970 None, None,
1971 wc_dir)
1974 def move_copied_file_and_dir(sbox):
1975 "move a copied file and dir"
1977 sbox.build()
1978 wc_dir = sbox.wc_dir
1980 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
1981 rho_copy_path = os.path.join(wc_dir, 'A', 'D', 'rho_copy')
1982 rho_copy_move_path = os.path.join(wc_dir, 'A', 'B', 'F', 'rho_copy_moved')
1984 # Copy A/D/G/rho to A/D/rho_copy
1985 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1986 rho_path, rho_copy_path)
1988 # Move the copied file: A/D/rho_copy to A/B/F/rho_copy_moved
1989 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
1990 rho_copy_path, rho_copy_move_path)
1992 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
1993 E_path_copy = os.path.join(wc_dir, 'A', 'B', 'F', 'E_copy')
1994 E_path_copy_move = os.path.join(wc_dir, 'A', 'D', 'G', 'E_copy_moved')
1996 # Copy A/B/E to A/B/F/E_copy
1997 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
1998 E_path, E_path_copy)
2000 # Move the copied file: A/B/F/E_copy to A/D/G/E_copy_moved
2001 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2002 E_path_copy, E_path_copy_move)
2004 # Created expected output tree for 'svn ci':
2005 # Since we are moving items that were only *scheduled* for addition
2006 # we expect only to additions when checking in, rather than a
2007 # deletion/addition pair.
2008 expected_output = svntest.wc.State(wc_dir, {
2009 'A/B/F/rho_copy_moved' : Item(verb='Adding'),
2010 'A/D/G/E_copy_moved/' : Item(verb='Adding'),
2013 # Create expected status tree
2014 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2015 expected_status.add({
2016 'A/B/F/rho_copy_moved' : Item(status=' ', wc_rev=2),
2017 'A/D/G/E_copy_moved' : Item(status=' ', wc_rev=2),
2018 'A/D/G/E_copy_moved/alpha' : Item(status=' ', wc_rev=2),
2019 'A/D/G/E_copy_moved/beta' : Item(status=' ', wc_rev=2),
2022 svntest.actions.run_and_verify_commit(wc_dir,
2023 expected_output,
2024 expected_status,
2025 None,
2026 None, None,
2027 None, None,
2028 wc_dir)
2031 def move_moved_file_and_dir(sbox):
2032 "move a moved file and dir"
2034 sbox.build()
2035 wc_dir = sbox.wc_dir
2037 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
2038 rho_move_path = os.path.join(wc_dir, 'A', 'D', 'rho_moved')
2039 rho_move_moved_path = os.path.join(wc_dir, 'A', 'B', 'F', 'rho_move_moved')
2041 # Move A/D/G/rho to A/D/rho_moved
2042 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2043 rho_path, rho_move_path)
2045 # Move the moved file: A/D/rho_moved to A/B/F/rho_move_moved
2046 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2047 rho_move_path, rho_move_moved_path)
2049 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
2050 E_path_moved = os.path.join(wc_dir, 'A', 'B', 'F', 'E_moved')
2051 E_path_move_moved = os.path.join(wc_dir, 'A', 'D', 'G', 'E_move_moved')
2053 # Copy A/B/E to A/B/F/E_moved
2054 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2055 E_path, E_path_moved)
2057 # Move the moved file: A/B/F/E_moved to A/D/G/E_move_moved
2058 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2059 E_path_moved, E_path_move_moved)
2061 # Created expected output tree for 'svn ci':
2062 expected_output = svntest.wc.State(wc_dir, {
2063 'A/B/E' : Item(verb='Deleting'),
2064 'A/D/G/E_move_moved/' : Item(verb='Adding'),
2065 'A/D/G/rho' : Item(verb='Deleting'),
2066 'A/B/F/rho_move_moved' : Item(verb='Adding'),
2069 # Create expected status tree
2070 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2071 expected_status.add({
2072 'A/D/G/E_move_moved/' : Item(status=' ', wc_rev=2),
2073 'A/D/G/E_move_moved/alpha' : Item(status=' ', wc_rev=2),
2074 'A/D/G/E_move_moved/beta' : Item(status=' ', wc_rev=2),
2075 'A/B/F/rho_move_moved' : Item(status=' ', wc_rev=2),
2078 expected_status.remove('A/B/E',
2079 'A/B/E/alpha',
2080 'A/B/E/beta',
2081 'A/D/G/rho')
2083 svntest.actions.run_and_verify_commit(wc_dir,
2084 expected_output,
2085 expected_status,
2086 None,
2087 None, None,
2088 None, None,
2089 wc_dir)
2092 def move_file_within_moved_dir(sbox):
2093 "move a file twice within a moved dir"
2095 sbox.build()
2096 wc_dir = sbox.wc_dir
2098 D_path = os.path.join(wc_dir, 'A', 'D')
2099 D_path_moved = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved')
2101 # Move A/B/D to A/B/F/D_moved
2102 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2103 D_path, D_path_moved)
2105 chi_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved', 'H', 'chi')
2106 chi_moved_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved',
2107 'H', 'chi_moved')
2108 chi_moved_again_path = os.path.join(wc_dir, 'A', 'B', 'F',
2109 'D_moved', 'H', 'chi_moved_again')
2111 # Move A/B/F/D_moved/H/chi to A/B/F/D_moved/H/chi_moved
2112 # then move that to A/B/F/D_moved/H/chi_moved_again
2113 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2114 chi_path, chi_moved_path)
2115 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2116 chi_moved_path,
2117 chi_moved_again_path)
2119 # Created expected output tree for 'svn ci':
2120 expected_output = svntest.wc.State(wc_dir, {
2121 'A/B/F/D_moved/' : Item(verb='Adding'),
2122 'A/B/F/D_moved/H/chi' : Item(verb='Deleting'),
2123 'A/B/F/D_moved/H/chi_moved_again' : Item(verb='Adding'),
2124 'A/D' : Item(verb='Deleting'),
2127 # Create expected status tree
2128 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2129 expected_status.add({
2130 'A/B/F/D_moved' : Item(status=' ', wc_rev=2),
2131 'A/B/F/D_moved/gamma' : Item(status=' ', wc_rev=2),
2132 'A/B/F/D_moved/G' : Item(status=' ', wc_rev=2),
2133 'A/B/F/D_moved/G/pi' : Item(status=' ', wc_rev=2),
2134 'A/B/F/D_moved/G/rho' : Item(status=' ', wc_rev=2),
2135 'A/B/F/D_moved/G/tau' : Item(status=' ', wc_rev=2),
2136 'A/B/F/D_moved/H' : Item(status=' ', wc_rev=2),
2137 'A/B/F/D_moved/H/omega' : Item(status=' ', wc_rev=2),
2138 'A/B/F/D_moved/H/psi' : Item(status=' ', wc_rev=2),
2139 'A/B/F/D_moved/H/chi_moved_again' : Item(status=' ', wc_rev=2),
2142 expected_status.remove('A/D',
2143 'A/D/gamma',
2144 'A/D/G',
2145 'A/D/G/pi',
2146 'A/D/G/rho',
2147 'A/D/G/tau',
2148 'A/D/H',
2149 'A/D/H/chi',
2150 'A/D/H/omega',
2151 'A/D/H/psi',
2154 svntest.actions.run_and_verify_commit(wc_dir,
2155 expected_output,
2156 expected_status,
2157 None,
2158 None, None,
2159 None, None,
2160 wc_dir)
2163 def move_file_out_of_moved_dir(sbox):
2164 "move a file out of a moved dir"
2166 sbox.build()
2167 wc_dir = sbox.wc_dir
2169 D_path = os.path.join(wc_dir, 'A', 'D')
2170 D_path_moved = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved')
2172 # Move A/B/D to A/B/F/D_moved
2173 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2174 D_path, D_path_moved)
2176 chi_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved', 'H', 'chi')
2177 chi_moved_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved',
2178 'H', 'chi_moved')
2179 chi_moved_again_path = os.path.join(wc_dir, 'A', 'C', 'chi_moved_again')
2181 # Move A/B/F/D_moved/H/chi to A/B/F/D_moved/H/chi_moved
2182 # then move that to A/C/chi_moved_again
2183 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2184 chi_path, chi_moved_path)
2185 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2186 chi_moved_path,
2187 chi_moved_again_path)
2189 # Created expected output tree for 'svn ci':
2190 expected_output = svntest.wc.State(wc_dir, {
2191 'A/B/F/D_moved/' : Item(verb='Adding'),
2192 'A/B/F/D_moved/H/chi' : Item(verb='Deleting'),
2193 'A/C/chi_moved_again' : Item(verb='Adding'),
2194 'A/D' : Item(verb='Deleting'),
2197 # Create expected status tree
2198 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2199 expected_status.add({
2200 'A/B/F/D_moved' : Item(status=' ', wc_rev=2),
2201 'A/B/F/D_moved/gamma' : Item(status=' ', wc_rev=2),
2202 'A/B/F/D_moved/G' : Item(status=' ', wc_rev=2),
2203 'A/B/F/D_moved/G/pi' : Item(status=' ', wc_rev=2),
2204 'A/B/F/D_moved/G/rho' : Item(status=' ', wc_rev=2),
2205 'A/B/F/D_moved/G/tau' : Item(status=' ', wc_rev=2),
2206 'A/B/F/D_moved/H' : Item(status=' ', wc_rev=2),
2207 'A/B/F/D_moved/H/omega' : Item(status=' ', wc_rev=2),
2208 'A/B/F/D_moved/H/psi' : Item(status=' ', wc_rev=2),
2209 'A/C/chi_moved_again' : Item(status=' ', wc_rev=2),
2212 expected_status.remove('A/D',
2213 'A/D/gamma',
2214 'A/D/G',
2215 'A/D/G/pi',
2216 'A/D/G/rho',
2217 'A/D/G/tau',
2218 'A/D/H',
2219 'A/D/H/chi',
2220 'A/D/H/omega',
2221 'A/D/H/psi',
2224 svntest.actions.run_and_verify_commit(wc_dir,
2225 expected_output,
2226 expected_status,
2227 None,
2228 None, None,
2229 None, None,
2230 wc_dir)
2233 def move_dir_within_moved_dir(sbox):
2234 "move a dir twice within a moved dir"
2236 sbox.build()
2237 wc_dir = sbox.wc_dir
2239 D_path = os.path.join(wc_dir, 'A', 'D')
2240 D_path_moved = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved')
2242 # Move A/D to A/B/F/D_moved
2243 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2244 D_path, D_path_moved)
2246 H_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved', 'H')
2247 H_moved_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved', 'H_moved')
2248 H_moved_again_path = os.path.join(wc_dir, 'A', 'B', 'F',
2249 'D_moved', 'H_moved_again')
2251 # Move A/B/F/D_moved/H to A/B/F/D_moved/H_moved
2252 # then move that to A/B/F/D_moved/H_moved_again
2253 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2254 H_path, H_moved_path)
2255 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2256 H_moved_path,
2257 H_moved_again_path)
2259 # Created expected output tree for 'svn ci':
2260 expected_output = svntest.wc.State(wc_dir, {
2261 'A/D' : Item(verb='Deleting'),
2262 'A/B/F/D_moved' : Item(verb='Adding'),
2263 'A/B/F/D_moved/H' : Item(verb='Deleting'),
2264 'A/B/F/D_moved/H_moved_again' : Item(verb='Adding'),
2267 # Create expected status tree
2268 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2269 expected_status.add({
2270 'A/B/F/D_moved' : Item(status=' ', wc_rev=2),
2271 'A/B/F/D_moved/gamma' : Item(status=' ', wc_rev=2),
2272 'A/B/F/D_moved/G' : Item(status=' ', wc_rev=2),
2273 'A/B/F/D_moved/G/pi' : Item(status=' ', wc_rev=2),
2274 'A/B/F/D_moved/G/rho' : Item(status=' ', wc_rev=2),
2275 'A/B/F/D_moved/G/tau' : Item(status=' ', wc_rev=2),
2276 'A/B/F/D_moved/H_moved_again' : Item(status=' ', wc_rev=2),
2277 'A/B/F/D_moved/H_moved_again/omega' : Item(status=' ', wc_rev=2),
2278 'A/B/F/D_moved/H_moved_again/psi' : Item(status=' ', wc_rev=2),
2279 'A/B/F/D_moved/H_moved_again/chi' : Item(status=' ', wc_rev=2),
2282 expected_status.remove('A/D',
2283 'A/D/gamma',
2284 'A/D/G',
2285 'A/D/G/pi',
2286 'A/D/G/rho',
2287 'A/D/G/tau',
2288 'A/D/H',
2289 'A/D/H/chi',
2290 'A/D/H/omega',
2291 'A/D/H/psi',
2294 svntest.actions.run_and_verify_commit(wc_dir,
2295 expected_output,
2296 expected_status,
2297 None,
2298 None, None,
2299 None, None,
2300 wc_dir)
2303 def move_dir_out_of_moved_dir(sbox):
2304 "move a dir out of a moved dir"
2306 sbox.build()
2307 wc_dir = sbox.wc_dir
2309 D_path = os.path.join(wc_dir, 'A', 'D')
2310 D_path_moved = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved')
2312 # Move A/D to A/B/F/D_moved
2313 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2314 D_path, D_path_moved)
2316 H_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved', 'H')
2317 H_moved_path = os.path.join(wc_dir, 'A', 'B', 'F', 'D_moved', 'H_moved')
2318 H_moved_again_path = os.path.join(wc_dir, 'A', 'C', 'H_moved_again')
2320 # Move A/B/F/D_moved/H to A/B/F/D_moved/H_moved
2321 # then move that to A/C/H_moved_again
2322 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2323 H_path, H_moved_path)
2324 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2325 H_moved_path,
2326 H_moved_again_path)
2328 # Created expected output tree for 'svn ci':
2329 expected_output = svntest.wc.State(wc_dir, {
2330 'A/D' : Item(verb='Deleting'),
2331 'A/B/F/D_moved' : Item(verb='Adding'),
2332 'A/B/F/D_moved/H' : Item(verb='Deleting'),
2333 'A/C/H_moved_again' : Item(verb='Adding'),
2336 # Create expected status tree
2337 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2338 expected_status.add({
2339 'A/B/F/D_moved' : Item(status=' ', wc_rev=2),
2340 'A/B/F/D_moved/gamma' : Item(status=' ', wc_rev=2),
2341 'A/B/F/D_moved/G' : Item(status=' ', wc_rev=2),
2342 'A/B/F/D_moved/G/pi' : Item(status=' ', wc_rev=2),
2343 'A/B/F/D_moved/G/rho' : Item(status=' ', wc_rev=2),
2344 'A/B/F/D_moved/G/tau' : Item(status=' ', wc_rev=2),
2345 'A/C/H_moved_again' : Item(status=' ', wc_rev=2),
2346 'A/C/H_moved_again/omega' : Item(status=' ', wc_rev=2),
2347 'A/C/H_moved_again/psi' : Item(status=' ', wc_rev=2),
2348 'A/C/H_moved_again/chi' : Item(status=' ', wc_rev=2),
2351 expected_status.remove('A/D',
2352 'A/D/gamma',
2353 'A/D/G',
2354 'A/D/G/pi',
2355 'A/D/G/rho',
2356 'A/D/G/tau',
2357 'A/D/H',
2358 'A/D/H/chi',
2359 'A/D/H/omega',
2360 'A/D/H/psi',
2363 svntest.actions.run_and_verify_commit(wc_dir,
2364 expected_output,
2365 expected_status,
2366 None,
2367 None, None,
2368 None, None,
2369 wc_dir)
2371 def move_file_back_and_forth(sbox):
2372 "move a moved file back to original location"
2374 sbox.build()
2375 wc_dir = sbox.wc_dir
2377 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
2378 rho_move_path = os.path.join(wc_dir, 'A', 'D', 'rho_moved')
2380 # Move A/D/G/rho to A/D/rho_moved
2381 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2382 rho_path, rho_move_path)
2384 # Move the moved file: A/D/rho_moved to A/B/F/rho_move_moved
2385 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2386 rho_move_path, rho_path)
2388 # Created expected output tree for 'svn ci':
2389 expected_output = svntest.wc.State(wc_dir, {
2390 'A/D/G/rho' : Item(verb='Replacing'),
2393 # Create expected status tree
2394 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2395 expected_status.add({
2396 'A/D/G/rho' : Item(status=' ', wc_rev=2),
2399 svntest.actions.run_and_verify_commit(wc_dir,
2400 expected_output,
2401 expected_status,
2402 None,
2403 None, None,
2404 None, None,
2405 wc_dir)
2408 def move_dir_back_and_forth(sbox):
2409 "move a moved dir back to original location"
2411 sbox.build()
2412 wc_dir = sbox.wc_dir
2414 D_path = os.path.join(wc_dir, 'A', 'D')
2415 D_move_path = os.path.join(wc_dir, 'D_moved')
2417 # Move A/D to D_moved
2418 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2419 D_path, D_move_path)
2421 # Move the moved dir: D_moved back to its starting
2422 # location at A/D.
2423 out, err = svntest.actions.run_and_verify_svn(None, None,
2424 svntest.verify.AnyOutput,
2425 'mv', D_move_path,
2426 D_path)
2428 for line in err:
2429 if re.match('.*Cannot copy to .*as it is scheduled for deletion',
2430 line, ):
2431 return
2432 raise svntest.Failure("mv failed but not in the expected way")
2435 def copy_move_added_paths(sbox):
2436 "copy and move added paths without commits"
2438 sbox.build()
2439 wc_dir = sbox.wc_dir
2441 # Create a new file and schedule it for addition
2442 upsilon_path = os.path.join(wc_dir, 'A', 'D', 'upsilon')
2443 svntest.main.file_write(upsilon_path, "This is the file 'upsilon'\n")
2444 svntest.actions.run_and_verify_svn(None, None, [], 'add', upsilon_path)
2446 # Create a dir with children and schedule it for addition
2447 I_path = os.path.join(wc_dir, 'A', 'D', 'I')
2448 J_path = os.path.join(I_path, 'J')
2449 eta_path = os.path.join(I_path, 'eta')
2450 theta_path = os.path.join(I_path, 'theta')
2451 kappa_path = os.path.join(J_path, 'kappa')
2452 os.mkdir(I_path)
2453 os.mkdir(J_path)
2454 svntest.main.file_write(eta_path, "This is the file 'eta'\n")
2455 svntest.main.file_write(theta_path, "This is the file 'theta'\n")
2456 svntest.main.file_write(kappa_path, "This is the file 'kappa'\n")
2457 svntest.actions.run_and_verify_svn(None, None, [], 'add', I_path)
2459 # Create another dir and schedule it for addition
2460 K_path = os.path.join(wc_dir, 'K')
2461 os.mkdir(K_path)
2462 svntest.actions.run_and_verify_svn(None, None, [], 'add', K_path)
2464 # Verify all the adds took place correctly.
2465 expected_status_after_adds = svntest.actions.get_virginal_state(wc_dir, 1)
2466 expected_status_after_adds.add({
2467 'A/D/I' : Item(status='A ', wc_rev='0'),
2468 'A/D/I/eta' : Item(status='A ', wc_rev='0'),
2469 'A/D/I/J' : Item(status='A ', wc_rev='0'),
2470 'A/D/I/J/kappa' : Item(status='A ', wc_rev='0'),
2471 'A/D/I/theta' : Item(status='A ', wc_rev='0'),
2472 'A/D/upsilon' : Item(status='A ', wc_rev='0'),
2473 'K' : Item(status='A ', wc_rev='0'),
2475 svntest.actions.run_and_verify_status(wc_dir, expected_status_after_adds)
2477 # Scatter some unversioned paths within the added dir I.
2478 unversioned_path_1 = os.path.join(I_path, 'unversioned1')
2479 unversioned_path_2 = os.path.join(J_path, 'unversioned2')
2480 L_path = os.path.join(I_path, "L_UNVERSIONED")
2481 unversioned_path_3 = os.path.join(L_path, 'unversioned3')
2482 svntest.main.file_write(unversioned_path_1, "An unversioned file\n")
2483 svntest.main.file_write(unversioned_path_2, "An unversioned file\n")
2484 os.mkdir(L_path)
2485 svntest.main.file_write(unversioned_path_3, "An unversioned file\n")
2487 # Copy added dir A/D/I to added dir K/I
2488 I_copy_path = os.path.join(K_path, 'I')
2489 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
2490 I_path, I_copy_path)
2492 # Copy added file A/D/upsilon into added dir K
2493 upsilon_copy_path = os.path.join(K_path, 'upsilon')
2494 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
2495 upsilon_path, upsilon_copy_path)
2497 # Move added file A/D/upsilon to upsilon,
2498 # then move it again to A/upsilon
2499 upsilon_move_path = os.path.join(wc_dir, 'upsilon')
2500 upsilon_move_path_2 = os.path.join(wc_dir, 'A', 'upsilon')
2501 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2502 upsilon_path, upsilon_move_path)
2503 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2504 upsilon_move_path, upsilon_move_path_2)
2506 # Move added dir A/D/I to A/B/I,
2507 # then move it again to A/D/H/I
2508 I_move_path = os.path.join(wc_dir, 'A', 'B', 'I')
2509 I_move_path_2 = os.path.join(wc_dir, 'A', 'D', 'H', 'I')
2510 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2511 I_path, I_move_path)
2512 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
2513 I_move_path, I_move_path_2)
2515 # Created expected output tree for 'svn ci'
2516 expected_output = svntest.wc.State(wc_dir, {
2517 'A/D/H/I' : Item(verb='Adding'),
2518 'A/D/H/I/J' : Item(verb='Adding'),
2519 'A/D/H/I/J/kappa' : Item(verb='Adding'),
2520 'A/D/H/I/eta' : Item(verb='Adding'),
2521 'A/D/H/I/theta' : Item(verb='Adding'),
2522 'A/upsilon' : Item(verb='Adding'),
2523 'K' : Item(verb='Adding'),
2524 'K/I' : Item(verb='Adding'),
2525 'K/I/J' : Item(verb='Adding'),
2526 'K/I/J/kappa' : Item(verb='Adding'),
2527 'K/I/eta' : Item(verb='Adding'),
2528 'K/I/theta' : Item(verb='Adding'),
2529 'K/upsilon' : Item(verb='Adding'),
2532 # Create expected status tree
2533 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2534 expected_status.add({
2535 'A/D/H/I' : Item(status=' ', wc_rev=2),
2536 'A/D/H/I/J' : Item(status=' ', wc_rev=2),
2537 'A/D/H/I/J/kappa' : Item(status=' ', wc_rev=2),
2538 'A/D/H/I/eta' : Item(status=' ', wc_rev=2),
2539 'A/D/H/I/theta' : Item(status=' ', wc_rev=2),
2540 'A/upsilon' : Item(status=' ', wc_rev=2),
2541 'K' : Item(status=' ', wc_rev=2),
2542 'K/I' : Item(status=' ', wc_rev=2),
2543 'K/I/J' : Item(status=' ', wc_rev=2),
2544 'K/I/J/kappa' : Item(status=' ', wc_rev=2),
2545 'K/I/eta' : Item(status=' ', wc_rev=2),
2546 'K/I/theta' : Item(status=' ', wc_rev=2),
2547 'K/upsilon' : Item(status=' ', wc_rev=2),
2550 svntest.actions.run_and_verify_commit(wc_dir,
2551 expected_output,
2552 expected_status,
2553 None,
2554 None, None,
2555 None, None,
2556 wc_dir)
2558 # Run_and_verify_commit() doesn't handle status of unversioned paths
2559 # so manually confirm unversioned paths got copied and moved too.
2560 unversioned_paths = [
2561 os.path.join(wc_dir, 'A', 'D', 'H', 'I', 'unversioned1'),
2562 os.path.join(wc_dir, 'A', 'D', 'H', 'I', 'L_UNVERSIONED'),
2563 os.path.join(wc_dir, 'A', 'D', 'H', 'I', 'L_UNVERSIONED',
2564 'unversioned3'),
2565 os.path.join(wc_dir, 'A', 'D', 'H', 'I', 'J', 'unversioned2'),
2566 os.path.join(wc_dir, 'K', 'I', 'unversioned1'),
2567 os.path.join(wc_dir, 'K', 'I', 'L_UNVERSIONED'),
2568 os.path.join(wc_dir, 'K', 'I', 'L_UNVERSIONED', 'unversioned3'),
2569 os.path.join(wc_dir, 'K', 'I', 'J', 'unversioned2')]
2570 for path in unversioned_paths:
2571 if not os.path.exists(path):
2572 raise svntest.Failure("Unversioned path '%s' not found." % path)
2574 def copy_added_paths_with_props(sbox):
2575 "copy added uncommitted paths with props"
2577 sbox.build()
2578 wc_dir = sbox.wc_dir
2580 # Create a new file, schedule it for addition and set properties
2581 upsilon_path = os.path.join(wc_dir, 'A', 'D', 'upsilon')
2582 svntest.main.file_write(upsilon_path, "This is the file 'upsilon'\n")
2583 svntest.actions.run_and_verify_svn(None, None, [], 'add', upsilon_path)
2584 svntest.actions.run_and_verify_svn(None, None, [], 'propset',
2585 'foo', 'bar', upsilon_path)
2587 # Create a dir and schedule it for addition and set properties
2588 I_path = os.path.join(wc_dir, 'A', 'D', 'I')
2589 os.mkdir(I_path)
2590 svntest.actions.run_and_verify_svn(None, None, [], 'add', I_path)
2591 svntest.actions.run_and_verify_svn(None, None, [], 'propset',
2592 'foo', 'bar', I_path)
2594 # Verify all the adds took place correctly.
2595 expected_status_after_adds = svntest.actions.get_virginal_state(wc_dir, 1)
2596 expected_status_after_adds.add({
2597 'A/D/upsilon' : Item(status='A ', wc_rev='0'),
2598 'A/D/I' : Item(status='A ', wc_rev='0'),
2600 svntest.actions.run_and_verify_status(wc_dir, expected_status_after_adds)
2602 expected_disk = svntest.main.greek_state.copy()
2603 expected_disk.add({
2604 'A/D/upsilon' : Item(props={'foo' : 'bar'},
2605 contents="This is the file 'upsilon'\n"),
2606 'A/D/I' : Item(props={'foo' : 'bar'}),
2609 # Read disk state with props
2610 actual_disk_tree = svntest.tree.build_tree_from_wc(wc_dir, 1)
2612 # Compare actual vs. expected disk trees.
2613 svntest.tree.compare_trees(actual_disk_tree, expected_disk.old_tree())
2615 # Copy added dir K to dir A/C
2616 I_copy_path = os.path.join(wc_dir, 'A', 'C', 'I')
2617 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
2618 I_path, I_copy_path)
2620 # Copy added file A/upsilon into dir A/C
2621 upsilon_copy_path = os.path.join(wc_dir, 'A', 'C', 'upsilon')
2622 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
2623 upsilon_path, upsilon_copy_path)
2625 # Created expected output tree for 'svn ci'
2626 expected_output = svntest.wc.State(wc_dir, {
2627 'A/D/upsilon' : Item(verb='Adding'),
2628 'A/D/I' : Item(verb='Adding'),
2629 'A/C/upsilon' : Item(verb='Adding'),
2630 'A/C/I' : Item(verb='Adding'),
2633 # Create expected status tree
2634 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2635 expected_status.add({
2636 'A/D/upsilon' : Item(status=' ', wc_rev=2),
2637 'A/D/I' : Item(status=' ', wc_rev=2),
2638 'A/C/upsilon' : Item(status=' ', wc_rev=2),
2639 'A/C/I' : Item(status=' ', wc_rev=2),
2642 # Tweak expected disk tree
2643 expected_disk.add({
2644 'A/C/upsilon' : Item(props={'foo' : 'bar'},
2645 contents="This is the file 'upsilon'\n"),
2646 'A/C/I' : Item(props={'foo' : 'bar'}),
2649 svntest.actions.run_and_verify_commit(wc_dir,
2650 expected_output,
2651 expected_status,
2652 None,
2653 None, None,
2654 None, None,
2655 wc_dir)
2656 # Read disk state with props
2657 actual_disk_tree = svntest.tree.build_tree_from_wc(wc_dir, 1)
2659 # Compare actual vs. expected disk trees.
2660 svntest.tree.compare_trees(actual_disk_tree, expected_disk.old_tree())
2662 def copy_added_paths_to_URL(sbox):
2663 "copy added path to URL"
2665 sbox.build()
2666 wc_dir = sbox.wc_dir
2668 # Create a new file and schedule it for addition
2669 upsilon_path = os.path.join(wc_dir, 'A', 'D', 'upsilon')
2670 svntest.main.file_write(upsilon_path, "This is the file 'upsilon'\n")
2671 svntest.actions.run_and_verify_svn(None, None, [], 'add', upsilon_path)
2673 # Create a dir with children and schedule it for addition
2674 I_path = os.path.join(wc_dir, 'A', 'D', 'I')
2675 J_path = os.path.join(I_path, 'J')
2676 eta_path = os.path.join(I_path, 'eta')
2677 theta_path = os.path.join(I_path, 'theta')
2678 kappa_path = os.path.join(J_path, 'kappa')
2679 os.mkdir(I_path)
2680 os.mkdir(J_path)
2681 svntest.main.file_write(eta_path, "This is the file 'eta'\n")
2682 svntest.main.file_write(theta_path, "This is the file 'theta'\n")
2683 svntest.main.file_write(kappa_path, "This is the file 'kappa'\n")
2684 svntest.actions.run_and_verify_svn(None, None, [], 'add', I_path)
2686 # Verify all the adds took place correctly.
2687 expected_status_after_adds = svntest.actions.get_virginal_state(wc_dir, 1)
2688 expected_status_after_adds.add({
2689 'A/D/I' : Item(status='A ', wc_rev='0'),
2690 'A/D/I/eta' : Item(status='A ', wc_rev='0'),
2691 'A/D/I/J' : Item(status='A ', wc_rev='0'),
2692 'A/D/I/J/kappa' : Item(status='A ', wc_rev='0'),
2693 'A/D/I/theta' : Item(status='A ', wc_rev='0'),
2694 'A/D/upsilon' : Item(status='A ', wc_rev='0'),
2696 svntest.actions.run_and_verify_status(wc_dir, expected_status_after_adds)
2698 # Scatter some unversioned paths within the added dir I.
2699 # These don't get copied in a WC->URL copy obviously.
2700 unversioned_path_1 = os.path.join(I_path, 'unversioned1')
2701 unversioned_path_2 = os.path.join(J_path, 'unversioned2')
2702 L_path = os.path.join(I_path, "L_UNVERSIONED")
2703 unversioned_path_3 = os.path.join(L_path, 'unversioned3')
2704 svntest.main.file_write(unversioned_path_1, "An unversioned file\n")
2705 svntest.main.file_write(unversioned_path_2, "An unversioned file\n")
2706 os.mkdir(L_path)
2707 svntest.main.file_write(unversioned_path_3, "An unversioned file\n")
2709 # Copy added file A/D/upsilon to URL://A/C/upsilon
2710 upsilon_copy_URL = sbox.repo_url + '/A/C/upsilon'
2711 svntest.actions.run_and_verify_svn(None, None, [],
2712 'cp', '-m', '',
2713 upsilon_path, upsilon_copy_URL)
2715 # Validate that the merge info of the copy destination matches the
2716 # implied merge info from the copy source.
2717 svntest.actions.run_and_verify_svn(None, ['\n'], [],
2718 'propget',
2719 SVN_PROP_MERGE_INFO, upsilon_copy_URL)
2721 # Copy added dir A/D/I to URL://A/D/G/I
2722 I_copy_URL = sbox.repo_url + '/A/D/G/I'
2723 svntest.actions.run_and_verify_svn(None, None, [],
2724 'cp', '-m', '',
2725 I_path, I_copy_URL)
2727 # Created expected output tree for 'svn ci'
2728 expected_output = svntest.wc.State(wc_dir, {
2729 'A/D/I' : Item(verb='Adding'),
2730 'A/D/I/J' : Item(verb='Adding'),
2731 'A/D/I/J/kappa' : Item(verb='Adding'),
2732 'A/D/I/eta' : Item(verb='Adding'),
2733 'A/D/I/theta' : Item(verb='Adding'),
2734 'A/D/upsilon' : Item(verb='Adding'),
2737 # Create expected status tree
2738 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2739 expected_status.add({
2740 'A/D/I' : Item(status=' ', wc_rev=4),
2741 'A/D/I/J' : Item(status=' ', wc_rev=4),
2742 'A/D/I/J/kappa' : Item(status=' ', wc_rev=4),
2743 'A/D/I/eta' : Item(status=' ', wc_rev=4),
2744 'A/D/I/theta' : Item(status=' ', wc_rev=4),
2745 'A/D/upsilon' : Item(status=' ', wc_rev=4),
2748 svntest.actions.run_and_verify_commit(wc_dir,
2749 expected_output,
2750 expected_status,
2751 None,
2752 None, None,
2753 None, None,
2754 wc_dir)
2756 # Created expected output for update
2757 expected_output = svntest.wc.State(wc_dir, {
2758 'A/D/G/I' : Item(status='A '),
2759 'A/D/G/I/theta' : Item(status='A '),
2760 'A/D/G/I/J' : Item(status='A '),
2761 'A/D/G/I/J/kappa' : Item(status='A '),
2762 'A/D/G/I/eta' : Item(status='A '),
2763 'A/C/upsilon' : Item(status='A '),
2766 # Created expected disk for update
2767 expected_disk = svntest.main.greek_state.copy()
2768 expected_disk.add({
2769 'A/D/G/I' : Item(),
2770 'A/D/G/I/theta' : Item("This is the file 'theta'\n"),
2771 'A/D/G/I/J' : Item(),
2772 'A/D/G/I/J/kappa' : Item("This is the file 'kappa'\n"),
2773 'A/D/G/I/eta' : Item("This is the file 'eta'\n"),
2774 'A/C/upsilon' : Item("This is the file 'upsilon'\n"),
2775 'A/D/I' : Item(),
2776 'A/D/I/J' : Item(),
2777 'A/D/I/J/kappa' : Item("This is the file 'kappa'\n"),
2778 'A/D/I/eta' : Item("This is the file 'eta'\n"),
2779 'A/D/I/theta' : Item("This is the file 'theta'\n"),
2780 'A/D/upsilon' : Item("This is the file 'upsilon'\n"),
2781 'A/D/I/L_UNVERSIONED/unversioned3' : Item("An unversioned file\n"),
2782 'A/D/I/L_UNVERSIONED' : Item(),
2783 'A/D/I/unversioned1' : Item("An unversioned file\n"),
2784 'A/D/I/J/unversioned2' : Item("An unversioned file\n"),
2787 # Some more changes to the expected_status to reflect post update WC
2788 expected_status.tweak(wc_rev=4)
2789 expected_status.add({
2790 'A/C' : Item(status=' ', wc_rev=4),
2791 'A/C/upsilon' : Item(status=' ', wc_rev=4),
2792 'A/D/G' : Item(status=' ', wc_rev=4),
2793 'A/D/G/I' : Item(status=' ', wc_rev=4),
2794 'A/D/G/I/theta' : Item(status=' ', wc_rev=4),
2795 'A/D/G/I/J' : Item(status=' ', wc_rev=4),
2796 'A/D/G/I/J/kappa' : Item(status=' ', wc_rev=4),
2797 'A/D/G/I/eta' : Item(status=' ', wc_rev=4),
2800 # Update WC, the WC->URL copies above should be added
2801 svntest.actions.run_and_verify_update(wc_dir,
2802 expected_output,
2803 expected_disk,
2804 expected_status)
2807 # Issue #1869.
2808 def move_to_relative_paths(sbox):
2809 "move file using relative dst path names"
2811 sbox.build()
2812 wc_dir = sbox.wc_dir
2813 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
2814 rel_path = os.path.join('..', '..', '..')
2816 current_dir = os.getcwd()
2817 os.chdir(E_path)
2818 svntest.main.run_svn(None, 'mv', 'beta', rel_path)
2819 os.chdir(current_dir)
2821 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2822 expected_status.add({
2823 'beta' : Item(status='A ', copied='+', wc_rev='-'),
2824 'A/B/E/beta' : Item(status='D ', wc_rev='1')
2826 svntest.actions.run_and_verify_status(wc_dir, expected_status)
2829 #----------------------------------------------------------------------
2830 def move_from_relative_paths(sbox):
2831 "move file using relative src path names"
2833 sbox.build()
2834 wc_dir = sbox.wc_dir
2835 F_path = os.path.join(wc_dir, 'A', 'B', 'F')
2836 beta_rel_path = os.path.join('..', 'E', 'beta')
2838 current_dir = os.getcwd()
2839 os.chdir(F_path)
2840 svntest.main.run_svn(None, 'mv', beta_rel_path, '.')
2841 os.chdir(current_dir)
2843 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2844 expected_status.add({
2845 'A/B/F/beta' : Item(status='A ', copied='+', wc_rev='-'),
2846 'A/B/E/beta' : Item(status='D ', wc_rev='1')
2848 svntest.actions.run_and_verify_status(wc_dir, expected_status)
2851 #----------------------------------------------------------------------
2852 def copy_to_relative_paths(sbox):
2853 "copy file using relative dst path names"
2855 sbox.build()
2856 wc_dir = sbox.wc_dir
2857 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
2858 rel_path = os.path.join('..', '..', '..')
2860 current_dir = os.getcwd()
2861 os.chdir(E_path)
2862 svntest.main.run_svn(None, 'cp', 'beta', rel_path)
2863 os.chdir(current_dir)
2865 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2866 expected_status.add({
2867 'beta' : Item(status='A ', copied='+', wc_rev='-'),
2869 svntest.actions.run_and_verify_status(wc_dir, expected_status)
2872 #----------------------------------------------------------------------
2873 def copy_from_relative_paths(sbox):
2874 "copy file using relative src path names"
2876 sbox.build()
2877 wc_dir = sbox.wc_dir
2878 F_path = os.path.join(wc_dir, 'A', 'B', 'F')
2879 beta_rel_path = os.path.join('..', 'E', 'beta')
2881 current_dir = os.getcwd()
2882 os.chdir(F_path)
2883 svntest.main.run_svn(None, 'cp', beta_rel_path, '.')
2884 os.chdir(current_dir)
2886 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2887 expected_status.add({
2888 'A/B/F/beta' : Item(status='A ', copied='+', wc_rev='-'),
2890 svntest.actions.run_and_verify_status(wc_dir, expected_status)
2893 #----------------------------------------------------------------------
2895 # Test moving multiple files within a wc.
2897 def move_multiple_wc(sbox):
2898 "svn mv multiple files to a common directory"
2900 sbox.build()
2901 wc_dir = sbox.wc_dir
2903 chi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'chi')
2904 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
2905 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
2906 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
2907 C_path = os.path.join(wc_dir, 'A', 'C')
2909 # Move chi, psi, omega and E to A/C
2910 svntest.actions.run_and_verify_svn(None, None, [], 'mv', chi_path, psi_path,
2911 omega_path, E_path, C_path)
2913 # Create expected output
2914 expected_output = svntest.wc.State(wc_dir, {
2915 'A/C/chi' : Item(verb='Adding'),
2916 'A/C/psi' : Item(verb='Adding'),
2917 'A/C/omega' : Item(verb='Adding'),
2918 'A/C/E' : Item(verb='Adding'),
2919 'A/D/H/chi' : Item(verb='Deleting'),
2920 'A/D/H/psi' : Item(verb='Deleting'),
2921 'A/D/H/omega' : Item(verb='Deleting'),
2922 'A/B/E' : Item(verb='Deleting'),
2925 # Create expected status tree
2926 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2928 # Add the moved files
2929 expected_status.add({
2930 'A/C/chi' : Item(status=' ', wc_rev=2),
2931 'A/C/psi' : Item(status=' ', wc_rev=2),
2932 'A/C/omega' : Item(status=' ', wc_rev=2),
2933 'A/C/E' : Item(status=' ', wc_rev=2),
2934 'A/C/E/alpha' : Item(status=' ', wc_rev=2),
2935 'A/C/E/beta' : Item(status=' ', wc_rev=2),
2938 # Removed the moved files
2939 expected_status.remove('A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega', 'A/B/E/alpha',
2940 'A/B/E/beta', 'A/B/E')
2942 svntest.actions.run_and_verify_commit(wc_dir,
2943 expected_output,
2944 expected_status,
2945 None,
2946 None, None,
2947 None, None,
2948 wc_dir)
2950 #----------------------------------------------------------------------
2952 # Test copying multiple files within a wc.
2954 def copy_multiple_wc(sbox):
2955 "svn cp multiple files to a common directory"
2957 sbox.build()
2958 wc_dir = sbox.wc_dir
2960 chi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'chi')
2961 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
2962 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
2963 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
2964 C_path = os.path.join(wc_dir, 'A', 'C')
2966 # Copy chi, psi, omega and E to A/C
2967 svntest.actions.run_and_verify_svn(None, None, [], 'cp', chi_path, psi_path,
2968 omega_path, E_path, C_path)
2970 # Create expected output
2971 expected_output = svntest.wc.State(wc_dir, {
2972 'A/C/chi' : Item(verb='Adding'),
2973 'A/C/psi' : Item(verb='Adding'),
2974 'A/C/omega' : Item(verb='Adding'),
2975 'A/C/E' : Item(verb='Adding'),
2978 # Create expected status tree
2979 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
2981 # Add the moved files
2982 expected_status.add({
2983 'A/C/chi' : Item(status=' ', wc_rev=2),
2984 'A/C/psi' : Item(status=' ', wc_rev=2),
2985 'A/C/omega' : Item(status=' ', wc_rev=2),
2986 'A/C/E' : Item(status=' ', wc_rev=2),
2987 'A/C/E/alpha' : Item(status=' ', wc_rev=2),
2988 'A/C/E/beta' : Item(status=' ', wc_rev=2),
2991 svntest.actions.run_and_verify_commit(wc_dir,
2992 expected_output,
2993 expected_status,
2994 None,
2995 None, None,
2996 None, None,
2997 wc_dir)
2999 #----------------------------------------------------------------------
3001 # Test moving multiple files within a repo.
3003 def move_multiple_repo(sbox):
3004 "move multiple files within a repo"
3006 sbox.build()
3007 wc_dir = sbox.wc_dir
3009 chi_url = sbox.repo_url + '/A/D/H/chi'
3010 psi_url = sbox.repo_url + '/A/D/H/psi'
3011 omega_url = sbox.repo_url + '/A/D/H/omega'
3012 E_url = sbox.repo_url + '/A/B/E'
3013 C_url = sbox.repo_url + '/A/C'
3015 # Move three files and a directory in the repo to a different location
3016 # in the repo
3017 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3018 chi_url, psi_url, omega_url, E_url, C_url,
3019 '-m', 'logmsg')
3021 # Update to HEAD, and check to see if the files really moved in the repo
3023 expected_output = svntest.wc.State(wc_dir, {
3024 'A/C/chi' : Item(status='A '),
3025 'A/C/psi' : Item(status='A '),
3026 'A/C/omega' : Item(status='A '),
3027 'A/C/E' : Item(status='A '),
3028 'A/C/E/alpha' : Item(status='A '),
3029 'A/C/E/beta' : Item(status='A '),
3030 'A/D/H/chi' : Item(status='D '),
3031 'A/D/H/psi' : Item(status='D '),
3032 'A/D/H/omega' : Item(status='D '),
3033 'A/B/E' : Item(status='D '),
3036 expected_disk = svntest.main.greek_state.copy()
3037 expected_disk.remove('A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega', 'A/B/E/alpha',
3038 'A/B/E/beta', 'A/B/E')
3039 expected_disk.add({
3040 'A/C/chi' : Item(contents="This is the file 'chi'.\n"),
3041 'A/C/psi' : Item(contents="This is the file 'psi'.\n"),
3042 'A/C/omega' : Item(contents="This is the file 'omega'.\n"),
3043 'A/C/E' : Item(),
3044 'A/C/E/alpha' : Item(contents="This is the file 'alpha'.\n"),
3045 'A/C/E/beta' : Item(contents="This is the file 'beta'.\n"),
3048 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
3049 expected_status.remove('A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega', 'A/B/E/alpha',
3050 'A/B/E/beta', 'A/B/E')
3051 expected_status.add({
3052 'A/C/chi' : Item(status=' ', wc_rev=2),
3053 'A/C/psi' : Item(status=' ', wc_rev=2),
3054 'A/C/omega' : Item(status=' ', wc_rev=2),
3055 'A/C/E' : Item(status=' ', wc_rev=2),
3056 'A/C/E/alpha' : Item(status=' ', wc_rev=2),
3057 'A/C/E/beta' : Item(status=' ', wc_rev=2),
3060 svntest.actions.run_and_verify_update(wc_dir,
3061 expected_output,
3062 expected_disk,
3063 expected_status)
3065 #----------------------------------------------------------------------
3067 # Test copying multiple files within a repo.
3069 def copy_multiple_repo(sbox):
3070 "copy multiple files within a repo"
3072 sbox.build()
3073 wc_dir = sbox.wc_dir
3075 chi_url = sbox.repo_url + '/A/D/H/chi'
3076 psi_url = sbox.repo_url + '/A/D/H/psi'
3077 omega_url = sbox.repo_url + '/A/D/H/omega'
3078 E_url = sbox.repo_url + '/A/B/E'
3079 C_url = sbox.repo_url + '/A/C'
3081 # Copy three files and a directory in the repo to a different location
3082 # in the repo
3083 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
3084 chi_url, psi_url, omega_url, E_url, C_url,
3085 '-m', 'logmsg')
3087 # Update to HEAD, and check to see if the files really moved in the repo
3089 expected_output = svntest.wc.State(wc_dir, {
3090 'A/C/chi' : Item(status='A '),
3091 'A/C/psi' : Item(status='A '),
3092 'A/C/omega' : Item(status='A '),
3093 'A/C/E' : Item(status='A '),
3094 'A/C/E/alpha' : Item(status='A '),
3095 'A/C/E/beta' : Item(status='A '),
3098 expected_disk = svntest.main.greek_state.copy()
3099 expected_disk.add({
3100 'A/C/chi' : Item(contents="This is the file 'chi'.\n"),
3101 'A/C/psi' : Item(contents="This is the file 'psi'.\n"),
3102 'A/C/omega' : Item(contents="This is the file 'omega'.\n"),
3103 'A/C/E' : Item(),
3104 'A/C/E/alpha' : Item(contents="This is the file 'alpha'.\n"),
3105 'A/C/E/beta' : Item(contents="This is the file 'beta'.\n"),
3108 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
3109 expected_status.add({
3110 'A/C/chi' : Item(status=' ', wc_rev=2),
3111 'A/C/psi' : Item(status=' ', wc_rev=2),
3112 'A/C/omega' : Item(status=' ', wc_rev=2),
3113 'A/C/E' : Item(status=' ', wc_rev=2),
3114 'A/C/E/alpha' : Item(status=' ', wc_rev=2),
3115 'A/C/E/beta' : Item(status=' ', wc_rev=2),
3118 svntest.actions.run_and_verify_update(wc_dir,
3119 expected_output,
3120 expected_disk,
3121 expected_status)
3123 #----------------------------------------------------------------------
3125 # Test moving copying multiple files from a repo to a wc
3127 def copy_multiple_repo_wc(sbox):
3128 "copy multiple files from a repo to a wc"
3130 sbox.build()
3131 wc_dir = sbox.wc_dir
3133 chi_url = sbox.repo_url + '/A/D/H/chi'
3134 psi_url = sbox.repo_url + '/A/D/H/psi'
3135 omega_with_space_url = sbox.repo_url + '/A/D/H/omega 2'
3136 E_url = sbox.repo_url + '/A/B/E'
3137 C_path = os.path.join(wc_dir, 'A', 'C')
3139 # We need this in order to check that we don't end up with URI-encoded
3140 # paths in the WC (issue #2955)
3141 svntest.actions.run_and_verify_svn(None, None, [], 'mv', '-m', 'log_msg',
3142 sbox.repo_url + '/A/D/H/omega',
3143 omega_with_space_url)
3145 # Perform the copy and check the output
3146 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
3147 chi_url, psi_url, omega_with_space_url,
3148 E_url, C_path)
3150 # Commit the changes, and verify the content actually got copied
3151 expected_output = svntest.wc.State(wc_dir, {
3152 'A/C/chi' : Item(verb='Adding'),
3153 'A/C/psi' : Item(verb='Adding'),
3154 'A/C/omega 2' : Item(verb='Adding'),
3155 'A/C/E' : Item(verb='Adding'),
3158 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
3159 expected_status.add({
3160 'A/C/chi' : Item(status=' ', wc_rev=3),
3161 'A/C/psi' : Item(status=' ', wc_rev=3),
3162 'A/C/omega 2' : Item(status=' ', wc_rev=3),
3163 'A/C/E' : Item(status=' ', wc_rev=3),
3164 'A/C/E/alpha' : Item(status=' ', wc_rev=3),
3165 'A/C/E/beta' : Item(status=' ', wc_rev=3),
3168 svntest.actions.run_and_verify_commit(wc_dir,
3169 expected_output,
3170 expected_status,
3171 None, None, None, None, None,
3172 wc_dir)
3174 #----------------------------------------------------------------------
3176 # Test moving copying multiple files from a wc to a repo
3178 def copy_multiple_wc_repo(sbox):
3179 "copy multiple files from a wc to a repo"
3181 sbox.build()
3182 wc_dir = sbox.wc_dir
3184 chi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'chi')
3185 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
3186 omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
3187 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
3188 C_url = sbox.repo_url + '/A/C'
3190 # Perform the copy and check the output
3191 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
3192 chi_path, psi_path, omega_path, E_path,
3193 C_url, '-m', 'logmsg')
3195 # Update to HEAD, and check to see if the files really got copied in the repo
3197 expected_output = svntest.wc.State(wc_dir, {
3198 'A/C/chi' : Item(status='A '),
3199 'A/C/psi' : Item(status='A '),
3200 'A/C/omega' : Item(status='A '),
3201 'A/C/E' : Item(status='A '),
3202 'A/C/E/alpha' : Item(status='A '),
3203 'A/C/E/beta' : Item(status='A '),
3206 expected_disk = svntest.main.greek_state.copy()
3207 expected_disk.add({
3208 'A/C/chi': Item(contents="This is the file 'chi'.\n"),
3209 'A/C/psi': Item(contents="This is the file 'psi'.\n"),
3210 'A/C/omega': Item(contents="This is the file 'omega'.\n"),
3211 'A/C/E' : Item(),
3212 'A/C/E/alpha' : Item(contents="This is the file 'alpha'.\n"),
3213 'A/C/E/beta' : Item(contents="This is the file 'beta'.\n"),
3216 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
3217 expected_status.add({
3218 'A/C/chi' : Item(status=' ', wc_rev=2),
3219 'A/C/psi' : Item(status=' ', wc_rev=2),
3220 'A/C/omega' : Item(status=' ', wc_rev=2),
3221 'A/C/E' : Item(status=' ', wc_rev=2),
3222 'A/C/E/alpha' : Item(status=' ', wc_rev=2),
3223 'A/C/E/beta' : Item(status=' ', wc_rev=2),
3226 svntest.actions.run_and_verify_update(wc_dir,
3227 expected_output,
3228 expected_disk,
3229 expected_status)
3231 #----------------------------------------------------------------------
3233 # Test copying local files using peg revision syntax
3234 # (Issue 2546)
3235 def copy_peg_rev_local_files(sbox):
3236 "copy local files using peg rev syntax"
3238 sbox.build()
3239 wc_dir = sbox.wc_dir
3241 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
3242 new_iota_path = os.path.join(wc_dir, 'new_iota')
3243 iota_path = os.path.join(wc_dir, 'iota')
3244 sigma_path = os.path.join(wc_dir, 'sigma')
3246 psi_text = "This is the file 'psi'.\n"
3247 iota_text = "This is the file 'iota'.\n"
3249 # Play a shell game with some WC files, then commit the changes back
3250 # to the repository (making r2).
3251 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3252 psi_path, new_iota_path)
3253 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3254 iota_path, psi_path)
3255 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3256 new_iota_path, iota_path)
3258 svntest.actions.run_and_verify_svn(None, None, [],
3259 'ci',
3260 '-m', 'rev 2',
3261 wc_dir)
3263 # Copy using a peg rev (remember, the object at iota_path at HEAD
3264 # was at psi_path back at r1).
3265 svntest.actions.run_and_verify_svn(None, None, [],
3266 'cp',
3267 iota_path + '@HEAD', '-r', '1',
3268 sigma_path)
3270 # Commit and verify disk contents
3271 svntest.actions.run_and_verify_svn(None, None, [],
3272 'ci', wc_dir,
3273 '-m', 'rev 3')
3275 expected_disk = svntest.main.greek_state.copy()
3276 expected_disk.tweak('A/D/H/psi', contents=iota_text)
3277 expected_disk.add({
3278 'iota' : Item(contents=psi_text, props={ SVN_PROP_MERGE_INFO : '' }),
3279 'A/D/H/psi' : Item(contents=iota_text, props={ SVN_PROP_MERGE_INFO : '' }),
3280 'sigma' : Item(contents=psi_text, props={ SVN_PROP_MERGE_INFO : '' }),
3283 actual_disk = svntest.tree.build_tree_from_wc(wc_dir, 3)
3284 svntest.tree.compare_trees(actual_disk, expected_disk.old_tree())
3287 #----------------------------------------------------------------------
3289 # Test copying local directories using peg revision syntax
3290 # (Issue 2546)
3291 def copy_peg_rev_local_dirs(sbox):
3292 "copy local dirs using peg rev syntax"
3294 sbox.build()
3295 wc_dir = sbox.wc_dir
3297 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
3298 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
3299 I_path = os.path.join(wc_dir, 'A', 'D', 'I')
3300 J_path = os.path.join(wc_dir, 'A', 'J')
3301 alpha_path = os.path.join(E_path, 'alpha')
3303 # Make some changes to the repository
3304 svntest.actions.run_and_verify_svn(None, None, [], 'rm',
3305 alpha_path)
3306 svntest.actions.run_and_verify_svn(None, None, [],
3307 'ci',
3308 '-m', 'rev 2',
3309 wc_dir)
3310 svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
3312 svntest.actions.run_and_verify_svn(None, None, [],
3313 'mv',
3314 E_path, I_path)
3315 svntest.actions.run_and_verify_svn(None, None, [],
3316 'ci',
3317 '-m', 'rev 3',
3318 wc_dir)
3320 svntest.actions.run_and_verify_svn(None, None, [],
3321 'mv',
3322 G_path, E_path)
3323 svntest.actions.run_and_verify_svn(None, None, [],
3324 'ci',
3325 '-m', 'rev 4',
3326 wc_dir)
3328 svntest.actions.run_and_verify_svn(None, None, [],
3329 'mv',
3330 I_path, G_path)
3331 svntest.actions.run_and_verify_svn(None, None, [],
3332 'ci',
3333 '-m', 'rev 5',
3334 wc_dir)
3336 # Copy using a peg rev
3337 svntest.actions.run_and_verify_svn(None, None, [],
3338 'cp',
3339 G_path + '@HEAD', '-r', '1',
3340 J_path)
3342 # Commit and verify disk contents
3343 svntest.actions.run_and_verify_svn(None, None, [],
3344 'ci', wc_dir,
3345 '-m', 'rev 6')
3347 expected_disk = svntest.main.greek_state.copy()
3348 expected_disk.remove('A/B/E/beta')
3349 expected_disk.remove('A/B/E/alpha')
3350 expected_disk.remove('A/D/G/pi')
3351 expected_disk.remove('A/D/G/rho')
3352 expected_disk.remove('A/D/G/tau')
3353 expected_disk.add({
3354 'A/B/E' : Item(props={ SVN_PROP_MERGE_INFO : '' }),
3355 'A/B/E/pi' : Item(contents="This is the file 'pi'.\n"),
3356 'A/B/E/rho' : Item(contents="This is the file 'rho'.\n"),
3357 'A/B/E/tau' : Item(contents="This is the file 'tau'.\n"),
3358 'A/D/G' : Item(props={ SVN_PROP_MERGE_INFO : '' }),
3359 'A/D/G/beta' : Item(contents="This is the file 'beta'.\n"),
3360 'A/J' : Item(props={ SVN_PROP_MERGE_INFO : '' }),
3361 'A/J/alpha' : Item(contents="This is the file 'alpha'.\n"),
3362 'A/J/beta' : Item(contents="This is the file 'beta'.\n"),
3365 actual_disk = svntest.tree.build_tree_from_wc(wc_dir, 5)
3366 svntest.tree.compare_trees(actual_disk, expected_disk.old_tree())
3369 #----------------------------------------------------------------------
3371 # Test copying urls using peg revision syntax
3372 # (Issue 2546)
3373 def copy_peg_rev_url(sbox):
3374 "copy urls using peg rev syntax"
3376 sbox.build()
3377 wc_dir = sbox.wc_dir
3379 psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
3380 new_iota_path = os.path.join(wc_dir, 'new_iota')
3381 iota_path = os.path.join(wc_dir, 'iota')
3382 iota_url = sbox.repo_url + '/iota'
3383 sigma_url = sbox.repo_url + '/sigma'
3385 psi_text = "This is the file 'psi'.\n"
3386 iota_text = "This is the file 'iota'.\n"
3388 # Make some changes to the repository
3389 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3390 psi_path, new_iota_path)
3391 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3392 iota_path, psi_path)
3393 svntest.actions.run_and_verify_svn(None, None, [], 'mv',
3394 new_iota_path, iota_path)
3396 svntest.actions.run_and_verify_svn(None, None, [],
3397 'ci',
3398 '-m', 'rev 2',
3399 wc_dir)
3401 # Copy using a peg rev
3402 svntest.actions.run_and_verify_svn(None, None, [],
3403 'cp',
3404 iota_url + '@HEAD', '-r', '1',
3405 sigma_url, '-m', 'rev 3')
3407 # Validate that copy destination has initialized mergeinfo.
3408 svntest.actions.run_and_verify_svn(None, ['\n'], [],
3409 'propget', SVN_PROP_MERGE_INFO, sigma_url)
3411 # Update to HEAD and verify disk contents
3412 expected_output = svntest.wc.State(wc_dir, {
3413 'sigma' : Item(status='A '),
3416 expected_disk = svntest.main.greek_state.copy()
3417 expected_disk.tweak('iota', contents=psi_text)
3418 expected_disk.tweak('A/D/H/psi', contents=iota_text)
3419 expected_disk.add({
3420 'sigma' : Item(contents=psi_text),
3423 expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
3424 expected_status.add({
3425 'sigma' : Item(status=' ', wc_rev=3)
3428 svntest.actions.run_and_verify_update(wc_dir,
3429 expected_output,
3430 expected_disk,
3431 expected_status)
3433 # Test copying an older revision of a wc directory in the wc.
3434 def old_dir_wc_to_wc(sbox):
3435 "copy old revision of wc dir to new dir"
3437 sbox.build()
3438 wc_dir = sbox.wc_dir
3440 E = os.path.join(wc_dir, 'A', 'B', 'E')
3441 E2 = os.path.join(wc_dir, 'E2')
3442 E_url = sbox.repo_url + '/A/B/E'
3443 alpha_url = E_url + '/alpha'
3445 # delete E/alpha in r2
3446 svntest.actions.run_and_verify_svn(None, None, [],
3447 'rm', '-m', '', alpha_url)
3449 # delete E in r3
3450 svntest.actions.run_and_verify_svn(None, None, [],
3451 'rm', '-m', '', E_url)
3453 # Copy an old revision of E into a new path in the WC
3454 svntest.actions.run_and_verify_svn(None, None, [],
3455 'cp', '-r1', E, E2)
3457 # Create expected output tree.
3458 expected_output = svntest.wc.State(wc_dir, {
3459 'E2' : Item(verb='Adding'),
3462 # Created expected status tree.
3463 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
3464 expected_status.add({
3465 'E2' : Item(status=' ', wc_rev=4),
3466 'E2/alpha' : Item(status=' ', wc_rev=4),
3467 'E2/beta' : Item(status=' ', wc_rev=4),
3469 # Commit the one file.
3470 svntest.actions.run_and_verify_commit(wc_dir,
3471 expected_output,
3472 expected_status,
3473 None,
3474 None, None,
3475 None, None,
3476 wc_dir)
3479 #----------------------------------------------------------------------
3480 # Test copying and creating parents in the wc
3482 def copy_make_parents_wc_wc(sbox):
3483 "svn cp --parents WC_PATH WC_PATH"
3485 sbox.build()
3486 wc_dir = sbox.wc_dir
3488 iota_path = os.path.join(wc_dir, 'iota')
3489 new_iota_path = os.path.join(wc_dir, 'X', 'Y', 'Z', 'iota')
3491 # Copy iota
3492 svntest.actions.run_and_verify_svn(None, None, [], 'cp', '--parents',
3493 iota_path, new_iota_path)
3495 # Create expected output
3496 expected_output = svntest.wc.State(wc_dir, {
3497 'X' : Item(verb='Adding'),
3498 'X/Y' : Item(verb='Adding'),
3499 'X/Y/Z' : Item(verb='Adding'),
3500 'X/Y/Z/iota' : Item(verb='Adding'),
3503 # Create expected status tree
3504 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
3506 # Add the moved files
3507 expected_status.add({
3508 'X' : Item(status=' ', wc_rev=2),
3509 'X/Y' : Item(status=' ', wc_rev=2),
3510 'X/Y/Z' : Item(status=' ', wc_rev=2),
3511 'X/Y/Z/iota' : Item(status=' ', wc_rev=2),
3514 svntest.actions.run_and_verify_commit(wc_dir,
3515 expected_output,
3516 expected_status,
3517 None,
3518 None, None,
3519 None, None,
3520 wc_dir)
3522 #----------------------------------------------------------------------
3523 # Test copying and creating parents from the repo to the wc
3525 def copy_make_parents_repo_wc(sbox):
3526 "svn cp --parents URL WC_PATH"
3528 sbox.build()
3529 wc_dir = sbox.wc_dir
3531 iota_url = sbox.repo_url + '/iota'
3532 new_iota_path = os.path.join(wc_dir, 'X', 'Y', 'Z', 'iota')
3534 # Copy iota
3535 svntest.actions.run_and_verify_svn(None, None, [],
3536 'cp', '--parents',
3537 iota_url, new_iota_path)
3539 # Create expected output
3540 expected_output = svntest.wc.State(wc_dir, {
3541 'X' : Item(verb='Adding'),
3542 'X/Y' : Item(verb='Adding'),
3543 'X/Y/Z' : Item(verb='Adding'),
3544 'X/Y/Z/iota' : Item(verb='Adding'),
3547 # Create expected status tree
3548 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
3550 # Add the moved files
3551 expected_status.add({
3552 'X' : Item(status=' ', wc_rev=2),
3553 'X/Y' : Item(status=' ', wc_rev=2),
3554 'X/Y/Z' : Item(status=' ', wc_rev=2),
3555 'X/Y/Z/iota' : Item(status=' ', wc_rev=2),
3558 svntest.actions.run_and_verify_commit(wc_dir,
3559 expected_output,
3560 expected_status,
3561 None,
3562 None, None,
3563 None, None,
3564 wc_dir)
3567 #----------------------------------------------------------------------
3568 # Test copying and creating parents from the wc to the repo
3570 def copy_make_parents_wc_repo(sbox):
3571 "svn cp --parents WC_PATH URL"
3573 sbox.build()
3574 wc_dir = sbox.wc_dir
3576 iota_path = os.path.join(wc_dir, 'iota')
3577 new_iota_url = sbox.repo_url + '/X/Y/Z/iota'
3579 # Copy iota
3580 svntest.actions.run_and_verify_svn(None, None, [],
3581 'cp', '--parents',
3582 '-m', 'log msg',
3583 iota_path, new_iota_url)
3585 # Update to HEAD and verify disk contents
3586 expected_output = svntest.wc.State(wc_dir, {
3587 'X' : Item(status='A '),
3588 'X/Y' : Item(status='A '),
3589 'X/Y/Z' : Item(status='A '),
3590 'X/Y/Z/iota' : Item(status='A '),
3593 expected_disk = svntest.main.greek_state.copy()
3594 expected_disk.add({
3595 'X' : Item(),
3596 'X/Y' : Item(),
3597 'X/Y/Z' : Item(),
3598 'X/Y/Z/iota' : Item(contents="This is the file 'iota'.\n"),
3601 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
3602 expected_status.add({
3603 'X' : Item(status=' ', wc_rev=2),
3604 'X/Y' : Item(status=' ', wc_rev=2),
3605 'X/Y/Z' : Item(status=' ', wc_rev=2),
3606 'X/Y/Z/iota' : Item(status=' ', wc_rev=2),
3609 svntest.actions.run_and_verify_update(wc_dir,
3610 expected_output,
3611 expected_disk,
3612 expected_status)
3615 #----------------------------------------------------------------------
3616 # Test copying and creating parents from repo to repo
3618 def copy_make_parents_repo_repo(sbox):
3619 "svn cp --parents URL URL"
3621 sbox.build()
3622 wc_dir = sbox.wc_dir
3624 iota_url = sbox.repo_url + '/iota'
3625 new_iota_url = sbox.repo_url + '/X/Y/Z/iota'
3627 # Copy iota
3628 svntest.actions.run_and_verify_svn(None, None, [],
3629 'cp', '--parents',
3630 '-m', 'log msg',
3631 iota_url, new_iota_url)
3633 # Update to HEAD and verify disk contents
3634 expected_output = svntest.wc.State(wc_dir, {
3635 'X' : Item(status='A '),
3636 'X/Y' : Item(status='A '),
3637 'X/Y/Z' : Item(status='A '),
3638 'X/Y/Z/iota' : Item(status='A '),
3641 expected_disk = svntest.main.greek_state.copy()
3642 expected_disk.add({
3643 'X' : Item(),
3644 'X/Y' : Item(),
3645 'X/Y/Z' : Item(),
3646 'X/Y/Z/iota' : Item(contents="This is the file 'iota'.\n"),
3649 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
3650 expected_status.add({
3651 'X' : Item(status=' ', wc_rev=2),
3652 'X/Y' : Item(status=' ', wc_rev=2),
3653 'X/Y/Z' : Item(status=' ', wc_rev=2),
3654 'X/Y/Z/iota' : Item(status=' ', wc_rev=2),
3657 svntest.actions.run_and_verify_update(wc_dir,
3658 expected_output,
3659 expected_disk,
3660 expected_status)
3662 # Test for issue #2894
3663 # Can't perform URL to WC copy if URL needs URI encoding.
3664 def URI_encoded_repos_to_wc(sbox):
3665 "copy a URL that needs URI encoding to WC"
3667 sbox.build()
3668 wc_dir = sbox.wc_dir
3669 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
3670 expected_disk = svntest.main.greek_state.copy()
3672 def copy_URL_to_WC(URL_rel_path, dest_name, rev):
3673 lines = [
3674 "A " + os.path.join(wc_dir, dest_name, "B") + "\n",
3675 "A " + os.path.join(wc_dir, dest_name, "B", "lambda") + "\n",
3676 "A " + os.path.join(wc_dir, dest_name, "B", "E") + "\n",
3677 "A " + os.path.join(wc_dir, dest_name, "B", "E", "alpha") + "\n",
3678 "A " + os.path.join(wc_dir, dest_name, "B", "E", "beta") + "\n",
3679 "A " + os.path.join(wc_dir, dest_name, "B", "F") + "\n",
3680 "A " + os.path.join(wc_dir, dest_name, "mu") + "\n",
3681 "A " + os.path.join(wc_dir, dest_name, "C") + "\n",
3682 "A " + os.path.join(wc_dir, dest_name, "D") + "\n",
3683 "A " + os.path.join(wc_dir, dest_name, "D", "gamma") + "\n",
3684 "A " + os.path.join(wc_dir, dest_name, "D", "G") + "\n",
3685 "A " + os.path.join(wc_dir, dest_name, "D", "G", "pi") + "\n",
3686 "A " + os.path.join(wc_dir, dest_name, "D", "G", "rho") + "\n",
3687 "A " + os.path.join(wc_dir, dest_name, "D", "G", "tau") + "\n",
3688 "A " + os.path.join(wc_dir, dest_name, "D", "H") + "\n",
3689 "A " + os.path.join(wc_dir, dest_name, "D", "H", "chi") + "\n",
3690 "A " + os.path.join(wc_dir, dest_name, "D", "H", "omega") + "\n",
3691 "A " + os.path.join(wc_dir, dest_name, "D", "H", "psi") + "\n",
3692 "Checked out revision " + str(rev - 1) + ".\n",
3693 "A " + os.path.join(wc_dir, dest_name) + "\n"]
3694 if rev == 3:
3695 lines.append(" U " + os.path.join(wc_dir, dest_name) + "\n")
3697 expected = svntest.verify.UnorderedOutput(lines)
3698 expected_status.add({
3699 dest_name + "/B" : Item(status=' ', wc_rev=rev),
3700 dest_name + "/B/lambda" : Item(status=' ', wc_rev=rev),
3701 dest_name + "/B/E" : Item(status=' ', wc_rev=rev),
3702 dest_name + "/B/E/alpha" : Item(status=' ', wc_rev=rev),
3703 dest_name + "/B/E/beta" : Item(status=' ', wc_rev=rev),
3704 dest_name + "/B/F" : Item(status=' ', wc_rev=rev),
3705 dest_name + "/mu" : Item(status=' ', wc_rev=rev),
3706 dest_name + "/C" : Item(status=' ', wc_rev=rev),
3707 dest_name + "/D" : Item(status=' ', wc_rev=rev),
3708 dest_name + "/D/gamma" : Item(status=' ', wc_rev=rev),
3709 dest_name + "/D/G" : Item(status=' ', wc_rev=rev),
3710 dest_name + "/D/G/pi" : Item(status=' ', wc_rev=rev),
3711 dest_name + "/D/G/rho" : Item(status=' ', wc_rev=rev),
3712 dest_name + "/D/G/tau" : Item(status=' ', wc_rev=rev),
3713 dest_name + "/D/H" : Item(status=' ', wc_rev=rev),
3714 dest_name + "/D/H/chi" : Item(status=' ', wc_rev=rev),
3715 dest_name + "/D/H/omega" : Item(status=' ', wc_rev=rev),
3716 dest_name + "/D/H/psi" : Item(status=' ', wc_rev=rev),
3717 dest_name : Item(status=' ', wc_rev=rev)})
3718 expected_disk.add({
3719 dest_name : Item(props={SVN_PROP_MERGE_INFO : ''}),
3720 dest_name + '/B' : Item(),
3721 dest_name + '/B/lambda' : Item("This is the file 'lambda'.\n"),
3722 dest_name + '/B/E' : Item(),
3723 dest_name + '/B/E/alpha' : Item("This is the file 'alpha'.\n"),
3724 dest_name + '/B/E/beta' : Item("This is the file 'beta'.\n"),
3725 dest_name + '/B/F' : Item(),
3726 dest_name + '/mu' : Item("This is the file 'mu'.\n"),
3727 dest_name + '/C' : Item(),
3728 dest_name + '/D' : Item(),
3729 dest_name + '/D/gamma' : Item("This is the file 'gamma'.\n"),
3730 dest_name + '/D/G' : Item(),
3731 dest_name + '/D/G/pi' : Item("This is the file 'pi'.\n"),
3732 dest_name + '/D/G/rho' : Item("This is the file 'rho'.\n"),
3733 dest_name + '/D/G/tau' : Item("This is the file 'tau'.\n"),
3734 dest_name + '/D/H' : Item(),
3735 dest_name + '/D/H/chi' : Item("This is the file 'chi'.\n"),
3736 dest_name + '/D/H/omega' : Item("This is the file 'omega'.\n"),
3737 dest_name + '/D/H/psi' : Item("This is the file 'psi'.\n"),
3740 # Make a copy
3741 svntest.actions.run_and_verify_svn(None, expected, [],
3742 'copy',
3743 sbox.repo_url + '/' + URL_rel_path,
3744 os.path.join(wc_dir,
3745 dest_name))
3747 expected_output = svntest.wc.State(wc_dir,
3748 {dest_name : Item(verb='Adding')})
3749 svntest.actions.run_and_verify_commit(wc_dir,
3750 expected_output,
3751 expected_status,
3752 None, None, None, None, None,
3753 wc_dir)
3755 copy_URL_to_WC('A', 'A COPY', 2)
3756 copy_URL_to_WC('A COPY', 'A_COPY_2', 3)
3758 ########################################################################
3759 # Run the tests
3762 # list all tests here, starting with None:
3763 test_list = [ None,
3764 basic_copy_and_move_files,
3765 receive_copy_in_update,
3766 resurrect_deleted_dir,
3767 no_copy_overwrites,
3768 no_wc_copy_overwrites,
3769 copy_modify_commit,
3770 copy_files_with_properties,
3771 copy_delete_commit,
3772 mv_and_revert_directory,
3773 SkipUnless(copy_preserve_executable_bit, svntest.main.is_posix_os),
3774 wc_to_repos,
3775 repos_to_wc,
3776 copy_to_root,
3777 url_copy_parent_into_child,
3778 wc_copy_parent_into_child,
3779 resurrect_deleted_file,
3780 diff_repos_to_wc_copy,
3781 repos_to_wc_copy_eol_keywords,
3782 revision_kinds_local_source,
3783 copy_over_missing_file,
3784 repos_to_wc_1634,
3785 double_uri_escaping_1814,
3786 wc_to_wc_copy_between_different_repos,
3787 wc_to_wc_copy_deleted,
3788 url_to_non_existent_url_path,
3789 non_existent_url_to_url,
3790 old_dir_url_to_url,
3791 wc_copy_dir_to_itself,
3792 mixed_wc_to_url,
3793 wc_copy_replacement,
3794 wc_copy_replace_with_props,
3795 repos_to_wc_copy_replacement,
3796 repos_to_wc_copy_replace_with_props,
3797 delete_replaced_file,
3798 mv_unversioned_file,
3799 force_move,
3800 copy_deleted_dir_into_prefix,
3801 copy_copied_file_and_dir,
3802 move_copied_file_and_dir,
3803 move_moved_file_and_dir,
3804 move_file_within_moved_dir,
3805 move_file_out_of_moved_dir,
3806 move_dir_within_moved_dir,
3807 move_dir_out_of_moved_dir,
3808 move_file_back_and_forth,
3809 move_dir_back_and_forth,
3810 copy_move_added_paths,
3811 XFail(copy_added_paths_with_props),
3812 copy_added_paths_to_URL,
3813 move_to_relative_paths,
3814 move_from_relative_paths,
3815 copy_to_relative_paths,
3816 copy_from_relative_paths,
3817 move_multiple_wc,
3818 copy_multiple_wc,
3819 move_multiple_repo,
3820 copy_multiple_repo,
3821 copy_multiple_repo_wc,
3822 copy_multiple_wc_repo,
3823 copy_peg_rev_local_files,
3824 copy_peg_rev_local_dirs,
3825 copy_peg_rev_url,
3826 old_dir_wc_to_wc,
3827 copy_make_parents_wc_wc,
3828 copy_make_parents_repo_wc,
3829 copy_make_parents_wc_repo,
3830 copy_make_parents_repo_repo,
3831 URI_encoded_repos_to_wc,
3834 if __name__ == '__main__':
3835 svntest.main.run_tests(test_list)
3836 # NOTREACHED
3839 ### End of file.