3 # changelist_tests.py: testing changelist uses.
5 # Subversion is a tool for revision control.
6 # See http://subversion.tigris.org for more information.
8 # ====================================================================
9 # Copyright (c) 2008 CollabNet. All rights reserved.
11 # This software is licensed as described in the file COPYING, which
12 # you should have received as part of this distribution. The terms
13 # are also available at http://subversion.tigris.org/license-1.html.
14 # If newer versions of this license are posted there, you may use a
15 # newer version instead, at your option.
17 ######################################################################
20 import string
, sys
, os
, re
26 Skip
= svntest
.testcase
.Skip
27 SkipUnless
= svntest
.testcase
.SkipUnless
28 XFail
= svntest
.testcase
.XFail
29 Item
= svntest
.wc
.StateItem
32 ######################################################################
36 def mod_all_files(wc_dir
, new_text
):
37 """Walk over working copy WC_DIR, appending NEW_TEXT to all the
38 files in that tree (but not inside the .svn areas of that tree)."""
40 def tweak_files(new_text
, dirname
, names
):
41 if os
.path
.basename(dirname
) == ".svn":
45 full_path
= os
.path
.join(dirname
, name
)
46 if os
.path
.isfile(full_path
):
47 svntest
.main
.file_append(full_path
, new_text
)
49 os
.path
.walk(wc_dir
, tweak_files
, new_text
)
51 def changelist_all_files(wc_dir
, name_func
):
52 """Walk over working copy WC_DIR, adding versioned files to
53 changelists named by invoking NAME_FUNC(full-path-of-file) and
54 noting its string return value (or None, if we wish to remove the
55 file from a changelist)."""
57 def do_changelist(name_func
, dirname
, names
):
58 if os
.path
.basename(dirname
) == ".svn":
62 full_path
= os
.path
.join(dirname
, name
)
63 if os
.path
.isfile(full_path
):
64 clname
= name_func(full_path
)
66 svntest
.main
.run_svn(None, "changelist", "--remove", full_path
)
68 svntest
.main
.run_svn(None, "changelist", clname
, full_path
)
70 os
.path
.walk(wc_dir
, do_changelist
, name_func
)
72 def clname_from_lastchar_cb(full_path
):
73 """Callback for changelist_all_files() that returns a changelist
74 name matching the last character in the file's name. For example,
75 after running this on a greek tree where every file has some text
76 modification, 'svn status' shows:
101 # Regular expressions for 'svn changelist' output.
102 _re_cl_add
= re
.compile("Path '(.*)' is now a member of changelist '(.*)'.")
103 _re_cl_rem
= re
.compile("Path '(.*)' is no longer a member of a changelist.")
105 def verify_changelist_output(output
, expected_adds
=None,
106 expected_removals
=None):
107 """Compare lines of OUTPUT from 'svn changelist' against
108 EXPECTED_ADDS (a dictionary mapping paths to changelist names) and
109 EXPECTED_REMOVALS (a dictionary mapping paths to ... whatever)."""
113 num_expected
+= len(expected_adds
)
114 if expected_removals
:
115 num_expected
+= len(expected_removals
)
117 if len(output
) != num_expected
:
118 raise svntest
.Failure("Unexpected number of 'svn changelist' output lines")
122 match
= _re_cl_rem
.match(line
)
124 and expected_removals \
125 and expected_removals
.has_key(match
.group(1)):
128 raise svntest
.Failure("Unexpected changelist removal line: " + line
)
129 match
= _re_cl_add
.match(line
)
132 and expected_adds
.get(match
.group(1)) == match
.group(2):
135 raise svntest
.Failure("Unexpected changelist add line: " + line
)
136 raise svntest
.Failure("Unexpected line: " + line
)
138 def verify_pget_output(output
, expected_props
):
139 """Compare lines of OUTPUT from 'svn propget' against EXPECTED_PROPS
140 (a dictionary mapping paths to property values)."""
142 _re_pget
= re
.compile('^(.*) - (.*)$')
146 path
, prop
= line
.rstrip().split(' - ')
148 raise svntest
.Failure("Unexpected output line: " + line
)
149 actual_props
[path
] = prop
150 if expected_props
!= actual_props
:
151 raise svntest
.Failure("Got unexpected property results")
154 ######################################################################
157 # Each test must return on success or raise on failure.
160 #----------------------------------------------------------------------
162 def add_remove_changelists(sbox
):
163 "add and remove files from changelists"
168 ### First, we play with just adding to changelists ###
170 # svn changelist foo WC_DIR
171 output
, errput
= svntest
.main
.run_svn(None, "changelist", "foo",
173 verify_changelist_output(output
) # nothing expected
175 # svn changelist foo WC_DIR --depth files
176 output
, errput
= svntest
.main
.run_svn(None, "changelist", "foo",
180 os
.path
.join(wc_dir
, 'iota') : 'foo',
182 verify_changelist_output(output
, expected_adds
)
184 # svn changelist foo WC_DIR --depth infinity
185 output
, errput
= svntest
.main
.run_svn(None, "changelist", "foo",
186 "--depth", "infinity",
189 os
.path
.join(wc_dir
, 'A', 'B', 'E', 'alpha') : 'foo',
190 os
.path
.join(wc_dir
, 'A', 'B', 'E', 'beta') : 'foo',
191 os
.path
.join(wc_dir
, 'A', 'B', 'lambda') : 'foo',
192 os
.path
.join(wc_dir
, 'A', 'D', 'G', 'pi') : 'foo',
193 os
.path
.join(wc_dir
, 'A', 'D', 'G', 'rho') : 'foo',
194 os
.path
.join(wc_dir
, 'A', 'D', 'G', 'tau') : 'foo',
195 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'chi') : 'foo',
196 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'omega') : 'foo',
197 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'psi') : 'foo',
198 os
.path
.join(wc_dir
, 'A', 'D', 'gamma') : 'foo',
199 os
.path
.join(wc_dir
, 'A', 'mu') : 'foo',
201 verify_changelist_output(output
, expected_adds
)
203 ### Now, change some changelists ###
205 # svn changelist bar WC_DIR/A/D --depth infinity
206 output
, errput
= svntest
.main
.run_svn(".*", "changelist", "bar",
207 "--depth", "infinity",
208 os
.path
.join(wc_dir
, 'A', 'D'))
210 os
.path
.join(wc_dir
, 'A', 'D', 'G', 'pi') : 'bar',
211 os
.path
.join(wc_dir
, 'A', 'D', 'G', 'rho') : 'bar',
212 os
.path
.join(wc_dir
, 'A', 'D', 'G', 'tau') : 'bar',
213 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'chi') : 'bar',
214 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'omega') : 'bar',
215 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'psi') : 'bar',
216 os
.path
.join(wc_dir
, 'A', 'D', 'gamma') : 'bar',
218 verify_changelist_output(output
, expected_adds
)
220 # svn changelist baz WC_DIR/A/D/H --depth infinity
221 output
, errput
= svntest
.main
.run_svn(".*", "changelist", "baz",
222 "--depth", "infinity",
223 os
.path
.join(wc_dir
, 'A', 'D', 'H'))
225 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'chi') : 'baz',
226 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'omega') : 'baz',
227 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'psi') : 'baz',
229 verify_changelist_output(output
, expected_adds
)
231 ### Now, let's selectively rename some changelists ###
233 # svn changelist foo-rename WC_DIR --depth infinity --changelist foo
234 output
, errput
= svntest
.main
.run_svn(".*", "changelist", "foo-rename",
235 "--depth", "infinity",
236 "--changelist", "foo",
239 os
.path
.join(wc_dir
, 'A', 'B', 'E', 'alpha') : 'foo-rename',
240 os
.path
.join(wc_dir
, 'A', 'B', 'E', 'beta') : 'foo-rename',
241 os
.path
.join(wc_dir
, 'A', 'B', 'lambda') : 'foo-rename',
242 os
.path
.join(wc_dir
, 'A', 'mu') : 'foo-rename',
243 os
.path
.join(wc_dir
, 'iota') : 'foo-rename',
245 verify_changelist_output(output
, expected_adds
)
247 # svn changelist bar WC_DIR --depth infinity
248 # --changelist foo-rename --changelist baz
249 output
, errput
= svntest
.main
.run_svn(".*", "changelist", "bar",
250 "--depth", "infinity",
251 "--changelist", "foo-rename",
252 "--changelist", "baz",
255 os
.path
.join(wc_dir
, 'A', 'B', 'E', 'alpha') : 'bar',
256 os
.path
.join(wc_dir
, 'A', 'B', 'E', 'beta') : 'bar',
257 os
.path
.join(wc_dir
, 'A', 'B', 'lambda') : 'bar',
258 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'chi') : 'bar',
259 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'omega') : 'bar',
260 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'psi') : 'bar',
261 os
.path
.join(wc_dir
, 'A', 'mu') : 'bar',
262 os
.path
.join(wc_dir
, 'iota') : 'bar',
264 verify_changelist_output(output
, expected_adds
)
266 ### Okay. Time to remove some stuff from changelists now. ###
268 # svn changelist --remove WC_DIR
269 output
, errput
= svntest
.main
.run_svn(None, "changelist", "--remove",
271 verify_changelist_output(output
) # nothing expected
273 # svn changelist --remove WC_DIR --depth files
274 output
, errput
= svntest
.main
.run_svn(None, "changelist", "--remove",
277 expected_removals
= {
278 os
.path
.join(wc_dir
, 'iota') : None,
280 verify_changelist_output(output
, None, expected_removals
)
282 # svn changelist --remove WC_DIR --depth infinity
283 output
, errput
= svntest
.main
.run_svn(None, "changelist", "--remove",
284 "--depth", "infinity",
286 expected_removals
= {
287 os
.path
.join(wc_dir
, 'A', 'B', 'E', 'alpha') : None,
288 os
.path
.join(wc_dir
, 'A', 'B', 'E', 'beta') : None,
289 os
.path
.join(wc_dir
, 'A', 'B', 'lambda') : None,
290 os
.path
.join(wc_dir
, 'A', 'D', 'G', 'pi') : None,
291 os
.path
.join(wc_dir
, 'A', 'D', 'G', 'rho') : None,
292 os
.path
.join(wc_dir
, 'A', 'D', 'G', 'tau') : None,
293 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'chi') : None,
294 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'omega') : None,
295 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'psi') : None,
296 os
.path
.join(wc_dir
, 'A', 'D', 'gamma') : None,
297 os
.path
.join(wc_dir
, 'A', 'mu') : None,
299 verify_changelist_output(output
, None, expected_removals
)
301 ### Add files to changelists based on the last character in their names ###
303 changelist_all_files(wc_dir
, clname_from_lastchar_cb
)
305 ### Now, do selective changelist removal ###
307 # svn changelist --remove WC_DIR --depth infinity --changelist a
308 output
, errput
= svntest
.main
.run_svn(None, "changelist", "--remove",
309 "--depth", "infinity",
312 expected_removals
= {
313 os
.path
.join(wc_dir
, 'A', 'B', 'E', 'alpha') : None,
314 os
.path
.join(wc_dir
, 'A', 'B', 'E', 'beta') : None,
315 os
.path
.join(wc_dir
, 'A', 'B', 'lambda') : None,
316 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'omega') : None,
317 os
.path
.join(wc_dir
, 'A', 'D', 'gamma') : None,
318 os
.path
.join(wc_dir
, 'iota') : None,
320 verify_changelist_output(output
, None, expected_removals
)
322 # svn changelist --remove WC_DIR --depth infinity
323 # --changelist i --changelist o
324 output
, errput
= svntest
.main
.run_svn(None, "changelist", "--remove",
325 "--depth", "infinity",
329 expected_removals
= {
330 os
.path
.join(wc_dir
, 'A', 'D', 'G', 'pi') : None,
331 os
.path
.join(wc_dir
, 'A', 'D', 'G', 'rho') : None,
332 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'chi') : None,
333 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'psi') : None,
335 verify_changelist_output(output
, None, expected_removals
)
337 #----------------------------------------------------------------------
339 def commit_one_changelist(sbox
):
340 "commit with single --changelist"
345 # Add a line of text to all the versioned files in the tree.
346 mod_all_files(wc_dir
, "New text.\n")
348 # Add files to changelists based on the last character in their names.
349 changelist_all_files(wc_dir
, clname_from_lastchar_cb
)
351 # Now, test a commit that uses a single changelist filter (--changelist a).
352 expected_output
= svntest
.wc
.State(wc_dir
, {
353 'A/B/lambda' : Item(verb
='Sending'),
354 'A/B/E/alpha' : Item(verb
='Sending'),
355 'A/B/E/beta' : Item(verb
='Sending'),
356 'A/D/gamma' : Item(verb
='Sending'),
357 'A/D/H/omega' : Item(verb
='Sending'),
358 'iota' : Item(verb
='Sending'),
360 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
361 expected_status
.tweak('A/mu', 'A/D/G/tau', 'A/D/G/pi', 'A/D/H/chi',
362 'A/D/H/psi', 'A/D/G/rho', wc_rev
=1, status
='M ')
363 expected_status
.tweak('iota', 'A/B/lambda', 'A/B/E/alpha', 'A/B/E/beta',
364 'A/D/gamma', 'A/D/H/omega', wc_rev
=2, status
=' ')
365 svntest
.actions
.run_and_verify_commit(wc_dir
,
373 #----------------------------------------------------------------------
375 def commit_multiple_changelists(sbox
):
376 "commit with multiple --changelist's"
381 # Add a line of text to all the versioned files in the tree.
382 mod_all_files(wc_dir
, "New text.\n")
384 # Add files to changelists based on the last character in their names.
385 changelist_all_files(wc_dir
, clname_from_lastchar_cb
)
387 # Now, test a commit that uses multiple changelist filters
388 # (--changelist=a --changelist=i).
389 expected_output
= svntest
.wc
.State(wc_dir
, {
390 'A/B/lambda' : Item(verb
='Sending'),
391 'A/B/E/alpha' : Item(verb
='Sending'),
392 'A/B/E/beta' : Item(verb
='Sending'),
393 'A/D/gamma' : Item(verb
='Sending'),
394 'A/D/H/omega' : Item(verb
='Sending'),
395 'iota' : Item(verb
='Sending'),
396 'A/D/G/pi' : Item(verb
='Sending'),
397 'A/D/H/chi' : Item(verb
='Sending'),
398 'A/D/H/psi' : Item(verb
='Sending'),
400 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
401 expected_status
.tweak('A/mu', 'A/D/G/tau', 'A/D/G/rho',
402 wc_rev
=1, status
='M ')
403 expected_status
.tweak('iota', 'A/B/lambda', 'A/B/E/alpha', 'A/B/E/beta',
404 'A/D/gamma', 'A/D/H/omega', 'A/D/G/pi', 'A/D/H/chi',
405 'A/D/H/psi', wc_rev
=2, status
=' ')
406 svntest
.actions
.run_and_verify_commit(wc_dir
,
414 #----------------------------------------------------------------------
416 def info_with_changelists(sbox
):
422 # Add files to changelists based on the last character in their names.
423 changelist_all_files(wc_dir
, clname_from_lastchar_cb
)
425 # Now, test various combinations of changelist specification and depths.
426 for clname
in [['a'], ['i'], ['a', 'i']]:
427 for depth
in [None, 'files', 'infinity']:
429 # Figure out what we expect to see in our info output.
432 if depth
== 'infinity':
433 expected_paths
.append('A/B/lambda')
434 expected_paths
.append('A/B/E/alpha')
435 expected_paths
.append('A/B/E/beta')
436 expected_paths
.append('A/D/gamma')
437 expected_paths
.append('A/D/H/omega')
438 if depth
== 'files' or depth
== 'infinity':
439 expected_paths
.append('iota')
441 if depth
== 'infinity':
442 expected_paths
.append('A/D/G/pi')
443 expected_paths
.append('A/D/H/chi')
444 expected_paths
.append('A/D/H/psi')
445 expected_paths
= map(lambda x
:
446 os
.path
.join(wc_dir
, x
.replace('/', os
.sep
)),
448 expected_paths
.sort()
450 # Build the command line.
451 args
= ['info', wc_dir
]
453 args
.append('--changelist')
456 args
.append('--depth')
460 output
, errput
= svntest
.main
.run_svn(None, *args
)
462 # Filter the output for lines that begin with 'Path:', and
463 # reduce even those lines to just the actual path.
464 def startswith_path(line
):
465 return line
[:6] == 'Path: ' and 1 or 0
466 paths
= map(lambda x
: x
[6:].rstrip(), filter(startswith_path
, output
))
470 if (paths
!= expected_paths
):
471 raise svntest
.Failure("Expected paths (%s) and actual paths (%s) "
472 "don't gel" % (str(expected_paths
), str(paths
)))
474 #----------------------------------------------------------------------
476 def diff_with_changelists(sbox
):
477 "diff --changelist (wc-wc and repos-wc)"
482 # Add a line of text to all the versioned files in the tree.
483 mod_all_files(wc_dir
, "New text.\n")
485 # Add files to changelists based on the last character in their names.
486 changelist_all_files(wc_dir
, clname_from_lastchar_cb
)
488 # Now, test various combinations of changelist specification and depths.
489 for is_repos_wc
in [0, 1]:
490 for clname
in [['a'], ['i'], ['a', 'i']]:
491 for depth
in ['files', 'infinity']:
493 # Figure out what we expect to see in our diff output.
496 if depth
== 'infinity':
497 expected_paths
.append('A/B/lambda')
498 expected_paths
.append('A/B/E/alpha')
499 expected_paths
.append('A/B/E/beta')
500 expected_paths
.append('A/D/gamma')
501 expected_paths
.append('A/D/H/omega')
502 if depth
== 'files' or depth
== 'infinity':
503 expected_paths
.append('iota')
505 if depth
== 'infinity':
506 expected_paths
.append('A/D/G/pi')
507 expected_paths
.append('A/D/H/chi')
508 expected_paths
.append('A/D/H/psi')
509 expected_paths
= map(lambda x
:
510 os
.path
.join(wc_dir
, x
.replace('/', os
.sep
)),
512 expected_paths
.sort()
514 # Build the command line.
517 args
.append('--changelist')
520 args
.append('--depth')
524 args
.append(sbox
.repo_url
)
526 args
.append(sbox
.wc_dir
)
531 output
, errput
= svntest
.main
.run_svn(None, *args
)
533 # Filter the output for lines that begin with 'Index:', and
534 # reduce even those lines to just the actual path.
535 def startswith_path(line
):
536 return line
[:7] == 'Index: ' and 1 or 0
537 paths
= map(lambda x
: x
[7:].rstrip(), filter(startswith_path
, output
))
540 # Diff output on Win32 uses '/' path separators.
541 if sys
.platform
== 'win32':
542 paths
= map(lambda x
:
543 x
.replace('/', os
.sep
),
547 if (paths
!= expected_paths
):
548 raise svntest
.Failure("Expected paths (%s) and actual paths (%s) "
550 % (str(expected_paths
), str(paths
)))
552 #----------------------------------------------------------------------
554 def propmods_with_changelists(sbox
):
555 "propset/del/get --changelist"
560 # Add files to changelists based on the last character in their names.
561 changelist_all_files(wc_dir
, clname_from_lastchar_cb
)
563 # Set property 'name'='value' on all working copy items.
564 svntest
.main
.run_svn(None, "pset", "--depth", "infinity",
565 "name", "value", wc_dir
)
566 expected_disk
= svntest
.main
.greek_state
.copy()
567 expected_disk
.add({'' : Item(props
={ 'name' : 'value' })})
568 expected_disk
.tweak('A', 'A/B', 'A/B/E', 'A/B/E/alpha', 'A/B/E/beta',
569 'A/B/F', 'A/B/lambda', 'A/C', 'A/D', 'A/D/G',
570 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 'A/D/H',
571 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi', 'A/D/gamma',
572 'A/mu', 'iota', props
={ 'name' : 'value' })
573 actual_disk_tree
= svntest
.tree
.build_tree_from_wc(wc_dir
, 1)
574 svntest
.tree
.compare_trees("disk", actual_disk_tree
,
575 expected_disk
.old_tree())
577 # Remove the 'name' property from files in the 'o' and 'i' changelists.
578 svntest
.main
.run_svn(None, "pdel", "--depth", "infinity",
579 "name", "--changelist", "o", "--changelist", "i",
581 expected_disk
.tweak('A/D/G/pi', 'A/D/G/rho', 'A/D/H/chi', 'A/D/H/psi',
583 actual_disk_tree
= svntest
.tree
.build_tree_from_wc(wc_dir
, 1)
584 svntest
.tree
.compare_trees("disk", actual_disk_tree
,
585 expected_disk
.old_tree())
587 # Add 'foo'='bar' property on all files under A/B to depth files and
589 svntest
.main
.run_svn(None, "pset", "--depth", "files",
590 "foo", "bar", "--changelist", "a",
591 os
.path
.join(wc_dir
, 'A', 'B'))
592 expected_disk
.tweak('A/B/lambda', props
={ 'name' : 'value',
594 actual_disk_tree
= svntest
.tree
.build_tree_from_wc(wc_dir
, 1)
595 svntest
.tree
.compare_trees("disk", actual_disk_tree
,
596 expected_disk
.old_tree())
598 # Add 'bloo'='blarg' property to all files in changelist 'a'.
599 svntest
.main
.run_svn(None, "pset", "--depth", "infinity",
600 "bloo", "blarg", "--changelist", "a",
602 expected_disk
.tweak('A/B/lambda', props
={ 'name' : 'value',
605 expected_disk
.tweak('A/B/E/alpha', 'A/B/E/beta', 'A/D/H/omega', 'A/D/gamma',
606 'iota', props
={ 'name' : 'value',
608 actual_disk_tree
= svntest
.tree
.build_tree_from_wc(wc_dir
, 1)
609 svntest
.tree
.compare_trees("disk", actual_disk_tree
,
610 expected_disk
.old_tree())
612 # Propget 'name' in files in changelists 'a' and 'i' to depth files.
613 output
, errput
= svntest
.main
.run_svn(None, "pget",
614 "--depth", "files", "name",
618 verify_pget_output(output
, {
619 os
.path
.join(wc_dir
, 'iota') : 'value',
622 # Propget 'name' in files in changelists 'a' and 'i' to depth infinity.
623 output
, errput
= svntest
.main
.run_svn(None, "pget",
624 "--depth", "infinity", "name",
628 verify_pget_output(output
, {
629 os
.path
.join(wc_dir
, 'A', 'D', 'gamma') : 'value',
630 os
.path
.join(wc_dir
, 'A', 'B', 'E', 'alpha') : 'value',
631 os
.path
.join(wc_dir
, 'iota') : 'value',
632 os
.path
.join(wc_dir
, 'A', 'B', 'E', 'beta') : 'value',
633 os
.path
.join(wc_dir
, 'A', 'B', 'lambda') : 'value',
634 os
.path
.join(wc_dir
, 'A', 'D', 'H', 'omega') : 'value',
638 #----------------------------------------------------------------------
640 def revert_with_changelists(sbox
):
641 "revert --changelist"
646 # Add files to changelists based on the last character in their names.
647 changelist_all_files(wc_dir
, clname_from_lastchar_cb
)
649 # Add a line of text to all the versioned files in the tree.
650 mod_all_files(wc_dir
, "Please, oh please, revert me!\n")
651 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
652 expected_status
.tweak('A/B/lambda', 'A/B/E/alpha', 'A/B/E/beta',
653 'A/D/gamma', 'A/D/H/omega', 'iota', 'A/mu',
654 'A/D/G/tau', 'A/D/G/pi', 'A/D/H/chi',
655 'A/D/H/psi', 'A/D/G/rho', status
='M ')
656 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status
)
658 # 'svn revert --changelist a WC_DIR' (without depth, no change expected)
659 svntest
.main
.run_svn(None, "revert", "--changelist", "a", wc_dir
)
660 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status
)
662 # 'svn revert --changelist o --depth files WC_DIR WC_DIR/A/B' (no change)
663 svntest
.main
.run_svn(None, "revert", "--depth", "files",
665 wc_dir
, os
.path
.join(wc_dir
, 'A', 'B'))
666 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status
)
668 # 'svn revert --changelist a --depth files WC_DIR WC_DIR/A/B'
669 # (iota, lambda reverted)
670 svntest
.main
.run_svn(None, "revert", "--depth", "files",
672 wc_dir
, os
.path
.join(wc_dir
, 'A', 'B'))
673 expected_status
.tweak('iota', 'A/B/lambda', status
=' ')
674 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status
)
676 # 'svn revert --changelist a --changelist i --depth infinity WC_DIR'
677 # (alpha, beta, gamma, omega, pi, chi, psi reverted)
678 svntest
.main
.run_svn(None, "revert", "--depth", "infinity",
679 "--changelist", "a", "--changelist", "i",
681 expected_status
.tweak('A/B/E/alpha', 'A/B/E/beta', 'A/D/gamma',
682 'A/D/H/omega', 'A/D/G/pi', 'A/D/H/chi',
683 'A/D/H/psi', status
=' ')
684 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status
)
686 # 'svn revert --depth infinity WC_DIR' (back to pristine-ness)
687 svntest
.main
.run_svn(None, "revert", "--depth", "infinity",
689 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 1)
690 svntest
.actions
.run_and_verify_status(wc_dir
, expected_status
)
692 #----------------------------------------------------------------------
694 def update_with_changelists(sbox
):
695 "update --changelist"
700 # Add a line of text to all the versioned files in the tree, commit, update.
701 mod_all_files(wc_dir
, "Added line.\n")
702 svntest
.main
.run_svn(None, "commit", "-m", "logmsg", wc_dir
)
703 svntest
.main
.run_svn(None, "update", wc_dir
)
705 # Add files to changelists based on the last character in their names.
706 changelist_all_files(wc_dir
, clname_from_lastchar_cb
)
708 ### Backdate only the files in the 'a' and 'i' changelists at depth
709 ### files under WC_DIR and WC_DIR/A/B.
711 # We expect update to only touch lambda and iota.
712 expected_output
= svntest
.wc
.State(wc_dir
, {
713 'A/B/lambda' : Item(status
='U '),
714 'iota' : Item(status
='U '),
717 # Disk state should have all the files except iota and lambda
719 expected_disk
= svntest
.main
.greek_state
.copy()
720 expected_disk
.tweak('A/B/E/alpha',
721 contents
="This is the file 'alpha'.\nAdded line.\n")
722 expected_disk
.tweak('A/B/E/beta',
723 contents
="This is the file 'beta'.\nAdded line.\n")
724 expected_disk
.tweak('A/D/gamma',
725 contents
="This is the file 'gamma'.\nAdded line.\n")
726 expected_disk
.tweak('A/D/H/omega',
727 contents
="This is the file 'omega'.\nAdded line.\n")
728 expected_disk
.tweak('A/mu',
729 contents
="This is the file 'mu'.\nAdded line.\n")
730 expected_disk
.tweak('A/D/G/tau',
731 contents
="This is the file 'tau'.\nAdded line.\n")
732 expected_disk
.tweak('A/D/G/pi',
733 contents
="This is the file 'pi'.\nAdded line.\n")
734 expected_disk
.tweak('A/D/H/chi',
735 contents
="This is the file 'chi'.\nAdded line.\n")
736 expected_disk
.tweak('A/D/H/psi',
737 contents
="This is the file 'psi'.\nAdded line.\n")
738 expected_disk
.tweak('A/D/G/rho',
739 contents
="This is the file 'rho'.\nAdded line.\n")
741 # Status is clean, but with iota and lambda at r1 and all else at r2.
742 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 2)
743 expected_status
.tweak('iota', 'A/B/lambda', wc_rev
=1)
746 svntest
.actions
.run_and_verify_update(wc_dir
,
757 os
.path
.join(wc_dir
, 'A', 'B'))
759 ### Backdate to depth infinity all changelists "a", "i", and "o" now.
761 # We expect update to only touch all the files ending in 'a', 'i',
762 # and 'o' (except lambda and iota which were previously updated).
763 expected_output
= svntest
.wc
.State(wc_dir
, {
764 'A/D/G/pi' : Item(status
='U '),
765 'A/D/H/chi' : Item(status
='U '),
766 'A/D/H/psi' : Item(status
='U '),
767 'A/D/G/rho' : Item(status
='U '),
768 'A/B/E/alpha' : Item(status
='U '),
769 'A/B/E/beta' : Item(status
='U '),
770 'A/D/gamma' : Item(status
='U '),
771 'A/D/H/omega' : Item(status
='U '),
774 # Disk state should have only tau and mu carrying new text.
775 expected_disk
= svntest
.main
.greek_state
.copy()
776 expected_disk
.tweak('A/mu',
777 contents
="This is the file 'mu'.\nAdded line.\n")
778 expected_disk
.tweak('A/D/G/tau',
779 contents
="This is the file 'tau'.\nAdded line.\n")
781 # Status is clean, but with iota and lambda at r1 and all else at r2.
782 expected_status
= svntest
.actions
.get_virginal_state(wc_dir
, 2)
783 expected_status
.tweak('iota', 'A/B/lambda', 'A/D/G/pi', 'A/D/H/chi',
784 'A/D/H/psi', 'A/D/G/rho', 'A/B/E/alpha',
785 'A/B/E/beta', 'A/D/gamma', 'A/D/H/omega', wc_rev
=1)
788 svntest
.actions
.run_and_verify_update(wc_dir
,
798 "--depth", "infinity",
802 ########################################################################
805 # list all tests here, starting with None:
807 add_remove_changelists
,
808 commit_one_changelist
,
809 commit_multiple_changelists
,
810 info_with_changelists
,
811 diff_with_changelists
,
812 propmods_with_changelists
,
813 revert_with_changelists
,
814 update_with_changelists
,
817 if __name__
== '__main__':
818 svntest
.main
.run_tests(test_list
)