Add test case to verify that folding a subtree will not destroy to content of
[svn.git] / subversion / tests / cmdline / depth_tests.py
blobf9c7cabe3a581c31b7cf84a14b5969a6d789d66d
1 #!/usr/bin/env python
3 # depth_tests.py: Testing that operations work as expected at
4 # various depths (depth-empty, depth-files,
5 # depth-immediates, depth-infinity).
7 # Subversion is a tool for revision control.
8 # See http://subversion.tigris.org for more information.
10 # ====================================================================
11 # Copyright (c) 2007 CollabNet. All rights reserved.
13 # This software is licensed as described in the file COPYING, which
14 # you should have received as part of this distribution. The terms
15 # are also available at http://subversion.tigris.org/license-1.html.
16 # If newer versions of this license are posted there, you may use a
17 # newer version instead, at your option.
19 ######################################################################
21 # General modules
22 import os
24 # Our testing module
25 import svntest
26 from svntest import wc
28 # (abbreviation)
29 Skip = svntest.testcase.Skip
30 XFail = svntest.testcase.XFail
31 Item = wc.StateItem
33 # For errors setting up the depthy working copies.
34 class DepthSetupError(Exception):
35 def __init__ (self, args=None):
36 self.args = args
38 def set_up_depthy_working_copies(sbox, empty=False, files=False,
39 immediates=False, infinity=False):
40 """Set up up to four working copies, at various depths. At least
41 one of depths EMPTY, FILES, IMMEDIATES, or INFINITY must be passed
42 as True. The corresponding working copy paths are returned in a
43 four-element tuple in that order, with element value of None for
44 working copies that were not created. If all args are False, raise
45 DepthSetupError."""
47 if not (infinity or empty or files or immediates):
48 raise DepthSetupError("At least one working copy depth must be passed.")
50 wc = None
51 if infinity:
52 sbox.build()
53 wc = sbox.wc_dir
54 else:
55 sbox.build(create_wc = False)
56 sbox.add_test_path(sbox.wc_dir, True)
58 wc_empty = None
59 if empty:
60 wc_empty = sbox.wc_dir + '-depth-empty'
61 sbox.add_test_path(wc_empty, True)
62 svntest.actions.run_and_verify_svn(
63 "Unexpected error from co --depth=empty",
64 svntest.verify.AnyOutput, [],
65 "co", "--depth", "empty", sbox.repo_url, wc_empty)
67 wc_files = None
68 if files:
69 wc_files = sbox.wc_dir + '-depth-files'
70 sbox.add_test_path(wc_files, True)
71 svntest.actions.run_and_verify_svn(
72 "Unexpected error from co --depth=files",
73 svntest.verify.AnyOutput, [],
74 "co", "--depth", "files", sbox.repo_url, wc_files)
76 wc_immediates = None
77 if immediates:
78 wc_immediates = sbox.wc_dir + '-depth-immediates'
79 sbox.add_test_path(wc_immediates, True)
80 svntest.actions.run_and_verify_svn(
81 "Unexpected error from co --depth=immediates",
82 svntest.verify.AnyOutput, [],
83 "co", "--depth", "immediates",
84 sbox.repo_url, wc_immediates)
86 return wc_empty, wc_files, wc_immediates, wc
88 def verify_depth(msg, depth, path="."):
89 """Verifies that PATH has depth DEPTH. MSG is the failure message."""
90 if depth == "infinity":
91 # Check for absence of depth line.
92 exit_code, out, err = svntest.actions.run_and_verify_svn(None, None,
93 [], "info", path)
94 for line in out:
95 if line.startswith("Depth:"):
96 raise svntest.failure(msg)
97 else:
98 svntest.actions.run_and_verify_svn_match_any(
99 msg, "^Depth: %s\n$" % depth, [], "info", path)
101 #----------------------------------------------------------------------
102 # Ensure that 'checkout --depth=empty' results in a depth-empty working copy.
103 def depth_empty_checkout(sbox):
104 "depth-empty checkout"
106 wc_empty, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True)
108 if os.path.exists(os.path.join(wc_empty, "iota")):
109 raise svntest.Failure("depth-empty checkout created file 'iota'")
111 if os.path.exists(os.path.join(wc_empty, "A")):
112 raise svntest.Failure("depth-empty checkout created subdir 'A'")
114 verify_depth("Expected depth empty for top of WC, got some other depth",
115 "empty", wc_empty)
118 # Helper for two test functions.
119 def depth_files_same_as_nonrecursive(sbox, opt):
120 """Run a depth-files or non-recursive checkout, depending on whether
121 passed '-N' or '--depth=files' for OPT. The two should get the same
122 result, hence this helper containing the common code between the
123 two tests."""
125 # This duplicates some code from set_up_depthy_working_copies(), but
126 # that's because it's abstracting out a different axis.
128 sbox.build(create_wc = False, read_only = True)
129 if os.path.exists(sbox.wc_dir):
130 svntest.main.safe_rmtree(sbox.wc_dir)
132 svntest.actions.run_and_verify_svn("Unexpected error during co %s" % opt,
133 svntest.verify.AnyOutput, [],
134 "co", opt, sbox.repo_url, sbox.wc_dir)
136 # Should create a depth-files top directory, so both iota and A
137 # should exist, and A should be empty and depth-empty.
139 if not os.path.exists(os.path.join(sbox.wc_dir, "iota")):
140 raise svntest.Failure("'checkout %s' failed to create file 'iota'" % opt)
142 if os.path.exists(os.path.join(sbox.wc_dir, "A")):
143 raise svntest.Failure("'checkout %s' unexpectedly created subdir 'A'" % opt)
145 verify_depth("Expected depth files for top of WC, got some other depth",
146 "files", sbox.wc_dir)
149 def depth_files_checkout(sbox):
150 "depth-files checkout"
151 depth_files_same_as_nonrecursive(sbox, "--depth=files")
154 def nonrecursive_checkout(sbox):
155 "non-recursive checkout equals depth-files"
156 depth_files_same_as_nonrecursive(sbox, "-N")
159 #----------------------------------------------------------------------
160 def depth_empty_update_bypass_single_file(sbox):
161 "update depth-empty wc shouldn't receive file mod"
163 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True,
164 infinity=True)
166 iota_path = os.path.join(wc, 'iota')
167 svntest.main.file_append(iota_path, "new text\n")
169 # Commit in the "other" wc.
170 expected_output = svntest.wc.State(wc, { 'iota' : Item(verb='Sending'), })
171 expected_status = svntest.actions.get_virginal_state(wc, 1)
172 expected_status.tweak('iota', wc_rev=2, status=' ')
173 svntest.actions.run_and_verify_commit(wc,
174 expected_output,
175 expected_status,
176 None, wc)
178 # Update the depth-empty wc, expecting not to receive the change to iota.
179 expected_output = svntest.wc.State(wc_empty, { })
180 expected_disk = svntest.wc.State('', { })
181 expected_status = svntest.wc.State(wc_empty, { '' : svntest.wc.StateItem() })
182 expected_status.tweak(contents=None, status=' ', wc_rev=2)
183 svntest.actions.run_and_verify_update(wc_empty,
184 expected_output,
185 expected_disk,
186 expected_status,
187 None, None, None, None, None)
189 # And the wc should still be depth-empty.
190 verify_depth(None, "empty", wc_empty)
192 # Even if we explicitly ask for a depth-infinity update, we still shouldn't
193 # get the change to iota.
194 svntest.actions.run_and_verify_update(wc_empty,
195 expected_output,
196 expected_disk,
197 expected_status,
198 None, None, None, None, None, False,
199 "--depth=infinity", wc_empty)
201 # And the wc should still be depth-empty.
202 verify_depth(None, "empty", wc_empty)
205 #----------------------------------------------------------------------
206 def depth_immediates_get_top_file_mod_only(sbox):
207 "update depth-immediates wc gets top file mod only"
209 ign_a, ign_b, wc_immediates, wc \
210 = set_up_depthy_working_copies(sbox, immediates=True, infinity=True)
212 iota_path = os.path.join(wc, 'iota')
213 svntest.main.file_append(iota_path, "new text in iota\n")
214 mu_path = os.path.join(wc, 'A', 'mu')
215 svntest.main.file_append(mu_path, "new text in mu\n")
217 # Commit in the "other" wc.
218 expected_output = svntest.wc.State(wc,
219 { 'iota' : Item(verb='Sending'),
220 'A/mu' : Item(verb='Sending'),
222 expected_status = svntest.actions.get_virginal_state(wc, 1)
223 expected_status.tweak('iota', wc_rev=2, status=' ')
224 expected_status.tweak('A/mu', wc_rev=2, status=' ')
225 svntest.actions.run_and_verify_commit(wc,
226 expected_output,
227 expected_status,
228 None, wc)
230 # Update the depth-immediates wc, expecting to receive only the
231 # change to iota.
232 expected_output = svntest.wc.State(wc_immediates,
233 { 'iota' : Item(status='U ') })
234 expected_disk = svntest.wc.State('', { })
235 expected_disk.add(\
236 {'iota' : Item(contents="This is the file 'iota'.\nnew text in iota\n"),
237 'A' : Item(contents=None) } )
238 expected_status = svntest.wc.State(wc_immediates,
239 { '' : svntest.wc.StateItem() })
240 expected_status.tweak(contents=None, status=' ', wc_rev=2)
241 expected_status.add(\
242 {'iota' : Item(status=' ', wc_rev=2),
243 'A' : Item(status=' ', wc_rev=2) } )
244 svntest.actions.run_and_verify_update(wc_immediates,
245 expected_output,
246 expected_disk,
247 expected_status,
248 None, None, None, None, None)
249 verify_depth(None, "immediates", wc_immediates)
252 #----------------------------------------------------------------------
253 def depth_empty_commit(sbox):
254 "commit a file from a depth-empty working copy"
255 # Bring iota into a depth-empty working copy, then commit a change to it.
256 wc_empty, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox,
257 empty=True)
259 # Form the working path of iota
260 wc_empty_iota = os.path.join(wc_empty, 'iota')
262 # Update 'iota' in the depth-empty working copy and modify it
263 svntest.actions.run_and_verify_svn(None, None, [],
264 'up', wc_empty_iota)
265 svntest.main.file_write(wc_empty_iota, "iota modified")
267 # Commit the modified changes from a depth-empty working copy
268 expected_output = svntest.wc.State(wc_empty, {
269 'iota' : Item(verb='Sending'),
271 expected_status = svntest.wc.State(wc_empty, { })
272 expected_status.add({
273 '' : Item(status=' ', wc_rev=1),
274 'iota' : Item(status=' ', wc_rev=2),
276 svntest.actions.run_and_verify_commit(wc_empty,
277 expected_output,
278 expected_status,
279 None,
280 wc_empty)
282 #----------------------------------------------------------------------
283 def depth_empty_with_file(sbox):
284 "act on a file in a depth-empty working copy"
285 # Run 'svn up iota' to bring iota permanently into the working copy.
286 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True,
287 infinity=True)
289 iota_path = os.path.join(wc_empty, 'iota')
290 if os.path.exists(iota_path):
291 raise svntest.Failure("'%s' exists when it shouldn't" % iota_path)
293 # ### I'd love to do this using the recommended {expected_output,
294 # ### expected_status, expected_disk} method here, but after twenty
295 # ### minutes of trying to figure out how, I decided to compromise.
297 # Update iota by name, expecting to receive it.
298 svntest.actions.run_and_verify_svn(None, None, [], 'up', iota_path)
300 # Test that we did receive it.
301 if not os.path.exists(iota_path):
302 raise svntest.Failure("'%s' doesn't exist when it should" % iota_path)
304 # Commit a change to iota in the "other" wc.
305 other_iota_path = os.path.join(wc, 'iota')
306 svntest.main.file_append(other_iota_path, "new text\n")
307 expected_output = svntest.wc.State(wc, { 'iota' : Item(verb='Sending'), })
308 expected_status = svntest.actions.get_virginal_state(wc, 1)
309 expected_status.tweak('iota', wc_rev=2, status=' ')
310 svntest.actions.run_and_verify_commit(wc,
311 expected_output,
312 expected_status,
313 None, wc)
315 # Delete iota in the "other" wc.
316 other_iota_path = os.path.join(wc, 'iota')
317 svntest.actions.run_and_verify_svn(None, None, [], 'rm', other_iota_path)
318 expected_output = svntest.wc.State(wc, { 'iota' : Item(verb='Deleting'), })
319 expected_status = svntest.actions.get_virginal_state(wc, 1)
320 expected_status.remove('iota')
321 svntest.actions.run_and_verify_commit(wc,
322 expected_output,
323 expected_status,
324 None, wc)
326 # Update the depth-empty wc just a little, expecting to receive
327 # the change in iota.
328 expected_output = svntest.wc.State(\
329 wc_empty, { 'iota' : Item(status='U ') })
330 expected_disk = svntest.wc.State(\
331 '', { 'iota' : Item(contents="This is the file 'iota'.\nnew text\n") })
332 expected_status = svntest.wc.State(wc_empty,
333 { '' : Item(status=' ', wc_rev=2),
334 'iota' : Item(status=' ', wc_rev=2),})
335 svntest.actions.run_and_verify_update(wc_empty,
336 expected_output,
337 expected_disk,
338 expected_status,
339 None, None, None, None, None, False,
340 '-r2', wc_empty)
342 # Update the depth-empty wc all the way, expecting to receive the deletion
343 # of iota.
344 expected_output = svntest.wc.State(\
345 wc_empty, { 'iota' : Item(status='D ') })
346 expected_disk = svntest.wc.State('', { })
347 expected_status = svntest.wc.State(\
348 wc_empty, { '' : Item(status=' ', wc_rev=3) })
349 svntest.actions.run_and_verify_update(wc_empty,
350 expected_output,
351 expected_disk,
352 expected_status,
353 None, None, None, None, None)
356 #----------------------------------------------------------------------
357 def depth_empty_with_dir(sbox):
358 "bring a dir into a depth-empty working copy"
359 # Run 'svn up A' to bring A permanently into the working copy.
360 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True,
361 infinity=True)
363 A_path = os.path.join(wc_empty, 'A')
364 other_mu_path = os.path.join(wc, 'A', 'mu')
366 # We expect A to be added at depth infinity, so a normal 'svn up A'
367 # should be sufficient to add all descendants.
368 expected_output = svntest.wc.State(wc_empty, {
369 'A' : Item(status='A '),
370 'A/mu' : Item(status='A '),
371 'A/B' : Item(status='A '),
372 'A/B/lambda' : Item(status='A '),
373 'A/B/E' : Item(status='A '),
374 'A/B/E/alpha' : Item(status='A '),
375 'A/B/E/beta' : Item(status='A '),
376 'A/B/F' : Item(status='A '),
377 'A/C' : Item(status='A '),
378 'A/D' : Item(status='A '),
379 'A/D/gamma' : Item(status='A '),
380 'A/D/G' : Item(status='A '),
381 'A/D/G/pi' : Item(status='A '),
382 'A/D/G/rho' : Item(status='A '),
383 'A/D/G/tau' : Item(status='A '),
384 'A/D/H' : Item(status='A '),
385 'A/D/H/chi' : Item(status='A '),
386 'A/D/H/psi' : Item(status='A '),
387 'A/D/H/omega' : Item(status='A ')
389 expected_disk = svntest.main.greek_state.copy()
390 expected_disk.remove('iota')
391 expected_status = svntest.actions.get_virginal_state(wc_empty, 1)
392 expected_status.remove('iota')
393 svntest.actions.run_and_verify_update(wc_empty,
394 expected_output,
395 expected_disk,
396 expected_status,
397 None, None,
398 None, None, None, None,
399 A_path)
401 # Commit a change to A/mu in the "other" wc.
402 svntest.main.file_write(other_mu_path, "new text\n")
403 expected_output = svntest.wc.State(\
404 wc, { 'A/mu' : Item(verb='Sending'), })
405 expected_status = svntest.actions.get_virginal_state(wc, 1)
406 expected_status.tweak('A/mu', wc_rev=2, status=' ')
407 svntest.actions.run_and_verify_commit(wc,
408 expected_output,
409 expected_status,
410 None, wc)
412 # Update "A" by name in wc_empty, expect to receive the change to A/mu.
413 expected_output = svntest.wc.State(wc_empty, { 'A/mu' : Item(status='U ') })
414 expected_disk = svntest.main.greek_state.copy()
415 expected_disk.remove('iota')
416 expected_disk.tweak('A/mu', contents='new text\n')
417 expected_status = svntest.actions.get_virginal_state(wc_empty, 2)
418 expected_status.remove('iota')
419 expected_status.tweak('', wc_rev=1)
420 svntest.actions.run_and_verify_update(wc_empty,
421 expected_output,
422 expected_disk,
423 expected_status,
424 None, None,
425 None, None, None, None,
426 A_path)
428 # Commit the deletion of A/mu from the "other" wc.
429 svntest.main.file_write(other_mu_path, "new text\n")
430 svntest.actions.run_and_verify_svn(None, None, [], 'rm', other_mu_path)
431 expected_output = svntest.wc.State(wc, { 'A/mu' : Item(verb='Deleting'), })
432 expected_status = svntest.actions.get_virginal_state(wc, 1)
433 expected_status.remove('A/mu')
434 svntest.actions.run_and_verify_commit(wc,
435 expected_output,
436 expected_status,
437 None, wc)
440 # Update "A" by name in wc_empty, expect to A/mu to disappear.
441 expected_output = svntest.wc.State(wc_empty, { 'A/mu' : Item(status='D ') })
442 expected_disk = svntest.main.greek_state.copy()
443 expected_disk.remove('iota')
444 expected_disk.remove('A/mu')
445 expected_status = svntest.actions.get_virginal_state(wc_empty, 3)
446 expected_status.remove('iota')
447 expected_status.remove('A/mu')
448 expected_status.tweak('', wc_rev=1)
449 svntest.actions.run_and_verify_update(wc_empty,
450 expected_output,
451 expected_disk,
452 expected_status,
453 None, None,
454 None, None, None, None,
455 A_path)
459 #----------------------------------------------------------------------
460 def depth_immediates_bring_in_file(sbox):
461 "bring a file into a depth-immediates working copy"
463 # Create an immediates working copy and form the paths
464 ign_a, ign_b, wc_imm, wc = set_up_depthy_working_copies(sbox,
465 immediates=True)
466 A_mu_path = os.path.join(wc_imm, 'A', 'mu')
467 gamma_path = os.path.join(wc_imm, 'A', 'D', 'gamma')
469 # Run 'svn up A/mu' to bring A/mu permanently into the working copy.
470 expected_output = svntest.wc.State(wc_imm, {
471 'A/mu' : Item(status='A '),
473 expected_disk = svntest.main.greek_state.copy()
474 expected_disk.remove('A/C', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
475 'A/B/E/beta', 'A/B/F', 'A/B', 'A/D/gamma', 'A/D/G',
476 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 'A/D/H/chi',
477 'A/D/H/psi', 'A/D/H/omega', 'A/D/H', 'A/D')
478 expected_status = svntest.actions.get_virginal_state(wc_imm, 1)
479 expected_status.remove('A/C', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
480 'A/B/E/beta', 'A/B/F', 'A/B', 'A/D/gamma', 'A/D/G',
481 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 'A/D/H/chi',
482 'A/D/H/psi', 'A/D/H/omega', 'A/D/H', 'A/D')
483 svntest.actions.run_and_verify_update(wc_imm,
484 expected_output,
485 expected_disk,
486 expected_status,
487 None, None, None,
488 None, None, None,
489 A_mu_path)
491 # Run 'svn up A/D/gamma' to test the edge case 'Skipped'.
492 expected_output = svntest.wc.State(wc_imm, {
493 'A/D/gamma' : Item(verb='Skipped'),
495 expected_disk = svntest.main.greek_state.copy()
496 expected_disk.remove('A/C', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
497 'A/B/E/beta', 'A/B/F', 'A/B', 'A/D/gamma', 'A/D/G',
498 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 'A/D/H/chi',
499 'A/D/H/psi', 'A/D/H/omega', 'A/D/H', 'A/D')
500 expected_status = svntest.actions.get_virginal_state(wc_imm, 1)
501 expected_status.remove('A/C', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
502 'A/B/E/beta', 'A/B/F', 'A/B', 'A/D/gamma', 'A/D/G',
503 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 'A/D/H/chi',
504 'A/D/H/psi', 'A/D/H/omega', 'A/D/H', 'A/D')
505 svntest.actions.run_and_verify_update(wc_imm,
506 expected_output,
507 expected_disk,
508 expected_status,
509 None, None, None,
510 None, None, None,
511 gamma_path)
513 #----------------------------------------------------------------------
514 def depth_immediates_fill_in_dir(sbox):
515 "bring a dir into a depth-immediates working copy"
517 # Run 'svn up A --set-depth=infinity' to fill in A as a
518 # depth-infinity subdir.
519 ign_a, ign_b, wc_immediates, wc \
520 = set_up_depthy_working_copies(sbox, immediates=True)
521 A_path = os.path.join(wc_immediates, 'A')
522 expected_output = svntest.wc.State(wc_immediates, {
523 'A/mu' : Item(status='A '),
524 'A/B' : Item(status='A '),
525 'A/B/lambda' : Item(status='A '),
526 'A/B/E' : Item(status='A '),
527 'A/B/E/alpha' : Item(status='A '),
528 'A/B/E/beta' : Item(status='A '),
529 'A/B/F' : Item(status='A '),
530 'A/C' : Item(status='A '),
531 'A/D' : Item(status='A '),
532 'A/D/gamma' : Item(status='A '),
533 'A/D/G' : Item(status='A '),
534 'A/D/G/pi' : Item(status='A '),
535 'A/D/G/rho' : Item(status='A '),
536 'A/D/G/tau' : Item(status='A '),
537 'A/D/H' : Item(status='A '),
538 'A/D/H/chi' : Item(status='A '),
539 'A/D/H/psi' : Item(status='A '),
540 'A/D/H/omega' : Item(status='A ')
542 expected_disk = svntest.main.greek_state.copy()
543 expected_status = svntest.actions.get_virginal_state(wc_immediates, 1)
544 svntest.actions.run_and_verify_update(wc_immediates,
545 expected_output,
546 expected_disk,
547 expected_status,
548 None, None,
549 None, None, None, None,
550 '--set-depth', 'infinity',
551 A_path)
553 #----------------------------------------------------------------------
554 def depth_mixed_bring_in_dir(sbox):
555 "bring a dir into a mixed-depth working copy"
557 # Run 'svn up --set-depth=immediates A' in a depth-empty working copy.
558 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True)
559 A_path = os.path.join(wc_empty, 'A')
560 B_path = os.path.join(wc_empty, 'A', 'B')
561 C_path = os.path.join(wc_empty, 'A', 'C')
563 expected_output = svntest.wc.State(wc_empty, {
564 'A' : Item(status='A '),
565 'A/mu' : Item(status='A '),
567 expected_disk = svntest.main.greek_state.copy()
568 expected_disk.remove('iota', 'A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
569 'A/B/E/beta', 'A/B/F', 'A/C', 'A/D', 'A/D/gamma',
570 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau',
571 'A/D/H', 'A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega')
572 expected_status = svntest.actions.get_virginal_state(wc_empty, 1)
573 expected_status.remove('iota', 'A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
574 'A/B/E/beta', 'A/B/F', 'A/C', 'A/D', 'A/D/gamma',
575 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau',
576 'A/D/H', 'A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega')
577 svntest.actions.run_and_verify_update(wc_empty,
578 expected_output,
579 expected_disk,
580 expected_status,
581 None, None,
582 None, None, None, None,
583 '--set-depth', 'files',
584 A_path)
585 # Check that A was added at depth=files.
586 verify_depth(None, "files", A_path)
588 # Now, bring in A/B at depth-immediates.
589 expected_output = svntest.wc.State(wc_empty, {
590 'A/B' : Item(status='A '),
591 'A/B/lambda' : Item(status='A '),
592 'A/B/E' : Item(status='A '),
593 'A/B/F' : Item(status='A '),
595 expected_disk = svntest.main.greek_state.copy()
596 expected_disk.remove('iota', 'A/B/E/alpha', 'A/B/E/beta', 'A/C',
597 'A/D', 'A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho',
598 'A/D/G/tau', 'A/D/H', 'A/D/H/chi', 'A/D/H/psi',
599 'A/D/H/omega')
600 expected_status = svntest.actions.get_virginal_state(wc_empty, 1)
601 expected_status.remove('iota', 'A/B/E/alpha', 'A/B/E/beta', 'A/C',
602 'A/D', 'A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho',
603 'A/D/G/tau', 'A/D/H', 'A/D/H/chi', 'A/D/H/psi',
604 'A/D/H/omega')
605 svntest.actions.run_and_verify_update(wc_empty,
606 expected_output,
607 expected_disk,
608 expected_status,
609 None, None,
610 None, None, None, None,
611 '--set-depth', 'immediates',
612 B_path)
613 # Check that A/B was added at depth=immediates.
614 verify_depth(None, "immediates", B_path)
616 # Now, bring in A/C at depth-empty.
617 expected_output = svntest.wc.State(wc_empty, {
618 'A/C' : Item(status='A '),
620 expected_disk = svntest.main.greek_state.copy()
621 expected_disk.remove('iota', 'A/B/E/alpha', 'A/B/E/beta',
622 'A/D', 'A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho',
623 'A/D/G/tau', 'A/D/H', 'A/D/H/chi', 'A/D/H/psi',
624 'A/D/H/omega')
625 expected_status = svntest.actions.get_virginal_state(wc_empty, 1)
626 expected_status.remove('iota', 'A/B/E/alpha', 'A/B/E/beta',
627 'A/D', 'A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho',
628 'A/D/G/tau', 'A/D/H', 'A/D/H/chi', 'A/D/H/psi',
629 'A/D/H/omega')
630 svntest.actions.run_and_verify_update(wc_empty,
631 expected_output,
632 expected_disk,
633 expected_status,
634 None, None,
635 None, None, None, None,
636 '--set-depth', 'empty',
637 C_path)
638 # Check that A/C was added at depth=empty.
639 verify_depth(None, "empty", C_path)
641 #----------------------------------------------------------------------
642 def depth_empty_unreceive_delete(sbox):
643 "depth-empty working copy ignores a deletion"
644 # Check out a depth-empty greek tree to wc1. In wc2, delete iota and
645 # commit. Update wc1; should not receive the delete.
646 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True,
647 infinity=True)
649 iota_path = os.path.join(wc, 'iota')
651 # Commit in the "other" wc.
652 svntest.actions.run_and_verify_svn(None, None, [], 'rm', iota_path)
653 expected_output = svntest.wc.State(wc, { 'iota' : Item(verb='Deleting'), })
654 expected_status = svntest.actions.get_virginal_state(wc, 1)
655 expected_status.remove('iota')
656 svntest.actions.run_and_verify_commit(wc,
657 expected_output,
658 expected_status,
659 None, wc)
661 # Update the depth-empty wc, expecting not to receive the deletion of iota.
662 expected_output = svntest.wc.State(wc_empty, { })
663 expected_disk = svntest.wc.State('', { })
664 expected_status = svntest.wc.State(wc_empty, { '' : svntest.wc.StateItem() })
665 expected_status.tweak(contents=None, status=' ', wc_rev=2)
666 svntest.actions.run_and_verify_update(wc_empty,
667 expected_output,
668 expected_disk,
669 expected_status,
670 None, None, None, None, None)
673 #----------------------------------------------------------------------
674 def depth_immediates_unreceive_delete(sbox):
675 "depth-immediates working copy ignores a deletion"
676 # Check out a depth-immediates greek tree to wc1. In wc2, delete
677 # A/mu and commit. Update wc1; should not receive the delete.
679 ign_a, ign_b, wc_immed, wc = set_up_depthy_working_copies(sbox,
680 immediates=True,
681 infinity=True)
683 mu_path = os.path.join(wc, 'A', 'mu')
685 # Commit in the "other" wc.
686 svntest.actions.run_and_verify_svn(None, None, [], 'rm', mu_path)
687 expected_output = svntest.wc.State(wc, { 'A/mu' : Item(verb='Deleting'), })
688 expected_status = svntest.actions.get_virginal_state(wc, 1)
689 expected_status.remove('A/mu')
690 svntest.actions.run_and_verify_commit(wc,
691 expected_output,
692 expected_status,
693 None, wc)
695 # Update the depth-immediates wc, expecting not to receive the deletion
696 # of A/mu.
697 expected_output = svntest.wc.State(wc_immed, { })
698 expected_disk = svntest.wc.State('', {
699 'iota' : Item(contents="This is the file 'iota'.\n"),
700 'A' : Item()
702 expected_status = svntest.wc.State(wc_immed, {
703 '' : Item(status=' ', wc_rev=2),
704 'iota' : Item(status=' ', wc_rev=2),
705 'A' : Item(status=' ', wc_rev=2)
707 svntest.actions.run_and_verify_update(wc_immed,
708 expected_output,
709 expected_disk,
710 expected_status,
711 None, None, None, None, None)
713 #----------------------------------------------------------------------
714 def depth_immediates_receive_delete(sbox):
715 "depth-immediates working copy receives a deletion"
716 # Check out a depth-immediates greek tree to wc1. In wc2, delete A and
717 # commit. Update wc1 should receive the delete.
719 ign_a, ign_b, wc_immed, wc = set_up_depthy_working_copies(sbox,
720 immediates=True,
721 infinity=True)
723 A_path = os.path.join(wc, 'A')
725 # Commit in the "other" wc.
726 svntest.actions.run_and_verify_svn(None, None, [], 'rm', A_path)
727 expected_output = svntest.wc.State(wc, { 'A' : Item(verb='Deleting'), })
728 expected_status = svntest.wc.State(wc, {
729 '' : Item(status=' ', wc_rev=1),
730 'iota' : Item(status=' ', wc_rev=1),
732 svntest.actions.run_and_verify_commit(wc,
733 expected_output,
734 expected_status,
735 None, wc)
737 # Update the depth-immediates wc, expecting to receive the deletion of A.
738 expected_output = svntest.wc.State(wc_immed, {
739 'A' : Item(status='D ')
741 expected_disk = svntest.wc.State('', {
742 'iota' : Item(contents="This is the file 'iota'.\n"),
744 expected_status = svntest.wc.State(wc_immed, {
745 '' : Item(status=' ', wc_rev=2),
746 'iota' : Item(status=' ', wc_rev=2)
748 svntest.actions.run_and_verify_update(wc_immed,
749 expected_output,
750 expected_disk,
751 expected_status,
752 None, None, None, None, None)
754 #----------------------------------------------------------------------
755 def depth_immediates_subdir_propset_1(sbox):
756 "depth-immediates commit subdir propset, update"
757 ign_a, ign_b, wc_immediates, ign_c \
758 = set_up_depthy_working_copies(sbox, immediates=True)
760 A_path = os.path.join(wc_immediates, 'A')
762 # Set a property on an immediate subdirectory of the working copy.
763 svntest.actions.run_and_verify_svn(None, None, [],
764 'pset', 'foo', 'bar',
765 A_path)
767 # Create expected output tree.
768 expected_output = svntest.wc.State(wc_immediates, {
769 'A' : Item(verb='Sending'),
772 # Create expected status tree.
773 expected_status = svntest.wc.State(wc_immediates, {
774 '' : Item(status=' ', wc_rev=1),
775 'iota' : Item(status=' ', wc_rev=1),
776 'A' : Item(status=' ', wc_rev=2)
779 # Commit wc_immediates/A.
780 svntest.actions.run_and_verify_commit(wc_immediates,
781 expected_output,
782 expected_status,
783 None,
784 A_path)
786 # Create expected output tree for the update.
787 expected_output = svntest.wc.State(wc_immediates, { })
789 # Create expected disk tree.
790 expected_disk = svntest.wc.State('', {
791 'iota' : Item(contents="This is the file 'iota'.\n"),
792 'A' : Item(contents=None, props={'foo' : 'bar'}),
795 expected_status.tweak(contents=None, status=' ', wc_rev=2)
797 # Update the depth-immediates wc.
798 svntest.actions.run_and_verify_update(wc_immediates,
799 expected_output,
800 expected_disk,
801 expected_status,
802 None, None, None, None, None, 1)
804 #----------------------------------------------------------------------
805 def depth_immediates_subdir_propset_2(sbox):
806 "depth-immediates update receives subdir propset"
807 sbox.build()
808 wc_dir = sbox.wc_dir
810 # Make the other working copy.
811 other_wc = sbox.add_wc_path('other')
812 svntest.actions.duplicate_dir(wc_dir, other_wc)
814 A_path = os.path.join(wc_dir, 'A')
816 # Set a property on an immediate subdirectory of the working copy.
817 svntest.actions.run_and_verify_svn(None, None, [],
818 'pset', 'foo', 'bar',
819 A_path)
820 # Commit.
821 svntest.actions.run_and_verify_svn(None, None, [],
822 'commit', '-m', 'logmsg', A_path)
824 # Update at depth=immediates in the other wc, expecting to see no errors.
825 svntest.actions.run_and_verify_svn("Output on stderr where none expected",
826 svntest.verify.AnyOutput, [],
827 'update', '--depth', 'immediates',
828 other_wc)
830 #----------------------------------------------------------------------
831 def depth_update_to_more_depth(sbox):
832 "gradually update an empty wc to depth=infinity"
834 wc_dir, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True)
836 os.chdir(wc_dir)
838 # Run 'svn up --set-depth=files' in a depth-empty working copy.
839 expected_output = svntest.wc.State('', {
840 'iota' : Item(status='A '),
842 expected_status = svntest.wc.State('', {
843 '' : Item(status=' ', wc_rev=1),
844 'iota' : Item(status=' ', wc_rev=1),
846 expected_disk = svntest.wc.State('', {
847 'iota' : Item("This is the file 'iota'.\n"),
849 svntest.actions.run_and_verify_update('',
850 expected_output,
851 expected_disk,
852 expected_status,
853 None, None,
854 None, None, None, None,
855 '--set-depth', 'files')
856 verify_depth(None, "files")
858 # Run 'svn up --set-depth=immediates' in the now depth-files working copy.
859 expected_output = svntest.wc.State('', {
860 'A' : Item(status='A '),
862 expected_status = svntest.wc.State('', {
863 '' : Item(status=' ', wc_rev=1),
864 'iota' : Item(status=' ', wc_rev=1),
865 'A' : Item(status=' ', wc_rev=1),
867 expected_disk = svntest.wc.State('', {
868 'iota' : Item("This is the file 'iota'.\n"),
869 'A' : Item(),
871 svntest.actions.run_and_verify_update('',
872 expected_output,
873 expected_disk,
874 expected_status,
875 None, None,
876 None, None, None, None,
877 '--set-depth', 'immediates')
878 verify_depth(None, "immediates")
879 verify_depth(None, "empty", "A")
881 # Upgrade 'A' to depth-files.
882 expected_output = svntest.wc.State('', {
883 'A/mu' : Item(status='A '),
885 expected_status = svntest.wc.State('', {
886 '' : Item(status=' ', wc_rev=1),
887 'iota' : Item(status=' ', wc_rev=1),
888 'A' : Item(status=' ', wc_rev=1),
889 'A/mu' : Item(status=' ', wc_rev=1),
891 expected_disk = svntest.wc.State('', {
892 'iota' : Item("This is the file 'iota'.\n"),
893 'A' : Item(),
894 'A/mu' : Item("This is the file 'mu'.\n"),
896 svntest.actions.run_and_verify_update('',
897 expected_output,
898 expected_disk,
899 expected_status,
900 None, None,
901 None, None, None, None,
902 '--set-depth', 'files', 'A')
903 verify_depth(None, "immediates")
904 verify_depth(None, "files", "A")
906 # Run 'svn up --set-depth=infinity' in the working copy.
907 expected_output = svntest.wc.State('', {
908 'A/B' : Item(status='A '),
909 'A/B/lambda' : Item(status='A '),
910 'A/B/E' : Item(status='A '),
911 'A/B/E/alpha' : Item(status='A '),
912 'A/B/E/beta' : Item(status='A '),
913 'A/B/F' : Item(status='A '),
914 'A/C' : Item(status='A '),
915 'A/D' : Item(status='A '),
916 'A/D/gamma' : Item(status='A '),
917 'A/D/G' : Item(status='A '),
918 'A/D/G/pi' : Item(status='A '),
919 'A/D/G/rho' : Item(status='A '),
920 'A/D/G/tau' : Item(status='A '),
921 'A/D/H' : Item(status='A '),
922 'A/D/H/chi' : Item(status='A '),
923 'A/D/H/psi' : Item(status='A '),
924 'A/D/H/omega' : Item(status='A ')
926 expected_disk = svntest.main.greek_state.copy()
927 expected_status = svntest.actions.get_virginal_state('', 1)
928 svntest.actions.run_and_verify_update('',
929 expected_output,
930 expected_disk,
931 expected_status,
932 None, None,
933 None, None, None, None,
934 '--set-depth', 'infinity')
935 verify_depth("Non-infinity depth detected after an upgrade to depth-infinity",
936 "infinity")
937 verify_depth("Non-infinity depth detected after an upgrade to depth-infinity",
938 "infinity", "A")
940 def commit_propmods_with_depth_empty(sbox):
941 "commit property mods only, using --depth=empty"
942 sbox.build()
943 wc_dir = sbox.wc_dir
945 iota_path = os.path.join(wc_dir, 'iota')
946 A_path = os.path.join(wc_dir, 'A')
947 D_path = os.path.join(A_path, 'D')
948 gamma_path = os.path.join(D_path, 'gamma')
949 G_path = os.path.join(D_path, 'G')
950 pi_path = os.path.join(G_path, 'pi')
951 H_path = os.path.join(D_path, 'H')
952 chi_path = os.path.join(H_path, 'chi')
954 # Set some properties, modify some files.
955 svntest.actions.run_and_verify_svn(None, None, [],
956 'propset', 'foo', 'foo-val', wc_dir)
957 svntest.actions.run_and_verify_svn(None, None, [],
958 'propset', 'bar', 'bar-val', D_path)
959 svntest.actions.run_and_verify_svn(None, None, [],
960 'propset', 'baz', 'baz-val', G_path)
961 svntest.actions.run_and_verify_svn(None, None, [],
962 'propset', 'qux', 'qux-val', H_path)
963 svntest.main.file_append(iota_path, "new iota\n")
964 svntest.main.file_append(gamma_path, "new gamma\n")
965 svntest.main.file_append(pi_path, "new pi\n")
966 svntest.main.file_append(chi_path, "new chi\n")
968 # The only things that should be committed are two of the propsets.
969 expected_output = svntest.wc.State(
970 wc_dir,
971 { '' : Item(verb='Sending'),
972 'A/D' : Item(verb='Sending'), }
974 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
975 # Expect the two propsets to be committed:
976 expected_status.tweak('', status=' ', wc_rev=2)
977 expected_status.tweak('A/D', status=' ', wc_rev=2)
978 # Expect every other change to remain uncommitted:
979 expected_status.tweak('iota', status='M ', wc_rev=1)
980 expected_status.tweak('A/D/G', status=' M', wc_rev=1)
981 expected_status.tweak('A/D/H', status=' M', wc_rev=1)
982 expected_status.tweak('A/D/gamma', status='M ', wc_rev=1)
983 expected_status.tweak('A/D/G/pi', status='M ', wc_rev=1)
984 expected_status.tweak('A/D/H/chi', status='M ', wc_rev=1)
986 svntest.actions.run_and_verify_commit(wc_dir,
987 expected_output,
988 expected_status,
989 None,
990 '--depth=empty',
991 wc_dir, D_path)
993 # Test for issue #2845.
994 def diff_in_depthy_wc(sbox):
995 "diff at various depths in non-infinity wc"
997 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True,
998 infinity=True)
1000 iota_path = os.path.join(wc, 'iota')
1001 A_path = os.path.join(wc, 'A')
1002 mu_path = os.path.join(wc, 'A', 'mu')
1003 gamma_path = os.path.join(wc, 'A', 'D', 'gamma')
1005 # Make some changes in the depth-infinity wc, and commit them
1006 svntest.actions.run_and_verify_svn(None, None, [],
1007 'propset', 'foo', 'foo-val', wc)
1008 svntest.main.file_write(iota_path, "new text\n")
1009 svntest.actions.run_and_verify_svn(None, None, [],
1010 'propset', 'bar', 'bar-val', A_path)
1011 svntest.main.file_write(mu_path, "new text\n")
1012 svntest.main.file_write(gamma_path, "new text\n")
1013 svntest.actions.run_and_verify_svn(None, None, [],
1014 'commit', '-m', '', wc)
1016 diff = [
1017 "\n",
1018 "Property changes on: .\n",
1019 "___________________________________________________________________\n",
1020 "Deleted: foo\n",
1021 " - foo-val\n",
1022 "\n",
1023 "Index: iota\n",
1024 "===================================================================\n",
1025 "--- iota\t(revision 2)\n",
1026 "+++ iota\t(working copy)\n",
1027 "@@ -1 +1 @@\n",
1028 "-new text\n",
1029 "+This is the file 'iota'.\n",
1030 "Property changes on: A\n",
1031 "___________________________________________________________________\n",
1032 "Deleted: bar\n",
1033 " - bar-val\n",
1034 "\n",
1035 "\n",
1036 "Index: A/mu\n",
1037 "===================================================================\n",
1038 "--- A/mu\t(revision 2)\n",
1039 "+++ A/mu\t(working copy)\n",
1040 "@@ -1 +1 @@\n",
1041 "-new text\n",
1042 "+This is the file 'mu'.\n" ]
1044 os.chdir(wc_empty)
1046 expected_output = svntest.verify.UnorderedOutput(diff[:6])
1047 # The diff should contain only the propchange on '.'
1048 svntest.actions.run_and_verify_svn(None, expected_output, [],
1049 'diff', '-rHEAD')
1051 # Upgrade to depth-files.
1052 svntest.actions.run_and_verify_svn(None, None, [], 'up',
1053 '--set-depth', 'files', '-r1')
1054 # The diff should contain only the propchange on '.' and the
1055 # contents change on iota.
1056 expected_output = svntest.verify.UnorderedOutput(diff[:13])
1057 svntest.actions.run_and_verify_svn(None, expected_output, [],
1058 'diff', '-rHEAD')
1059 # Do a diff at --depth empty.
1060 expected_output = svntest.verify.UnorderedOutput(diff[:6])
1061 svntest.actions.run_and_verify_svn(None, expected_output, [],
1062 'diff', '--depth', 'empty', '-rHEAD')
1064 # Upgrade to depth-immediates.
1065 svntest.actions.run_and_verify_svn(None, None, [], 'up',
1066 '--set-depth', 'immediates', '-r1')
1067 # The diff should contain the propchanges on '.' and 'A' and the
1068 # contents change on iota.
1069 expected_output = svntest.verify.UnorderedOutput(diff[:19])
1070 svntest.actions.run_and_verify_svn(None, expected_output, [],
1071 'diff', '-rHEAD')
1072 # Do a diff at --depth files.
1073 expected_output = svntest.verify.UnorderedOutput(diff[:13])
1074 svntest.actions.run_and_verify_svn(None, expected_output, [],
1075 'diff', '--depth', 'files', '-rHEAD')
1077 # Upgrade A to depth-files.
1078 svntest.actions.run_and_verify_svn(None, None, [], 'up',
1079 '--set-depth', 'files', '-r1', 'A')
1080 # The diff should contain everything but the contents change on
1081 # gamma (which does not exist in this working copy).
1082 expected_output = svntest.verify.UnorderedOutput(diff)
1083 svntest.actions.run_and_verify_svn(None, expected_output, [],
1084 'diff', '-rHEAD')
1085 # Do a diff at --depth immediates.
1086 expected_output = svntest.verify.UnorderedOutput(diff[:19])
1087 svntest.actions.run_and_verify_svn(None, expected_output, [],
1088 'diff', '--depth', 'immediates', '-rHEAD')
1090 def commit_depth_immediates(sbox):
1091 "commit some files with --depth=immediates"
1092 sbox.build()
1093 wc_dir = sbox.wc_dir
1095 # Test the fix for some bugs Mike Pilato reported here:
1097 # http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=128509
1098 # From: "C. Michael Pilato" <cmpilato@collab.net>
1099 # To: Karl Fogel <kfogel@red-bean.com>
1100 # CC: dev@subversion.tigris.org
1101 # References: <87d4yzcrro.fsf@red-bean.com>
1102 # Subject: Re: [PATCH] Make 'svn commit --depth=foo' work.
1103 # Message-ID: <46968831.2070906@collab.net>
1104 # Date: Thu, 12 Jul 2007 15:59:45 -0400
1106 # See also http://subversion.tigris.org/issues/show_bug.cgi?id=2882.
1108 # Outline of the test:
1109 # ====================
1111 # Modify these three files:
1113 # M A/mu
1114 # M A/D/G/rho
1115 # M iota
1117 # Then commit some of them using --depth=immediates:
1119 # svn ci -m "log msg" --depth=immediates wc_dir wc_dir/A/D/G/rho
1121 # Before the bugfix, that would result in an error:
1123 # subversion/libsvn_wc/lock.c:570: (apr_err=155004)
1124 # svn: Working copy '/blah/blah/blah/wc' locked
1125 # svn: run 'svn cleanup' to remove locks \
1126 # (type 'svn help cleanup' for details)
1128 # After the bugfix, it correctly commits two of the three files:
1130 # Sending A/D/G/rho
1131 # Sending iota
1132 # Transmitting file data ..
1133 # Committed revision 2.
1135 iota_path = os.path.join(wc_dir, 'iota')
1136 mu_path = os.path.join(wc_dir, 'A', 'mu')
1137 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
1138 rho_path = os.path.join(G_path, 'rho')
1140 svntest.main.file_append(iota_path, "new text in iota\n")
1141 svntest.main.file_append(mu_path, "new text in mu\n")
1142 svntest.main.file_append(rho_path, "new text in rho\n")
1144 expected_output = svntest.wc.State(wc_dir, {
1145 'iota' : Item(verb='Sending'),
1146 'A/D/G/rho' : Item(verb='Sending'),
1148 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1149 expected_status.tweak('iota', status=' ', wc_rev=2)
1150 expected_status.tweak('A/mu', status='M ', wc_rev=1)
1151 expected_status.tweak('A/D/G/rho', status=' ', wc_rev=2)
1152 svntest.actions.run_and_verify_commit(wc_dir,
1153 expected_output,
1154 expected_status,
1155 None,
1156 '--depth', 'immediates',
1157 wc_dir, G_path)
1159 def depth_immediates_receive_new_dir(sbox):
1160 "depth-immediates wc receives new directory"
1162 ign_a, ign_b, wc_immed, wc = set_up_depthy_working_copies(sbox,
1163 immediates=True,
1164 infinity=True)
1166 I_path = os.path.join(wc, 'I')
1167 zeta_path = os.path.join(wc, 'I', 'zeta')
1168 other_I_path = os.path.join(wc_immed, 'I')
1170 os.mkdir(I_path)
1171 svntest.main.file_write(zeta_path, "This is the file 'zeta'.\n")
1173 # Commit in the "other" wc.
1174 svntest.actions.run_and_verify_svn(None, None, [], 'add', I_path)
1175 expected_output = svntest.wc.State(wc, {
1176 'I' : Item(verb='Adding'),
1177 'I/zeta' : Item(verb='Adding'),
1179 expected_status = svntest.actions.get_virginal_state(wc, 1)
1180 expected_status.add({
1181 'I' : Item(status=' ', wc_rev=2),
1182 'I/zeta' : Item(status=' ', wc_rev=2),
1184 svntest.actions.run_and_verify_commit(wc,
1185 expected_output,
1186 expected_status,
1187 None, wc)
1189 # Update the depth-immediates wc, expecting to receive just the
1190 # new directory, without the file.
1191 expected_output = svntest.wc.State(wc_immed, {
1192 'I' : Item(status='A '),
1194 expected_disk = svntest.wc.State('', {
1195 'iota' : Item(contents="This is the file 'iota'.\n"),
1196 'A' : Item(),
1197 'I' : Item(),
1199 expected_status = svntest.wc.State(wc_immed, {
1200 '' : Item(status=' ', wc_rev=2),
1201 'iota' : Item(status=' ', wc_rev=2),
1202 'A' : Item(status=' ', wc_rev=2),
1203 'I' : Item(status=' ', wc_rev=2),
1205 svntest.actions.run_and_verify_update(wc_immed,
1206 expected_output,
1207 expected_disk,
1208 expected_status,
1209 None, None, None, None, None)
1210 # Check that the new directory was added at depth=empty.
1211 verify_depth(None, "empty", other_I_path)
1213 def add_tree_with_depth_files(sbox):
1214 "add multi-subdir tree with --depth=files" # For issue #2931
1215 sbox.build()
1216 wc_dir = sbox.wc_dir
1217 new1_path = os.path.join(wc_dir, 'new1')
1218 new2_path = os.path.join(new1_path, 'new2')
1219 os.mkdir(new1_path)
1220 os.mkdir(new2_path)
1221 svntest.actions.run_and_verify_svn(None, None, [],
1222 "add", "--depth", "files", new1_path)
1224 def upgrade_from_above(sbox):
1225 "upgrade a depth=empty wc from above"
1227 # The bug was that 'svn up --set-depth=files' worked from within the
1228 # working copy, but not from without with working copy top given
1229 # as an argument. Both ways would correctly cause 'iota' to
1230 # appear, but only the former actually upgraded the depth of the
1231 # working copy to 'files'. See this thread for details:
1233 # http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=130157
1234 # From: Alexander Sinyushkin <Alexander.Sinyushkin@svnkit.com>
1235 # To: dev@subversion.tigris.org
1236 # Subject: Problem upgrading working copy depth
1237 # Date: Wed, 19 Sep 2007 23:15:24 +0700
1238 # Message-ID: <46F14B1C.8010406@svnkit.com>
1240 wc, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True)
1242 # First verify that upgrading from within works.
1243 saved_cwd = os.getcwd()
1244 try:
1245 os.chdir(wc)
1246 expected_output = svntest.wc.State('', {
1247 'iota' : Item(status='A '),
1249 expected_disk = svntest.wc.State('', {
1250 'iota' : Item(contents="This is the file 'iota'.\n"),
1252 expected_status = svntest.wc.State('', {
1253 '' : Item(status=' ', wc_rev=1),
1254 'iota' : Item(status=' ', wc_rev=1),
1256 svntest.actions.run_and_verify_update('',
1257 expected_output,
1258 expected_disk,
1259 expected_status,
1260 None, None, None, None, None, None,
1261 '--set-depth=files')
1262 verify_depth(None, "files")
1263 finally:
1264 os.chdir(saved_cwd)
1266 # Reset and do it again, this time from above the working copy.
1267 svntest.main.safe_rmtree(wc)
1268 wc, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True)
1269 expected_output = svntest.wc.State(wc, {
1270 'iota' : Item(status='A '),
1272 expected_disk = svntest.wc.State('', {
1273 'iota' : Item(contents="This is the file 'iota'.\n"),
1275 expected_status = svntest.wc.State(wc, {
1276 '' : Item(status=' ', wc_rev=1),
1277 'iota' : Item(status=' ', wc_rev=1),
1279 svntest.actions.run_and_verify_update(wc,
1280 expected_output,
1281 expected_disk,
1282 expected_status,
1283 None, None, None, None, None, None,
1284 '--set-depth=files', wc)
1285 verify_depth(None, "files", wc)
1287 def status_in_depthy_wc(sbox):
1288 "status -u at various depths in non-infinity wc"
1290 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True,
1291 infinity=True)
1293 iota_path = os.path.join(wc, 'iota')
1294 A_path = os.path.join(wc, 'A')
1295 mu_path = os.path.join(wc, 'A', 'mu')
1296 gamma_path = os.path.join(wc, 'A', 'D', 'gamma')
1298 # Make some changes in the depth-infinity wc, and commit them
1299 svntest.actions.run_and_verify_svn(None, None, [],
1300 'propset', 'foo', 'foo-val', wc)
1301 svntest.main.file_write(iota_path, "new text\n")
1302 svntest.actions.run_and_verify_svn(None, None, [],
1303 'propset', 'bar', 'bar-val', A_path)
1304 svntest.main.file_write(mu_path, "new text\n")
1305 svntest.main.file_write(gamma_path, "new text\n")
1306 svntest.actions.run_and_verify_svn(None, None, [],
1307 'commit', '-m', '', wc)
1309 status = [
1310 "Status against revision: 2\n",
1311 " * 1 .\n",
1312 " * 1 iota\n",
1313 " * 1 A\n",
1314 " * 1 " + os.path.join('A', 'mu') + "\n",
1317 os.chdir(wc_empty)
1319 expected_output = svntest.verify.UnorderedOutput(status[:2])
1320 # The output should contain only the change on '.'.
1321 svntest.actions.run_and_verify_svn(None, expected_output, [],
1322 'st', '-u')
1324 # Upgrade to depth-files.
1325 svntest.actions.run_and_verify_svn(None, None, [], 'up',
1326 '--set-depth', 'files', '-r1')
1327 # The output should contain only the changes on '.' and 'iota'.
1328 expected_output = svntest.verify.UnorderedOutput(status[:3])
1329 svntest.actions.run_and_verify_svn(None, expected_output, [],
1330 'st', '-u')
1331 # Do a status -u at --depth empty.
1332 expected_output = svntest.verify.UnorderedOutput(status[:2])
1333 svntest.actions.run_and_verify_svn(None, expected_output, [],
1334 'st', '-u', '--depth', 'empty')
1336 # Upgrade to depth-immediates.
1337 svntest.actions.run_and_verify_svn(None, None, [], 'up',
1338 '--set-depth', 'immediates', '-r1')
1339 # The output should contain the changes on '.', 'A' and 'iota'.
1340 expected_output = svntest.verify.UnorderedOutput(status[:4])
1341 svntest.actions.run_and_verify_svn(None, expected_output, [],
1342 'st', '-u')
1343 # Do a status -u at --depth files.
1344 expected_output = svntest.verify.UnorderedOutput(status[:3])
1345 svntest.actions.run_and_verify_svn(None, expected_output, [],
1346 'st', '-u', '--depth', 'files')
1348 # Upgrade A to depth-files.
1349 svntest.actions.run_and_verify_svn(None, None, [], 'up',
1350 '--set-depth', 'files', '-r1', 'A')
1351 # The output should contain everything but the change on
1352 # gamma (which does not exist in this working copy).
1353 expected_output = svntest.verify.UnorderedOutput(status)
1354 svntest.actions.run_and_verify_svn(None, expected_output, [],
1355 'st', '-u')
1356 # Do a status -u at --depth immediates.
1357 expected_output = svntest.verify.UnorderedOutput(status[:4])
1358 svntest.actions.run_and_verify_svn(None, expected_output, [],
1359 'st', '-u', '--depth', 'immediates')
1361 #----------------------------------------------------------------------
1363 # Issue #3039.
1364 def depthy_update_above_dir_to_be_deleted(sbox):
1365 "'update -N' above a WC path deleted in repos HEAD"
1366 sbox.build()
1368 sbox_for_depth = {
1369 "files" : sbox,
1370 "immediates" : sbox.clone_dependent(copy_wc=True),
1371 "empty" : sbox.clone_dependent(copy_wc=True),
1374 exit_code, output, err = svntest.actions.run_and_verify_svn(
1375 None, None, [],
1376 "delete", "-m", "Delete A.", sbox.repo_url + "/A")
1378 def empty_output(wc_dir):
1379 return svntest.wc.State(wc_dir, { })
1381 def output_with_A(wc_dir):
1382 expected_output = empty_output(wc_dir)
1383 expected_output.add({
1384 "A" : Item(status="D "),
1386 return expected_output
1388 initial_disk = svntest.main.greek_state.copy()
1389 disk_with_only_iota = svntest.wc.State("", {
1390 "iota" : Item("This is the file 'iota'.\n"),
1393 def status_with_dot(wc_dir):
1394 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1395 expected_status.tweak("", wc_rev=2)
1396 return expected_status
1398 def status_with_iota(wc_dir):
1399 expected_status = status_with_dot(wc_dir)
1400 expected_status.tweak("iota", wc_rev=2)
1401 return expected_status
1403 def status_with_only_iota(wc_dir):
1404 return svntest.wc.State(wc_dir, {
1405 "" : Item(status=" ", wc_rev=2),
1406 "iota" : Item(status=" ", wc_rev=2),
1409 expected_trees_for_depth = {
1410 "files" : (empty_output, initial_disk, status_with_iota),
1411 "immediates" : (output_with_A, disk_with_only_iota, status_with_only_iota),
1412 "empty" : (empty_output, initial_disk, status_with_dot),
1415 for depth in sbox_for_depth.keys():
1416 wc_dir = sbox_for_depth[depth].wc_dir
1417 (expected_output_func, expected_disk, expected_status_func) = \
1418 expected_trees_for_depth[depth]
1419 #print depth
1420 svntest.actions.run_and_verify_update(wc_dir,
1421 expected_output_func(wc_dir),
1422 expected_disk,
1423 expected_status_func(wc_dir),
1424 None, None, None, None, None,
1425 False,
1426 "--depth=%s" % depth, wc_dir)
1429 #----------------------------------------------------------------------
1431 # Tests for deselection interface (a.k.a folding subtrees).
1432 # XFail until issue #2843 is resolved.
1433 #----------------------------------------------------------------------
1434 def depth_folding_clean_trees_1(sbox):
1435 "gradually fold wc from depth=infinity to empty"
1437 # Covers the following situations:
1439 # infinity->immediates (metadata only)
1440 # immediates->files (metadata only)
1441 # mixed(infinity+files)=>immediates
1442 # infinity=>empty
1443 # immediates=>empty
1444 # mixed(infinity+empty)=>immediates
1445 # mixed(infinity+empty/immediates)=>immediates
1446 # immediates=>files
1447 # files=>empty
1448 # mixed(infinity+empty)=>files
1450 ign_a, ign_b, ign_c, wc_dir = set_up_depthy_working_copies(sbox,
1451 infinity=True)
1453 A_path = os.path.join(wc_dir, 'A')
1454 C_path = os.path.join(A_path, 'C')
1455 B_path = os.path.join(A_path, 'B')
1456 E_path = os.path.join(B_path, 'E')
1457 F_path = os.path.join(B_path, 'F')
1458 D_path = os.path.join(A_path, 'D')
1459 H_path = os.path.join(A_path, 'H')
1461 # Run 'svn up --set-depth=immediates' to directory A/B/E.
1462 # This is an infinity=>immediates folding, changes on metadata only
1463 expected_output = svntest.wc.State(wc_dir, {})
1464 expected_status = svntest.actions.get_virginal_state('', 1)
1465 expected_disk = svntest.main.greek_state.copy()
1466 svntest.actions.run_and_verify_update(wc_dir,
1467 expected_output,
1468 expected_disk,
1469 expected_status,
1470 None, None,
1471 None, None, None, None,
1472 '--set-depth', 'immediates', E_path)
1473 verify_depth(None, "immediates", E_path)
1475 # Run 'svn up --set-depth=files' to directory A/B/E.
1476 # This is an immediates=>files folding, changes on metadata only
1477 svntest.actions.run_and_verify_update(wc_dir,
1478 expected_output,
1479 expected_disk,
1480 expected_status,
1481 None, None,
1482 None, None, None, None,
1483 '--set-depth', 'files', E_path)
1484 verify_depth(None, "files", E_path)
1486 # Run 'svn up --set-depth=immediates' to directory A/B.
1487 # This is an mixed(infinity+files)=>immediates folding
1488 expected_output = svntest.wc.State(wc_dir, {
1489 'A/B/E/alpha' : Item(status='D '),
1490 'A/B/E/beta' : Item(status='D '),
1492 expected_status.remove('A/B/E/alpha', 'A/B/E/beta')
1493 expected_disk.remove('A/B/E/alpha', 'A/B/E/beta')
1494 svntest.actions.run_and_verify_update(wc_dir,
1495 expected_output,
1496 expected_disk,
1497 expected_status,
1498 None, None,
1499 None, None, None, None,
1500 '--set-depth', 'immediates', B_path)
1501 verify_depth(None, "immediates", B_path)
1502 verify_depth(None, "empty", E_path)
1503 verify_depth(None, "empty", F_path)
1505 # Run 'svn up --set-depth=empty' to directory A/D/H
1506 # This is an infinity=>empty folding.
1507 expected_output = svntest.wc.State(wc_dir, {
1508 'A/D/H/chi' : Item(status='D '),
1509 'A/D/H/psi' : Item(status='D '),
1510 'A/D/H/omega' : Item(status='D ')
1512 expected_status.remove( 'A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega')
1513 expected_disk.remove( 'A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega')
1514 svntest.actions.run_and_verify_update(wc_dir,
1515 expected_output,
1516 expected_disk,
1517 expected_status,
1518 None, None,
1519 None, None, None, None,
1520 '--set-depth', 'empty', H_path)
1521 verify_depth(None, "empty", H_path)
1523 # Run 'svn up --set-depth=immediates' to directory A/D
1524 # This is an mixed(infinity+empty)=>immediates folding.
1525 expected_output = svntest.wc.State(wc_dir, {
1526 'A/D/G/pi' : Item(status='D '),
1527 'A/D/G/rho' : Item(status='D '),
1528 'A/D/G/tau' : Item(status='D '),
1530 expected_status.remove('A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau')
1531 expected_disk.remove('A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau')
1532 svntest.actions.run_and_verify_update(wc_dir,
1533 expected_output,
1534 expected_disk,
1535 expected_status,
1536 None, None,
1537 None, None, None, None,
1538 '--set-depth', 'immediates', D_path)
1539 verify_depth(None, "immediates", D_path)
1540 verify_depth(None, "empty", G_path)
1542 # Run 'svn up --set-depth=empty' to directory A/D
1543 # This is an immediates=>empty folding.
1544 expected_output = svntest.wc.State(wc_dir, {
1545 'A/D/G' : Item(status='D '),
1546 'A/D/H' : Item(status='D '),
1547 'A/D/gamma' : Item(status='D ')
1549 expected_status.remove('A/D/gamma', 'A/D/G', 'A/D/H')
1550 expected_disk.remove('A/D/gamma', 'A/D/G', 'A/D/H')
1551 svntest.actions.run_and_verify_update(wc_dir,
1552 expected_output,
1553 expected_disk,
1554 expected_status,
1555 None, None,
1556 None, None, None, None,
1557 '--set-depth', 'empty', D_path)
1558 verify_depth(None, "empty", D_path)
1560 # Run 'svn up --set-depth=immediates' to directory A
1561 # This is an mixed(infinity+empty/immediates)=>immediates folding.
1562 expected_output = svntest.wc.State(wc_dir, {
1563 'A/B/E' : Item(status='D '),
1564 'A/B/F' : Item(status='D '),
1565 'A/B/lambda' : Item(status='D ')
1567 expected_status.remove('A/B/lambda', 'A/B/E', 'A/B/F')
1568 expected_disk.remove('A/B/lambda', 'A/B/E', 'A/B/F')
1569 svntest.actions.run_and_verify_update(wc_dir,
1570 expected_output,
1571 expected_disk,
1572 expected_status,
1573 None, None,
1574 None, None, None, None,
1575 '--set-depth', 'immediates', A_path)
1576 verify_depth(None, "immediates", A_path)
1577 verify_depth(None, "empty", C_path)
1578 verify_depth(None, "empty", B_path)
1580 # Run 'svn up --set-depth=files' to directory A
1581 # This is an immediates=>files folding.
1582 expected_output = svntest.wc.State(wc_dir, {
1583 'A/B' : Item(status='D '),
1584 'A/C' : Item(status='D '),
1585 'A/D' : Item(status='D ')
1587 expected_status.remove('A/B', 'A/C', 'A/D')
1588 expected_disk.remove('A/B', 'A/C', 'A/D')
1589 svntest.actions.run_and_verify_update(wc_dir,
1590 expected_output,
1591 expected_disk,
1592 expected_status,
1593 None, None,
1594 None, None, None, None,
1595 '--set-depth', 'files', A_path)
1596 verify_depth(None, "files", A_path)
1598 # Run 'svn up --set-depth=empty' to directory A
1599 # This is an files=>empty folding.
1600 expected_output = svntest.wc.State(wc_dir, {
1601 'A/mu' : Item(status='D ')
1603 expected_status.remove('A/mu')
1604 expected_disk.remove('A/mu')
1605 svntest.actions.run_and_verify_update(wc_dir,
1606 expected_output,
1607 expected_disk,
1608 expected_status,
1609 None, None,
1610 None, None, None, None,
1611 '--set-depth', 'empty', A_path)
1612 verify_depth(None, "empty", A_path)
1614 # Run 'svn up --set-depth=files' to wc
1615 # This is an mixed(infinity+empty)=>files folding.
1616 expected_output = svntest.wc.State(wc_dir, {
1617 'A' : Item(status='D ')
1619 expected_status.remove('A')
1620 expected_disk.remove('A')
1621 svntest.actions.run_and_verify_update(wc_dir,
1622 expected_output,
1623 expected_disk,
1624 expected_status,
1625 None, None,
1626 None, None, None, None,
1627 '--set-depth', 'files')
1628 verify_depth(None, "files")
1631 #------------------------------------------------------------------------------
1632 def depth_folding_clean_trees_2(sbox):
1633 "gradually fold wc, focusing on depth=immediates"
1635 # Covers the following situations:
1637 # infinity=>immediates
1638 # mixed(immediates+immediates)=>immediates
1639 # mixed(immediates+infinity)=>immediates
1640 # mixed(immediates+files)=>immediates
1641 # immediates=>empty(remove the target since the parent is at files/empty)
1643 ign_a, wc_dir, ign_b, ign_c = set_up_depthy_working_copies(sbox, files=True)
1645 A_path = os.path.join(wc_dir, 'A')
1646 D_path = os.path.join(A_path, 'D')
1647 H_path = os.path.join(D_path, 'H')
1648 G_path = os.path.join(D_path, 'G')
1650 # pull in directory A at immediates
1651 svntest.actions.run_and_verify_svn(None, None, [],
1652 'up', '--depth', 'immediates', A_path)
1653 # check to see if it's really at immediates
1654 verify_depth(None, "immediates", A_path)
1656 # pull in directory D at infinity
1657 svntest.actions.run_and_verify_svn(None, None, [], 'up', D_path)
1659 # Run 'svn up --set-depth=immediates' to directory A/D.
1660 # This is an infinity=>immediates folding
1661 expected_output = svntest.wc.State(wc_dir, {
1662 'A/D/G/pi' : Item(status='D '),
1663 'A/D/G/rho' : Item(status='D '),
1664 'A/D/G/tau' : Item(status='D '),
1665 'A/D/H/chi' : Item(status='D '),
1666 'A/D/H/psi' : Item(status='D '),
1667 'A/D/H/omega' : Item(status='D ')
1669 expected_status = svntest.wc.State(wc_dir, {
1670 '' : Item(status=' ', wc_rev=1),
1671 'iota' : Item(status=' ', wc_rev=1),
1672 'A' : Item(status=' ', wc_rev=1),
1673 'A/mu' : Item(status=' ', wc_rev=1),
1674 'A/B' : Item(status=' ', wc_rev=1),
1675 'A/C' : Item(status=' ', wc_rev=1),
1676 'A/D' : Item(status=' ', wc_rev=1),
1677 'A/D/gamma' : Item(status=' ', wc_rev=1),
1678 'A/D/G' : Item(status=' ', wc_rev=1),
1679 'A/D/H' : Item(status=' ', wc_rev=1)
1681 expected_disk = svntest.wc.State(wc_dir, {
1682 'iota' : Item(contents="This is the file 'iota'.\n"),
1683 'A' : Item(contents=None),
1684 'A/mu' : Item(contents="This is the file 'mu'.\n"),
1685 'A/B' : Item(contents=None),
1686 'A/C' : Item(contents=None),
1687 'A/D' : Item(contents=None),
1688 'A/D/gamma' : Item(contents="This is the file 'gamma'.\n"),
1689 'A/D/G' : Item(contents=None),
1690 'A/D/H' : Item(contents=None)
1692 svntest.actions.run_and_verify_update(wc_dir,
1693 expected_output,
1694 expected_disk,
1695 expected_status,
1696 None, None,
1697 None, None, None, None,
1698 '--set-depth', 'immediates', D_path)
1699 verify_depth(None, "immediates", D_path)
1700 verify_depth(None, "empty", G_path)
1701 verify_depth(None, "empty", H_path)
1703 # Run 'svn up --set-depth=immediates' to directory A.
1704 # This is an mixed(immediates+immediates)=>immediates folding
1705 expected_output = svntest.wc.State(wc_dir, {
1706 'A/D/G' : Item(status='D '),
1707 'A/D/H' : Item(status='D '),
1708 'A/D/gamma' : Item(status='D ')
1710 expected_status.remove( 'A/D/G', 'A/D/H', 'A/D/gamma')
1711 expected_disk.remove( 'A/D/G', 'A/D/H', 'A/D/gamma')
1712 svntest.actions.run_and_verify_update(wc_dir,
1713 expected_output,
1714 expected_disk,
1715 expected_status,
1716 None, None,
1717 None, None, None, None,
1718 '--set-depth', 'immediates', A_path)
1719 verify_depth(None, "immediates", A_path)
1720 verify_depth(None, "empty", D_path)
1722 # pull in directory D at infinity
1723 svntest.actions.run_and_verify_svn(None, None, [],
1724 'up', D_path)
1726 # Run 'svn up --set-depth=immediates' to directory A.
1727 # This is an mixed(immediates+infinity)=>immediates folding
1728 expected_output = svntest.wc.State(wc_dir, {
1729 'A/D/gamma' : Item(status='D '),
1730 'A/D/G' : Item(status='D '),
1731 'A/D/G/pi' : Item(status='D '),
1732 'A/D/G/rho' : Item(status='D '),
1733 'A/D/G/tau' : Item(status='D '),
1734 'A/D/H' : Item(status='D '),
1735 'A/D/H/chi' : Item(status='D '),
1736 'A/D/H/psi' : Item(status='D '),
1737 'A/D/H/omega' : Item(status='D ')
1739 svntest.actions.run_and_verify_update(wc_dir,
1740 expected_output,
1741 expected_disk,
1742 expected_status,
1743 None, None,
1744 None, None, None, None,
1745 '--set-depth', 'immediates', A_path)
1746 verify_depth(None, "immediates", A_path)
1747 verify_depth(None, "empty", D_path)
1749 # pull in directory D at files
1750 svntest.actions.run_and_verify_svn(None, None, [],
1751 'up', '--depth', 'files', D_path)
1753 # Run 'svn up --set-depth=immediates' to directory A.
1754 # This is an mixed(immediates+files)=>immediates folding
1755 expected_output = svntest.wc.State(wc_dir, {
1756 'A/D/gamma' : Item(status='D ')
1758 svntest.actions.run_and_verify_update(wc_dir,
1759 expected_output,
1760 expected_disk,
1761 expected_status,
1762 None, None,
1763 None, None, None, None,
1764 '--set-depth', 'immediates', A_path)
1765 verify_depth(None, "immediates", A_path)
1766 verify_depth(None, "empty", D_path)
1768 # Run 'svn up --set-depth=empty' to directory A.
1769 # This is an immediates=>empty folding, the directory A should be deleted
1770 # too since the parent directory is at files/empty
1771 expected_output = svntest.wc.State(wc_dir, {
1772 'A' : Item(status='D '),
1773 'A/mu' : Item(status='D '),
1774 'A/D' : Item(status='D '),
1775 'A/C' : Item(status='D '),
1776 'A/B' : Item(status='D ')
1778 expected_status = svntest.wc.State(wc_dir, {
1779 '' : Item(status=' ', wc_rev=1),
1780 'iota' : Item(status=' ', wc_rev=1)
1782 expected_disk = svntest.wc.State(wc_dir, {
1783 'iota' : Item(contents="This is the file 'iota'.\n")
1785 svntest.actions.run_and_verify_update(wc_dir,
1786 expected_output,
1787 expected_disk,
1788 expected_status,
1789 None, None,
1790 None, None, None, None,
1791 '--set-depth', 'empty', A_path)
1793 def depth_fold_expand_clean_trees(sbox):
1794 "expand target while contracting subtree"
1795 # --set-depth=immediates/files to an empty target with infinity
1796 # sub-tree should both fold the subtree and expand the target
1798 wc_dir, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True)
1800 A_path = os.path.join(wc_dir, 'A')
1801 B_path = os.path.join(A_path, 'B')
1802 C_path = os.path.join(A_path, 'C')
1803 D_path = os.path.join(A_path, 'D')
1805 # pull in directory A at empty
1806 svntest.actions.run_and_verify_svn(None, None, [],
1807 'up', '--depth', 'empty', A_path)
1808 verify_depth(None, "empty", A_path)
1810 # pull in directory D at infinity
1811 svntest.actions.run_and_verify_svn(None, None, [],
1812 'up', D_path)
1814 # Make the other working copy.
1815 other_wc = sbox.add_wc_path('other')
1816 svntest.actions.duplicate_dir(wc_dir, other_wc)
1818 # Run 'svn up --set-depth=immediates' to directory A. This both folds
1819 # directory D to empty and expands directory A to immediates
1820 expected_output = svntest.wc.State(wc_dir, {
1821 'A/mu' : Item(status='A '),
1822 'A/B' : Item(status='A '),
1823 'A/C' : Item(status='A '),
1824 'A/D/gamma' : Item(status='D '),
1825 'A/D/G' : Item(status='D '),
1826 'A/D/G/pi' : Item(status='D '),
1827 'A/D/G/rho' : Item(status='D '),
1828 'A/D/G/tau' : Item(status='D '),
1829 'A/D/H' : Item(status='D '),
1830 'A/D/H/chi' : Item(status='D '),
1831 'A/D/H/psi' : Item(status='D '),
1832 'A/D/H/omega' : Item(status='D ')
1834 expected_status = svntest.wc.State(wc_dir, {
1835 '' : Item(status=' ', wc_rev=1),
1836 'A' : Item(status=' ', wc_rev=1),
1837 'A/mu' : Item(status=' ', wc_rev=1),
1838 'A/B' : Item(status=' ', wc_rev=1),
1839 'A/C' : Item(status=' ', wc_rev=1),
1840 'A/D' : Item(status=' ', wc_rev=1)
1842 expected_disk = svntest.wc.State(wc_dir, {
1843 'A' : Item(contents=None),
1844 'A/mu' : Item(contents="This is the file 'mu'.\n"),
1845 'A/B' : Item(contents=None),
1846 'A/C' : Item(contents=None),
1847 'A/D' : Item(contents=None)
1849 svntest.actions.run_and_verify_update(wc_dir,
1850 expected_output,
1851 expected_disk,
1852 expected_status,
1853 None, None,
1854 None, None, None, None,
1855 '--set-depth', 'immediates', A_path)
1856 verify_depth(None, "immediates", A_path)
1857 verify_depth(None, "empty", B_path)
1858 verify_depth(None, "empty", C_path)
1859 verify_depth(None, "empty", D_path)
1861 # Run 'svn up --set-depth=files' to directory A in other_wc. This both
1862 # removes directory D and expands directory A to files
1863 expected_output = svntest.wc.State(wc_dir, {
1864 'A/mu' : Item(status='A '),
1865 'A/D' : Item(status='D '),
1866 'A/D/gamma' : Item(status='D '),
1867 'A/D/G' : Item(status='D '),
1868 'A/D/G/pi' : Item(status='D '),
1869 'A/D/G/rho' : Item(status='D '),
1870 'A/D/G/tau' : Item(status='D '),
1871 'A/D/H' : Item(status='D '),
1872 'A/D/H/chi' : Item(status='D '),
1873 'A/D/H/psi' : Item(status='D '),
1874 'A/D/H/omega' : Item(status='D ')
1876 expected_status = svntest.wc.State(wc_dir, {
1877 '' : Item(status=' ', wc_rev=1),
1878 'A' : Item(status=' ', wc_rev=1),
1879 'A/mu' : Item(status=' ', wc_rev=1),
1881 expected_disk = svntest.wc.State(wc_dir, {
1882 'A' : Item(contents=None),
1883 'A/mu' : Item(contents="This is the file 'mu'.\n")
1885 Other_A_path = os.path.join(other_wc, 'A')
1886 svntest.actions.run_and_verify_update(other_wc,
1887 expected_output,
1888 expected_disk,
1889 expected_status,
1890 None, None,
1891 None, None, None, None,
1892 '--set-depth', 'files', Other_A_path)
1893 verify_depth(None, "files", Other_A_path)
1896 def pull_in_tree_with_depth_option(sbox):
1897 """checkout and verify subtree with depth immediates"""
1899 wc_empty,ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox,
1900 empty=True)
1901 A_path = os.path.join(wc_empty, 'A')
1902 expected_output = svntest.wc.State(wc_empty, {
1903 'A' : Item(status='A '),
1904 'A/mu' : Item(status='A '),
1905 'A/B' : Item(status='A '),
1906 'A/C' : Item(status='A '),
1907 'A/D' : Item(status='A ')
1909 expected_disk = svntest.wc.State('', {
1910 'A' : Item(),
1911 'A/mu' : Item("This is the file 'mu'.\n"),
1912 'A/B' : Item(),
1913 'A/C' : Item(),
1914 'A/D' : Item(),
1916 expected_status = svntest.wc.State(wc_empty, {
1917 '' : Item(status=' ', wc_rev=1),
1918 'A' : Item(status=' ', wc_rev=1),
1919 'A/mu' : Item(status=' ', wc_rev=1),
1920 'A/B' : Item(status=' ', wc_rev=1),
1921 'A/C' : Item(status=' ', wc_rev=1),
1922 'A/D' : Item(status=' ', wc_rev=1),
1924 svntest.actions.run_and_verify_update(wc_empty,
1925 expected_output,
1926 expected_disk,
1927 expected_status,
1928 None, None, None, None, None, False,
1929 "--depth=immediates", A_path)
1931 # Check that the A directory was pull ed in at depth=immediates.
1932 verify_depth(None, "immediates", A_path)
1934 def fold_tree_with_unversioned_modified_items(sbox):
1935 "unversioned & modified items left untouched"
1936 ign_a, ign_b, ign_c, wc_dir = set_up_depthy_working_copies(sbox,
1937 infinity=True)
1939 A_path = os.path.join(wc_dir, 'A')
1940 pi_path = os.path.join(A_path, 'D', 'G', 'pi')
1941 mu_path = os.path.join(A_path, 'mu')
1942 unv_path = os.path.join(A_path, 'B', 'unv')
1944 # Modify file pi
1945 svntest.main.file_write(pi_path, "pi modified\n")
1946 # Modify file mu
1947 svntest.main.file_write(mu_path, "mu modified\n")
1948 # Create an unversioned file
1949 svntest.main.file_write(unv_path, "new unversioned\n")
1951 # Fold the A dir to empty, expect the modified & unversioned ones left
1952 # unversioned rather than removed, along with paths to those items.
1953 expected_output = svntest.wc.State(wc_dir, {
1954 'A/B/lambda' : Item(status='D '),
1955 'A/B/E' : Item(status='D '),
1956 'A/B/E/alpha' : Item(status='D '),
1957 'A/B/E/beta' : Item(status='D '),
1958 'A/B/F' : Item(status='D '),
1959 'A/C' : Item(status='D '),
1960 'A/D/gamma' : Item(status='D '),
1961 'A/D/G/rho' : Item(status='D '),
1962 'A/D/G/tau' : Item(status='D '),
1963 'A/D/H' : Item(status='D '),
1964 'A/D/H/chi' : Item(status='D '),
1965 'A/D/H/psi' : Item(status='D '),
1966 'A/D/H/omega' : Item(status='D ')
1968 # unversioned items will be ignored in in the status tree, since the
1969 # run_and_verify_update() function uses a quiet version of svn status
1970 # Dir A is still versioned, since the wc root is in depth-infinity
1971 expected_status = svntest.wc.State(wc_dir, {
1972 '' : Item(status=' ', wc_rev=1),
1973 'iota' : Item(status=' ', wc_rev=1),
1974 'A' : Item(status=' ', wc_rev=1)
1976 expected_disk = svntest.wc.State(wc_dir, {
1977 'iota' : Item(contents="this is iota\n"),
1978 'A' : Item(contents=None),
1979 'A/mu' : Item(contents="mu modified\n"),
1980 'A/B' : Item(contents=None),
1981 'A/B/unv' : Item(contents="new unversioned\n"),
1982 'A/D' : Item(contents=None),
1983 'A/D/G' : Item(contents=None),
1984 'A/D/G/pi' : Item(contents="pi modified\n")
1986 svntest.actions.run_and_verify_update(wc_dir,
1987 expected_output,
1988 expected_disk,
1989 expected_status,
1990 None, None,
1991 None, None, None, None,
1992 '--set-depth', 'empty', A_path)
1993 verify_depth(None, "empty", A_path)
1995 #----------------------------------------------------------------------
1996 # list all tests here, starting with None:
1997 test_list = [ None,
1998 depth_empty_checkout,
1999 depth_files_checkout,
2000 nonrecursive_checkout,
2001 depth_empty_update_bypass_single_file,
2002 depth_immediates_get_top_file_mod_only,
2003 depth_empty_commit,
2004 depth_empty_with_file,
2005 depth_empty_with_dir,
2006 depth_immediates_bring_in_file,
2007 depth_immediates_fill_in_dir,
2008 depth_mixed_bring_in_dir,
2009 depth_empty_unreceive_delete,
2010 depth_immediates_unreceive_delete,
2011 depth_immediates_receive_delete,
2012 depth_update_to_more_depth,
2013 depth_immediates_subdir_propset_1,
2014 depth_immediates_subdir_propset_2,
2015 commit_propmods_with_depth_empty,
2016 diff_in_depthy_wc,
2017 commit_depth_immediates,
2018 depth_immediates_receive_new_dir,
2019 add_tree_with_depth_files,
2020 upgrade_from_above,
2021 status_in_depthy_wc,
2022 depthy_update_above_dir_to_be_deleted,
2023 XFail(depth_folding_clean_trees_1),
2024 XFail(depth_folding_clean_trees_2),
2025 XFail(depth_fold_expand_clean_trees),
2026 pull_in_tree_with_depth_option,
2027 XFail(fold_tree_with_unversioned_modified_items),
2030 if __name__ == "__main__":
2031 svntest.main.run_tests(test_list)
2032 # NOTREACHED
2035 ### End of file.