1#!/usr/bin/env python 2# 3# depth_tests.py: Testing that operations work as expected at 4# various depths (depth-empty, depth-files, 5# depth-immediates, depth-infinity). 6# 7# Subversion is a tool for revision control. 8# See http://subversion.apache.org for more information. 9# 10# ==================================================================== 11# Licensed to the Apache Software Foundation (ASF) under one 12# or more contributor license agreements. See the NOTICE file 13# distributed with this work for additional information 14# regarding copyright ownership. The ASF licenses this file 15# to you under the Apache License, Version 2.0 (the 16# "License"); you may not use this file except in compliance 17# with the License. You may obtain a copy of the License at 18# 19# http://www.apache.org/licenses/LICENSE-2.0 20# 21# Unless required by applicable law or agreed to in writing, 22# software distributed under the License is distributed on an 23# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 24# KIND, either express or implied. See the License for the 25# specific language governing permissions and limitations 26# under the License. 27###################################################################### 28 29# General modules 30import os 31import re 32 33# Our testing module 34import svntest 35from svntest import wc 36 37# (abbreviation) 38Skip = svntest.testcase.Skip_deco 39SkipUnless = svntest.testcase.SkipUnless_deco 40XFail = svntest.testcase.XFail_deco 41Issues = svntest.testcase.Issues_deco 42Issue = svntest.testcase.Issue_deco 43Wimp = svntest.testcase.Wimp_deco 44Item = wc.StateItem 45 46# For errors setting up the depthy working copies. 47class DepthSetupError(Exception): 48 def __init__ (self, args=None): 49 self.args = args 50 51def set_up_depthy_working_copies(sbox, empty=False, files=False, 52 immediates=False, infinity=False): 53 """Set up up to four working copies, at various depths. At least 54 one of depths EMPTY, FILES, IMMEDIATES, or INFINITY must be passed 55 as True. The corresponding working copy paths are returned in a 56 four-element tuple in that order, with element value of None for 57 working copies that were not created. If all args are False, raise 58 DepthSetupError.""" 59 60 if not (infinity or empty or files or immediates): 61 raise DepthSetupError("At least one working copy depth must be passed.") 62 63 wc = None 64 if infinity: 65 sbox.build() 66 wc = sbox.wc_dir 67 else: 68 sbox.build(create_wc = False) 69 sbox.add_test_path(sbox.wc_dir, True) 70 71 wc_empty = None 72 if empty: 73 wc_empty = sbox.wc_dir + '-depth-empty' 74 sbox.add_test_path(wc_empty, True) 75 svntest.actions.run_and_verify_svn( 76 svntest.verify.AnyOutput, [], 77 "co", "--depth", "empty", sbox.repo_url, wc_empty) 78 79 wc_files = None 80 if files: 81 wc_files = sbox.wc_dir + '-depth-files' 82 sbox.add_test_path(wc_files, True) 83 svntest.actions.run_and_verify_svn( 84 svntest.verify.AnyOutput, [], 85 "co", "--depth", "files", sbox.repo_url, wc_files) 86 87 wc_immediates = None 88 if immediates: 89 wc_immediates = sbox.wc_dir + '-depth-immediates' 90 sbox.add_test_path(wc_immediates, True) 91 svntest.actions.run_and_verify_svn( 92 svntest.verify.AnyOutput, [], 93 "co", "--depth", "immediates", 94 sbox.repo_url, wc_immediates) 95 96 return wc_empty, wc_files, wc_immediates, wc 97 98def verify_depth(msg, depth, path="."): 99 """Verifies that PATH has depth DEPTH. MSG is the failure message.""" 100 if depth == "infinity": 101 # Check for absence of depth line. 102 exit_code, out, err = svntest.actions.run_and_verify_svn(None, 103 [], "info", path) 104 for line in out: 105 if line.startswith("Depth:"): 106 raise svntest.Failure(msg) 107 else: 108 expected_stdout = svntest.verify.ExpectedOutput("Depth: %s\n" % depth, 109 match_all=False) 110 svntest.actions.run_and_verify_svn( 111 expected_stdout, [], "info", path) 112 113#---------------------------------------------------------------------- 114# Ensure that 'checkout --depth=empty' results in a depth-empty working copy. 115def depth_empty_checkout(sbox): 116 "depth-empty checkout" 117 118 wc_empty, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True) 119 120 if os.path.exists(os.path.join(wc_empty, "iota")): 121 raise svntest.Failure("depth-empty checkout created file 'iota'") 122 123 if os.path.exists(os.path.join(wc_empty, "A")): 124 raise svntest.Failure("depth-empty checkout created subdir 'A'") 125 126 verify_depth("Expected depth empty for top of WC, got some other depth", 127 "empty", wc_empty) 128 129 130# Helper for two test functions. 131def depth_files_same_as_nonrecursive(sbox, opt): 132 """Run a depth-files or non-recursive checkout, depending on whether 133 passed '-N' or '--depth=files' for OPT. The two should get the same 134 result, hence this helper containing the common code between the 135 two tests.""" 136 137 # This duplicates some code from set_up_depthy_working_copies(), but 138 # that's because it's abstracting out a different axis. 139 140 sbox.build(create_wc = False, read_only = True) 141 if os.path.exists(sbox.wc_dir): 142 svntest.main.safe_rmtree(sbox.wc_dir) 143 144 svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], 145 "co", opt, sbox.repo_url, sbox.wc_dir) 146 147 # Should create a depth-files top directory, so both iota and A 148 # should exist, and A should be empty and depth-empty. 149 150 if not os.path.exists(sbox.ospath('iota')): 151 raise svntest.Failure("'checkout %s' failed to create file 'iota'" % opt) 152 153 if os.path.exists(sbox.ospath('A')): 154 raise svntest.Failure("'checkout %s' unexpectedly created subdir 'A'" % opt) 155 156 verify_depth("Expected depth files for top of WC, got some other depth", 157 "files", sbox.wc_dir) 158 159 160def depth_files_checkout(sbox): 161 "depth-files checkout" 162 depth_files_same_as_nonrecursive(sbox, "--depth=files") 163 164 165def nonrecursive_checkout(sbox): 166 "non-recursive checkout equals depth-files" 167 depth_files_same_as_nonrecursive(sbox, "-N") 168 169 170#---------------------------------------------------------------------- 171def depth_empty_update_bypass_single_file(sbox): 172 "update depth-empty wc shouldn't receive file mod" 173 174 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True, 175 infinity=True) 176 177 iota_path = os.path.join(wc, 'iota') 178 svntest.main.file_append(iota_path, "new text\n") 179 180 # Commit in the "other" wc. 181 expected_output = svntest.wc.State(wc, { 'iota' : Item(verb='Sending'), }) 182 expected_status = svntest.actions.get_virginal_state(wc, 1) 183 expected_status.tweak('iota', wc_rev=2, status=' ') 184 svntest.actions.run_and_verify_commit(wc, 185 expected_output, 186 expected_status) 187 188 # Update the depth-empty wc, expecting not to receive the change to iota. 189 expected_output = svntest.wc.State(wc_empty, { }) 190 expected_disk = svntest.wc.State('', { }) 191 expected_status = svntest.wc.State(wc_empty, { '' : svntest.wc.StateItem() }) 192 expected_status.tweak(contents=None, status=' ', wc_rev=2) 193 svntest.actions.run_and_verify_update(wc_empty, 194 expected_output, 195 expected_disk, 196 expected_status) 197 198 # And the wc should still be depth-empty. 199 verify_depth(None, "empty", wc_empty) 200 201 # Even if we explicitly ask for a depth-infinity update, we still shouldn't 202 # get the change to iota. 203 svntest.actions.run_and_verify_update(wc_empty, 204 expected_output, 205 expected_disk, 206 expected_status, 207 [], False, 208 "--depth=infinity", wc_empty) 209 210 # And the wc should still be depth-empty. 211 verify_depth(None, "empty", wc_empty) 212 213 214#---------------------------------------------------------------------- 215def depth_immediates_get_top_file_mod_only(sbox): 216 "update depth-immediates wc gets top file mod only" 217 218 ign_a, ign_b, wc_immediates, wc \ 219 = set_up_depthy_working_copies(sbox, immediates=True, infinity=True) 220 221 iota_path = os.path.join(wc, 'iota') 222 svntest.main.file_append(iota_path, "new text in iota\n") 223 mu_path = os.path.join(wc, 'A', 'mu') 224 svntest.main.file_append(mu_path, "new text in mu\n") 225 226 # Commit in the "other" wc. 227 expected_output = svntest.wc.State(wc, 228 { 'iota' : Item(verb='Sending'), 229 'A/mu' : Item(verb='Sending'), 230 }) 231 expected_status = svntest.actions.get_virginal_state(wc, 1) 232 expected_status.tweak('iota', wc_rev=2, status=' ') 233 expected_status.tweak('A/mu', wc_rev=2, status=' ') 234 svntest.actions.run_and_verify_commit(wc, 235 expected_output, 236 expected_status) 237 238 # Update the depth-immediates wc, expecting to receive only the 239 # change to iota. 240 expected_output = svntest.wc.State(wc_immediates, 241 { 'iota' : Item(status='U ') }) 242 expected_disk = svntest.wc.State('', { }) 243 expected_disk.add(\ 244 {'iota' : Item(contents="This is the file 'iota'.\nnew text in iota\n"), 245 'A' : Item(contents=None) } ) 246 expected_status = svntest.wc.State(wc_immediates, 247 { '' : svntest.wc.StateItem() }) 248 expected_status.tweak(contents=None, status=' ', wc_rev=2) 249 expected_status.add(\ 250 {'iota' : Item(status=' ', wc_rev=2), 251 'A' : Item(status=' ', wc_rev=2) } ) 252 svntest.actions.run_and_verify_update(wc_immediates, 253 expected_output, 254 expected_disk, 255 expected_status) 256 verify_depth(None, "immediates", wc_immediates) 257 258 259#---------------------------------------------------------------------- 260def depth_empty_commit(sbox): 261 "commit a file from a depth-empty working copy" 262 # Bring iota into a depth-empty working copy, then commit a change to it. 263 wc_empty, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, 264 empty=True) 265 266 # Form the working path of iota 267 wc_empty_iota = os.path.join(wc_empty, 'iota') 268 269 # Update 'iota' in the depth-empty working copy and modify it 270 svntest.actions.run_and_verify_svn(None, [], 271 'up', wc_empty_iota) 272 svntest.main.file_write(wc_empty_iota, "iota modified") 273 274 # Commit the modified changes from a depth-empty working copy 275 expected_output = svntest.wc.State(wc_empty, { 276 'iota' : Item(verb='Sending'), 277 }) 278 expected_status = svntest.wc.State(wc_empty, { }) 279 expected_status.add({ 280 '' : Item(status=' ', wc_rev=1), 281 'iota' : Item(status=' ', wc_rev=2), 282 }) 283 svntest.actions.run_and_verify_commit(wc_empty, 284 expected_output, 285 expected_status) 286 287#---------------------------------------------------------------------- 288def depth_empty_with_file(sbox): 289 "act on a file in a depth-empty working copy" 290 # Run 'svn up iota' to bring iota permanently into the working copy. 291 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True, 292 infinity=True) 293 294 iota_path = os.path.join(wc_empty, 'iota') 295 if os.path.exists(iota_path): 296 raise svntest.Failure("'%s' exists when it shouldn't" % iota_path) 297 298 ### I'd love to do this using the recommended {expected_output, 299 ### expected_status, expected_disk} method here, but after twenty 300 ### minutes of trying to figure out how, I decided to compromise. 301 302 # Update iota by name, expecting to receive it. 303 svntest.actions.run_and_verify_svn(None, [], 'up', iota_path) 304 305 # Test that we did receive it. 306 if not os.path.exists(iota_path): 307 raise svntest.Failure("'%s' doesn't exist when it should" % iota_path) 308 309 # Commit a change to iota in the "other" wc. 310 other_iota_path = os.path.join(wc, 'iota') 311 svntest.main.file_append(other_iota_path, "new text\n") 312 expected_output = svntest.wc.State(wc, { 'iota' : Item(verb='Sending'), }) 313 expected_status = svntest.actions.get_virginal_state(wc, 1) 314 expected_status.tweak('iota', wc_rev=2, status=' ') 315 svntest.actions.run_and_verify_commit(wc, 316 expected_output, 317 expected_status) 318 319 # Delete iota in the "other" wc. 320 other_iota_path = os.path.join(wc, 'iota') 321 svntest.actions.run_and_verify_svn(None, [], 'rm', other_iota_path) 322 expected_output = svntest.wc.State(wc, { 'iota' : Item(verb='Deleting'), }) 323 expected_status = svntest.actions.get_virginal_state(wc, 1) 324 expected_status.remove('iota') 325 svntest.actions.run_and_verify_commit(wc, 326 expected_output, 327 expected_status) 328 329 # Update the depth-empty wc just a little, expecting to receive 330 # the change in iota. 331 expected_output = svntest.wc.State(\ 332 wc_empty, { 'iota' : Item(status='U ') }) 333 expected_disk = svntest.wc.State(\ 334 '', { 'iota' : Item(contents="This is the file 'iota'.\nnew text\n") }) 335 expected_status = svntest.wc.State(wc_empty, 336 { '' : Item(status=' ', wc_rev=2), 337 'iota' : Item(status=' ', wc_rev=2),}) 338 svntest.actions.run_and_verify_update(wc_empty, 339 expected_output, 340 expected_disk, 341 expected_status, 342 [], False, 343 '-r2', wc_empty) 344 345 # Update the depth-empty wc all the way, expecting to receive the deletion 346 # of iota. 347 expected_output = svntest.wc.State(\ 348 wc_empty, { 'iota' : Item(status='D ') }) 349 expected_disk = svntest.wc.State('', { }) 350 expected_status = svntest.wc.State(\ 351 wc_empty, { '' : Item(status=' ', wc_rev=3) }) 352 svntest.actions.run_and_verify_update(wc_empty, 353 expected_output, 354 expected_disk, 355 expected_status) 356 357 358#---------------------------------------------------------------------- 359def depth_empty_with_dir(sbox): 360 "bring a dir into a depth-empty working copy" 361 # Run 'svn up A' to bring A permanently into the working copy. 362 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True, 363 infinity=True) 364 365 A_path = os.path.join(wc_empty, 'A') 366 other_mu_path = os.path.join(wc, 'A', 'mu') 367 368 # We expect A to be added at depth infinity, so a normal 'svn up A' 369 # should be sufficient to add all descendants. 370 expected_output = svntest.wc.State(wc_empty, { 371 'A' : Item(status='A '), 372 'A/mu' : Item(status='A '), 373 'A/B' : Item(status='A '), 374 'A/B/lambda' : Item(status='A '), 375 'A/B/E' : Item(status='A '), 376 'A/B/E/alpha' : Item(status='A '), 377 'A/B/E/beta' : Item(status='A '), 378 'A/B/F' : Item(status='A '), 379 'A/C' : Item(status='A '), 380 'A/D' : Item(status='A '), 381 'A/D/gamma' : Item(status='A '), 382 'A/D/G' : Item(status='A '), 383 'A/D/G/pi' : Item(status='A '), 384 'A/D/G/rho' : Item(status='A '), 385 'A/D/G/tau' : Item(status='A '), 386 'A/D/H' : Item(status='A '), 387 'A/D/H/chi' : Item(status='A '), 388 'A/D/H/psi' : Item(status='A '), 389 'A/D/H/omega' : Item(status='A ') 390 }) 391 expected_disk = svntest.main.greek_state.copy() 392 expected_disk.remove('iota') 393 expected_status = svntest.actions.get_virginal_state(wc_empty, 1) 394 expected_status.remove('iota') 395 svntest.actions.run_and_verify_update(wc_empty, 396 expected_output, 397 expected_disk, 398 expected_status, 399 [], False, 400 A_path) 401 402 # Commit a change to A/mu in the "other" wc. 403 svntest.main.file_write(other_mu_path, "new text\n") 404 expected_output = svntest.wc.State(\ 405 wc, { 'A/mu' : Item(verb='Sending'), }) 406 expected_status = svntest.actions.get_virginal_state(wc, 1) 407 expected_status.tweak('A/mu', wc_rev=2, status=' ') 408 svntest.actions.run_and_verify_commit(wc, 409 expected_output, 410 expected_status) 411 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 [], False, 425 A_path) 426 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, [], '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 437 438 # Update "A" by name in wc_empty, expect to A/mu to disappear. 439 expected_output = svntest.wc.State(wc_empty, { 'A/mu' : Item(status='D ') }) 440 expected_disk = svntest.main.greek_state.copy() 441 expected_disk.remove('iota') 442 expected_disk.remove('A/mu') 443 expected_status = svntest.actions.get_virginal_state(wc_empty, 3) 444 expected_status.remove('iota') 445 expected_status.remove('A/mu') 446 expected_status.tweak('', wc_rev=1) 447 svntest.actions.run_and_verify_update(wc_empty, 448 expected_output, 449 expected_disk, 450 expected_status, 451 [], False, 452 A_path) 453 454 455 456#---------------------------------------------------------------------- 457def depth_immediates_bring_in_file(sbox): 458 "bring a file into a depth-immediates working copy" 459 460 # Create an immediates working copy and form the paths 461 ign_a, ign_b, wc_imm, wc = set_up_depthy_working_copies(sbox, 462 immediates=True) 463 A_mu_path = os.path.join(wc_imm, 'A', 'mu') 464 gamma_path = os.path.join(wc_imm, 'A', 'D', 'gamma') 465 466 # Run 'svn up A/mu' to bring A/mu permanently into the working copy. 467 expected_output = svntest.wc.State(wc_imm, { 468 'A/mu' : Item(status='A '), 469 }) 470 expected_disk = svntest.main.greek_state.copy() 471 expected_disk.remove('A/C', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha', 472 'A/B/E/beta', 'A/B/F', 'A/B', 'A/D/gamma', 'A/D/G', 473 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 'A/D/H/chi', 474 'A/D/H/psi', 'A/D/H/omega', 'A/D/H', 'A/D') 475 expected_status = svntest.actions.get_virginal_state(wc_imm, 1) 476 expected_status.remove('A/C', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha', 477 'A/B/E/beta', 'A/B/F', 'A/B', 'A/D/gamma', 'A/D/G', 478 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 'A/D/H/chi', 479 'A/D/H/psi', 'A/D/H/omega', 'A/D/H', 'A/D') 480 svntest.actions.run_and_verify_update(wc_imm, 481 expected_output, 482 expected_disk, 483 expected_status, 484 [], False, 485 A_mu_path) 486 487 # Run 'svn up A/D/gamma' to test the edge case 'Skipped'. 488 svntest.actions.run_and_verify_svn(["Skipped '"+gamma_path+"'\n", ], 489 "svn: E155007: ", 'update', gamma_path) 490 svntest.actions.run_and_verify_status(wc_imm, expected_status) 491 492#---------------------------------------------------------------------- 493def depth_immediates_fill_in_dir(sbox): 494 "bring a dir into a depth-immediates working copy" 495 496 # Run 'svn up A --set-depth=infinity' to fill in A as a 497 # depth-infinity subdir. 498 ign_a, ign_b, wc_immediates, wc \ 499 = set_up_depthy_working_copies(sbox, immediates=True) 500 A_path = os.path.join(wc_immediates, 'A') 501 expected_output = svntest.wc.State(wc_immediates, { 502 'A/mu' : Item(status='A '), 503 'A/B' : Item(status='A '), 504 'A/B/lambda' : Item(status='A '), 505 'A/B/E' : Item(status='A '), 506 'A/B/E/alpha' : Item(status='A '), 507 'A/B/E/beta' : Item(status='A '), 508 'A/B/F' : Item(status='A '), 509 'A/C' : Item(status='A '), 510 'A/D' : Item(status='A '), 511 'A/D/gamma' : Item(status='A '), 512 'A/D/G' : Item(status='A '), 513 'A/D/G/pi' : Item(status='A '), 514 'A/D/G/rho' : Item(status='A '), 515 'A/D/G/tau' : Item(status='A '), 516 'A/D/H' : Item(status='A '), 517 'A/D/H/chi' : Item(status='A '), 518 'A/D/H/psi' : Item(status='A '), 519 'A/D/H/omega' : Item(status='A ') 520 }) 521 expected_disk = svntest.main.greek_state.copy() 522 expected_status = svntest.actions.get_virginal_state(wc_immediates, 1) 523 svntest.actions.run_and_verify_update(wc_immediates, 524 expected_output, 525 expected_disk, 526 expected_status, 527 [], False, 528 '--set-depth', 'infinity', 529 A_path) 530 531#---------------------------------------------------------------------- 532def depth_mixed_bring_in_dir(sbox): 533 "bring a dir into a mixed-depth working copy" 534 535 # Run 'svn up --set-depth=immediates A' in a depth-empty working copy. 536 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True) 537 A_path = os.path.join(wc_empty, 'A') 538 B_path = os.path.join(wc_empty, 'A', 'B') 539 C_path = os.path.join(wc_empty, 'A', 'C') 540 541 expected_output = svntest.wc.State(wc_empty, { 542 'A' : Item(status='A '), 543 'A/mu' : Item(status='A '), 544 }) 545 expected_disk = svntest.main.greek_state.copy() 546 expected_disk.remove('iota', 'A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha', 547 'A/B/E/beta', 'A/B/F', 'A/C', 'A/D', 'A/D/gamma', 548 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 549 'A/D/H', 'A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega') 550 expected_status = svntest.actions.get_virginal_state(wc_empty, 1) 551 expected_status.remove('iota', 'A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha', 552 'A/B/E/beta', 'A/B/F', 'A/C', 'A/D', 'A/D/gamma', 553 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 554 'A/D/H', 'A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega') 555 svntest.actions.run_and_verify_update(wc_empty, 556 expected_output, 557 expected_disk, 558 expected_status, 559 [], False, 560 '--set-depth', 'files', 561 A_path) 562 # Check that A was added at depth=files. 563 verify_depth(None, "files", A_path) 564 565 # Now, bring in A/B at depth-immediates. 566 expected_output = svntest.wc.State(wc_empty, { 567 'A/B' : Item(status='A '), 568 'A/B/lambda' : Item(status='A '), 569 'A/B/E' : Item(status='A '), 570 'A/B/F' : Item(status='A '), 571 }) 572 expected_disk = svntest.main.greek_state.copy() 573 expected_disk.remove('iota', 'A/B/E/alpha', 'A/B/E/beta', 'A/C', 574 'A/D', 'A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 575 'A/D/G/tau', 'A/D/H', 'A/D/H/chi', 'A/D/H/psi', 576 'A/D/H/omega') 577 expected_status = svntest.actions.get_virginal_state(wc_empty, 1) 578 expected_status.remove('iota', 'A/B/E/alpha', 'A/B/E/beta', 'A/C', 579 'A/D', 'A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 580 'A/D/G/tau', 'A/D/H', 'A/D/H/chi', 'A/D/H/psi', 581 'A/D/H/omega') 582 svntest.actions.run_and_verify_update(wc_empty, 583 expected_output, 584 expected_disk, 585 expected_status, 586 [], False, 587 '--set-depth', 'immediates', 588 B_path) 589 # Check that A/B was added at depth=immediates. 590 verify_depth(None, "immediates", B_path) 591 592 # Now, bring in A/C at depth-empty. 593 expected_output = svntest.wc.State(wc_empty, { 594 'A/C' : Item(status='A '), 595 }) 596 expected_disk = svntest.main.greek_state.copy() 597 expected_disk.remove('iota', 'A/B/E/alpha', 'A/B/E/beta', 598 'A/D', 'A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 599 'A/D/G/tau', 'A/D/H', 'A/D/H/chi', 'A/D/H/psi', 600 'A/D/H/omega') 601 expected_status = svntest.actions.get_virginal_state(wc_empty, 1) 602 expected_status.remove('iota', 'A/B/E/alpha', 'A/B/E/beta', 603 'A/D', 'A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 604 'A/D/G/tau', 'A/D/H', 'A/D/H/chi', 'A/D/H/psi', 605 'A/D/H/omega') 606 svntest.actions.run_and_verify_update(wc_empty, 607 expected_output, 608 expected_disk, 609 expected_status, 610 [], False, 611 '--set-depth', 'empty', 612 C_path) 613 # Check that A/C was added at depth=empty. 614 verify_depth(None, "empty", C_path) 615 616#---------------------------------------------------------------------- 617def depth_empty_unreceive_delete(sbox): 618 "depth-empty working copy ignores a deletion" 619 # Check out a depth-empty greek tree to wc1. In wc2, delete iota and 620 # commit. Update wc1; should not receive the delete. 621 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True, 622 infinity=True) 623 624 iota_path = os.path.join(wc, 'iota') 625 626 # Commit in the "other" wc. 627 svntest.actions.run_and_verify_svn(None, [], 'rm', iota_path) 628 expected_output = svntest.wc.State(wc, { 'iota' : Item(verb='Deleting'), }) 629 expected_status = svntest.actions.get_virginal_state(wc, 1) 630 expected_status.remove('iota') 631 svntest.actions.run_and_verify_commit(wc, 632 expected_output, 633 expected_status) 634 635 # Update the depth-empty wc, expecting not to receive the deletion of iota. 636 expected_output = svntest.wc.State(wc_empty, { }) 637 expected_disk = svntest.wc.State('', { }) 638 expected_status = svntest.wc.State(wc_empty, { '' : svntest.wc.StateItem() }) 639 expected_status.tweak(contents=None, status=' ', wc_rev=2) 640 svntest.actions.run_and_verify_update(wc_empty, 641 expected_output, 642 expected_disk, 643 expected_status) 644 645 646#---------------------------------------------------------------------- 647def depth_immediates_unreceive_delete(sbox): 648 "depth-immediates working copy ignores a deletion" 649 # Check out a depth-immediates greek tree to wc1. In wc2, delete 650 # A/mu and commit. Update wc1; should not receive the delete. 651 652 ign_a, ign_b, wc_immed, wc = set_up_depthy_working_copies(sbox, 653 immediates=True, 654 infinity=True) 655 656 mu_path = os.path.join(wc, 'A', 'mu') 657 658 # Commit in the "other" wc. 659 svntest.actions.run_and_verify_svn(None, [], 'rm', mu_path) 660 expected_output = svntest.wc.State(wc, { 'A/mu' : Item(verb='Deleting'), }) 661 expected_status = svntest.actions.get_virginal_state(wc, 1) 662 expected_status.remove('A/mu') 663 svntest.actions.run_and_verify_commit(wc, 664 expected_output, 665 expected_status) 666 667 # Update the depth-immediates wc, expecting not to receive the deletion 668 # of A/mu. 669 expected_output = svntest.wc.State(wc_immed, { }) 670 expected_disk = svntest.wc.State('', { 671 'iota' : Item(contents="This is the file 'iota'.\n"), 672 'A' : Item() 673 }) 674 expected_status = svntest.wc.State(wc_immed, { 675 '' : Item(status=' ', wc_rev=2), 676 'iota' : Item(status=' ', wc_rev=2), 677 'A' : Item(status=' ', wc_rev=2) 678 }) 679 svntest.actions.run_and_verify_update(wc_immed, 680 expected_output, 681 expected_disk, 682 expected_status) 683 684#---------------------------------------------------------------------- 685def depth_immediates_receive_delete(sbox): 686 "depth-immediates working copy receives a deletion" 687 # Check out a depth-immediates greek tree to wc1. In wc2, delete A and 688 # commit. Update wc1 should receive the delete. 689 690 ign_a, ign_b, wc_immed, wc = set_up_depthy_working_copies(sbox, 691 immediates=True, 692 infinity=True) 693 694 A_path = os.path.join(wc, 'A') 695 696 # Commit in the "other" wc. 697 svntest.actions.run_and_verify_svn(None, [], 'rm', A_path) 698 expected_output = svntest.wc.State(wc, { 'A' : Item(verb='Deleting'), }) 699 expected_status = svntest.wc.State(wc, { 700 '' : Item(status=' ', wc_rev=1), 701 'iota' : Item(status=' ', wc_rev=1), 702 }) 703 svntest.actions.run_and_verify_commit(wc, 704 expected_output, 705 expected_status) 706 707 # Update the depth-immediates wc, expecting to receive the deletion of A. 708 expected_output = svntest.wc.State(wc_immed, { 709 'A' : Item(status='D ') 710 }) 711 expected_disk = svntest.wc.State('', { 712 'iota' : Item(contents="This is the file 'iota'.\n"), 713 }) 714 expected_status = svntest.wc.State(wc_immed, { 715 '' : Item(status=' ', wc_rev=2), 716 'iota' : Item(status=' ', wc_rev=2) 717 }) 718 svntest.actions.run_and_verify_update(wc_immed, 719 expected_output, 720 expected_disk, 721 expected_status) 722 723#---------------------------------------------------------------------- 724def depth_immediates_subdir_propset_1(sbox): 725 "depth-immediates commit subdir propset, update" 726 ign_a, ign_b, wc_immediates, ign_c \ 727 = set_up_depthy_working_copies(sbox, immediates=True) 728 729 A_path = os.path.join(wc_immediates, 'A') 730 731 # Set a property on an immediate subdirectory of the working copy. 732 svntest.actions.run_and_verify_svn(None, [], 733 'pset', 'foo', 'bar', 734 A_path) 735 736 # Create expected output tree. 737 expected_output = svntest.wc.State(wc_immediates, { 738 'A' : Item(verb='Sending'), 739 }) 740 741 # Create expected status tree. 742 expected_status = svntest.wc.State(wc_immediates, { 743 '' : Item(status=' ', wc_rev=1), 744 'iota' : Item(status=' ', wc_rev=1), 745 'A' : Item(status=' ', wc_rev=2) 746 }) 747 748 # Commit wc_immediates/A. 749 svntest.actions.run_and_verify_commit(wc_immediates, 750 expected_output, 751 expected_status, 752 [], 753 A_path) 754 755 # Create expected output tree for the update. 756 expected_output = svntest.wc.State(wc_immediates, { }) 757 758 # Create expected disk tree. 759 expected_disk = svntest.wc.State('', { 760 'iota' : Item(contents="This is the file 'iota'.\n"), 761 'A' : Item(contents=None, props={'foo' : 'bar'}), 762 }) 763 764 expected_status.tweak(contents=None, status=' ', wc_rev=2) 765 766 # Update the depth-immediates wc. 767 svntest.actions.run_and_verify_update(wc_immediates, 768 expected_output, 769 expected_disk, 770 expected_status, 771 check_props=True) 772 773#---------------------------------------------------------------------- 774def depth_immediates_subdir_propset_2(sbox): 775 "depth-immediates update receives subdir propset" 776 sbox.build() 777 wc_dir = sbox.wc_dir 778 779 # Make the other working copy. 780 other_wc = sbox.add_wc_path('other') 781 svntest.actions.duplicate_dir(wc_dir, other_wc) 782 783 A_path = sbox.ospath('A') 784 785 # Set a property on an immediate subdirectory of the working copy. 786 svntest.actions.run_and_verify_svn(None, [], 787 'pset', 'foo', 'bar', 788 A_path) 789 # Commit. 790 svntest.actions.run_and_verify_svn(None, [], 791 'commit', '-m', 'logmsg', A_path) 792 793 # Update at depth=immediates in the other wc, expecting to see no errors. 794 svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], 795 'update', '--depth', 'immediates', 796 other_wc) 797 798#---------------------------------------------------------------------- 799def depth_update_to_more_depth(sbox): 800 "gradually update an empty wc to depth=infinity" 801 802 wc_dir, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True) 803 804 os.chdir(wc_dir) 805 806 # Run 'svn up --set-depth=files' in a depth-empty working copy. 807 expected_output = svntest.wc.State('', { 808 'iota' : Item(status='A '), 809 }) 810 expected_status = svntest.wc.State('', { 811 '' : Item(status=' ', wc_rev=1), 812 'iota' : Item(status=' ', wc_rev=1), 813 }) 814 expected_disk = svntest.wc.State('', { 815 'iota' : Item("This is the file 'iota'.\n"), 816 }) 817 svntest.actions.run_and_verify_update('', 818 expected_output, 819 expected_disk, 820 expected_status, 821 [], False, 822 '--set-depth', 'files') 823 verify_depth(None, "files") 824 825 # Run 'svn up --set-depth=immediates' in the now depth-files working copy. 826 expected_output = svntest.wc.State('', { 827 'A' : Item(status='A '), 828 }) 829 expected_status = svntest.wc.State('', { 830 '' : Item(status=' ', wc_rev=1), 831 'iota' : Item(status=' ', wc_rev=1), 832 'A' : Item(status=' ', wc_rev=1), 833 }) 834 expected_disk = svntest.wc.State('', { 835 'iota' : Item("This is the file 'iota'.\n"), 836 'A' : Item(), 837 }) 838 svntest.actions.run_and_verify_update('', 839 expected_output, 840 expected_disk, 841 expected_status, 842 [], False, 843 '--set-depth', 'immediates') 844 verify_depth(None, "immediates") 845 verify_depth(None, "empty", "A") 846 847 # Upgrade 'A' to depth-files. 848 expected_output = svntest.wc.State('', { 849 'A/mu' : Item(status='A '), 850 }) 851 expected_status = svntest.wc.State('', { 852 '' : Item(status=' ', wc_rev=1), 853 'iota' : Item(status=' ', wc_rev=1), 854 'A' : Item(status=' ', wc_rev=1), 855 'A/mu' : Item(status=' ', wc_rev=1), 856 }) 857 expected_disk = svntest.wc.State('', { 858 'iota' : Item("This is the file 'iota'.\n"), 859 'A' : Item(), 860 'A/mu' : Item("This is the file 'mu'.\n"), 861 }) 862 svntest.actions.run_and_verify_update('', 863 expected_output, 864 expected_disk, 865 expected_status, 866 [], False, 867 '--set-depth', 'files', 'A') 868 verify_depth(None, "immediates") 869 verify_depth(None, "files", "A") 870 871 # Run 'svn up --set-depth=infinity' in the working copy. 872 expected_output = svntest.wc.State('', { 873 'A/B' : Item(status='A '), 874 'A/B/lambda' : Item(status='A '), 875 'A/B/E' : Item(status='A '), 876 'A/B/E/alpha' : Item(status='A '), 877 'A/B/E/beta' : Item(status='A '), 878 'A/B/F' : Item(status='A '), 879 'A/C' : Item(status='A '), 880 'A/D' : Item(status='A '), 881 'A/D/gamma' : Item(status='A '), 882 'A/D/G' : Item(status='A '), 883 'A/D/G/pi' : Item(status='A '), 884 'A/D/G/rho' : Item(status='A '), 885 'A/D/G/tau' : Item(status='A '), 886 'A/D/H' : Item(status='A '), 887 'A/D/H/chi' : Item(status='A '), 888 'A/D/H/psi' : Item(status='A '), 889 'A/D/H/omega' : Item(status='A ') 890 }) 891 expected_disk = svntest.main.greek_state.copy() 892 expected_status = svntest.actions.get_virginal_state('', 1) 893 svntest.actions.run_and_verify_update('', 894 expected_output, 895 expected_disk, 896 expected_status, 897 [], False, 898 '--set-depth', 'infinity') 899 verify_depth("Non-infinity depth detected after an upgrade to depth-infinity", 900 "infinity") 901 verify_depth("Non-infinity depth detected after an upgrade to depth-infinity", 902 "infinity", "A") 903 904def commit_propmods_with_depth_empty_helper(sbox, depth_arg): 905 """Helper for commit_propmods_with_depth_empty(). 906 DEPTH_ARG should be either '--depth=empty' or '-N'.""" 907 908 sbox.build() 909 wc_dir = sbox.wc_dir 910 911 iota_path = sbox.ospath('iota') 912 A_path = sbox.ospath('A') 913 D_path = os.path.join(A_path, 'D') 914 gamma_path = os.path.join(D_path, 'gamma') 915 G_path = os.path.join(D_path, 'G') 916 pi_path = os.path.join(G_path, 'pi') 917 H_path = os.path.join(D_path, 'H') 918 chi_path = os.path.join(H_path, 'chi') 919 920 # Set some properties, modify some files. 921 svntest.actions.run_and_verify_svn(None, [], 922 'propset', 'foo', 'foo-val', wc_dir) 923 svntest.actions.run_and_verify_svn(None, [], 924 'propset', 'bar', 'bar-val', D_path) 925 svntest.actions.run_and_verify_svn(None, [], 926 'propset', 'baz', 'baz-val', G_path) 927 svntest.actions.run_and_verify_svn(None, [], 928 'propset', 'qux', 'qux-val', H_path) 929 svntest.main.file_append(iota_path, "new iota\n") 930 svntest.main.file_append(gamma_path, "new gamma\n") 931 svntest.main.file_append(pi_path, "new pi\n") 932 svntest.main.file_append(chi_path, "new chi\n") 933 934 # The only things that should be committed are two of the propsets. 935 expected_output = svntest.wc.State( 936 wc_dir, 937 { '' : Item(verb='Sending'), 938 'A/D' : Item(verb='Sending'), } 939 ) 940 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 941 # Expect the two propsets to be committed: 942 expected_status.tweak('', status=' ', wc_rev=2) 943 expected_status.tweak('A/D', status=' ', wc_rev=2) 944 # Expect every other change to remain uncommitted: 945 expected_status.tweak('iota', status='M ', wc_rev=1) 946 expected_status.tweak('A/D/G', status=' M', wc_rev=1) 947 expected_status.tweak('A/D/H', status=' M', wc_rev=1) 948 expected_status.tweak('A/D/gamma', status='M ', wc_rev=1) 949 expected_status.tweak('A/D/G/pi', status='M ', wc_rev=1) 950 expected_status.tweak('A/D/H/chi', status='M ', wc_rev=1) 951 952 svntest.actions.run_and_verify_commit(wc_dir, 953 expected_output, 954 expected_status, 955 [], 956 depth_arg, 957 wc_dir, D_path) 958 959# See also commit_tests 26: commit_nonrecursive 960def commit_propmods_with_depth_empty(sbox): 961 "commit property mods only, using --depth=empty" 962 963 sbox2 = sbox.clone_dependent() 964 965 # Run once with '-N' and once with '--depth=empty' to make sure they 966 # function identically. 967 commit_propmods_with_depth_empty_helper(sbox, '-N') 968 commit_propmods_with_depth_empty_helper(sbox2, '--depth=empty') 969 970# Test for issue #2845. 971@Issue(2845) 972def diff_in_depthy_wc(sbox): 973 "diff at various depths in non-infinity wc" 974 975 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True, 976 infinity=True) 977 978 iota_path = os.path.join(wc, 'iota') 979 A_path = os.path.join(wc, 'A') 980 mu_path = os.path.join(wc, 'A', 'mu') 981 gamma_path = os.path.join(wc, 'A', 'D', 'gamma') 982 983 # Make some changes in the depth-infinity wc, and commit them 984 svntest.actions.run_and_verify_svn(None, [], 985 'propset', 'foo', 'foo-val', wc) 986 svntest.main.file_write(iota_path, "new text\n") 987 svntest.actions.run_and_verify_svn(None, [], 988 'propset', 'bar', 'bar-val', A_path) 989 svntest.main.file_write(mu_path, "new text\n") 990 svntest.main.file_write(gamma_path, "new text\n") 991 svntest.actions.run_and_verify_svn(None, [], 992 'commit', '-m', '', wc) 993 994 from svntest.verify import make_diff_header, make_diff_prop_header, \ 995 make_diff_prop_deleted, make_diff_prop_added 996 diff_mu = make_diff_header('A/mu', 'revision 2', 'working copy') + [ 997 "@@ -1 +1 @@\n", 998 "-new text\n", 999 "+This is the file 'mu'.\n"] 1000 diff_A = make_diff_header('A', 'revision 2', 'working copy') + \ 1001 make_diff_prop_header('A') + \ 1002 make_diff_prop_deleted('bar', 'bar-val') 1003 diff_iota = make_diff_header('iota', 'revision 2', 'working copy') + [ 1004 "@@ -1 +1 @@\n", 1005 "-new text\n", 1006 "+This is the file 'iota'.\n"] 1007 diff_dot = make_diff_header('.', 'revision 2', 'working copy') + \ 1008 make_diff_prop_header('.') + \ 1009 make_diff_prop_deleted('foo', 'foo-val') 1010 1011 os.chdir(wc_empty) 1012 1013 expected_output = svntest.verify.UnorderedOutput(diff_dot) 1014 # The diff should contain only the propchange on '.' 1015 svntest.actions.run_and_verify_svn(expected_output, [], 1016 'diff', '-rHEAD') 1017 1018 # Upgrade to depth-files. 1019 svntest.actions.run_and_verify_svn(None, [], 'up', 1020 '--set-depth', 'files', '-r1') 1021 # The diff should contain only the propchange on '.' and the 1022 # contents change on iota. 1023 expected_output = svntest.verify.UnorderedOutput(diff_iota + diff_dot) 1024 svntest.actions.run_and_verify_svn(expected_output, [], 1025 'diff', '-rHEAD') 1026 # Do a diff at --depth empty. 1027 expected_output = svntest.verify.UnorderedOutput(diff_dot) 1028 svntest.actions.run_and_verify_svn(expected_output, [], 1029 'diff', '--depth', 'empty', '-rHEAD') 1030 1031 # Upgrade to depth-immediates. 1032 svntest.actions.run_and_verify_svn(None, [], 'up', 1033 '--set-depth', 'immediates', '-r1') 1034 # The diff should contain the propchanges on '.' and 'A' and the 1035 # contents change on iota. 1036 expected_output = svntest.verify.UnorderedOutput(diff_A + diff_iota + 1037 diff_dot) 1038 svntest.actions.run_and_verify_svn(expected_output, [], 1039 'diff', '-rHEAD') 1040 # Do a diff at --depth files. 1041 expected_output = svntest.verify.UnorderedOutput(diff_iota + diff_dot) 1042 svntest.actions.run_and_verify_svn(expected_output, [], 1043 'diff', '--depth', 'files', '-rHEAD') 1044 1045 # Upgrade A to depth-files. 1046 svntest.actions.run_and_verify_svn(None, [], 'up', 1047 '--set-depth', 'files', '-r1', 'A') 1048 # The diff should contain everything but the contents change on 1049 # gamma (which does not exist in this working copy). 1050 expected_output = svntest.verify.UnorderedOutput(diff_mu + diff_A + 1051 diff_iota + diff_dot) 1052 svntest.actions.run_and_verify_svn(expected_output, [], 1053 'diff', '-rHEAD') 1054 # Do a diff at --depth immediates. 1055 expected_output = svntest.verify.UnorderedOutput(diff_A + diff_iota + diff_dot) 1056 svntest.actions.run_and_verify_svn(expected_output, [], 1057 'diff', '--depth', 'immediates', '-rHEAD') 1058 1059@Issue(2882) 1060def commit_depth_immediates(sbox): 1061 "commit some files with --depth=immediates" 1062 sbox.build() 1063 wc_dir = sbox.wc_dir 1064 1065 # Test the fix for some bugs Mike Pilato reported here: 1066 # 1067 # http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=128509 1068 # From: "C. Michael Pilato" <cmpilato@collab.net> 1069 # To: Karl Fogel <kfogel@red-bean.com> 1070 # CC: dev@subversion.tigris.org 1071 # References: <87d4yzcrro.fsf@red-bean.com> 1072 # Subject: Re: [PATCH] Make 'svn commit --depth=foo' work. 1073 # Message-ID: <46968831.2070906@collab.net> 1074 # Date: Thu, 12 Jul 2007 15:59:45 -0400 1075 # 1076 # See also https://issues.apache.org/jira/browse/SVN-2882. 1077 # 1078 # Outline of the test: 1079 # ==================== 1080 # 1081 # Modify these three files: 1082 # 1083 # M A/mu 1084 # M A/D/G/rho 1085 # M iota 1086 # 1087 # Then commit some of them using --depth=immediates: 1088 # 1089 # svn ci -m "log msg" --depth=immediates wc_dir wc_dir/A/D/G/rho 1090 # 1091 # Before the bugfix, that would result in an error: 1092 # 1093 # subversion/libsvn_wc/lock.c:570: (apr_err=155004) 1094 # svn: Working copy '/blah/blah/blah/wc' locked 1095 # svn: run 'svn cleanup' to remove locks \ 1096 # (type 'svn help cleanup' for details) 1097 # 1098 # After the bugfix, it correctly commits two of the three files: 1099 # 1100 # Sending A/D/G/rho 1101 # Sending iota 1102 # Transmitting file data .. 1103 # Committing transaction... 1104 # Committed revision 2. 1105 1106 iota_path = sbox.ospath('iota') 1107 mu_path = sbox.ospath('A/mu') 1108 G_path = sbox.ospath('A/D/G') 1109 rho_path = os.path.join(G_path, 'rho') 1110 1111 svntest.main.file_append(iota_path, "new text in iota\n") 1112 svntest.main.file_append(mu_path, "new text in mu\n") 1113 svntest.main.file_append(rho_path, "new text in rho\n") 1114 1115 expected_output = svntest.wc.State(wc_dir, { 1116 'iota' : Item(verb='Sending'), 1117 'A/D/G/rho' : Item(verb='Sending'), 1118 }) 1119 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 1120 expected_status.tweak('iota', status=' ', wc_rev=2) 1121 expected_status.tweak('A/mu', status='M ', wc_rev=1) 1122 expected_status.tweak('A/D/G/rho', status=' ', wc_rev=2) 1123 svntest.actions.run_and_verify_commit(wc_dir, 1124 expected_output, 1125 expected_status, 1126 [], 1127 '--depth', 'immediates', 1128 wc_dir, G_path) 1129 1130def depth_immediates_receive_new_dir(sbox): 1131 "depth-immediates wc receives new directory" 1132 1133 ign_a, ign_b, wc_immed, wc = set_up_depthy_working_copies(sbox, 1134 immediates=True, 1135 infinity=True) 1136 1137 I_path = os.path.join(wc, 'I') 1138 zeta_path = os.path.join(wc, 'I', 'zeta') 1139 other_I_path = os.path.join(wc_immed, 'I') 1140 1141 os.mkdir(I_path) 1142 svntest.main.file_write(zeta_path, "This is the file 'zeta'.\n") 1143 1144 # Commit in the "other" wc. 1145 svntest.actions.run_and_verify_svn(None, [], 'add', I_path) 1146 expected_output = svntest.wc.State(wc, { 1147 'I' : Item(verb='Adding'), 1148 'I/zeta' : Item(verb='Adding'), 1149 }) 1150 expected_status = svntest.actions.get_virginal_state(wc, 1) 1151 expected_status.add({ 1152 'I' : Item(status=' ', wc_rev=2), 1153 'I/zeta' : Item(status=' ', wc_rev=2), 1154 }) 1155 svntest.actions.run_and_verify_commit(wc, 1156 expected_output, 1157 expected_status) 1158 1159 # Update the depth-immediates wc, expecting to receive just the 1160 # new directory, without the file. 1161 expected_output = svntest.wc.State(wc_immed, { 1162 'I' : Item(status='A '), 1163 }) 1164 expected_disk = svntest.wc.State('', { 1165 'iota' : Item(contents="This is the file 'iota'.\n"), 1166 'A' : Item(), 1167 'I' : Item(), 1168 }) 1169 expected_status = svntest.wc.State(wc_immed, { 1170 '' : Item(status=' ', wc_rev=2), 1171 'iota' : Item(status=' ', wc_rev=2), 1172 'A' : Item(status=' ', wc_rev=2), 1173 'I' : Item(status=' ', wc_rev=2), 1174 }) 1175 svntest.actions.run_and_verify_update(wc_immed, 1176 expected_output, 1177 expected_disk, 1178 expected_status) 1179 # Check that the new directory was added at depth=empty. 1180 verify_depth(None, "empty", other_I_path) 1181 1182@Issue(2931) 1183def add_tree_with_depth(sbox): 1184 "add multi-subdir tree with --depth options" # For issue #2931 1185 sbox.build() 1186 wc_dir = sbox.wc_dir 1187 new1_path = sbox.ospath('new1') 1188 new2_path = os.path.join(new1_path, 'new2') 1189 new3_path = os.path.join(new2_path, 'new3') 1190 new4_path = os.path.join(new3_path, 'new4') 1191 os.mkdir(new1_path) 1192 os.mkdir(new2_path) 1193 os.mkdir(new3_path) 1194 os.mkdir(new4_path) 1195 # Simple case, add new1 only, set depth to files 1196 svntest.actions.run_and_verify_svn(None, [], 1197 "add", "--depth", "files", new1_path) 1198 verify_depth(None, "infinity", new1_path) 1199 1200 # Force add new1 at new1 again, should include new2 at empty, the depth of 1201 # new1 should not change 1202 svntest.actions.run_and_verify_svn(None, [], 1203 "add", "--depth", "immediates", 1204 "--force", new1_path) 1205 verify_depth(None, "infinity", new1_path) 1206 verify_depth(None, "infinity", new2_path) 1207 1208 # add new4 with intermediate path, the intermediate path is added at empty 1209 svntest.actions.run_and_verify_svn(None, [], 1210 "add", "--depth", "immediates", 1211 "--parents", new4_path) 1212 verify_depth(None, "infinity", new3_path) 1213 verify_depth(None, "infinity", new4_path) 1214 1215def upgrade_from_above(sbox): 1216 "upgrade a depth=empty wc from above" 1217 1218 # The bug was that 'svn up --set-depth=files' worked from within the 1219 # working copy, but not from without with working copy top given 1220 # as an argument. Both ways would correctly cause 'iota' to 1221 # appear, but only the former actually upgraded the depth of the 1222 # working copy to 'files'. See this thread for details: 1223 # 1224 # http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=130157 1225 # From: Alexander Sinyushkin <Alexander.Sinyushkin@svnkit.com> 1226 # To: dev@subversion.tigris.org 1227 # Subject: Problem upgrading working copy depth 1228 # Date: Wed, 19 Sep 2007 23:15:24 +0700 1229 # Message-ID: <46F14B1C.8010406@svnkit.com> 1230 1231 sbox2 = sbox.clone_dependent() 1232 1233 wc, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True) 1234 1235 # First verify that upgrading from within works. 1236 saved_cwd = os.getcwd() 1237 try: 1238 os.chdir(wc) 1239 expected_output = svntest.wc.State('', { 1240 'iota' : Item(status='A '), 1241 }) 1242 expected_disk = svntest.wc.State('', { 1243 'iota' : Item(contents="This is the file 'iota'.\n"), 1244 }) 1245 expected_status = svntest.wc.State('', { 1246 '' : Item(status=' ', wc_rev=1), 1247 'iota' : Item(status=' ', wc_rev=1), 1248 }) 1249 svntest.actions.run_and_verify_update('', 1250 expected_output, 1251 expected_disk, 1252 expected_status, 1253 [], False, 1254 '--set-depth=files', '.') 1255 verify_depth(None, "files") 1256 finally: 1257 os.chdir(saved_cwd) 1258 1259 # Do it again, this time from above the working copy. 1260 wc, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox2, empty=True) 1261 expected_output = svntest.wc.State(wc, { 1262 'iota' : Item(status='A '), 1263 }) 1264 expected_disk = svntest.wc.State('', { 1265 'iota' : Item(contents="This is the file 'iota'.\n"), 1266 }) 1267 expected_status = svntest.wc.State(wc, { 1268 '' : Item(status=' ', wc_rev=1), 1269 'iota' : Item(status=' ', wc_rev=1), 1270 }) 1271 svntest.actions.run_and_verify_update(wc, 1272 expected_output, 1273 expected_disk, 1274 expected_status, 1275 [], False, 1276 '--set-depth=files', wc) 1277 verify_depth(None, "files", wc) 1278 1279def status_in_depthy_wc(sbox): 1280 "status -u at various depths in non-infinity wc" 1281 1282 wc_empty, ign_a, ign_b, wc = set_up_depthy_working_copies(sbox, empty=True, 1283 infinity=True) 1284 1285 iota_path = os.path.join(wc, 'iota') 1286 A_path = os.path.join(wc, 'A') 1287 mu_path = os.path.join(wc, 'A', 'mu') 1288 gamma_path = os.path.join(wc, 'A', 'D', 'gamma') 1289 1290 # Make some changes in the depth-infinity wc, and commit them 1291 svntest.actions.run_and_verify_svn(None, [], 1292 'propset', 'foo', 'foo-val', wc) 1293 svntest.main.file_write(iota_path, "new text\n") 1294 svntest.actions.run_and_verify_svn(None, [], 1295 'propset', 'bar', 'bar-val', A_path) 1296 svntest.main.file_write(mu_path, "new text\n") 1297 svntest.main.file_write(gamma_path, "new text\n") 1298 svntest.actions.run_and_verify_svn(None, [], 1299 'commit', '-m', '', wc) 1300 1301 status = [ 1302 "Status against revision: 2\n", 1303 " * 1 .\n", 1304 " * 1 iota\n", 1305 " * 1 A\n", 1306 " * 1 " + os.path.join('A', 'mu') + "\n", 1307 ] 1308 1309 os.chdir(wc_empty) 1310 1311 expected_output = svntest.verify.UnorderedOutput(status[:2]) 1312 # The output should contain only the change on '.'. 1313 svntest.actions.run_and_verify_svn(expected_output, [], 1314 'st', '-u') 1315 1316 # Upgrade to depth-files. 1317 svntest.actions.run_and_verify_svn(None, [], 'up', 1318 '--set-depth', 'files', '-r1') 1319 # The output should contain only the changes on '.' and 'iota'. 1320 expected_output = svntest.verify.UnorderedOutput(status[:3]) 1321 svntest.actions.run_and_verify_svn(expected_output, [], 1322 'st', '-u') 1323 # Do a status -u at --depth empty. 1324 expected_output = svntest.verify.UnorderedOutput(status[:2]) 1325 svntest.actions.run_and_verify_svn(expected_output, [], 1326 'st', '-u', '--depth', 'empty') 1327 1328 # Upgrade to depth-immediates. 1329 svntest.actions.run_and_verify_svn(None, [], 'up', 1330 '--set-depth', 'immediates', '-r1') 1331 # The output should contain the changes on '.', 'A' and 'iota'. 1332 expected_output = svntest.verify.UnorderedOutput(status[:4]) 1333 svntest.actions.run_and_verify_svn(expected_output, [], 1334 'st', '-u') 1335 # Do a status -u at --depth files. 1336 expected_output = svntest.verify.UnorderedOutput(status[:3]) 1337 svntest.actions.run_and_verify_svn(expected_output, [], 1338 'st', '-u', '--depth', 'files') 1339 1340 # Upgrade A to depth-files. 1341 svntest.actions.run_and_verify_svn(None, [], 'up', 1342 '--set-depth', 'files', '-r1', 'A') 1343 # The output should contain everything but the change on 1344 # gamma (which does not exist in this working copy). 1345 expected_output = svntest.verify.UnorderedOutput(status) 1346 svntest.actions.run_and_verify_svn(expected_output, [], 1347 'st', '-u') 1348 # Do a status -u at --depth immediates. 1349 expected_output = svntest.verify.UnorderedOutput(status[:4]) 1350 svntest.actions.run_and_verify_svn(expected_output, [], 1351 'st', '-u', '--depth', 'immediates') 1352 1353#---------------------------------------------------------------------- 1354 1355# Issue #3039. 1356@Issue(3039) 1357def depthy_update_above_dir_to_be_deleted(sbox): 1358 "'update -N' above a WC path deleted in repos HEAD" 1359 sbox.build() 1360 1361 sbox_for_depth = { 1362 "files" : sbox, 1363 "immediates" : sbox.clone_dependent(copy_wc=True), 1364 "empty" : sbox.clone_dependent(copy_wc=True), 1365 } 1366 1367 exit_code, output, err = svntest.actions.run_and_verify_svn( 1368 None, [], 1369 "delete", "-m", "Delete A.", sbox.repo_url + "/A") 1370 1371 def empty_output(wc_dir): 1372 return svntest.wc.State(wc_dir, { }) 1373 1374 def output_with_A(wc_dir): 1375 expected_output = empty_output(wc_dir) 1376 expected_output.add({ 1377 "A" : Item(status="D "), 1378 }) 1379 return expected_output 1380 1381 initial_disk = svntest.main.greek_state.copy() 1382 disk_with_only_iota = svntest.wc.State("", { 1383 "iota" : Item("This is the file 'iota'.\n"), 1384 }) 1385 1386 def status_with_dot(wc_dir): 1387 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 1388 expected_status.tweak("", wc_rev=2) 1389 return expected_status 1390 1391 def status_with_iota(wc_dir): 1392 expected_status = status_with_dot(wc_dir) 1393 expected_status.tweak("iota", wc_rev=2) 1394 return expected_status 1395 1396 def status_with_only_iota(wc_dir): 1397 return svntest.wc.State(wc_dir, { 1398 "" : Item(status=" ", wc_rev=2), 1399 "iota" : Item(status=" ", wc_rev=2), 1400 }) 1401 1402 expected_trees_for_depth = { 1403 "files" : (empty_output, initial_disk, status_with_iota), 1404 "immediates" : (output_with_A, disk_with_only_iota, status_with_only_iota), 1405 "empty" : (empty_output, initial_disk, status_with_dot), 1406 } 1407 1408 for depth in sbox_for_depth.keys(): 1409 wc_dir = sbox_for_depth[depth].wc_dir 1410 (expected_output_func, expected_disk, expected_status_func) = \ 1411 expected_trees_for_depth[depth] 1412 #print depth 1413 svntest.actions.run_and_verify_update(wc_dir, 1414 expected_output_func(wc_dir), 1415 expected_disk, 1416 expected_status_func(wc_dir), 1417 [], False, 1418 "--depth=%s" % depth, wc_dir) 1419 1420 1421#---------------------------------------------------------------------- 1422 1423# Tests for deselection interface (a.k.a folding subtrees). 1424#---------------------------------------------------------------------- 1425def depth_folding_clean_trees_1(sbox): 1426 "gradually fold wc from depth=infinity to empty" 1427 1428 # Covers the following situations: 1429 # 1430 # infinity->immediates (metadata only) 1431 # immediates->files (metadata only) 1432 # mixed(infinity+files)=>immediates 1433 # infinity=>empty 1434 # immediates=>empty 1435 # mixed(infinity+empty)=>immediates 1436 # mixed(infinity+empty/immediates)=>immediates 1437 # immediates=>files 1438 # files=>empty 1439 # mixed(infinity+empty)=>files 1440 1441 ign_a, ign_b, ign_c, wc_dir = set_up_depthy_working_copies(sbox, 1442 infinity=True) 1443 1444 A_path = sbox.ospath('A') 1445 C_path = os.path.join(A_path, 'C') 1446 B_path = os.path.join(A_path, 'B') 1447 D_path = os.path.join(A_path, 'D') 1448 E_path = os.path.join(B_path, 'E') 1449 F_path = os.path.join(B_path, 'F') 1450 G_path = os.path.join(D_path, 'G') 1451 H_path = os.path.join(D_path, 'H') 1452 1453 # Run 'svn up --set-depth=immediates' to directory A/B/E. 1454 # This is an infinity=>immediates folding, changes on metadata only 1455 expected_output = svntest.wc.State(wc_dir, {}) 1456 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 1457 expected_disk = svntest.main.greek_state.copy() 1458 svntest.actions.run_and_verify_update(wc_dir, 1459 expected_output, 1460 expected_disk, 1461 expected_status, 1462 [], False, 1463 '--set-depth', 'immediates', E_path) 1464 verify_depth(None, "immediates", E_path) 1465 1466 # Run 'svn up --set-depth=files' to directory A/B/E. 1467 # This is an immediates=>files folding, changes on metadata only 1468 svntest.actions.run_and_verify_update(wc_dir, 1469 expected_output, 1470 expected_disk, 1471 expected_status, 1472 [], False, 1473 '--set-depth', 'files', E_path) 1474 verify_depth(None, "files", E_path) 1475 1476 # Run 'svn up --set-depth=immediates' to directory A/B. 1477 # This is an mixed(infinity+files)=>immediates folding 1478 expected_output = svntest.wc.State(wc_dir, { 1479 'A/B/E/alpha' : Item(status='D '), 1480 'A/B/E/beta' : Item(status='D '), 1481 }) 1482 expected_status.remove('A/B/E/alpha', 'A/B/E/beta') 1483 expected_disk.remove('A/B/E/alpha', 'A/B/E/beta') 1484 svntest.actions.run_and_verify_update(wc_dir, 1485 expected_output, 1486 expected_disk, 1487 expected_status, 1488 [], False, 1489 '--set-depth', 'immediates', B_path) 1490 verify_depth(None, "immediates", B_path) 1491 verify_depth(None, "empty", E_path) 1492 verify_depth(None, "empty", F_path) 1493 1494 # Run 'svn up --set-depth=empty' to directory A/D/H 1495 # This is an infinity=>empty folding. 1496 expected_output = svntest.wc.State(wc_dir, { 1497 'A/D/H/chi' : Item(status='D '), 1498 'A/D/H/psi' : Item(status='D '), 1499 'A/D/H/omega' : Item(status='D ') 1500 }) 1501 expected_status.remove( 'A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega') 1502 expected_disk.remove( 'A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega') 1503 svntest.actions.run_and_verify_update(wc_dir, 1504 expected_output, 1505 expected_disk, 1506 expected_status, 1507 [], False, 1508 '--set-depth', 'empty', H_path) 1509 verify_depth(None, "empty", H_path) 1510 1511 # Run 'svn up --set-depth=immediates' to directory A/D 1512 # This is an mixed(infinity+empty)=>immediates folding. 1513 expected_output = svntest.wc.State(wc_dir, { 1514 'A/D/G/pi' : Item(status='D '), 1515 'A/D/G/rho' : Item(status='D '), 1516 'A/D/G/tau' : Item(status='D '), 1517 }) 1518 expected_status.remove('A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau') 1519 expected_disk.remove('A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau') 1520 svntest.actions.run_and_verify_update(wc_dir, 1521 expected_output, 1522 expected_disk, 1523 expected_status, 1524 [], False, 1525 '--set-depth', 'immediates', D_path) 1526 verify_depth(None, "immediates", D_path) 1527 verify_depth(None, "empty", G_path) 1528 1529 # Run 'svn up --set-depth=empty' to directory A/D 1530 # This is an immediates=>empty folding. 1531 expected_output = svntest.wc.State(wc_dir, { 1532 'A/D/G' : Item(status='D '), 1533 'A/D/H' : Item(status='D '), 1534 'A/D/gamma' : Item(status='D ') 1535 }) 1536 expected_status.remove('A/D/gamma', 'A/D/G', 'A/D/H') 1537 expected_disk.remove('A/D/gamma', 'A/D/G', 'A/D/H') 1538 svntest.actions.run_and_verify_update(wc_dir, 1539 expected_output, 1540 expected_disk, 1541 expected_status, 1542 [], False, 1543 '--set-depth', 'empty', D_path) 1544 verify_depth(None, "empty", D_path) 1545 1546 # Run 'svn up --set-depth=immediates' to directory A 1547 # This is an mixed(infinity+empty/immediates)=>immediates folding. 1548 expected_output = svntest.wc.State(wc_dir, { 1549 'A/B/E' : Item(status='D '), 1550 'A/B/F' : Item(status='D '), 1551 'A/B/lambda' : Item(status='D ') 1552 }) 1553 expected_status.remove('A/B/lambda', 'A/B/E', 'A/B/F') 1554 expected_disk.remove('A/B/lambda', 'A/B/E', 'A/B/F') 1555 svntest.actions.run_and_verify_update(wc_dir, 1556 expected_output, 1557 expected_disk, 1558 expected_status, 1559 [], False, 1560 '--set-depth', 'immediates', A_path) 1561 verify_depth(None, "immediates", A_path) 1562 verify_depth(None, "empty", C_path) 1563 verify_depth(None, "empty", B_path) 1564 1565 # Run 'svn up --set-depth=files' to directory A 1566 # This is an immediates=>files folding. 1567 expected_output = svntest.wc.State(wc_dir, { 1568 'A/B' : Item(status='D '), 1569 'A/C' : Item(status='D '), 1570 'A/D' : Item(status='D ') 1571 }) 1572 expected_status.remove('A/B', 'A/C', 'A/D') 1573 expected_disk.remove('A/B', 'A/C', 'A/D') 1574 svntest.actions.run_and_verify_update(wc_dir, 1575 expected_output, 1576 expected_disk, 1577 expected_status, 1578 [], False, 1579 '--set-depth', 'files', A_path) 1580 verify_depth(None, "files", A_path) 1581 1582 # Run 'svn up --set-depth=empty' to directory A 1583 # This is an files=>empty folding. 1584 expected_output = svntest.wc.State(wc_dir, { 1585 'A/mu' : Item(status='D ') 1586 }) 1587 expected_status.remove('A/mu') 1588 expected_disk.remove('A/mu') 1589 svntest.actions.run_and_verify_update(wc_dir, 1590 expected_output, 1591 expected_disk, 1592 expected_status, 1593 [], False, 1594 '--set-depth', 'empty', A_path) 1595 verify_depth(None, "empty", A_path) 1596 1597 # Run 'svn up --set-depth=files' to wc 1598 # This is an mixed(infinity+empty)=>files folding. 1599 expected_output = svntest.wc.State(wc_dir, { 1600 'A' : Item(status='D ') 1601 }) 1602 expected_status.remove('A') 1603 expected_disk.remove('A') 1604 svntest.actions.run_and_verify_update(wc_dir, 1605 expected_output, 1606 expected_disk, 1607 expected_status, 1608 [], False, 1609 '--set-depth', 'files', wc_dir) 1610 verify_depth(None, "files", wc_dir) 1611 1612 1613#------------------------------------------------------------------------------ 1614def depth_folding_clean_trees_2(sbox): 1615 "gradually fold wc, focusing on depth=immediates" 1616 1617 # Covers the following situations: 1618 # 1619 # infinity=>immediates 1620 # mixed(immediates+immediates)=>immediates 1621 # mixed(immediates+infinity)=>immediates 1622 # mixed(immediates+files)=>immediates 1623 # immediates=>empty(remove the target since the parent is at files/empty) 1624 1625 ign_a, wc_dir, ign_b, ign_c = set_up_depthy_working_copies(sbox, files=True) 1626 1627 A_path = os.path.join(wc_dir, 'A') 1628 D_path = os.path.join(A_path, 'D') 1629 H_path = os.path.join(D_path, 'H') 1630 G_path = os.path.join(D_path, 'G') 1631 1632 # pull in directory A at immediates 1633 svntest.actions.run_and_verify_svn(None, [], 1634 'up', '--depth', 'immediates', A_path) 1635 # check to see if it's really at immediates 1636 verify_depth(None, "immediates", A_path) 1637 1638 # pull in directory D at infinity 1639 svntest.actions.run_and_verify_svn(None, [], 1640 'up', '--set-depth', 'infinity', D_path) 1641 1642 # Run 'svn up --set-depth=immediates' to directory A/D. 1643 # This is an infinity=>immediates folding 1644 expected_output = svntest.wc.State(wc_dir, { 1645 'A/D/G/pi' : Item(status='D '), 1646 'A/D/G/rho' : Item(status='D '), 1647 'A/D/G/tau' : Item(status='D '), 1648 'A/D/H/chi' : Item(status='D '), 1649 'A/D/H/psi' : Item(status='D '), 1650 'A/D/H/omega' : Item(status='D ') 1651 }) 1652 expected_status = svntest.wc.State(wc_dir, { 1653 '' : Item(status=' ', wc_rev=1), 1654 'iota' : Item(status=' ', wc_rev=1), 1655 'A' : Item(status=' ', wc_rev=1), 1656 'A/mu' : Item(status=' ', wc_rev=1), 1657 'A/B' : Item(status=' ', wc_rev=1), 1658 'A/C' : Item(status=' ', wc_rev=1), 1659 'A/D' : Item(status=' ', wc_rev=1), 1660 'A/D/gamma' : Item(status=' ', wc_rev=1), 1661 'A/D/G' : Item(status=' ', wc_rev=1), 1662 'A/D/H' : Item(status=' ', wc_rev=1) 1663 }) 1664 expected_disk = svntest.wc.State('', { 1665 'iota' : Item(contents="This is the file 'iota'.\n"), 1666 'A' : Item(contents=None), 1667 'A/mu' : Item(contents="This is the file 'mu'.\n"), 1668 'A/B' : Item(contents=None), 1669 'A/C' : Item(contents=None), 1670 'A/D' : Item(contents=None), 1671 'A/D/gamma' : Item(contents="This is the file 'gamma'.\n"), 1672 'A/D/G' : Item(contents=None), 1673 'A/D/H' : Item(contents=None), 1674 }) 1675 svntest.actions.run_and_verify_update(wc_dir, 1676 expected_output, 1677 expected_disk, 1678 expected_status, 1679 [], False, 1680 '--set-depth', 'immediates', D_path) 1681 verify_depth(None, "immediates", D_path) 1682 verify_depth(None, "empty", G_path) 1683 verify_depth(None, "empty", H_path) 1684 1685 # Run 'svn up --set-depth=immediates' to directory A. 1686 # This is an mixed(immediates+immediates)=>immediates folding 1687 expected_output = svntest.wc.State(wc_dir, { 1688 'A/D/G' : Item(status='D '), 1689 'A/D/H' : Item(status='D '), 1690 'A/D/gamma' : Item(status='D ') 1691 }) 1692 expected_status.remove( 'A/D/G', 'A/D/H', 'A/D/gamma') 1693 expected_disk.remove( 'A/D/G', 'A/D/H', 'A/D/gamma') 1694 svntest.actions.run_and_verify_update(wc_dir, 1695 expected_output, 1696 expected_disk, 1697 expected_status, 1698 [], False, 1699 '--set-depth', 'immediates', A_path) 1700 verify_depth(None, "immediates", A_path) 1701 verify_depth(None, "empty", D_path) 1702 1703 # pull in directory D at infinity 1704 svntest.actions.run_and_verify_svn(None, [], 1705 'up', '--set-depth', 'infinity', D_path) 1706 1707 # Run 'svn up --set-depth=immediates' to directory A. 1708 # This is an mixed(immediates+infinity)=>immediates folding 1709 expected_output = svntest.wc.State(wc_dir, { 1710 'A/D/gamma' : Item(status='D '), 1711 'A/D/G' : Item(status='D '), 1712 'A/D/H' : Item(status='D '), 1713 }) 1714 svntest.actions.run_and_verify_update(wc_dir, 1715 expected_output, 1716 expected_disk, 1717 expected_status, 1718 [], False, 1719 '--set-depth', 'immediates', A_path) 1720 verify_depth(None, "immediates", A_path) 1721 verify_depth(None, "empty", D_path) 1722 1723 # pull in directory D at files 1724 svntest.actions.run_and_verify_svn(None, [], 1725 'up', '--set-depth', 'files', D_path) 1726 1727 # Run 'svn up --set-depth=immediates' to directory A. 1728 # This is an mixed(immediates+files)=>immediates folding 1729 expected_output = svntest.wc.State(wc_dir, { 1730 'A/D/gamma' : Item(status='D ') 1731 }) 1732 svntest.actions.run_and_verify_update(wc_dir, 1733 expected_output, 1734 expected_disk, 1735 expected_status, 1736 [], False, 1737 '--set-depth', 'immediates', A_path) 1738 verify_depth(None, "immediates", A_path) 1739 verify_depth(None, "empty", D_path) 1740 1741# Comment the following out, since cropping out the root of tree is now 1742# handled by svn_depth_exclude and should have a separate test case for all 1743# influenced commands. 1744# 1745# # Run 'svn up --set-depth=empty' to directory A. 1746# # This is an immediates=>empty folding, the directory A should be deleted 1747# # too since the parent directory is at files/empty 1748# expected_output = svntest.wc.State(wc_dir, { 1749# 'A' : Item(status='D '), 1750# }) 1751# expected_status = svntest.wc.State(wc_dir, { 1752# '' : Item(status=' ', wc_rev=1), 1753# 'iota' : Item(status=' ', wc_rev=1) 1754# }) 1755# expected_disk = svntest.wc.State('', { 1756# 'iota' : Item(contents="This is the file 'iota'.\n") 1757# }) 1758# svntest.actions.run_and_verify_update(wc_dir, 1759# expected_output, 1760# expected_disk, 1761# expected_status, 1762# [], False, 1763# '--set-depth', 'empty', A_path) 1764 1765def depth_fold_expand_clean_trees(sbox): 1766 "expand target while contracting subtree" 1767 # --set-depth=immediates/files to an empty target with infinity 1768 # sub-tree should both fold the subtree and expand the target 1769 1770 wc_dir, ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, empty=True) 1771 1772 A_path = os.path.join(wc_dir, 'A') 1773 B_path = os.path.join(A_path, 'B') 1774 C_path = os.path.join(A_path, 'C') 1775 D_path = os.path.join(A_path, 'D') 1776 1777 # pull in directory A at empty 1778 svntest.actions.run_and_verify_svn(None, [], 1779 'up', '--depth', 'empty', A_path) 1780 verify_depth(None, "empty", A_path) 1781 1782 # pull in directory D at infinity 1783 svntest.actions.run_and_verify_svn(None, [], 1784 'up', D_path) 1785 1786 # Make the other working copy. 1787 other_wc = sbox.add_wc_path('other') 1788 svntest.actions.duplicate_dir(wc_dir, other_wc) 1789 1790 # Run 'svn up --set-depth=immediates' to directory A. This both folds 1791 # directory D to empty and expands directory A to immediates 1792 expected_output = svntest.wc.State(wc_dir, { 1793 'A/mu' : Item(status='A '), 1794 'A/B' : Item(status='A '), 1795 'A/C' : Item(status='A '), 1796 'A/D/gamma' : Item(status='D '), 1797 'A/D/G' : Item(status='D '), 1798 'A/D/H' : Item(status='D '), 1799 }) 1800 expected_status = svntest.wc.State(wc_dir, { 1801 '' : Item(status=' ', wc_rev=1), 1802 'A' : Item(status=' ', wc_rev=1), 1803 'A/mu' : Item(status=' ', wc_rev=1), 1804 'A/B' : Item(status=' ', wc_rev=1), 1805 'A/C' : Item(status=' ', wc_rev=1), 1806 'A/D' : Item(status=' ', wc_rev=1) 1807 }) 1808 expected_disk = svntest.wc.State('', { 1809 'A' : Item(contents=None), 1810 'A/mu' : Item(contents="This is the file 'mu'.\n"), 1811 'A/B' : Item(contents=None), 1812 'A/C' : Item(contents=None), 1813 'A/D' : Item(contents=None) 1814 }) 1815 svntest.actions.run_and_verify_update(wc_dir, 1816 expected_output, 1817 expected_disk, 1818 expected_status, 1819 [], False, 1820 '--set-depth', 'immediates', A_path) 1821 verify_depth(None, "immediates", A_path) 1822 verify_depth(None, "empty", B_path) 1823 verify_depth(None, "empty", C_path) 1824 verify_depth(None, "empty", D_path) 1825 1826 # Run 'svn up --set-depth=files' to directory A in other_wc. This both 1827 # removes directory D and expands directory A to files 1828 expected_output = svntest.wc.State(other_wc, { 1829 'A/mu' : Item(status='A '), 1830 'A/D' : Item(status='D '), 1831 }) 1832 expected_status = svntest.wc.State(other_wc, { 1833 '' : Item(status=' ', wc_rev=1), 1834 'A' : Item(status=' ', wc_rev=1), 1835 'A/mu' : Item(status=' ', wc_rev=1), 1836 }) 1837 expected_disk = svntest.wc.State('', { 1838 'A' : Item(contents=None), 1839 'A/mu' : Item(contents="This is the file 'mu'.\n") 1840 }) 1841 Other_A_path = os.path.join(other_wc, 'A') 1842 svntest.actions.run_and_verify_update(other_wc, 1843 expected_output, 1844 expected_disk, 1845 expected_status, 1846 [], False, 1847 '--set-depth', 'files', Other_A_path) 1848 verify_depth(None, "files", Other_A_path) 1849 1850 1851def pull_in_tree_with_depth_option(sbox): 1852 """checkout and verify subtree with depth immediates""" 1853 1854 wc_empty,ign_a, ign_b, ign_c = set_up_depthy_working_copies(sbox, 1855 empty=True) 1856 A_path = os.path.join(wc_empty, 'A') 1857 expected_output = svntest.wc.State(wc_empty, { 1858 'A' : Item(status='A '), 1859 'A/mu' : Item(status='A '), 1860 'A/B' : Item(status='A '), 1861 'A/C' : Item(status='A '), 1862 'A/D' : Item(status='A ') 1863 }) 1864 expected_disk = svntest.wc.State('', { 1865 'A' : Item(), 1866 'A/mu' : Item("This is the file 'mu'.\n"), 1867 'A/B' : Item(), 1868 'A/C' : Item(), 1869 'A/D' : Item(), 1870 }) 1871 expected_status = svntest.wc.State(wc_empty, { 1872 '' : Item(status=' ', wc_rev=1), 1873 'A' : Item(status=' ', wc_rev=1), 1874 'A/mu' : Item(status=' ', wc_rev=1), 1875 'A/B' : Item(status=' ', wc_rev=1), 1876 'A/C' : Item(status=' ', wc_rev=1), 1877 'A/D' : Item(status=' ', wc_rev=1), 1878 }) 1879 svntest.actions.run_and_verify_update(wc_empty, 1880 expected_output, 1881 expected_disk, 1882 expected_status, 1883 [], False, 1884 "--depth=immediates", A_path) 1885 1886 # Check that the A directory was pull ed in at depth=immediates. 1887 verify_depth(None, "immediates", A_path) 1888 1889def fold_tree_with_unversioned_modified_items(sbox): 1890 "unversioned & modified items left untouched" 1891 ign_a, ign_b, ign_c, wc_dir = set_up_depthy_working_copies(sbox, 1892 infinity=True) 1893 1894 A_path = sbox.ospath('A') 1895 pi_path = os.path.join(A_path, 'D', 'G', 'pi') 1896 mu_path = os.path.join(A_path, 'mu') 1897 unv_path = os.path.join(A_path, 'B', 'unv') 1898 1899 # Modify file pi 1900 svntest.main.file_write(pi_path, "pi modified\n") 1901 # Modify file mu 1902 svntest.main.file_write(mu_path, "mu modified\n") 1903 # Create an unversioned file 1904 svntest.main.file_write(unv_path, "new unversioned\n") 1905 1906 # Fold the A dir to empty, expect the modified & unversioned ones left 1907 # unversioned rather than removed, along with paths to those items. 1908 1909 # Directories B and D won't be deleted, because that would remove their 1910 # local modifications. Their unmodified descendants are deleted though. 1911 expected_output = svntest.wc.State(wc_dir, { 1912 'A/B/E' : Item(status='D '), 1913 'A/B/F' : Item(status='D '), 1914 'A/B/lambda' : Item(status='D '), 1915 'A/C' : Item(status='D '), 1916 'A/D/G/rho' : Item(status='D '), 1917 'A/D/G/tau' : Item(status='D '), 1918 'A/D/H' : Item(status='D '), 1919 'A/D/gamma' : Item(status='D '), 1920 }) 1921 # unversioned items will be ignored in in the status tree, since the 1922 # run_and_verify_update() function uses a quiet version of svn status 1923 expected_status = svntest.wc.State(wc_dir, { 1924 '' : Item(status=' ', wc_rev=1), 1925 'iota' : Item(status=' ', wc_rev=1), 1926 'A' : Item(status=' ', wc_rev=1), 1927 'A/D' : Item(status=' ', wc_rev='1'), 1928 'A/D/G' : Item(status=' ', wc_rev='1'), 1929 'A/D/G/pi' : Item(status='M ', wc_rev='1'), 1930 'A/B' : Item(status=' ', wc_rev='1'), 1931 'A/mu' : Item(status='M ', wc_rev='1'), 1932 }) 1933 expected_disk = svntest.wc.State('', { 1934 'iota' : Item(contents="This is the file 'iota'.\n"), 1935 'A' : Item(contents=None), 1936 'A/mu' : Item(contents="mu modified\n"), 1937 'A/B' : Item(contents=None), 1938 'A/B/unv' : Item(contents="new unversioned\n"), 1939 'A/D' : Item(contents=None), 1940 'A/D/G' : Item(contents=None), 1941 'A/D/G/pi' : Item(contents="pi modified\n") 1942 }) 1943 svntest.actions.run_and_verify_update(wc_dir, 1944 expected_output, 1945 expected_disk, 1946 expected_status, 1947 [], False, 1948 '--set-depth', 'empty', A_path) 1949 verify_depth(None, "empty", A_path) 1950 1951def depth_empty_update_on_file(sbox): 1952 "depth-empty update on a file doesn't break it" 1953 sbox.build() 1954 wc_dir = sbox.wc_dir 1955 1956 iota_path = sbox.ospath('iota') 1957 1958 # Change iota and commit it in r2. 1959 svntest.main.file_write(iota_path, 'Modified iota\n') 1960 expected_output = svntest.wc.State(wc_dir, { 'iota' : Item(verb='Sending'), }) 1961 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 1962 expected_status.tweak('iota', wc_rev=2, status=' ') 1963 svntest.actions.run_and_verify_commit(wc_dir, 1964 expected_output, 1965 expected_status) 1966 1967 # Update iota with depth=empty. 1968 expected_output = svntest.wc.State(wc_dir, 1969 {'iota': Item(status='U ') }) 1970 expected_disk = svntest.main.greek_state.copy() 1971 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 1972 svntest.actions.run_and_verify_update(wc_dir, 1973 expected_output, 1974 expected_disk, 1975 expected_status, 1976 [], False, 1977 '--depth=empty', '-r1', iota_path) 1978 1979 # Check the revision and created rev. 1980 expected_infos = { 1981 'Revision' : '^1$', 1982 'Last Changed Rev' : '^1$', 1983 } 1984 svntest.actions.run_and_verify_info([expected_infos], iota_path) 1985 1986 1987@Issue(3544) 1988def excluded_path_update_operation(sbox): 1989 """make sure update handle svn_depth_exclude properly""" 1990 1991 ign_a, ign_b, ign_c, wc_dir = set_up_depthy_working_copies(sbox, 1992 infinity=True) 1993 A_path = sbox.ospath('A') 1994 B_path = os.path.join(A_path, 'B') 1995 L_path = os.path.join(A_path, 'L') 1996 E_path = os.path.join(B_path, 'E') 1997 iota_path = sbox.ospath('iota') 1998 1999 # Simply exclude a subtree 2000 expected_output = svntest.wc.State(wc_dir, { 2001 'A/B/E' : Item(status='D '), 2002 }) 2003 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 2004 expected_status.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E') 2005 expected_disk = svntest.main.greek_state.copy() 2006 expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E') 2007 2008 svntest.actions.run_and_verify_update(wc_dir, 2009 expected_output, 2010 expected_disk, 2011 expected_status, 2012 [], False, 2013 '--set-depth', 'exclude', E_path) 2014 # verify_depth exclude? not implemented yet 2015 2016 # crop path B to immediates, this just pull in A/B/E again 2017 expected_output = svntest.wc.State(wc_dir, { 2018 'A/B/E' : Item(status='A '), 2019 }) 2020 expected_status.add({ 2021 'A/B/E' : Item(status=' ', wc_rev=1) 2022 }) 2023 expected_disk.add({ 2024 'A/B/E' : Item(contents=None), 2025 }) 2026 svntest.actions.run_and_verify_update(wc_dir, 2027 expected_output, 2028 expected_disk, 2029 expected_status, 2030 [], False, 2031 '--set-depth', 'immediates', B_path) 2032 verify_depth(None, "immediates", B_path) 2033 2034 # Exclude A/B/E again 2035 svntest.actions.run_and_verify_svn(None, [], 2036 'up', '--set-depth', 'exclude', E_path) 2037 2038 # Exclude path B totally, in which contains an excluded subtree. 2039 expected_output = svntest.wc.State(wc_dir, { 2040 'A/B' : Item(status='D '), 2041 }) 2042 expected_status.remove('A/B/F', 'A/B/E', 'A/B/lambda', 'A/B') 2043 expected_disk.remove('A/B/F', 'A/B/E', 'A/B/lambda', 'A/B') 2044 svntest.actions.run_and_verify_update(wc_dir, 2045 expected_output, 2046 expected_disk, 2047 expected_status, 2048 [], False, 2049 '--set-depth', 'exclude', B_path) 2050 2051 # Explicitly pull in excluded path B. 2052 expected_output = svntest.wc.State(wc_dir, { 2053 'A/B' : Item(status='A '), 2054 'A/B/lambda' : Item(status='A '), 2055 'A/B/E' : Item(status='A '), 2056 'A/B/E/alpha' : Item(status='A '), 2057 'A/B/E/beta' : Item(status='A '), 2058 'A/B/F' : Item(status='A '), 2059 }) 2060 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 2061 expected_disk = svntest.main.greek_state.copy() 2062 svntest.actions.run_and_verify_update(wc_dir, 2063 expected_output, 2064 expected_disk, 2065 expected_status, 2066 [], False, 2067 B_path) 2068 2069 # Test issue # 2070 # Exclude a file then set depth of WC to infinity, the file should return. 2071 expected_output = svntest.wc.State(wc_dir, { 2072 'iota' : Item(status='D '), 2073 }) 2074 expected_status.remove('iota') 2075 expected_disk.remove('iota') 2076 svntest.actions.run_and_verify_update(wc_dir, 2077 expected_output, 2078 expected_disk, 2079 expected_status, 2080 [], False, 2081 '--set-depth', 'exclude', iota_path) 2082 2083 # Update the whole WC to depth=infinity. 2084 expected_output = svntest.wc.State(wc_dir, { 2085 'iota' : Item(status='A '), 2086 }) 2087 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 2088 expected_disk = svntest.main.greek_state.copy() 2089 # This update currently fails when iota is reported as added, but shows in 2090 # status as unversioned. See issue #3544 'svn update does not restore 2091 # excluded files'. This test is marked as XFail until that issue is fixed. 2092 svntest.actions.run_and_verify_update(wc_dir, 2093 expected_output, 2094 expected_disk, 2095 expected_status, 2096 [], False, 2097 '--set-depth', 'infinity', wc_dir) 2098 2099def excluded_path_misc_operation(sbox): 2100 """make sure other subcommands handle exclude""" 2101 2102 ign_a, ign_b, ign_c, wc_dir = set_up_depthy_working_copies(sbox, 2103 infinity=True) 2104 A_path = sbox.ospath('A') 2105 B_path = os.path.join(A_path, 'B') 2106 L_path = os.path.join(A_path, 'L') 2107 M_path = os.path.join(A_path, 'M') 2108 E_path = os.path.join(B_path, 'E') 2109 LE_path = os.path.join(L_path, 'E') 2110 2111 # Simply exclude a subtree 2112 expected_output = svntest.wc.State(wc_dir, { 2113 'A/B/E' : Item(status='D '), 2114 }) 2115 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 2116 expected_status.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E') 2117 expected_disk = svntest.main.greek_state.copy() 2118 expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E') 2119 2120 svntest.actions.run_and_verify_update(wc_dir, 2121 expected_output, 2122 expected_disk, 2123 expected_status, 2124 [], False, 2125 '--set-depth', 'exclude', E_path) 2126 2127 # copy A/B to A/L, excluded entry should be copied too 2128 expected_output = ['A '+L_path+'\n'] 2129 svntest.actions.run_and_verify_svn(expected_output, [], 2130 'cp', B_path, L_path) 2131 # verify_depth exclude? not implemented yet 2132 #verify_depth(None, "empty", LE_path) 2133 2134 # revert A/L, with an excluded item in the tree 2135 revert_paths = [L_path] + [os.path.join(L_path, child) 2136 for child in ['E', 'F', 'lambda']] 2137 expected_output = svntest.verify.UnorderedOutput([ 2138 "Reverted '%s'\n" % path for path in revert_paths]) 2139 2140 svntest.actions.run_and_verify_svn(expected_output, [], 2141 'revert', '--depth=infinity', L_path) 2142 2143 # copy A/B to A/L and then cp A/L to A/M, excluded entry should be 2144 # copied both times 2145 expected_output = ['A '+L_path+'\n'] 2146 svntest.actions.run_and_verify_svn(expected_output, [], 2147 'cp', B_path, L_path) 2148 expected_output = ['A '+M_path+'\n'] 2149 svntest.actions.run_and_verify_svn(expected_output, [], 2150 'cp', L_path, M_path) 2151 2152 # commit this copy, with an excluded item. 2153 expected_output = svntest.wc.State(wc_dir, { 'A/L' : Item(verb='Adding'), 2154 'A/M' : Item(verb='Adding'), }) 2155 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 2156 expected_status.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E') 2157 expected_status.add({ 2158 'A/L' : Item(status=' ', wc_rev=2), 2159 'A/L/lambda' : Item(status=' ', wc_rev=2), 2160 'A/L/F' : Item(status=' ', wc_rev=2), 2161 'A/M' : Item(status=' ', wc_rev=2), 2162 'A/M/lambda' : Item(status=' ', wc_rev=2), 2163 'A/M/F' : Item(status=' ', wc_rev=2), 2164 }) 2165 svntest.actions.run_and_verify_commit(wc_dir, 2166 expected_output, 2167 expected_status) 2168 2169 # Relocate wc, with excluded items in it. 2170 repo_dir = sbox.repo_dir 2171 repo_url = sbox.repo_url 2172 other_repo_dir, other_repo_url = sbox.add_repo_path('other') 2173 svntest.main.copy_repos(repo_dir, other_repo_dir, 2, 0) 2174 svntest.main.safe_rmtree(repo_dir, 1) 2175 svntest.actions.run_and_verify_svn(None, [], 'switch', '--relocate', 2176 repo_url, other_repo_url, wc_dir) 2177 2178 # remove the new directory A/L, with an excluded item. 2179 # If successed, no error will be thrown 2180 svntest.actions.run_and_verify_svn(None, [], 2181 'rm', L_path) 2182 2183 # revert the delete 2184 # If successed, no error will be thrown 2185 svntest.actions.run_and_verify_svn(None, [], 2186 'revert', '--depth=infinity', L_path) 2187 2188 2189def excluded_receive_remote_removal(sbox): 2190 """exclude flag should be cleared upon remote removal""" 2191 ign_a, ign_b, ign_c, wc \ 2192 = set_up_depthy_working_copies(sbox, infinity=True) 2193 2194 A_path = os.path.join(wc, 'A') 2195 B_path = os.path.join(A_path, 'B') 2196 C_path = os.path.join(A_path, 'C') 2197 2198 # Exclude path B from wc 2199 expected_output = svntest.wc.State(wc, { 2200 'A/B' : Item(status='D '), 2201 }) 2202 expected_disk = svntest.main.greek_state.copy() 2203 expected_disk.remove('A/B/lambda', 'A/B/E/alpha', 'A/B/E/beta', 2204 'A/B/E', 'A/B/F', 'A/B') 2205 expected_status = svntest.actions.get_virginal_state(wc, 1) 2206 expected_status.remove('A/B/lambda', 'A/B/E/alpha', 'A/B/E/beta', 2207 'A/B/E', 'A/B/F', 'A/B') 2208 svntest.actions.run_and_verify_update(wc, 2209 expected_output, 2210 expected_disk, 2211 expected_status, 2212 [], False, 2213 "--set-depth", "exclude", B_path) 2214 2215 # Remove path B in the repos. 2216 svntest.actions.run_and_verify_svn(None, [], "delete", "-m", 2217 "Delete B.", sbox.repo_url + "/A/B") 2218 2219 # Update wc, should receive the removal of excluded path B 2220 # and handle it silently. 2221 expected_status = svntest.actions.get_virginal_state(wc, 2) 2222 expected_status.remove('A/B/lambda', 'A/B/E/alpha', 'A/B/E/beta', 2223 'A/B/E', 'A/B/F', 'A/B') 2224 svntest.actions.run_and_verify_update(wc, 2225 None, 2226 expected_disk, 2227 expected_status) 2228 2229 # Introduce a new path with the same name B. 2230 # This should succeed if the exclude entry is gone with the update, 2231 # otherwise a name conflict will rise up. 2232 expected_output = ['A '+B_path+'\n'] 2233 svntest.actions.run_and_verify_svn(expected_output, [], 2234 'cp', C_path, B_path) 2235 2236 2237# Regression test for r876760. 2238def exclude_keeps_hidden_entries(sbox): 2239 "'up --set-depth exclude' doesn't lose entries" 2240 2241 sbox.build() 2242 wc_dir = sbox.wc_dir 2243 2244 A_path = sbox.ospath('A') 2245 os.chdir(A_path) 2246 2247 # the second 'up' used to cause the entry of 'C' to be lost. 2248 svntest.main.run_svn(None, 'up', '--set-depth', 'exclude', 'C') 2249 svntest.main.run_svn(None, 'up', '--set-depth', 'exclude', 'D') 2250 # we could grep the 'entries' file, but... 2251 # or we could use 'info', but info_excluded() is XFail. 2252 expected_stderr = ".*svn: E150002: '.*C' is already under version control.*" 2253 svntest.actions.run_and_verify_svn(None, expected_stderr, 2254 'mkdir', 'C') 2255 2256 2257@Issue(3792) 2258def info_excluded(sbox): 2259 "'info' should treat excluded item as versioned" 2260 2261 # The problem: 'svn info' on an excluded item would behave as if it 2262 # was not versioned at all: 2263 # 2264 # % svn up --set-depth exclude A 2265 # D A 2266 # % svn info A 2267 # A: (Not a versioned resource) 2268 # 2269 # ..\..\..\subversion\svn\info-cmd.c:562: (apr_err=200000) 2270 # svn: A problem occurred; see other errors for details 2271 # 2272 # It should acknowledge the existence (in the repos) of ./A and print some 2273 # info about it, like it does if '--set-depth empty' is used instead. 2274 2275 sbox.build() 2276 wc_dir = sbox.wc_dir 2277 2278 A_path = sbox.ospath('A') 2279 svntest.main.run_svn(None, 'up', '--set-depth', 'exclude', A_path) 2280 2281 expected_info = { 2282 'Path' : re.escape(A_path), 2283 'Repository Root' : sbox.repo_url, 2284 'Repository UUID' : svntest.actions.get_wc_uuid(wc_dir), 2285 'Depth' : 'exclude', 2286 } 2287 svntest.actions.run_and_verify_info([expected_info], A_path) 2288 2289 2290 2291#---------------------------------------------------------------------- 2292# Check that "svn resolved" visits tree-conflicts *on unversioned items* 2293# according to the --depth parameter. 2294 2295def make_depth_tree_conflicts(sbox): 2296 "Helper for tree_conflicts_resolved_depth_*" 2297 2298 sbox.build() 2299 wc = sbox.wc_dir 2300 2301 j = os.path.join 2302 A = j(wc, 'A') 2303 m = j(A, 'mu') 2304 B = j(A, 'B') 2305 D = j(A, 'D') 2306 g = j(D, 'gamma') 2307 2308 # Store node modifications as rev 2 2309 svntest.actions.run_and_verify_svn(None, [], 2310 'propset', 'foo', 'foo-val', B) 2311 svntest.main.file_append(m, "Modified mu.\n") 2312 svntest.main.file_append(g, "Modified gamma.\n") 2313 2314 expected_output = svntest.wc.State(wc, { 2315 'A/mu' : Item(verb='Sending'), 2316 'A/B' : Item(verb='Sending'), 2317 'A/D/gamma' : Item(verb='Sending'), 2318 }) 2319 2320 expected_status = svntest.actions.get_virginal_state(wc, 1) 2321 expected_status.tweak('A/mu', 'A/B', 'A/D/gamma', 2322 wc_rev = 2) 2323 2324 svntest.actions.run_and_verify_commit(wc, 2325 expected_output, 2326 expected_status, 2327 [], 2328 A) 2329 2330 # Go back to rev 1 2331 expected_output = svntest.wc.State(wc, { 2332 'A/mu' : Item(status='U '), 2333 'A/B' : Item(status=' U'), 2334 'A/D/gamma' : Item(status='U '), 2335 }) 2336 expected_status = svntest.actions.get_virginal_state(wc, 1) 2337 expected_disk = svntest.main.greek_state.copy() 2338 svntest.actions.run_and_verify_update(wc, 2339 expected_output, 2340 expected_disk, 2341 expected_status, 2342 [], False, 2343 '-r1', A) 2344 2345 # Perform node deletions so that items become unversioned and 2346 # will have tree-conflicts upon update. 2347 svntest.actions.run_and_verify_svn(None, [], 2348 'rm', m, B, g) 2349 2350 # Update so that conflicts appear 2351 expected_output = svntest.wc.State(wc, { 2352 'A/mu' : Item(status=' ', treeconflict='C'), 2353 'A/B' : Item(status=' ', treeconflict='C'), 2354 'A/D/gamma' : Item(status=' ', treeconflict='C'), 2355 }) 2356 2357 expected_disk = svntest.main.greek_state.copy() 2358 expected_disk.remove('A/mu', 2359 'A/B', 'A/B/lambda', 'A/B/E/alpha', 'A/B/E/beta', 2360 'A/D/gamma', 2361 'A/B/E', 'A/B/F') 2362 2363 # This test is set XFail because this (correct) status cannot be 2364 # verified due to an "svn update" bug. The tree-conflict on A/B 2365 # which is notified about during the update does not show in the 2366 # status. When removing file 'mu' from above 'rm' command, 'B' is 2367 # reported as tree-conflicted correctly. Also use these to verify: 2368 # expected_output = None 2369 # expected_disk = None 2370 expected_status = svntest.actions.get_virginal_state(wc, 2) 2371 expected_status.tweak('A/mu', 2372 'A/B', 'A/B/lambda', 2373 'A/B/E', 'A/B/E/alpha', 'A/B/E/beta', 2374 'A/B/F', 2375 'A/D/gamma', 2376 status='D ') 2377 expected_status.tweak('A/mu', 'A/B', 'A/D/gamma', 2378 treeconflict='C') 2379 2380 svntest.actions.run_and_verify_update(wc, 2381 expected_output, 2382 expected_disk, 2383 expected_status, 2384 [], False, 2385 wc) 2386 2387 2388 2389def tree_conflicts_resolved_depth_empty(sbox): 2390 "tree conflicts resolved depth-empty" 2391 2392 make_depth_tree_conflicts(sbox) 2393 2394 wc = sbox.wc_dir 2395 A = os.path.join(wc, 'A') 2396 2397 svntest.actions.run_and_verify_resolved([], '--depth=empty', A) 2398 2399 2400def tree_conflicts_resolved_depth_files(sbox): 2401 "tree conflicts resolved depth-files" 2402 2403 make_depth_tree_conflicts(sbox) 2404 2405 wc = sbox.wc_dir 2406 j = os.path.join 2407 A = j(wc, 'A') 2408 m = j(A, 'mu') 2409 2410 svntest.actions.run_and_verify_resolved([m], '--depth=files', A) 2411 2412 2413def tree_conflicts_resolved_depth_immediates(sbox): 2414 "tree conflicts resolved depth-immediates" 2415 2416 make_depth_tree_conflicts(sbox) 2417 2418 wc = sbox.wc_dir 2419 j = os.path.join 2420 A = j(wc, 'A') 2421 m = j(A, 'mu') 2422 B = j(A, 'B') 2423 2424 svntest.actions.run_and_verify_resolved([m, B], '--depth=immediates', A) 2425 2426 2427def tree_conflicts_resolved_depth_infinity(sbox): 2428 "tree conflicts resolved depth-infinity" 2429 2430 make_depth_tree_conflicts(sbox) 2431 2432 wc = sbox.wc_dir 2433 j = os.path.join 2434 A = j(wc, 'A') 2435 m = j(A, 'mu') 2436 B = j(A, 'B') 2437 g = j(A, 'D', 'gamma') 2438 2439 svntest.actions.run_and_verify_resolved([m, B, g], '--depth=infinity', A) 2440 2441def update_excluded_path_sticky_depths(sbox): 2442 """set-depth from excluded to all other depths""" 2443 2444 ign_a, ign_b, ign_c, wc_dir = set_up_depthy_working_copies(sbox, 2445 infinity=True) 2446 A_path = sbox.ospath('A') 2447 B_path = os.path.join(A_path, 'B') 2448 2449 # Exclude the subtree 'A/B' 2450 expected_output = svntest.wc.State(wc_dir, { 2451 'A/B' : Item(status='D '), 2452 }) 2453 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 2454 expected_status.remove('A/B/lambda', 'A/B/E/alpha', 'A/B/E/beta', 'A/B/E', 2455 'A/B/F', 'A/B') 2456 expected_disk = svntest.main.greek_state.copy() 2457 expected_disk.remove('A/B/lambda', 'A/B/E/alpha', 'A/B/E/beta', 'A/B/E', 2458 'A/B/F', 'A/B') 2459 2460 svntest.actions.run_and_verify_update(wc_dir, 2461 expected_output, 2462 expected_disk, 2463 expected_status, 2464 [], False, 2465 '--set-depth', 'exclude', B_path) 2466 2467 # Update to depth 'empty' for the excluded path A/B 2468 expected_output = svntest.wc.State(wc_dir, { 2469 'A/B' : Item(status='A '), 2470 }) 2471 expected_status.add({ 2472 'A/B' : Item(status=' ', wc_rev=1) 2473 }) 2474 expected_disk.add({ 2475 'A/B' : Item(contents=None), 2476 }) 2477 svntest.actions.run_and_verify_update(wc_dir, 2478 expected_output, 2479 expected_disk, 2480 expected_status, 2481 [], False, 2482 '--set-depth', 'empty', B_path) 2483 verify_depth(None, "empty", B_path) 2484 expected_info = { 2485 'Path' : re.escape(B_path), 2486 'Repository Root' : sbox.repo_url, 2487 'Repository UUID' : svntest.actions.get_wc_uuid(wc_dir), 2488 'Depth' : 'empty', 2489 } 2490 svntest.actions.run_and_verify_info([expected_info], B_path) 2491 2492 # Exclude A/B again 2493 svntest.actions.run_and_verify_svn(None, [], 2494 'up', '--set-depth', 'exclude', B_path) 2495 2496 # Update to depth 'files' for the excluded path A/B 2497 expected_output = svntest.wc.State(wc_dir, { 2498 'A/B' : Item(status='A '), 2499 'A/B/lambda' : Item(status='A '), 2500 }) 2501 expected_status.add({ 2502 'A/B' : Item(status=' ', wc_rev=1), 2503 'A/B/lambda' : Item(status=' ', wc_rev=1), 2504 }) 2505 expected_disk.add({ 2506 'A/B' : Item(contents=None), 2507 'A/B/lambda' : Item(contents="This is the file 'lambda'.\n"), 2508 }) 2509 svntest.actions.run_and_verify_update(wc_dir, 2510 expected_output, 2511 expected_disk, 2512 expected_status, 2513 [], False, 2514 '--set-depth', 'files', B_path) 2515 verify_depth(None, "files", B_path) 2516 expected_info = { 2517 'Path' : re.escape(B_path), 2518 'Repository Root' : sbox.repo_url, 2519 'Repository UUID' : svntest.actions.get_wc_uuid(wc_dir), 2520 'Depth' : 'files', 2521 } 2522 svntest.actions.run_and_verify_info([expected_info], B_path) 2523 2524 # Exclude A/B again 2525 svntest.actions.run_and_verify_svn(None, [], 2526 'up', '--set-depth', 'exclude', B_path) 2527 2528 # Update to depth 'immediates' for the excluded path A/B 2529 expected_output = svntest.wc.State(wc_dir, { 2530 'A/B' : Item(status='A '), 2531 'A/B/lambda' : Item(status='A '), 2532 'A/B/E' : Item(status='A '), 2533 'A/B/F' : Item(status='A '), 2534 }) 2535 expected_status.add({ 2536 'A/B' : Item(status=' ', wc_rev=1), 2537 'A/B/lambda' : Item(status=' ', wc_rev=1), 2538 'A/B/E' : Item(status=' ', wc_rev=1), 2539 'A/B/F' : Item(status=' ', wc_rev=1), 2540 }) 2541 expected_disk.add({ 2542 'A/B' : Item(contents=None), 2543 'A/B/lambda' : Item(contents="This is the file 'lambda'.\n"), 2544 'A/B/E' : Item(contents=None), 2545 'A/B/F' : Item(contents=None), 2546 }) 2547 svntest.actions.run_and_verify_update(wc_dir, 2548 expected_output, 2549 expected_disk, 2550 expected_status, 2551 [], False, 2552 '--set-depth', 'immediates', B_path) 2553 verify_depth(None, "immediates", B_path) 2554 expected_info = { 2555 'Path' : re.escape(B_path), 2556 'Repository Root' : sbox.repo_url, 2557 'Repository UUID' : svntest.actions.get_wc_uuid(wc_dir), 2558 'Depth' : 'immediates', 2559 } 2560 svntest.actions.run_and_verify_info([expected_info], B_path) 2561 2562 # Exclude A/B again 2563 svntest.actions.run_and_verify_svn(None, [], 2564 'up', '--set-depth', 'exclude', B_path) 2565 2566 # Update to depth 'infinity' for the excluded path A/B 2567 expected_output = svntest.wc.State(wc_dir, { 2568 'A/B' : Item(status='A '), 2569 'A/B/lambda' : Item(status='A '), 2570 'A/B/E' : Item(status='A '), 2571 'A/B/E/beta' : Item(status='A '), 2572 'A/B/E/alpha' : Item(status='A '), 2573 'A/B/F' : Item(status='A '), 2574 }) 2575 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 2576 expected_disk = svntest.main.greek_state.copy() 2577 svntest.actions.run_and_verify_update(wc_dir, 2578 expected_output, 2579 expected_disk, 2580 expected_status, 2581 [], False, 2582 '--set-depth', 'infinity', B_path) 2583 verify_depth(None, "infinity", B_path) 2584 expected_info = { 2585 'Path' : re.escape(B_path), 2586 'Repository Root' : sbox.repo_url, 2587 'Repository UUID' : svntest.actions.get_wc_uuid(wc_dir), 2588 # 'Depth' value is absent for 'infinity' 2589 } 2590 svntest.actions.run_and_verify_info([expected_info], B_path) 2591 2592 2593def update_depth_empty_root_of_infinite_children(sbox): 2594 """update depth=empty root of depth=infinite children""" 2595 2596 wc_dir, ign_a, ign_b, wc_other = set_up_depthy_working_copies(sbox, 2597 empty=True, 2598 infinity=True) 2599 A_path = os.path.join(wc_dir, 'A') 2600 2601 # Update A to depth 'infinity' 2602 svntest.actions.run_and_verify_svn(None, [], 2603 'up', '--set-depth', 'infinity', A_path) 2604 2605 # Tweak some files in the full working copy and commit. 2606 svntest.main.file_append(os.path.join(wc_other, 'A', 'B', 'E', 'alpha'), 2607 "Modified alpha.\n") 2608 svntest.main.file_append(os.path.join(wc_other, 'A', 'D', 'G', 'rho'), 2609 "Modified rho.\n") 2610 svntest.actions.run_and_verify_svn(None, [], 2611 'ci', '-m', '', wc_other) 2612 2613 # Now update the original working copy and make sure we get those changes. 2614 expected_output = svntest.wc.State(wc_dir, { 2615 'A/B/E/alpha' : Item(status='U '), 2616 'A/D/G/rho' : Item(status='U '), 2617 }) 2618 expected_status = svntest.actions.get_virginal_state(wc_dir, 2) 2619 expected_status.remove('iota') 2620 expected_disk = svntest.main.greek_state.copy() 2621 expected_disk.remove('iota') 2622 expected_disk.tweak('A/B/E/alpha', contents="This is the file 'alpha'.\nModified alpha.\n") 2623 expected_disk.tweak('A/D/G/rho', contents="This is the file 'rho'.\nModified rho.\n") 2624 svntest.actions.run_and_verify_update(wc_dir, 2625 expected_output, 2626 expected_disk, 2627 expected_status) 2628 2629def sparse_update_with_dash_dash_parents(sbox): 2630 """update --parents""" 2631 2632 sbox.build(create_wc = False) 2633 sbox.add_test_path(sbox.wc_dir, True) 2634 alpha_path = sbox.ospath('A/B/E/alpha') 2635 pi_path = sbox.ospath('A/D/G/pi') 2636 omega_path = sbox.ospath('A/D/H/omega') 2637 2638 # Start with a depth=empty root checkout. 2639 svntest.actions.run_and_verify_svn( 2640 svntest.verify.AnyOutput, [], 2641 "co", "--depth", "empty", sbox.repo_url, sbox.wc_dir) 2642 2643 # Now, let's use --parents to pull in some scattered file children. 2644 expected_output = svntest.wc.State(sbox.wc_dir, { 2645 'A' : Item(status='A '), 2646 'A/B' : Item(status='A '), 2647 'A/B/E' : Item(status='A '), 2648 'A/B/E/alpha' : Item(status='A '), 2649 }) 2650 expected_disk = svntest.wc.State('', { 2651 'A' : Item(contents=None), 2652 'A/B' : Item(contents=None), 2653 'A/B/E' : Item(contents=None), 2654 'A/B/E/alpha' : Item(contents="This is the file 'alpha'.\n"), 2655 }) 2656 expected_status = svntest.wc.State(sbox.wc_dir, { 2657 '' : Item(status=' ', wc_rev=1), 2658 'A' : Item(status=' ', wc_rev=1), 2659 'A/B' : Item(status=' ', wc_rev=1), 2660 'A/B/E' : Item(status=' ', wc_rev=1), 2661 'A/B/E/alpha' : Item(status=' ', wc_rev=1), 2662 }) 2663 svntest.actions.run_and_verify_update(sbox.wc_dir, 2664 expected_output, 2665 expected_disk, 2666 expected_status, 2667 [], False, 2668 '--parents', alpha_path) 2669 2670 expected_output = svntest.wc.State(sbox.wc_dir, { 2671 'A/D' : Item(status='A '), 2672 'A/D/G' : Item(status='A '), 2673 'A/D/G/pi' : Item(status='A '), 2674 }) 2675 expected_disk.add({ 2676 'A/D' : Item(contents=None), 2677 'A/D/G' : Item(contents=None), 2678 'A/D/G/pi' : Item(contents="This is the file 'pi'.\n"), 2679 }) 2680 expected_status.add({ 2681 'A/D' : Item(status=' ', wc_rev=1), 2682 'A/D/G' : Item(status=' ', wc_rev=1), 2683 'A/D/G/pi' : Item(status=' ', wc_rev=1), 2684 }) 2685 svntest.actions.run_and_verify_update(sbox.wc_dir, 2686 expected_output, 2687 expected_disk, 2688 expected_status, 2689 [], False, 2690 '--parents', pi_path) 2691 2692 expected_output = svntest.wc.State(sbox.wc_dir, { 2693 'A/D/H' : Item(status='A '), 2694 'A/D/H/omega' : Item(status='A '), 2695 }) 2696 expected_disk.add({ 2697 'A/D/H' : Item(contents=None), 2698 'A/D/H/omega' : Item(contents="This is the file 'omega'.\n"), 2699 }) 2700 expected_status.add({ 2701 'A/D/H' : Item(status=' ', wc_rev=1), 2702 'A/D/H/omega' : Item(status=' ', wc_rev=1), 2703 }) 2704 svntest.actions.run_and_verify_update(sbox.wc_dir, 2705 expected_output, 2706 expected_disk, 2707 expected_status, 2708 [], False, 2709 '--parents', omega_path) 2710 2711def update_below_depth_empty(sbox): 2712 "update below depth empty shouldn't be applied" 2713 sbox.build() 2714 2715 repo_url = sbox.repo_url 2716 A = sbox.ospath('A') 2717 2718 expected_output = svntest.wc.State(sbox.wc_dir, { 2719 'A/C' : Item(status='D '), 2720 'A/B' : Item(status='D '), 2721 'A/mu' : Item(status='D '), 2722 'A/D' : Item(status='D '), 2723 }) 2724 svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output, None, 2725 None, 2726 [], False, 2727 '--set-depth', 'empty', A) 2728 2729 svntest.actions.run_and_verify_svn(None, [], 2730 'cp', repo_url + '/iota', 2731 repo_url + '/A/B', 2732 '-m', 'remote copy') 2733 2734 expected_output = svntest.wc.State(sbox.wc_dir, { 2735 }) 2736 2737 # This update should just update the revision of the working copy 2738 svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output, None, 2739 None) 2740 2741# Test for issue #4136. 2742@Issue(4136) 2743def commit_then_immediates_update(sbox): 2744 "deep commit followed by update --depth immediates" 2745 sbox.build() 2746 2747 repo_url = sbox.repo_url 2748 wc_dir = sbox.wc_dir 2749 mu_path = sbox.ospath('A/mu') 2750 2751 # Modify A/mu and commit the changes. 2752 svntest.main.file_write(mu_path, "modified mu\n") 2753 expected_output = svntest.wc.State(wc_dir, { 2754 'A/mu' : Item(verb='Sending'), 2755 }) 2756 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 2757 expected_status.tweak('A/mu', wc_rev=2, status=' ') 2758 svntest.actions.run_and_verify_commit(wc_dir, 2759 expected_output, 2760 expected_status) 2761 2762 # Now, update --depth immediates in the root of the working copy. 2763 expected_output = svntest.wc.State(wc_dir, { }) 2764 expected_disk = svntest.main.greek_state.copy() 2765 expected_disk.tweak('A/mu', contents="modified mu\n") 2766 expected_status = svntest.wc.State(wc_dir, { '' : svntest.wc.StateItem() }) 2767 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 2768 expected_status.tweak('', wc_rev=2, status=' ') 2769 expected_status.tweak('A', wc_rev=2, status=' ') 2770 expected_status.tweak('A/mu', wc_rev=2, status=' ') 2771 expected_status.tweak('iota', wc_rev=2, status=' ') 2772 svntest.actions.run_and_verify_update(wc_dir, 2773 expected_output, 2774 expected_disk, 2775 expected_status, 2776 [], False, 2777 "--depth=immediates", wc_dir) 2778 2779def revert_depth_files(sbox): 2780 "depth immediate+files should revert deleted files" 2781 2782 sbox.build(read_only = True) 2783 2784 expected_output = "Reverted '" + re.escape(sbox.ospath('A/mu')) + "'" 2785 2786 # Apply an unrelated delete one level to deep 2787 sbox.simple_rm('A/D/gamma') 2788 2789 sbox.simple_rm('A/mu') 2790 # Expect reversion of just 'mu' 2791 svntest.actions.run_and_verify_svn(expected_output, [], 2792 'revert', '--depth=immediates', sbox.ospath('A')) 2793 2794 # Apply an unrelated directory delete 2795 sbox.simple_rm('A/D') 2796 2797 sbox.simple_rm('A/mu') 2798 # Expect reversion of just 'mu' 2799 svntest.actions.run_and_verify_svn(expected_output, [], 2800 'revert', '--depth=files', sbox.ospath('A')) 2801 2802@Issue(4257) 2803def spurious_nodes_row(sbox): 2804 "update produces no spurious rows" 2805 2806 sbox.build(read_only = True) 2807 return 2808 2809 val1 = svntest.wc.sqlite_stmt(sbox.wc_dir, "select count(*) from nodes") 2810 expected_output = svntest.wc.State(sbox.wc_dir, { }) 2811 expected_disk = svntest.main.greek_state.copy() 2812 expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1) 2813 svntest.actions.run_and_verify_update(sbox.wc_dir, 2814 expected_output, 2815 expected_disk, 2816 expected_status, 2817 [], False, 2818 "--depth=empty", sbox.wc_dir) 2819 val2 = svntest.wc.sqlite_stmt(sbox.wc_dir, "select count(*) from nodes") 2820 if (val1 != val2): 2821 # ra_neon added a spurious not-present row that does not show up in status 2822 raise svntest.Failure("count changed from '%s' to '%s'" % (val1, val2)) 2823 2824def commit_excluded(sbox): 2825 "commit an excluded node" 2826 2827 sbox.build() 2828 wc_dir = sbox.wc_dir 2829 2830 expected_output = svntest.wc.State(wc_dir, { 2831 'A/D/G' : Item(status='D '), 2832 }) 2833 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 2834 expected_status.remove('A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau') 2835 2836 svntest.actions.run_and_verify_update(wc_dir, 2837 expected_output, 2838 None, 2839 expected_status, 2840 [], False, 2841 "--set-depth=exclude", 2842 sbox.ospath('A/D/G')) 2843 2844 sbox.simple_copy('A/D', 'D') 2845 2846 expected_output = svntest.wc.State(wc_dir, { 2847 'D' : Item(verb='Adding'), 2848 }) 2849 2850 expected_status.add({ 2851 'D' : Item(status=' ', wc_rev='2'), 2852 'D/H' : Item(status=' ', wc_rev='2'), 2853 'D/H/chi' : Item(status=' ', wc_rev='2'), 2854 'D/H/psi' : Item(status=' ', wc_rev='2'), 2855 'D/H/omega' : Item(status=' ', wc_rev='2'), 2856 'D/gamma' : Item(status=' ', wc_rev='2') 2857 }) 2858 2859 svntest.actions.run_and_verify_commit(wc_dir, 2860 expected_output, 2861 expected_status) 2862 2863 expected_output = svntest.wc.State(wc_dir, { 2864 'A/D/G' : Item(status='A '), 2865 'A/D/G/pi' : Item(status='A '), 2866 'A/D/G/tau' : Item(status='A '), 2867 'A/D/G/rho' : Item(status='A '), 2868 'D/G' : Item(status='A '), 2869 'D/G/pi' : Item(status='A '), 2870 'D/G/tau' : Item(status='A '), 2871 'D/G/rho' : Item(status='A ') 2872 }) 2873 2874 expected_status.tweak(wc_rev=2) 2875 2876 expected_status.add({ 2877 'D' : Item(status=' ', wc_rev='2'), 2878 'D/G' : Item(status=' ', wc_rev='2'), 2879 'D/G/pi' : Item(status=' ', wc_rev='2'), 2880 'D/G/rho' : Item(status=' ', wc_rev='2'), 2881 'D/G/tau' : Item(status=' ', wc_rev='2'), 2882 'D/H' : Item(status=' ', wc_rev='2'), 2883 'D/H/chi' : Item(status=' ', wc_rev='2'), 2884 'D/H/psi' : Item(status=' ', wc_rev='2'), 2885 'D/H/omega' : Item(status=' ', wc_rev='2'), 2886 'D/gamma' : Item(status=' ', wc_rev='2'), 2887 'A/D/G' : Item(status=' ', wc_rev='2'), 2888 'A/D/G/rho' : Item(status=' ', wc_rev='2'), 2889 'A/D/G/tau' : Item(status=' ', wc_rev='2'), 2890 'A/D/G/pi' : Item(status=' ', wc_rev='2') 2891 }) 2892 2893 svntest.actions.run_and_verify_update(wc_dir, 2894 expected_output, 2895 None, 2896 expected_status, 2897 [], False, 2898 "--set-depth=infinity", wc_dir) 2899 2900@Issue(4636) 2901@XFail() 2902def fold_tree_with_deleted_moved_items(sbox): 2903 "deleted & moved items left untouched" 2904 ign_a, ign_b, ign_c, wc_dir = set_up_depthy_working_copies(sbox, 2905 infinity=True) 2906 2907 A_path = sbox.ospath('A') 2908 2909 # Delete file lambda, move file pi and directory C 2910 sbox.simple_rm('A/B/lambda') 2911 sbox.simple_move('A/D/G/pi', 'A/D/G/pi_moved') 2912 sbox.simple_move('A/C', 'A/C_moved') 2913 2914 # Fold the A dir to empty, expect the deleted & moved items ones left 2915 # and visible in status, rather than gone without a trace. 2916 2917 # Directories B and D won't be deleted, because that would remove their 2918 # local modifications. Their unmodified descendants are deleted though. 2919 expected_output = svntest.wc.State(wc_dir, { 2920 'A/B/E' : Item(status='D '), 2921 'A/B/F' : Item(status='D '), 2922 'A/D/G/rho' : Item(status='D '), 2923 'A/D/G/tau' : Item(status='D '), 2924 'A/D/H' : Item(status='D '), 2925 'A/D/gamma' : Item(status='D '), 2926 'A/mu' : Item(status='D '), 2927 }) 2928 expected_status = svntest.wc.State(wc_dir, { 2929 '' : Item(status=' ', wc_rev=1), 2930 'iota' : Item(status=' ', wc_rev=1), 2931 'A' : Item(status=' ', wc_rev=1), 2932 'A/B' : Item(status=' ', wc_rev=1), 2933 'A/B/lambda' : Item(status='D ', wc_rev=1), 2934 'A/C' : Item(status='D ', wc_rev=1, moved_to='A/C_moved'), 2935 'A/C_moved' : Item(status='A ', wc_rev='-', copied='+', 2936 moved_from='A/C'), 2937 'A/D' : Item(status=' ', wc_rev=1), 2938 'A/D/G' : Item(status=' ', wc_rev=1), 2939 'A/D/G/pi' : Item(status='D ', wc_rev=1, moved_to='A/D/G/pi_moved'), 2940 'A/D/G/pi_moved' : Item(status='A ', wc_rev='-', copied='+', 2941 moved_from='A/D/G/pi'), 2942 }) 2943 expected_disk = svntest.wc.State('', { 2944 'iota' : Item(contents="This is the file 'iota'.\n"), 2945 'A' : Item(contents=None), 2946 'A/B' : Item(contents=None), 2947 'A/C_moved' : Item(contents=None), 2948 'A/D' : Item(contents=None), 2949 'A/D/G' : Item(contents=None), 2950 'A/D/G/pi_moved' : Item(contents="This is the file 'pi'.\n"), 2951 }) 2952 svntest.actions.run_and_verify_update(wc_dir, 2953 expected_output, 2954 expected_disk, 2955 expected_status, 2956 [], False, 2957 '--set-depth', 'empty', A_path) 2958 verify_depth(None, "empty", A_path) 2959 2960@Issue(4642) 2961@XFail() 2962def fold_tree_with_unversioned_items(sbox): 2963 "unversioned files in excluded directory" 2964 ign_a, ign_b, ign_c, wc_dir = set_up_depthy_working_copies(sbox, 2965 infinity=True) 2966 2967 # create an unversioned directory within a versioned one 2968 A_path = sbox.ospath('A') 2969 A_local_path = os.path.join(A_path, 'A_local') 2970 os.mkdir(A_local_path) 2971 2972 # Set A to be excluded. 2973 svntest.main.run_svn(None, 'update', '--set-depth=exclude', A_path) 2974 2975 # try a simple update afterwards 2976 sbox.simple_update() 2977 2978#---------------------------------------------------------------------- 2979# list all tests here, starting with None: 2980test_list = [ None, 2981 depth_empty_checkout, 2982 depth_files_checkout, 2983 nonrecursive_checkout, 2984 depth_empty_update_bypass_single_file, 2985 depth_immediates_get_top_file_mod_only, 2986 depth_empty_commit, 2987 depth_empty_with_file, 2988 depth_empty_with_dir, 2989 depth_immediates_bring_in_file, 2990 depth_immediates_fill_in_dir, 2991 depth_mixed_bring_in_dir, 2992 depth_empty_unreceive_delete, 2993 depth_immediates_unreceive_delete, 2994 depth_immediates_receive_delete, 2995 depth_update_to_more_depth, 2996 depth_immediates_subdir_propset_1, 2997 depth_immediates_subdir_propset_2, 2998 commit_propmods_with_depth_empty, 2999 diff_in_depthy_wc, 3000 commit_depth_immediates, 3001 depth_immediates_receive_new_dir, 3002 add_tree_with_depth, 3003 upgrade_from_above, 3004 status_in_depthy_wc, 3005 depthy_update_above_dir_to_be_deleted, 3006 depth_folding_clean_trees_1, 3007 depth_folding_clean_trees_2, 3008 depth_fold_expand_clean_trees, 3009 pull_in_tree_with_depth_option, 3010 fold_tree_with_unversioned_modified_items, 3011 depth_empty_update_on_file, 3012 excluded_path_update_operation, 3013 excluded_path_misc_operation, 3014 excluded_receive_remote_removal, 3015 exclude_keeps_hidden_entries, 3016 info_excluded, 3017 tree_conflicts_resolved_depth_empty, 3018 tree_conflicts_resolved_depth_files, 3019 tree_conflicts_resolved_depth_immediates, 3020 tree_conflicts_resolved_depth_infinity, 3021 update_excluded_path_sticky_depths, 3022 update_depth_empty_root_of_infinite_children, 3023 sparse_update_with_dash_dash_parents, 3024 update_below_depth_empty, 3025 commit_then_immediates_update, 3026 revert_depth_files, 3027 spurious_nodes_row, 3028 commit_excluded, 3029 fold_tree_with_deleted_moved_items, 3030 fold_tree_with_unversioned_items, 3031 ] 3032 3033if __name__ == "__main__": 3034 svntest.main.run_tests(test_list) 3035 # NOTREACHED 3036 3037 3038### End of file. 3039