Add a little more to the svn_rangelist_intersect test to test the
[svn.git] / subversion / tests / cmdline / depth_tests.py
blob9af7efe2c6ab9ae24a922dbe462fdd3cbf6562d8
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 out, err = svntest.actions.run_and_verify_svn(None, None, [], "info", path)
93 for line in out:
94 if line.startswith("Depth:"):
95 raise svntest.failure(msg)
96 else:
97 svntest.actions.run_and_verify_svn_match_any(
98 msg, "^Depth: %s\n$" % depth, [], "info", path)
100 #----------------------------------------------------------------------
101 # Ensure that 'checkout --depth=empty' results in a depth-empty working copy.
102 def depth_empty_checkout(sbox):
103 "depth-empty checkout"
105 wc_empty, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True)
107 if os.path.exists(os.path.join(wc_empty, "iota")):
108 raise svntest.Failure("depth-empty checkout created file 'iota'")
110 if os.path.exists(os.path.join(wc_empty, "A")):
111 raise svntest.Failure("depth-empty checkout created subdir 'A'")
113 verify_depth("Expected depth empty for top of WC, got some other depth",
114 "empty", wc_empty)
117 # Helper for two test functions.
118 def depth_files_same_as_nonrecursive(sbox, opt):
119 """Run a depth-files or non-recursive checkout, depending on whether
120 passed '-N' or '--depth=files' for OPT. The two should get the same
121 result, hence this helper containing the common code between the
122 two tests."""
124 # This duplicates some code from set_up_depthy_working_copies(), but
125 # that's because it's abstracting out a different axis.
127 sbox.build(create_wc = False, read_only = True)
128 if os.path.exists(sbox.wc_dir):
129 svntest.main.safe_rmtree(sbox.wc_dir)
131 svntest.actions.run_and_verify_svn("Unexpected error during co %s" % opt,
132 svntest.verify.AnyOutput, [],
133 "co", opt, sbox.repo_url, sbox.wc_dir)
135 # Should create a depth-files top directory, so both iota and A
136 # should exist, and A should be empty and depth-empty.
138 if not os.path.exists(os.path.join(sbox.wc_dir, "iota")):
139 raise svntest.Failure("'checkout %s' failed to create file 'iota'" % opt)
141 if os.path.exists(os.path.join(sbox.wc_dir, "A")):
142 raise svntest.Failure("'checkout %s' unexpectedly created subdir 'A'" % opt)
144 verify_depth("Expected depth files for top of WC, got some other depth",
145 "files", sbox.wc_dir)
148 def depth_files_checkout(sbox):
149 "depth-files checkout"
150 depth_files_same_as_nonrecursive(sbox, "--depth=files")
153 def nonrecursive_checkout(sbox):
154 "non-recursive checkout equals depth-files"
155 depth_files_same_as_nonrecursive(sbox, "-N")
158 #----------------------------------------------------------------------
159 def depth_empty_update_bypass_single_file(sbox):
160 "update depth-empty wc shouldn't receive file mod"
162 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True,
163 infinity=True)
165 iota_path = os.path.join(wc, 'iota')
166 svntest.main.file_append(iota_path, "new text\n")
168 # Commit in the "other" wc.
169 expected_output = svntest.wc.State(wc, { 'iota' : Item(verb='Sending'), })
170 expected_status = svntest.actions.get_virginal_state(wc, 1)
171 expected_status.tweak('iota', wc_rev=2, status=' ')
172 svntest.actions.run_and_verify_commit(wc,
173 expected_output,
174 expected_status,
175 None, wc)
177 # Update the depth-empty wc, expecting not to receive the change to iota.
178 expected_output = svntest.wc.State(wc_empty, { })
179 expected_disk = svntest.wc.State('', { })
180 expected_status = svntest.wc.State(wc_empty, { '' : svntest.wc.StateItem() })
181 expected_status.tweak(contents=None, status=' ', wc_rev=2)
182 svntest.actions.run_and_verify_update(wc_empty,
183 expected_output,
184 expected_disk,
185 expected_status,
186 None, None, None, None, None)
188 # And the wc should still be depth-empty.
189 verify_depth(None, "empty", wc_empty)
191 # Even if we explicitly ask for a depth-infinity update, we still shouldn't
192 # get the change to iota.
193 svntest.actions.run_and_verify_update(wc_empty,
194 expected_output,
195 expected_disk,
196 expected_status,
197 None, None, None, None, None, False,
198 "--depth=infinity", wc_empty)
200 # And the wc should still be depth-empty.
201 verify_depth(None, "empty", wc_empty)
204 #----------------------------------------------------------------------
205 def depth_immediates_get_top_file_mod_only(sbox):
206 "update depth-immediates wc gets top file mod only"
208 ign_a, ign_b, wc_immediates, wc \
209 = set_up_depthy_working_copies(sbox, immediates=True, infinity=True)
211 iota_path = os.path.join(wc, 'iota')
212 svntest.main.file_append(iota_path, "new text in iota\n")
213 mu_path = os.path.join(wc, 'A', 'mu')
214 svntest.main.file_append(mu_path, "new text in mu\n")
216 # Commit in the "other" wc.
217 expected_output = svntest.wc.State(wc,
218 { 'iota' : Item(verb='Sending'),
219 'A/mu' : Item(verb='Sending'),
221 expected_status = svntest.actions.get_virginal_state(wc, 1)
222 expected_status.tweak('iota', wc_rev=2, status=' ')
223 expected_status.tweak('A/mu', wc_rev=2, status=' ')
224 svntest.actions.run_and_verify_commit(wc,
225 expected_output,
226 expected_status,
227 None, wc)
229 # Update the depth-immediates wc, expecting to receive only the
230 # change to iota.
231 expected_output = svntest.wc.State(wc_immediates,
232 { 'iota' : Item(status='U ') })
233 expected_disk = svntest.wc.State('', { })
234 expected_disk.add(\
235 {'iota' : Item(contents="This is the file 'iota'.\nnew text in iota\n"),
236 'A' : Item(contents=None) } )
237 expected_status = svntest.wc.State(wc_immediates,
238 { '' : svntest.wc.StateItem() })
239 expected_status.tweak(contents=None, status=' ', wc_rev=2)
240 expected_status.add(\
241 {'iota' : Item(status=' ', wc_rev=2),
242 'A' : Item(status=' ', wc_rev=2) } )
243 svntest.actions.run_and_verify_update(wc_immediates,
244 expected_output,
245 expected_disk,
246 expected_status,
247 None, None, None, None, None)
248 verify_depth(None, "immediates", wc_immediates)
251 #----------------------------------------------------------------------
252 def depth_empty_commit(sbox):
253 "commit a file from a depth-empty working copy"
254 # Bring iota into a depth-empty working copy, then commit a change to it.
255 wc_empty, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox,
256 empty=True)
258 # Form the working path of iota
259 wc_empty_iota = os.path.join(wc_empty, 'iota')
261 # Update 'iota' in the depth-empty working copy and modify it
262 svntest.actions.run_and_verify_svn(None, None, [],
263 'up', wc_empty_iota)
264 svntest.main.file_write(wc_empty_iota, "iota modified")
266 # Commit the modified changes from a depth-empty working copy
267 expected_output = svntest.wc.State(wc_empty, {
268 'iota' : Item(verb='Sending'),
270 expected_status = svntest.wc.State(wc_empty, { })
271 expected_status.add({
272 '' : Item(status=' ', wc_rev=1),
273 'iota' : Item(status=' ', wc_rev=2),
275 svntest.actions.run_and_verify_commit(wc_empty,
276 expected_output,
277 expected_status,
278 None,
279 wc_empty)
281 #----------------------------------------------------------------------
282 def depth_empty_with_file(sbox):
283 "act on a file in a depth-empty working copy"
284 # Run 'svn up iota' to bring iota permanently into the working copy.
285 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True,
286 infinity=True)
288 iota_path = os.path.join(wc_empty, 'iota')
289 if os.path.exists(iota_path):
290 raise svntest.Failure("'%s' exists when it shouldn't" % iota_path)
292 # ### I'd love to do this using the recommended {expected_output,
293 # ### expected_status, expected_disk} method here, but after twenty
294 # ### minutes of trying to figure out how, I decided to compromise.
296 # Update iota by name, expecting to receive it.
297 svntest.actions.run_and_verify_svn(None, None, [], 'up', iota_path)
299 # Test that we did receive it.
300 if not os.path.exists(iota_path):
301 raise svntest.Failure("'%s' doesn't exist when it should" % iota_path)
303 # Commit a change to iota in the "other" wc.
304 other_iota_path = os.path.join(wc, 'iota')
305 svntest.main.file_append(other_iota_path, "new text\n")
306 expected_output = svntest.wc.State(wc, { 'iota' : Item(verb='Sending'), })
307 expected_status = svntest.actions.get_virginal_state(wc, 1)
308 expected_status.tweak('iota', wc_rev=2, status=' ')
309 svntest.actions.run_and_verify_commit(wc,
310 expected_output,
311 expected_status,
312 None, wc)
314 # Delete iota in the "other" wc.
315 other_iota_path = os.path.join(wc, 'iota')
316 svntest.actions.run_and_verify_svn(None, None, [], 'rm', other_iota_path)
317 expected_output = svntest.wc.State(wc, { 'iota' : Item(verb='Deleting'), })
318 expected_status = svntest.actions.get_virginal_state(wc, 1)
319 expected_status.remove('iota')
320 svntest.actions.run_and_verify_commit(wc,
321 expected_output,
322 expected_status,
323 None, wc)
325 # Update the depth-empty wc just a little, expecting to receive
326 # the change in iota.
327 expected_output = svntest.wc.State(\
328 wc_empty, { 'iota' : Item(status='U ') })
329 expected_disk = svntest.wc.State(\
330 '', { 'iota' : Item(contents="This is the file 'iota'.\nnew text\n") })
331 expected_status = svntest.wc.State(wc_empty,
332 { '' : Item(status=' ', wc_rev=2),
333 'iota' : Item(status=' ', wc_rev=2),})
334 svntest.actions.run_and_verify_update(wc_empty,
335 expected_output,
336 expected_disk,
337 expected_status,
338 None, None, None, None, None, False,
339 '-r2', wc_empty)
341 # Update the depth-empty wc all the way, expecting to receive the deletion
342 # of iota.
343 expected_output = svntest.wc.State(\
344 wc_empty, { 'iota' : Item(status='D ') })
345 expected_disk = svntest.wc.State('', { })
346 expected_status = svntest.wc.State(\
347 wc_empty, { '' : Item(status=' ', wc_rev=3) })
348 svntest.actions.run_and_verify_update(wc_empty,
349 expected_output,
350 expected_disk,
351 expected_status,
352 None, None, None, None, None)
355 #----------------------------------------------------------------------
356 def depth_empty_with_dir(sbox):
357 "bring a dir into a depth-empty working copy"
358 # Run 'svn up A' to bring A permanently into the working copy.
359 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True,
360 infinity=True)
362 A_path = os.path.join(wc_empty, 'A')
363 other_mu_path = os.path.join(wc, 'A', 'mu')
365 # We expect A to be added at depth infinity, so a normal 'svn up A'
366 # should be sufficient to add all descendants.
367 expected_output = svntest.wc.State(wc_empty, {
368 'A' : Item(status='A '),
369 'A/mu' : Item(status='A '),
370 'A/B' : Item(status='A '),
371 'A/B/lambda' : Item(status='A '),
372 'A/B/E' : Item(status='A '),
373 'A/B/E/alpha' : Item(status='A '),
374 'A/B/E/beta' : Item(status='A '),
375 'A/B/F' : Item(status='A '),
376 'A/C' : Item(status='A '),
377 'A/D' : Item(status='A '),
378 'A/D/gamma' : Item(status='A '),
379 'A/D/G' : Item(status='A '),
380 'A/D/G/pi' : Item(status='A '),
381 'A/D/G/rho' : Item(status='A '),
382 'A/D/G/tau' : Item(status='A '),
383 'A/D/H' : Item(status='A '),
384 'A/D/H/chi' : Item(status='A '),
385 'A/D/H/psi' : Item(status='A '),
386 'A/D/H/omega' : Item(status='A ')
388 expected_disk = svntest.main.greek_state.copy()
389 expected_disk.remove('iota')
390 expected_status = svntest.actions.get_virginal_state(wc_empty, 1)
391 expected_status.remove('iota')
392 svntest.actions.run_and_verify_update(wc_empty,
393 expected_output,
394 expected_disk,
395 expected_status,
396 None, None,
397 None, None, None, None,
398 A_path)
400 # Commit a change to A/mu in the "other" wc.
401 svntest.main.file_write(other_mu_path, "new text\n")
402 expected_output = svntest.wc.State(\
403 wc, { 'A/mu' : Item(verb='Sending'), })
404 expected_status = svntest.actions.get_virginal_state(wc, 1)
405 expected_status.tweak('A/mu', wc_rev=2, status=' ')
406 svntest.actions.run_and_verify_commit(wc,
407 expected_output,
408 expected_status,
409 None, wc)
411 # Update "A" by name in wc_empty, expect to receive the change to A/mu.
412 expected_output = svntest.wc.State(wc_empty, { 'A/mu' : Item(status='U ') })
413 expected_disk = svntest.main.greek_state.copy()
414 expected_disk.remove('iota')
415 expected_disk.tweak('A/mu', contents='new text\n')
416 expected_status = svntest.actions.get_virginal_state(wc_empty, 2)
417 expected_status.remove('iota')
418 expected_status.tweak('', wc_rev=1)
419 svntest.actions.run_and_verify_update(wc_empty,
420 expected_output,
421 expected_disk,
422 expected_status,
423 None, None,
424 None, None, None, None,
425 A_path)
427 # Commit the deletion of A/mu from the "other" wc.
428 svntest.main.file_write(other_mu_path, "new text\n")
429 svntest.actions.run_and_verify_svn(None, None, [], 'rm', other_mu_path)
430 expected_output = svntest.wc.State(wc, { 'A/mu' : Item(verb='Deleting'), })
431 expected_status = svntest.actions.get_virginal_state(wc, 1)
432 expected_status.remove('A/mu')
433 svntest.actions.run_and_verify_commit(wc,
434 expected_output,
435 expected_status,
436 None, wc)
439 # Update "A" by name in wc_empty, expect to A/mu to disappear.
440 expected_output = svntest.wc.State(wc_empty, { 'A/mu' : Item(status='D ') })
441 expected_disk = svntest.main.greek_state.copy()
442 expected_disk.remove('iota')
443 expected_disk.remove('A/mu')
444 expected_status = svntest.actions.get_virginal_state(wc_empty, 3)
445 expected_status.remove('iota')
446 expected_status.remove('A/mu')
447 expected_status.tweak('', wc_rev=1)
448 svntest.actions.run_and_verify_update(wc_empty,
449 expected_output,
450 expected_disk,
451 expected_status,
452 None, None,
453 None, None, None, None,
454 A_path)
458 #----------------------------------------------------------------------
459 def depth_immediates_bring_in_file(sbox):
460 "bring a file into a depth-immediates working copy"
462 # Create an immediates working copy and form the paths
463 ign_a, ign_b, wc_imm, wc = set_up_depthy_working_copies(sbox,
464 immediates=True)
465 A_mu_path = os.path.join(wc_imm, 'A', 'mu')
466 gamma_path = os.path.join(wc_imm, 'A', 'D', 'gamma')
468 # Run 'svn up A/mu' to bring A/mu permanently into the working copy.
469 expected_output = svntest.wc.State(wc_imm, {
470 'A/mu' : Item(status='A '),
472 expected_disk = svntest.main.greek_state.copy()
473 expected_disk.remove('A/C', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
474 'A/B/E/beta', 'A/B/F', 'A/B', 'A/D/gamma', 'A/D/G',
475 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 'A/D/H/chi',
476 'A/D/H/psi', 'A/D/H/omega', 'A/D/H', 'A/D')
477 expected_status = svntest.actions.get_virginal_state(wc_imm, 1)
478 expected_status.remove('A/C', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
479 'A/B/E/beta', 'A/B/F', 'A/B', 'A/D/gamma', 'A/D/G',
480 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 'A/D/H/chi',
481 'A/D/H/psi', 'A/D/H/omega', 'A/D/H', 'A/D')
482 svntest.actions.run_and_verify_update(wc_imm,
483 expected_output,
484 expected_disk,
485 expected_status,
486 None, None, None,
487 None, None, None,
488 A_mu_path)
490 # Run 'svn up A/D/gamma' to test the edge case 'Skipped'.
491 expected_output = svntest.wc.State(wc_imm, {
492 'A/D/gamma' : Item(verb='Skipped'),
494 expected_disk = svntest.main.greek_state.copy()
495 expected_disk.remove('A/C', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
496 'A/B/E/beta', 'A/B/F', 'A/B', 'A/D/gamma', 'A/D/G',
497 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 'A/D/H/chi',
498 'A/D/H/psi', 'A/D/H/omega', 'A/D/H', 'A/D')
499 expected_status = svntest.actions.get_virginal_state(wc_imm, 1)
500 expected_status.remove('A/C', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
501 'A/B/E/beta', 'A/B/F', 'A/B', 'A/D/gamma', 'A/D/G',
502 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 'A/D/H/chi',
503 'A/D/H/psi', 'A/D/H/omega', 'A/D/H', 'A/D')
504 svntest.actions.run_and_verify_update(wc_imm,
505 expected_output,
506 expected_disk,
507 expected_status,
508 None, None, None,
509 None, None, None,
510 gamma_path)
512 #----------------------------------------------------------------------
513 def depth_immediates_fill_in_dir(sbox):
514 "bring a dir into a depth-immediates working copy"
516 # Run 'svn up A --set-depth=infinity' to fill in A as a
517 # depth-infinity subdir.
518 ign_a, ign_b, wc_immediates, wc \
519 = set_up_depthy_working_copies(sbox, immediates=True)
520 A_path = os.path.join(wc_immediates, 'A')
521 expected_output = svntest.wc.State(wc_immediates, {
522 'A/mu' : Item(status='A '),
523 'A/B' : Item(status='A '),
524 'A/B/lambda' : Item(status='A '),
525 'A/B/E' : Item(status='A '),
526 'A/B/E/alpha' : Item(status='A '),
527 'A/B/E/beta' : Item(status='A '),
528 'A/B/F' : Item(status='A '),
529 'A/C' : Item(status='A '),
530 'A/D' : Item(status='A '),
531 'A/D/gamma' : Item(status='A '),
532 'A/D/G' : Item(status='A '),
533 'A/D/G/pi' : Item(status='A '),
534 'A/D/G/rho' : Item(status='A '),
535 'A/D/G/tau' : Item(status='A '),
536 'A/D/H' : Item(status='A '),
537 'A/D/H/chi' : Item(status='A '),
538 'A/D/H/psi' : Item(status='A '),
539 'A/D/H/omega' : Item(status='A ')
541 expected_disk = svntest.main.greek_state.copy()
542 expected_status = svntest.actions.get_virginal_state(wc_immediates, 1)
543 svntest.actions.run_and_verify_update(wc_immediates,
544 expected_output,
545 expected_disk,
546 expected_status,
547 None, None,
548 None, None, None, None,
549 '--set-depth', 'infinity',
550 A_path)
552 #----------------------------------------------------------------------
553 def depth_mixed_bring_in_dir(sbox):
554 "bring a dir into a mixed-depth working copy"
556 # Run 'svn up --set-depth=immediates A' in a depth-empty working copy.
557 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True)
558 A_path = os.path.join(wc_empty, 'A')
559 B_path = os.path.join(wc_empty, 'A', 'B')
560 C_path = os.path.join(wc_empty, 'A', 'C')
562 expected_output = svntest.wc.State(wc_empty, {
563 'A' : Item(status='A '),
564 'A/mu' : Item(status='A '),
566 expected_disk = svntest.main.greek_state.copy()
567 expected_disk.remove('iota', 'A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
568 'A/B/E/beta', 'A/B/F', 'A/C', 'A/D', 'A/D/gamma',
569 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau',
570 'A/D/H', 'A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega')
571 expected_status = svntest.actions.get_virginal_state(wc_empty, 1)
572 expected_status.remove('iota', 'A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
573 'A/B/E/beta', 'A/B/F', 'A/C', 'A/D', 'A/D/gamma',
574 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau',
575 'A/D/H', 'A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega')
576 svntest.actions.run_and_verify_update(wc_empty,
577 expected_output,
578 expected_disk,
579 expected_status,
580 None, None,
581 None, None, None, None,
582 '--set-depth', 'files',
583 A_path)
584 # Check that A was added at depth=files.
585 verify_depth(None, "files", A_path)
587 # Now, bring in A/B at depth-immediates.
588 expected_output = svntest.wc.State(wc_empty, {
589 'A/B' : Item(status='A '),
590 'A/B/lambda' : Item(status='A '),
591 'A/B/E' : Item(status='A '),
592 'A/B/F' : Item(status='A '),
594 expected_disk = svntest.main.greek_state.copy()
595 expected_disk.remove('iota', 'A/B/E/alpha', 'A/B/E/beta', 'A/C',
596 'A/D', 'A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho',
597 'A/D/G/tau', 'A/D/H', 'A/D/H/chi', 'A/D/H/psi',
598 'A/D/H/omega')
599 expected_status = svntest.actions.get_virginal_state(wc_empty, 1)
600 expected_status.remove('iota', 'A/B/E/alpha', 'A/B/E/beta', 'A/C',
601 'A/D', 'A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho',
602 'A/D/G/tau', 'A/D/H', 'A/D/H/chi', 'A/D/H/psi',
603 'A/D/H/omega')
604 svntest.actions.run_and_verify_update(wc_empty,
605 expected_output,
606 expected_disk,
607 expected_status,
608 None, None,
609 None, None, None, None,
610 '--set-depth', 'immediates',
611 B_path)
612 # Check that A/B was added at depth=immediates.
613 verify_depth(None, "immediates", B_path)
615 # Now, bring in A/C at depth-empty.
616 expected_output = svntest.wc.State(wc_empty, {
617 'A/C' : Item(status='A '),
619 expected_disk = svntest.main.greek_state.copy()
620 expected_disk.remove('iota', 'A/B/E/alpha', 'A/B/E/beta',
621 'A/D', 'A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho',
622 'A/D/G/tau', 'A/D/H', 'A/D/H/chi', 'A/D/H/psi',
623 'A/D/H/omega')
624 expected_status = svntest.actions.get_virginal_state(wc_empty, 1)
625 expected_status.remove('iota', 'A/B/E/alpha', 'A/B/E/beta',
626 'A/D', 'A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho',
627 'A/D/G/tau', 'A/D/H', 'A/D/H/chi', 'A/D/H/psi',
628 'A/D/H/omega')
629 svntest.actions.run_and_verify_update(wc_empty,
630 expected_output,
631 expected_disk,
632 expected_status,
633 None, None,
634 None, None, None, None,
635 '--set-depth', 'empty',
636 C_path)
637 # Check that A/C was added at depth=empty.
638 verify_depth(None, "empty", C_path)
640 #----------------------------------------------------------------------
641 def depth_empty_unreceive_delete(sbox):
642 "depth-empty working copy ignores a deletion"
643 # Check out a depth-empty greek tree to wc1. In wc2, delete iota and
644 # commit. Update wc1; should not receive the delete.
645 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True,
646 infinity=True)
648 iota_path = os.path.join(wc, 'iota')
650 # Commit in the "other" wc.
651 svntest.actions.run_and_verify_svn(None, None, [], 'rm', iota_path)
652 expected_output = svntest.wc.State(wc, { 'iota' : Item(verb='Deleting'), })
653 expected_status = svntest.actions.get_virginal_state(wc, 1)
654 expected_status.remove('iota')
655 svntest.actions.run_and_verify_commit(wc,
656 expected_output,
657 expected_status,
658 None, wc)
660 # Update the depth-empty wc, expecting not to receive the deletion of iota.
661 expected_output = svntest.wc.State(wc_empty, { })
662 expected_disk = svntest.wc.State('', { })
663 expected_status = svntest.wc.State(wc_empty, { '' : svntest.wc.StateItem() })
664 expected_status.tweak(contents=None, status=' ', wc_rev=2)
665 svntest.actions.run_and_verify_update(wc_empty,
666 expected_output,
667 expected_disk,
668 expected_status,
669 None, None, None, None, None)
672 #----------------------------------------------------------------------
673 def depth_immediates_unreceive_delete(sbox):
674 "depth-immediates working copy ignores a deletion"
675 # Check out a depth-immediates greek tree to wc1. In wc2, delete
676 # A/mu and commit. Update wc1; should not receive the delete.
678 ign_a, ign_b, wc_immed, wc = set_up_depthy_working_copies(sbox,
679 immediates=True,
680 infinity=True)
682 mu_path = os.path.join(wc, 'A', 'mu')
684 # Commit in the "other" wc.
685 svntest.actions.run_and_verify_svn(None, None, [], 'rm', mu_path)
686 expected_output = svntest.wc.State(wc, { 'A/mu' : Item(verb='Deleting'), })
687 expected_status = svntest.actions.get_virginal_state(wc, 1)
688 expected_status.remove('A/mu')
689 svntest.actions.run_and_verify_commit(wc,
690 expected_output,
691 expected_status,
692 None, wc)
694 # Update the depth-immediates wc, expecting not to receive the deletion
695 # of A/mu.
696 expected_output = svntest.wc.State(wc_immed, { })
697 expected_disk = svntest.wc.State('', {
698 'iota' : Item(contents="This is the file 'iota'.\n"),
699 'A' : Item()
701 expected_status = svntest.wc.State(wc_immed, {
702 '' : Item(status=' ', wc_rev=2),
703 'iota' : Item(status=' ', wc_rev=2),
704 'A' : Item(status=' ', wc_rev=2)
706 svntest.actions.run_and_verify_update(wc_immed,
707 expected_output,
708 expected_disk,
709 expected_status,
710 None, None, None, None, None)
712 #----------------------------------------------------------------------
713 def depth_immediates_receive_delete(sbox):
714 "depth-immediates working copy receives a deletion"
715 # Check out a depth-immediates greek tree to wc1. In wc2, delete A and
716 # commit. Update wc1 should receive the delete.
718 ign_a, ign_b, wc_immed, wc = set_up_depthy_working_copies(sbox,
719 immediates=True,
720 infinity=True)
722 A_path = os.path.join(wc, 'A')
724 # Commit in the "other" wc.
725 svntest.actions.run_and_verify_svn(None, None, [], 'rm', A_path)
726 expected_output = svntest.wc.State(wc, { 'A' : Item(verb='Deleting'), })
727 expected_status = svntest.wc.State(wc, {
728 '' : Item(status=' ', wc_rev=1),
729 'iota' : Item(status=' ', wc_rev=1),
731 svntest.actions.run_and_verify_commit(wc,
732 expected_output,
733 expected_status,
734 None, wc)
736 # Update the depth-immediates wc, expecting to receive the deletion of A.
737 expected_output = svntest.wc.State(wc_immed, {
738 'A' : Item(status='D ')
740 expected_disk = svntest.wc.State('', {
741 'iota' : Item(contents="This is the file 'iota'.\n"),
743 expected_status = svntest.wc.State(wc_immed, {
744 '' : Item(status=' ', wc_rev=2),
745 'iota' : Item(status=' ', wc_rev=2)
747 svntest.actions.run_and_verify_update(wc_immed,
748 expected_output,
749 expected_disk,
750 expected_status,
751 None, None, None, None, None)
753 #----------------------------------------------------------------------
754 def depth_immediates_subdir_propset_1(sbox):
755 "depth-immediates commit subdir propset, update"
756 ign_a, ign_b, wc_immediates, ign_c \
757 = set_up_depthy_working_copies(sbox, immediates=True)
759 A_path = os.path.join(wc_immediates, 'A')
761 # Set a property on an immediate subdirectory of the working copy.
762 svntest.actions.run_and_verify_svn(None, None, [],
763 'pset', 'foo', 'bar',
764 A_path)
766 # Create expected output tree.
767 expected_output = svntest.wc.State(wc_immediates, {
768 'A' : Item(verb='Sending'),
771 # Create expected status tree.
772 expected_status = svntest.wc.State(wc_immediates, {
773 '' : Item(status=' ', wc_rev=1),
774 'iota' : Item(status=' ', wc_rev=1),
775 'A' : Item(status=' ', wc_rev=2)
778 # Commit wc_immediates/A.
779 svntest.actions.run_and_verify_commit(wc_immediates,
780 expected_output,
781 expected_status,
782 None,
783 A_path)
785 # Create expected output tree for the update.
786 expected_output = svntest.wc.State(wc_immediates, { })
788 # Create expected disk tree.
789 expected_disk = svntest.wc.State('', {
790 'iota' : Item(contents="This is the file 'iota'.\n"),
791 'A' : Item(contents=None, props={'foo' : 'bar'}),
794 expected_status.tweak(contents=None, status=' ', wc_rev=2)
796 # Update the depth-immediates wc.
797 svntest.actions.run_and_verify_update(wc_immediates,
798 expected_output,
799 expected_disk,
800 expected_status,
801 None, None, None, None, None, 1)
803 #----------------------------------------------------------------------
804 def depth_immediates_subdir_propset_2(sbox):
805 "depth-immediates update receives subdir propset"
806 sbox.build()
807 wc_dir = sbox.wc_dir
809 # Make the other working copy.
810 other_wc = sbox.add_wc_path('other')
811 svntest.actions.duplicate_dir(wc_dir, other_wc)
813 A_path = os.path.join(wc_dir, 'A')
815 # Set a property on an immediate subdirectory of the working copy.
816 svntest.actions.run_and_verify_svn(None, None, [],
817 'pset', 'foo', 'bar',
818 A_path)
819 # Commit.
820 svntest.actions.run_and_verify_svn(None, None, [],
821 'commit', '-m', 'logmsg', A_path)
823 # Update at depth=immediates in the other wc, expecting to see no errors.
824 svntest.actions.run_and_verify_svn("Output on stderr where none expected",
825 svntest.verify.AnyOutput, [],
826 'update', '--depth', 'immediates',
827 other_wc)
829 #----------------------------------------------------------------------
830 def depth_update_to_more_depth(sbox):
831 "gradually update an empty wc to depth=infinity"
833 wc_dir, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True)
835 os.chdir(wc_dir)
837 # Run 'svn up --set-depth=files' in a depth-empty working copy.
838 expected_output = svntest.wc.State('', {
839 'iota' : Item(status='A '),
841 expected_status = svntest.wc.State('', {
842 '' : Item(status=' ', wc_rev=1),
843 'iota' : Item(status=' ', wc_rev=1),
845 expected_disk = svntest.wc.State('', {
846 'iota' : Item("This is the file 'iota'.\n"),
848 svntest.actions.run_and_verify_update('',
849 expected_output,
850 expected_disk,
851 expected_status,
852 None, None,
853 None, None, None, None,
854 '--set-depth', 'files')
855 verify_depth(None, "files")
857 # Run 'svn up --set-depth=immediates' in the now depth-files working copy.
858 expected_output = svntest.wc.State('', {
859 'A' : Item(status='A '),
861 expected_status = svntest.wc.State('', {
862 '' : Item(status=' ', wc_rev=1),
863 'iota' : Item(status=' ', wc_rev=1),
864 'A' : Item(status=' ', wc_rev=1),
866 expected_disk = svntest.wc.State('', {
867 'iota' : Item("This is the file 'iota'.\n"),
868 'A' : Item(),
870 svntest.actions.run_and_verify_update('',
871 expected_output,
872 expected_disk,
873 expected_status,
874 None, None,
875 None, None, None, None,
876 '--set-depth', 'immediates')
877 verify_depth(None, "immediates")
878 verify_depth(None, "empty", "A")
880 # Upgrade 'A' to depth-files.
881 expected_output = svntest.wc.State('', {
882 'A/mu' : Item(status='A '),
884 expected_status = svntest.wc.State('', {
885 '' : Item(status=' ', wc_rev=1),
886 'iota' : Item(status=' ', wc_rev=1),
887 'A' : Item(status=' ', wc_rev=1),
888 'A/mu' : Item(status=' ', wc_rev=1),
890 expected_disk = svntest.wc.State('', {
891 'iota' : Item("This is the file 'iota'.\n"),
892 'A' : Item(),
893 'A/mu' : Item("This is the file 'mu'.\n"),
895 svntest.actions.run_and_verify_update('',
896 expected_output,
897 expected_disk,
898 expected_status,
899 None, None,
900 None, None, None, None,
901 '--set-depth', 'files', 'A')
902 verify_depth(None, "immediates")
903 verify_depth(None, "files", "A")
905 # Run 'svn up --set-depth=infinity' in the working copy.
906 expected_output = svntest.wc.State('', {
907 'A/B' : Item(status='A '),
908 'A/B/lambda' : Item(status='A '),
909 'A/B/E' : Item(status='A '),
910 'A/B/E/alpha' : Item(status='A '),
911 'A/B/E/beta' : Item(status='A '),
912 'A/B/F' : Item(status='A '),
913 'A/C' : Item(status='A '),
914 'A/D' : Item(status='A '),
915 'A/D/gamma' : Item(status='A '),
916 'A/D/G' : Item(status='A '),
917 'A/D/G/pi' : Item(status='A '),
918 'A/D/G/rho' : Item(status='A '),
919 'A/D/G/tau' : Item(status='A '),
920 'A/D/H' : Item(status='A '),
921 'A/D/H/chi' : Item(status='A '),
922 'A/D/H/psi' : Item(status='A '),
923 'A/D/H/omega' : Item(status='A ')
925 expected_disk = svntest.main.greek_state.copy()
926 expected_status = svntest.actions.get_virginal_state('', 1)
927 svntest.actions.run_and_verify_update('',
928 expected_output,
929 expected_disk,
930 expected_status,
931 None, None,
932 None, None, None, None,
933 '--set-depth', 'infinity')
934 verify_depth("Non-infinity depth detected after an upgrade to depth-infinity",
935 "infinity")
936 verify_depth("Non-infinity depth detected after an upgrade to depth-infinity",
937 "infinity", "A")
939 def commit_propmods_with_depth_empty(sbox):
940 "commit property mods only, using --depth=empty"
941 sbox.build()
942 wc_dir = sbox.wc_dir
944 iota_path = os.path.join(wc_dir, 'iota')
945 A_path = os.path.join(wc_dir, 'A')
946 D_path = os.path.join(A_path, 'D')
947 gamma_path = os.path.join(D_path, 'gamma')
948 G_path = os.path.join(D_path, 'G')
949 pi_path = os.path.join(G_path, 'pi')
950 H_path = os.path.join(D_path, 'H')
951 chi_path = os.path.join(H_path, 'chi')
953 # Set some properties, modify some files.
954 svntest.actions.run_and_verify_svn(None, None, [],
955 'propset', 'foo', 'foo-val', wc_dir)
956 svntest.actions.run_and_verify_svn(None, None, [],
957 'propset', 'bar', 'bar-val', D_path)
958 svntest.actions.run_and_verify_svn(None, None, [],
959 'propset', 'baz', 'baz-val', G_path)
960 svntest.actions.run_and_verify_svn(None, None, [],
961 'propset', 'qux', 'qux-val', H_path)
962 svntest.main.file_append(iota_path, "new iota\n")
963 svntest.main.file_append(gamma_path, "new gamma\n")
964 svntest.main.file_append(pi_path, "new pi\n")
965 svntest.main.file_append(chi_path, "new chi\n")
967 # The only things that should be committed are two of the propsets.
968 expected_output = svntest.wc.State(
969 wc_dir,
970 { '' : Item(verb='Sending'),
971 'A/D' : Item(verb='Sending'), }
973 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
974 # Expect the two propsets to be committed:
975 expected_status.tweak('', status=' ', wc_rev=2)
976 expected_status.tweak('A/D', status=' ', wc_rev=2)
977 # Expect every other change to remain uncommitted:
978 expected_status.tweak('iota', status='M ', wc_rev=1)
979 expected_status.tweak('A/D/G', status=' M', wc_rev=1)
980 expected_status.tweak('A/D/H', status=' M', wc_rev=1)
981 expected_status.tweak('A/D/gamma', status='M ', wc_rev=1)
982 expected_status.tweak('A/D/G/pi', status='M ', wc_rev=1)
983 expected_status.tweak('A/D/H/chi', status='M ', wc_rev=1)
985 svntest.actions.run_and_verify_commit(wc_dir,
986 expected_output,
987 expected_status,
988 None,
989 '--depth=empty',
990 wc_dir, D_path)
992 # Test for issue #2845.
993 def diff_in_depthy_wc(sbox):
994 "diff at various depths in non-infinity wc"
996 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True,
997 infinity=True)
999 iota_path = os.path.join(wc, 'iota')
1000 A_path = os.path.join(wc, 'A')
1001 mu_path = os.path.join(wc, 'A', 'mu')
1002 gamma_path = os.path.join(wc, 'A', 'D', 'gamma')
1004 # Make some changes in the depth-infinity wc, and commit them
1005 svntest.actions.run_and_verify_svn(None, None, [],
1006 'propset', 'foo', 'foo-val', wc)
1007 svntest.main.file_write(iota_path, "new text\n")
1008 svntest.actions.run_and_verify_svn(None, None, [],
1009 'propset', 'bar', 'bar-val', A_path)
1010 svntest.main.file_write(mu_path, "new text\n")
1011 svntest.main.file_write(gamma_path, "new text\n")
1012 svntest.actions.run_and_verify_svn(None, None, [],
1013 'commit', '-m', '', wc)
1015 diff = [
1016 "\n",
1017 "Property changes on: .\n",
1018 "___________________________________________________________________\n",
1019 "Deleted: foo\n",
1020 " - foo-val\n",
1021 "\n",
1022 "Index: iota\n",
1023 "===================================================================\n",
1024 "--- iota\t(revision 2)\n",
1025 "+++ iota\t(working copy)\n",
1026 "@@ -1 +1 @@\n",
1027 "-new text\n",
1028 "+This is the file 'iota'.\n",
1029 "Property changes on: A\n",
1030 "___________________________________________________________________\n",
1031 "Deleted: bar\n",
1032 " - bar-val\n",
1033 "\n",
1034 "\n",
1035 "Index: A/mu\n",
1036 "===================================================================\n",
1037 "--- A/mu\t(revision 2)\n",
1038 "+++ A/mu\t(working copy)\n",
1039 "@@ -1 +1 @@\n",
1040 "-new text\n",
1041 "+This is the file 'mu'.\n" ]
1043 os.chdir(wc_empty)
1045 expected_output = svntest.verify.UnorderedOutput(diff[:6])
1046 # The diff should contain only the propchange on '.'
1047 svntest.actions.run_and_verify_svn(None, expected_output, [],
1048 'diff', '-rHEAD')
1050 # Upgrade to depth-files.
1051 svntest.actions.run_and_verify_svn(None, None, [], 'up',
1052 '--set-depth', 'files', '-r1')
1053 # The diff should contain only the propchange on '.' and the
1054 # contents change on iota.
1055 expected_output = svntest.verify.UnorderedOutput(diff[:13])
1056 svntest.actions.run_and_verify_svn(None, expected_output, [],
1057 'diff', '-rHEAD')
1058 # Do a diff at --depth empty.
1059 expected_output = svntest.verify.UnorderedOutput(diff[:6])
1060 svntest.actions.run_and_verify_svn(None, expected_output, [],
1061 'diff', '--depth', 'empty', '-rHEAD')
1063 # Upgrade to depth-immediates.
1064 svntest.actions.run_and_verify_svn(None, None, [], 'up',
1065 '--set-depth', 'immediates', '-r1')
1066 # The diff should contain the propchanges on '.' and 'A' and the
1067 # contents change on iota.
1068 expected_output = svntest.verify.UnorderedOutput(diff[:19])
1069 svntest.actions.run_and_verify_svn(None, expected_output, [],
1070 'diff', '-rHEAD')
1071 # Do a diff at --depth files.
1072 expected_output = svntest.verify.UnorderedOutput(diff[:13])
1073 svntest.actions.run_and_verify_svn(None, expected_output, [],
1074 'diff', '--depth', 'files', '-rHEAD')
1076 # Upgrade A to depth-files.
1077 svntest.actions.run_and_verify_svn(None, None, [], 'up',
1078 '--set-depth', 'files', '-r1', 'A')
1079 # The diff should contain everything but the contents change on
1080 # gamma (which does not exist in this working copy).
1081 expected_output = svntest.verify.UnorderedOutput(diff)
1082 svntest.actions.run_and_verify_svn(None, expected_output, [],
1083 'diff', '-rHEAD')
1084 # Do a diff at --depth immediates.
1085 expected_output = svntest.verify.UnorderedOutput(diff[:19])
1086 svntest.actions.run_and_verify_svn(None, expected_output, [],
1087 'diff', '--depth', 'immediates', '-rHEAD')
1089 def commit_depth_immediates(sbox):
1090 "commit some files with --depth=immediates"
1091 sbox.build()
1092 wc_dir = sbox.wc_dir
1094 # Test the fix for some bugs Mike Pilato reported here:
1096 # http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=128509
1097 # From: "C. Michael Pilato" <cmpilato@collab.net>
1098 # To: Karl Fogel <kfogel@red-bean.com>
1099 # CC: dev@subversion.tigris.org
1100 # References: <87d4yzcrro.fsf@red-bean.com>
1101 # Subject: Re: [PATCH] Make 'svn commit --depth=foo' work.
1102 # Message-ID: <46968831.2070906@collab.net>
1103 # Date: Thu, 12 Jul 2007 15:59:45 -0400
1105 # See also http://subversion.tigris.org/issues/show_bug.cgi?id=2882.
1107 # Outline of the test:
1108 # ====================
1110 # Modify these three files:
1112 # M A/mu
1113 # M A/D/G/rho
1114 # M iota
1116 # Then commit some of them using --depth=immediates:
1118 # svn ci -m "log msg" --depth=immediates wc_dir wc_dir/A/D/G/rho
1120 # Before the bugfix, that would result in an error:
1122 # subversion/libsvn_wc/lock.c:570: (apr_err=155004)
1123 # svn: Working copy '/blah/blah/blah/wc' locked
1124 # svn: run 'svn cleanup' to remove locks \
1125 # (type 'svn help cleanup' for details)
1127 # After the bugfix, it correctly commits two of the three files:
1129 # Sending A/D/G/rho
1130 # Sending iota
1131 # Transmitting file data ..
1132 # Committed revision 2.
1134 iota_path = os.path.join(wc_dir, 'iota')
1135 mu_path = os.path.join(wc_dir, 'A', 'mu')
1136 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
1137 rho_path = os.path.join(G_path, 'rho')
1139 svntest.main.file_append(iota_path, "new text in iota\n")
1140 svntest.main.file_append(mu_path, "new text in mu\n")
1141 svntest.main.file_append(rho_path, "new text in rho\n")
1143 expected_output = svntest.wc.State(wc_dir, {
1144 'iota' : Item(verb='Sending'),
1145 'A/D/G/rho' : Item(verb='Sending'),
1147 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
1148 expected_status.tweak('iota', status=' ', wc_rev=2)
1149 expected_status.tweak('A/mu', status='M ', wc_rev=1)
1150 expected_status.tweak('A/D/G/rho', status=' ', wc_rev=2)
1151 svntest.actions.run_and_verify_commit(wc_dir,
1152 expected_output,
1153 expected_status,
1154 None,
1155 '--depth', 'immediates',
1156 wc_dir, G_path)
1158 def depth_immediates_receive_new_dir(sbox):
1159 "depth-immediates wc receives new directory"
1161 ign_a, ign_b, wc_immed, wc = set_up_depthy_working_copies(sbox,
1162 immediates=True,
1163 infinity=True)
1165 I_path = os.path.join(wc, 'I')
1166 zeta_path = os.path.join(wc, 'I', 'zeta')
1167 other_I_path = os.path.join(wc_immed, 'I')
1169 os.mkdir(I_path)
1170 svntest.main.file_write(zeta_path, "This is the file 'zeta'.\n")
1172 # Commit in the "other" wc.
1173 svntest.actions.run_and_verify_svn(None, None, [], 'add', I_path)
1174 expected_output = svntest.wc.State(wc, {
1175 'I' : Item(verb='Adding'),
1176 'I/zeta' : Item(verb='Adding'),
1178 expected_status = svntest.actions.get_virginal_state(wc, 1)
1179 expected_status.add({
1180 'I' : Item(status=' ', wc_rev=2),
1181 'I/zeta' : Item(status=' ', wc_rev=2),
1183 svntest.actions.run_and_verify_commit(wc,
1184 expected_output,
1185 expected_status,
1186 None, wc)
1188 # Update the depth-immediates wc, expecting to receive just the
1189 # new directory, without the file.
1190 expected_output = svntest.wc.State(wc_immed, {
1191 'I' : Item(status='A '),
1193 expected_disk = svntest.wc.State('', {
1194 'iota' : Item(contents="This is the file 'iota'.\n"),
1195 'A' : Item(),
1196 'I' : Item(),
1198 expected_status = svntest.wc.State(wc_immed, {
1199 '' : Item(status=' ', wc_rev=2),
1200 'iota' : Item(status=' ', wc_rev=2),
1201 'A' : Item(status=' ', wc_rev=2),
1202 'I' : Item(status=' ', wc_rev=2),
1204 svntest.actions.run_and_verify_update(wc_immed,
1205 expected_output,
1206 expected_disk,
1207 expected_status,
1208 None, None, None, None, None)
1209 # Check that the new directory was added at depth=empty.
1210 verify_depth(None, "empty", other_I_path)
1212 def add_tree_with_depth_files(sbox):
1213 "add multi-subdir tree with --depth=files" # For issue #2931
1214 sbox.build()
1215 wc_dir = sbox.wc_dir
1216 new1_path = os.path.join(wc_dir, 'new1')
1217 new2_path = os.path.join(new1_path, 'new2')
1218 os.mkdir(new1_path)
1219 os.mkdir(new2_path)
1220 svntest.actions.run_and_verify_svn(None, None, [],
1221 "add", "--depth", "files", new1_path)
1223 def upgrade_from_above(sbox):
1224 "upgrade a depth=empty wc from above"
1226 # The bug was that 'svn up --set-depth=files' worked from within the
1227 # working copy, but not from without with working copy top given
1228 # as an argument. Both ways would correctly cause 'iota' to
1229 # appear, but only the former actually upgraded the depth of the
1230 # working copy to 'files'. See this thread for details:
1232 # http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=130157
1233 # From: Alexander Sinyushkin <Alexander.Sinyushkin@svnkit.com>
1234 # To: dev@subversion.tigris.org
1235 # Subject: Problem upgrading working copy depth
1236 # Date: Wed, 19 Sep 2007 23:15:24 +0700
1237 # Message-ID: <46F14B1C.8010406@svnkit.com>
1239 wc, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True)
1241 # First verify that upgrading from within works.
1242 saved_cwd = os.getcwd()
1243 try:
1244 os.chdir(wc)
1245 expected_output = svntest.wc.State('', {
1246 'iota' : Item(status='A '),
1248 expected_disk = svntest.wc.State('', {
1249 'iota' : Item(contents="This is the file 'iota'.\n"),
1251 expected_status = svntest.wc.State('', {
1252 '' : Item(status=' ', wc_rev=1),
1253 'iota' : Item(status=' ', wc_rev=1),
1255 svntest.actions.run_and_verify_update('',
1256 expected_output,
1257 expected_disk,
1258 expected_status,
1259 None, None, None, None, None, None,
1260 '--set-depth=files')
1261 verify_depth(None, "files")
1262 finally:
1263 os.chdir(saved_cwd)
1265 # Reset and do it again, this time from above the working copy.
1266 svntest.main.safe_rmtree(wc)
1267 wc, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True)
1268 expected_output = svntest.wc.State(wc, {
1269 'iota' : Item(status='A '),
1271 expected_disk = svntest.wc.State('', {
1272 'iota' : Item(contents="This is the file 'iota'.\n"),
1274 expected_status = svntest.wc.State(wc, {
1275 '' : Item(status=' ', wc_rev=1),
1276 'iota' : Item(status=' ', wc_rev=1),
1278 svntest.actions.run_and_verify_update(wc,
1279 expected_output,
1280 expected_disk,
1281 expected_status,
1282 None, None, None, None, None, None,
1283 '--set-depth=files', wc)
1284 verify_depth(None, "files", wc)
1286 def status_in_depthy_wc(sbox):
1287 "status -u at various depths in non-infinity wc"
1289 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True,
1290 infinity=True)
1292 iota_path = os.path.join(wc, 'iota')
1293 A_path = os.path.join(wc, 'A')
1294 mu_path = os.path.join(wc, 'A', 'mu')
1295 gamma_path = os.path.join(wc, 'A', 'D', 'gamma')
1297 # Make some changes in the depth-infinity wc, and commit them
1298 svntest.actions.run_and_verify_svn(None, None, [],
1299 'propset', 'foo', 'foo-val', wc)
1300 svntest.main.file_write(iota_path, "new text\n")
1301 svntest.actions.run_and_verify_svn(None, None, [],
1302 'propset', 'bar', 'bar-val', A_path)
1303 svntest.main.file_write(mu_path, "new text\n")
1304 svntest.main.file_write(gamma_path, "new text\n")
1305 svntest.actions.run_and_verify_svn(None, None, [],
1306 'commit', '-m', '', wc)
1308 status = [
1309 "Status against revision: 2\n",
1310 " * 1 .\n",
1311 " * 1 iota\n",
1312 " * 1 A\n",
1313 " * 1 " + os.path.join('A', 'mu') + "\n",
1316 os.chdir(wc_empty)
1318 expected_output = svntest.verify.UnorderedOutput(status[:2])
1319 # The output should contain only the change on '.'.
1320 svntest.actions.run_and_verify_svn(None, expected_output, [],
1321 'st', '-u')
1323 # Upgrade to depth-files.
1324 svntest.actions.run_and_verify_svn(None, None, [], 'up',
1325 '--set-depth', 'files', '-r1')
1326 # The output should contain only the changes on '.' and 'iota'.
1327 expected_output = svntest.verify.UnorderedOutput(status[:3])
1328 svntest.actions.run_and_verify_svn(None, expected_output, [],
1329 'st', '-u')
1330 # Do a status -u at --depth empty.
1331 expected_output = svntest.verify.UnorderedOutput(status[:2])
1332 svntest.actions.run_and_verify_svn(None, expected_output, [],
1333 'st', '-u', '--depth', 'empty')
1335 # Upgrade to depth-immediates.
1336 svntest.actions.run_and_verify_svn(None, None, [], 'up',
1337 '--set-depth', 'immediates', '-r1')
1338 # The output should contain the changes on '.', 'A' and 'iota'.
1339 expected_output = svntest.verify.UnorderedOutput(status[:4])
1340 svntest.actions.run_and_verify_svn(None, expected_output, [],
1341 'st', '-u')
1342 # Do a status -u at --depth files.
1343 expected_output = svntest.verify.UnorderedOutput(status[:3])
1344 svntest.actions.run_and_verify_svn(None, expected_output, [],
1345 'st', '-u', '--depth', 'files')
1347 # Upgrade A to depth-files.
1348 svntest.actions.run_and_verify_svn(None, None, [], 'up',
1349 '--set-depth', 'files', '-r1', 'A')
1350 # The output should contain everything but the change on
1351 # gamma (which does not exist in this working copy).
1352 expected_output = svntest.verify.UnorderedOutput(status)
1353 svntest.actions.run_and_verify_svn(None, expected_output, [],
1354 'st', '-u')
1355 # Do a status -u at --depth immediates.
1356 expected_output = svntest.verify.UnorderedOutput(status[:4])
1357 svntest.actions.run_and_verify_svn(None, expected_output, [],
1358 'st', '-u', '--depth', 'immediates')
1360 #----------------------------------------------------------------------
1362 # Issue #3039.
1363 def depthy_update_above_dir_to_be_deleted(sbox):
1364 "'update -N' above a WC path deleted in repos HEAD"
1365 sbox.build()
1367 sbox_for_depth = {
1368 "files" : sbox,
1369 "immediates" : sbox.clone_dependent(copy_wc=True),
1370 "empty" : sbox.clone_dependent(copy_wc=True),
1373 output, err = \
1374 svntest.actions.run_and_verify_svn(None, None, [],
1375 "delete", "-m", "Delete A.",
1376 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 # list all tests here, starting with None:
1432 test_list = [ None,
1433 depth_empty_checkout,
1434 depth_files_checkout,
1435 nonrecursive_checkout,
1436 depth_empty_update_bypass_single_file,
1437 depth_immediates_get_top_file_mod_only,
1438 depth_empty_commit,
1439 depth_empty_with_file,
1440 depth_empty_with_dir,
1441 depth_immediates_bring_in_file,
1442 depth_immediates_fill_in_dir,
1443 depth_mixed_bring_in_dir,
1444 depth_empty_unreceive_delete,
1445 depth_immediates_unreceive_delete,
1446 depth_immediates_receive_delete,
1447 depth_update_to_more_depth,
1448 depth_immediates_subdir_propset_1,
1449 depth_immediates_subdir_propset_2,
1450 commit_propmods_with_depth_empty,
1451 diff_in_depthy_wc,
1452 commit_depth_immediates,
1453 depth_immediates_receive_new_dir,
1454 add_tree_with_depth_files,
1455 upgrade_from_above,
1456 status_in_depthy_wc,
1457 depthy_update_above_dir_to_be_deleted,
1460 if __name__ == "__main__":
1461 svntest.main.run_tests(test_list)
1462 # NOTREACHED
1465 ### End of file.