summaryrefslogtreecommitdiff
path: root/subversion/tests/cmdline/externals_tests.py
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/tests/cmdline/externals_tests.py')
-rwxr-xr-xsubversion/tests/cmdline/externals_tests.py1234
1 files changed, 1135 insertions, 99 deletions
diff --git a/subversion/tests/cmdline/externals_tests.py b/subversion/tests/cmdline/externals_tests.py
index cea6933..36ccaa6 100755
--- a/subversion/tests/cmdline/externals_tests.py
+++ b/subversion/tests/cmdline/externals_tests.py
@@ -28,7 +28,7 @@
import sys
import os
import re
-import tempfile
+import shutil
# Our testing module
import svntest
@@ -214,25 +214,18 @@ def externals_test_setup(sbox):
def change_external(path, new_val, commit=True):
"""Change the value of the externals property on PATH to NEW_VAL,
and commit the change unless COMMIT is False."""
- (fd, tmp_f) = tempfile.mkstemp(dir=svntest.main.temp_dir)
- svntest.main.file_append(tmp_f, new_val)
- svntest.actions.run_and_verify_svn(None, None, [], 'pset',
- '-F', tmp_f, 'svn:externals', path)
+
+ svntest.actions.set_prop('svn:externals', new_val, path)
if commit:
svntest.actions.run_and_verify_svn(None, None, [], 'ci',
'-m', 'log msg', '--quiet', path)
- os.close(fd)
- os.remove(tmp_f)
def change_external_expect_error(path, new_val, expected_err):
"""Try to change the value of the externals property on PATH to NEW_VAL,
but expect to get an error message that matches EXPECTED_ERR."""
- (fd, tmp_f) = tempfile.mkstemp(dir=svntest.main.temp_dir)
- svntest.main.file_append(tmp_f, new_val)
- svntest.actions.run_and_verify_svn(None, None, expected_err, 'pset',
- '-F', tmp_f, 'svn:externals', path)
- os.close(fd)
- os.remove(tmp_f)
+
+ svntest.actions.set_prop('svn:externals', new_val, path,
+ expected_re_string=expected_err)
def probe_paths_exist(paths):
@@ -282,24 +275,24 @@ def checkout_with_externals(sbox):
# Probe the working copy a bit, see if it's as expected.
expected_existing_paths = [
- os.path.join(wc_dir, "A", "B", "gamma"),
- os.path.join(wc_dir, "A", "C", "exdir_G"),
- os.path.join(wc_dir, "A", "C", "exdir_G", "pi"),
- os.path.join(wc_dir, "A", "C", "exdir_H"),
- os.path.join(wc_dir, "A", "C", "exdir_H", "omega"),
- os.path.join(wc_dir, "A", "D", "x"),
- os.path.join(wc_dir, "A", "D", "x", "y"),
- os.path.join(wc_dir, "A", "D", "x", "y", "z"),
- os.path.join(wc_dir, "A", "D", "x", "y", "z", "blah"),
- os.path.join(wc_dir, "A", "D", "x", "y", "z", "blah", "E", "alpha"),
- os.path.join(wc_dir, "A", "D", "x", "y", "z", "blah", "E", "beta"),
+ sbox.ospath('A/B/gamma'),
+ sbox.ospath('A/C/exdir_G'),
+ sbox.ospath('A/C/exdir_G/pi'),
+ sbox.ospath('A/C/exdir_H'),
+ sbox.ospath('A/C/exdir_H/omega'),
+ sbox.ospath('A/D/x'),
+ sbox.ospath('A/D/x/y'),
+ sbox.ospath('A/D/x/y/z'),
+ sbox.ospath('A/D/x/y/z/blah'),
+ sbox.ospath('A/D/x/y/z/blah/E/alpha'),
+ sbox.ospath('A/D/x/y/z/blah/E/beta'),
]
probe_paths_exist(expected_existing_paths)
# Pick a file at random, make sure it has the expected contents.
- for path, contents in ((os.path.join(wc_dir, "A", "C", "exdir_H", "omega"),
+ for path, contents in ((sbox.ospath('A/C/exdir_H/omega'),
"This is the file 'omega'.\n"),
- (os.path.join(wc_dir, "A", "B", "gamma"),
+ (sbox.ospath('A/B/gamma'),
"This is the file 'gamma'.\n")):
if open(path).read() != contents:
raise svntest.Failure("Unexpected contents for rev 1 of " + path)
@@ -340,7 +333,7 @@ def update_receive_new_external(sbox):
"\n"
# Set and commit the property
- change_external(os.path.join(wc_dir, "A/D"), new_externals_desc)
+ change_external(sbox.ospath('A/D'), new_externals_desc)
# Update the other working copy, see if we get the new item.
expected_output = svntest.wc.State(other_wc_dir, {
@@ -398,7 +391,7 @@ def update_lose_external(sbox):
"\n"
# Set and commit the property
- change_external(os.path.join(wc_dir, "A/D"), new_externals_desc)
+ change_external(sbox.ospath('A/D'), new_externals_desc)
# The code should handle a missing local externals item
svntest.main.safe_rmtree(os.path.join(other_wc_dir, "A", "D", "exdir_A", \
@@ -462,7 +455,7 @@ def update_change_pristine_external(sbox):
"\n"
# Set and commit the property
- change_external(os.path.join(wc_dir, "A/D"), new_externals_desc)
+ change_external(sbox.ospath('A/D'), new_externals_desc)
# Update other working copy, see if get the right change.
expected_output = svntest.wc.State(other_wc_dir, {
@@ -523,7 +516,7 @@ def update_change_modified_external(sbox):
"\n"
# Set and commit the property
- change_external(os.path.join(wc_dir, "A/D"), new_externals_desc)
+ change_external(sbox.ospath('A/D'), new_externals_desc)
# Update other working copy, see if get the right change.
expected_output = svntest.wc.State(other_wc_dir, {
@@ -591,7 +584,7 @@ def update_receive_change_under_external(sbox):
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
- external_gamma_path = os.path.join(wc_dir, 'A', 'D', 'exdir_A', 'D', 'gamma')
+ external_gamma_path = sbox.ospath('A/D/exdir_A/D/gamma')
contents = open(external_gamma_path).read()
if contents != ("This is the file 'gamma'.\n"
"New text in other gamma.\n"):
@@ -619,7 +612,7 @@ def update_receive_change_under_external(sbox):
svntest.actions.run_and_verify_update(sbox.ospath('A/C'),
expected_output, None, None)
- external_rho_path = os.path.join(wc_dir, 'A', 'C', 'exdir_G', 'rho')
+ external_rho_path = sbox.ospath('A/C/exdir_G/rho')
contents = open(external_rho_path).read()
if contents != ("This is the file 'rho'.\n"
"New text in other rho.\n"):
@@ -641,7 +634,7 @@ def modify_and_update_receive_new_external(sbox):
repo_url, wc_dir)
# Add one more external item
- B_path = os.path.join(wc_dir, "A/B")
+ B_path = sbox.ospath('A/B')
externals_desc = \
external_url_for["A/D/exdir_A/G/"] + " exdir_G" + \
"\n" + \
@@ -685,11 +678,11 @@ def disallow_dot_or_dotdot_directory_reference(sbox):
"'.*' is an absolute path or involves '..'.*"
change_external_expect_error(path, val, expected_err)
- B_path = os.path.join(wc_dir, 'A', 'B')
- G_path = os.path.join(wc_dir, 'A', 'D', 'G')
- H_path = os.path.join(wc_dir, 'A', 'D', 'H')
- C_path = os.path.join(wc_dir, 'A', 'C')
- F_path = os.path.join(wc_dir, 'A', 'B', 'F')
+ B_path = sbox.ospath('A/B')
+ G_path = sbox.ospath('A/D/G')
+ H_path = sbox.ospath('A/D/H')
+ C_path = sbox.ospath('A/C')
+ F_path = sbox.ospath('A/B/F')
external_urls = list(external_url_for.values())
@@ -752,28 +745,28 @@ def export_with_externals(sbox):
# Probe the working copy a bit, see if it's as expected.
expected_existing_paths = [
- os.path.join(wc_dir, "A", "C", "exdir_G"),
- os.path.join(wc_dir, "A", "C", "exdir_G", "pi"),
- os.path.join(wc_dir, "A", "C", "exdir_H"),
- os.path.join(wc_dir, "A", "C", "exdir_H", "omega"),
- os.path.join(wc_dir, "A", "D", "x"),
- os.path.join(wc_dir, "A", "D", "x", "y"),
- os.path.join(wc_dir, "A", "D", "x", "y", "z"),
- os.path.join(wc_dir, "A", "D", "x", "y", "z", "blah"),
- os.path.join(wc_dir, "A", "D", "x", "y", "z", "blah", "E", "alpha"),
- os.path.join(wc_dir, "A", "D", "x", "y", "z", "blah", "E", "beta"),
+ sbox.ospath('A/C/exdir_G'),
+ sbox.ospath('A/C/exdir_G/pi'),
+ sbox.ospath('A/C/exdir_H'),
+ sbox.ospath('A/C/exdir_H/omega'),
+ sbox.ospath('A/D/x'),
+ sbox.ospath('A/D/x/y'),
+ sbox.ospath('A/D/x/y/z'),
+ sbox.ospath('A/D/x/y/z/blah'),
+ sbox.ospath('A/D/x/y/z/blah/E/alpha'),
+ sbox.ospath('A/D/x/y/z/blah/E/beta'),
]
probe_paths_exist(expected_existing_paths)
# Pick some files, make sure their contents are as expected.
- exdir_G_pi_path = os.path.join(wc_dir, "A", "C", "exdir_G", "pi")
+ exdir_G_pi_path = sbox.ospath('A/C/exdir_G/pi')
contents = open(exdir_G_pi_path).read()
if contents != ("This is the file 'pi'.\n"
"Added to pi in revision 3.\n"):
raise svntest.Failure("Unexpected contents for rev 1 of " +
exdir_G_pi_path)
- exdir_H_omega_path = os.path.join(wc_dir, "A", "C", "exdir_H", "omega")
+ exdir_H_omega_path = sbox.ospath('A/C/exdir_H/omega')
contents = open(exdir_H_omega_path).read()
if contents != "This is the file 'omega'.\n":
raise svntest.Failure("Unexpected contents for rev 1 of " +
@@ -855,7 +848,7 @@ def external_with_peg_and_op_revision(sbox):
"\n"
# Set and commit the property.
- change_external(os.path.join(wc_dir, "A/D"), new_externals_desc)
+ change_external(sbox.ospath('A/D'), new_externals_desc)
# Update other working copy, see if we get the right change.
expected_output = svntest.wc.State(wc_dir, {
@@ -866,7 +859,7 @@ def external_with_peg_and_op_revision(sbox):
expected_output, None, None)
- external_chi_path = os.path.join(wc_dir, 'A', 'D', 'exdir_A', 'H', 'chi')
+ external_chi_path = sbox.ospath('A/D/exdir_A/H/chi')
contents = open(external_chi_path).read()
if contents != "This is the file 'chi'.\n":
raise svntest.Failure("Unexpected contents for externally modified " +
@@ -896,7 +889,7 @@ def new_style_externals(sbox):
"\n"
# Set and commit the property.
- change_external(os.path.join(wc_dir, "A/C"), new_externals_desc)
+ change_external(sbox.ospath('A/C'), new_externals_desc)
# Update other working copy.
expected_output = svntest.wc.State(wc_dir, {
@@ -922,7 +915,7 @@ def disallow_propset_invalid_formatted_externals(sbox):
sbox.build()
wc_dir = sbox.wc_dir
- A_path = os.path.join(wc_dir, 'A')
+ A_path = sbox.ospath('A')
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -997,7 +990,7 @@ def old_style_externals_ignore_peg_reg(sbox):
ext = "exdir_G " + external_url_for["A/C/exdir_G"] + "@HEAD\n"
# Set and commit the property.
- change_external(os.path.join(wc_dir, "A"), ext)
+ change_external(sbox.ospath('A'), ext)
# Update the working copy. This should succeed (exitcode 0) but
# should print warnings on the external because the URL with '@HEAD'
@@ -1034,7 +1027,7 @@ def cannot_move_or_remove_file_externals(sbox):
".*gamma.*; please .* "
"the svn:externals .*",
'rm',
- os.path.join(wc_dir, 'A', 'B', 'gamma'))
+ sbox.ospath('A/B/gamma'))
# Should not be able to move the file external.
svntest.actions.run_and_verify_svn("Able to move file external",
@@ -1043,15 +1036,15 @@ def cannot_move_or_remove_file_externals(sbox):
".*gamma.*; please .*edit.*"
"svn:externals.*",
'mv',
- os.path.join(wc_dir, 'A', 'B', 'gamma'),
- os.path.join(wc_dir, 'A', 'B', 'gamma1'))
+ sbox.ospath('A/B/gamma'),
+ sbox.ospath('A/B/gamma1'))
# But the directory that contains it can be deleted.
expected_status = svntest.actions.get_virginal_state(wc_dir, 6)
svntest.actions.run_and_verify_svn(None, None, [],
'rm',
- os.path.join(wc_dir, "A", "B"))
+ sbox.ospath('A/B'))
expected_status.tweak('A/B', status='D ')
expected_output = svntest.wc.State(wc_dir, {
@@ -1062,10 +1055,51 @@ def cannot_move_or_remove_file_externals(sbox):
'A/B/F', 'A/B/lambda')
expected_status.add({
- 'A/D/exdir_A' : Item(status='X '),
- 'A/D/x' : Item(status='X '),
- 'A/C/exdir_H' : Item(status='X '),
- 'A/C/exdir_G' : Item(status='X '),
+ 'A/D/exdir_A' : Item(status=' ', wc_rev='5', prev_status='X '),
+ 'A/D/exdir_A/D' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/gamma' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/G' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/G/pi' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/G/rho' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/G/tau' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/H' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/H/chi' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/H/psi' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/H/omega' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/B' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/B/E' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/B/E/beta' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/B/E/alpha' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/B/F' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/B/lambda' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/G' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/G/pi' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/G/tau' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/G/rho' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/H' : Item(status=' ', wc_rev='1'),
+ 'A/D/exdir_A/H/psi' : Item(status=' ', wc_rev='1'),
+ 'A/D/exdir_A/H/omega' : Item(status=' ', wc_rev='1'),
+ 'A/D/exdir_A/H/chi' : Item(status=' ', wc_rev='1'),
+ 'A/D/exdir_A/C' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/mu' : Item(status=' ', wc_rev='5'),
+
+ 'A/C/exdir_G' : Item(status=' ', prev_status='X ', wc_rev='5'),
+ 'A/C/exdir_G/tau' : Item(status=' ', wc_rev='5'),
+ 'A/C/exdir_G/pi' : Item(status=' ', wc_rev='5'),
+ 'A/C/exdir_G/rho' : Item(status=' ', wc_rev='5'),
+
+ 'A/D/x' : Item(status='X '),
+ 'A/D/x/y/z/blah' : Item(status=' ', wc_rev='5'),
+ 'A/D/x/y/z/blah/lambda' : Item(status=' ', wc_rev='5'),
+ 'A/D/x/y/z/blah/E' : Item(status=' ', wc_rev='5'),
+ 'A/D/x/y/z/blah/E/beta' : Item(status=' ', wc_rev='5'),
+ 'A/D/x/y/z/blah/E/alpha': Item(status=' ', wc_rev='5'),
+ 'A/D/x/y/z/blah/F' : Item(status=' ', wc_rev='5'),
+
+ 'A/C/exdir_H' : Item(status=' ', prev_status='X ', wc_rev='1'),
+ 'A/C/exdir_H/omega' : Item(status=' ', wc_rev='1'),
+ 'A/C/exdir_H/chi' : Item(status=' ', wc_rev='1'),
+ 'A/C/exdir_H/psi' : Item(status=' ', wc_rev='1'),
})
svntest.actions.run_and_verify_commit(wc_dir,
@@ -1079,7 +1113,7 @@ def cannot_move_or_remove_file_externals(sbox):
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
- open(os.path.join(wc_dir, 'A', 'D', 'gamma')).close()
+ open(sbox.ospath('A/D/gamma')).close()
#----------------------------------------------------------------------
@@ -1146,8 +1180,8 @@ def external_into_path_with_spaces(sbox):
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
probe_paths_exist([
- os.path.join(wc_dir, 'A', 'copy of D'),
- os.path.join(wc_dir, 'A', 'another copy of D'),
+ sbox.ospath('A/copy of D'),
+ sbox.ospath('A/another copy of D'),
])
#----------------------------------------------------------------------
@@ -1162,7 +1196,7 @@ def binary_file_externals(sbox):
# Add a binary file A/theta, write PNG file data into it.
theta_contents = open(os.path.join(sys.path[0], "theta.bin"), 'rb').read()
- theta_path = os.path.join(wc_dir, 'A', 'theta')
+ theta_path = sbox.ospath('A/theta')
svntest.main.file_write(theta_path, theta_contents, 'wb')
svntest.main.run_svn(None, 'add', theta_path)
@@ -1182,7 +1216,7 @@ def binary_file_externals(sbox):
# Create a file external on the binary file A/theta
- C = os.path.join(wc_dir, 'A', 'C')
+ C = sbox.ospath('A/C')
external = os.path.join(C, 'external')
externals_prop = "^/A/theta external\n"
@@ -1233,7 +1267,7 @@ def update_lose_file_external(sbox):
# Create a file external in A/C/external on the file A/mu
- C = os.path.join(wc_dir, 'A', 'C')
+ C = sbox.ospath('A/C')
external = os.path.join(C, 'external')
externals_prop = "^/A/mu external\n"
@@ -1303,7 +1337,7 @@ def update_lose_file_external(sbox):
None, None, None, None, None,
True)
- probe_paths_missing([os.path.join(wc_dir, 'A', 'C', 'external')])
+ probe_paths_missing([sbox.ospath('A/C/external')])
#----------------------------------------------------------------------
@@ -1318,8 +1352,8 @@ def switch_relative_external(sbox):
repo_url = sbox.repo_url
# Create a relative external in A/D on ../B
- A_path = os.path.join(wc_dir, 'A')
- A_copy_path = os.path.join(wc_dir, 'A_copy')
+ A_path = sbox.ospath('A')
+ A_copy_path = sbox.ospath('A_copy')
A_copy_url = repo_url + '/A_copy'
D_path = os.path.join(A_path, 'D')
ext_path = os.path.join(D_path, 'ext')
@@ -1405,7 +1439,7 @@ def relegate_external(sbox):
wc_dir = sbox.wc_dir
repo_dir = sbox.repo_dir
repo_url = sbox.repo_url
- A_path = os.path.join(wc_dir, 'A')
+ A_path = sbox.ospath('A')
# setup an external within the same repository
externals_desc = '^/A/B/E external'
@@ -1440,7 +1474,9 @@ def relegate_external(sbox):
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
expected_status.add({
- 'A/external' : Item(status='X '),
+ 'A/external' : Item(status=' ', prev_status='X ', wc_rev='2'),
+ 'A/external/alpha' : Item(status=' ', wc_rev='2'),
+ 'A/external/beta' : Item(status=' ', wc_rev='2'),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
@@ -1461,7 +1497,7 @@ def wc_repos_file_externals(sbox):
repo_url = sbox.repo_url
# Add a file A/theta.
- theta_path = os.path.join(wc_dir, 'A', 'theta')
+ theta_path = sbox.ospath('A/theta')
svntest.main.file_write(theta_path, 'theta', 'w')
svntest.main.run_svn(None, 'add', theta_path)
@@ -1482,7 +1518,7 @@ def wc_repos_file_externals(sbox):
# Create a file external on the file A/theta
- C = os.path.join(wc_dir, 'A', 'C')
+ C = sbox.ospath('A/C')
external = os.path.join(C, 'theta')
externals_prop = "^/A/theta theta\n"
@@ -1564,9 +1600,9 @@ def merge_target_with_externals(sbox):
repo_url = sbox.repo_url
# Some paths we'll care about
- A_path = os.path.join(wc_dir, "A")
- A_branch_path = os.path.join(wc_dir, "A-branch")
- A_gamma_branch_path = os.path.join(wc_dir, "A-branch", "D", "gamma")
+ A_path = sbox.ospath('A')
+ A_branch_path = sbox.ospath('A-branch')
+ A_gamma_branch_path = sbox.ospath('A-branch/D/gamma')
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
@@ -1733,7 +1769,7 @@ def update_external_on_locally_added_dir(sbox):
svntest.actions.run_and_verify_update(wc_dir,
expected_output, None, None)
- probe_paths_exist([os.path.join(wc_dir, "A", "foo", "exdir_E")])
+ probe_paths_exist([sbox.ospath('A/foo/exdir_E')])
# Test for issue #2267
@Issue(2267)
@@ -1782,7 +1818,7 @@ def switch_external_on_locally_added_dir(sbox):
# Switch the working copy to the branch, see if we get the new item.
svntest.actions.run_and_verify_svn(None, None, [], 'sw', A_copy_path, wc_dir)
- probe_paths_exist([os.path.join(wc_dir, "foo", "exdir_E")])
+ probe_paths_exist([sbox.ospath('foo/exdir_E')])
@Issue(3819)
def file_external_in_sibling(sbox):
@@ -1885,10 +1921,52 @@ def exclude_externals(sbox):
expected_status = svntest.actions.get_virginal_state(wc_dir, 6)
expected_status.add({
'A/B/gamma' : Item(status=' ', wc_rev='6', switched='X'),
- 'A/C/exdir_H' : Item(status='X '),
- 'A/C/exdir_G' : Item(status='X '),
- 'A/D/exdir_A' : Item(status='X '),
+
+ 'A/C/exdir_H' : Item(status=' ', prev_status='X ', wc_rev='1'),
+ 'A/C/exdir_H/omega' : Item(status=' ', wc_rev='1'),
+ 'A/C/exdir_H/chi' : Item(status=' ', wc_rev='1'),
+ 'A/C/exdir_H/psi' : Item(status=' ', wc_rev='1'),
+
+ 'A/C/exdir_G' : Item(status=' ', prev_status='X ', wc_rev='5'),
+ 'A/C/exdir_G/pi' : Item(status=' ', wc_rev='5'),
+ 'A/C/exdir_G/rho' : Item(status=' ', wc_rev='5'),
+ 'A/C/exdir_G/tau' : Item(status=' ', wc_rev='5'),
+
+ 'A/D/exdir_A' : Item(status=' ', prev_status='X ', wc_rev='5'),
+ 'A/D/exdir_A/H' : Item(status=' ', wc_rev='1'),
+ 'A/D/exdir_A/H/psi' : Item(status=' ', wc_rev='1'),
+ 'A/D/exdir_A/H/chi' : Item(status=' ', wc_rev='1'),
+ 'A/D/exdir_A/H/omega': Item(status=' ', wc_rev='1'),
+ 'A/D/exdir_A/D' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/H' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/H/chi': Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/H/omega': Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/H/psi': Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/G' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/G/pi': Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/G/rho': Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/G/tau': Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/D/gamma': Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/B' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/B/F' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/B/E' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/B/E/beta': Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/B/E/alpha': Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/B/lambda': Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/C' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/G' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/G/tau' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/G/rho' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/G/pi' : Item(status=' ', wc_rev='5'),
+ 'A/D/exdir_A/mu' : Item(status=' ', wc_rev='5'),
+
'A/D/x' : Item(status='X '),
+ 'A/D/x/y/z/blah' : Item(status=' ', wc_rev='5'),
+ 'A/D/x/y/z/blah/E' : Item(status=' ', wc_rev='5'),
+ 'A/D/x/y/z/blah/E/alpha': Item(status=' ', wc_rev='5'),
+ 'A/D/x/y/z/blah/E/beta': Item(status=' ', wc_rev='5'),
+ 'A/D/x/y/z/blah/lambda': Item(status=' ', wc_rev='5'),
+ 'A/D/x/y/z/blah/F' : Item(status=' ', wc_rev='5'),
})
svntest.actions.run_and_verify_update(wc_dir,
None, None, expected_status, None,
@@ -1941,7 +2019,7 @@ def file_externals_different_url(sbox):
for e in ['r1-e-1', 'r1-e-2', 'r2-e-1', 'r2-e-2', 'rr-e-1']:
actions.run_and_verify_info([{'Repository Root' : r1_url}],
os.path.join(sbox.wc_dir, e))
-
+
svntest.actions.run_and_verify_svn(None, None, [],
'relocate', r1_url, r2_url, wc_dir)
@@ -1986,13 +2064,14 @@ def copy_file_externals(sbox):
# svntest.factory.make(sbox,"""
# svn mkdir X
+ # ### manual edit: add '\n ^/A/mu xmu' to externals definition:
# svn ps svn:externals "^/iota xiota" X
# """)
sbox.build()
wc_dir = sbox.wc_dir
- X = os.path.join(wc_dir, 'X')
+ X = sbox.ospath('X')
# svn mkdir X
expected_stdout = ['A ' + X + '\n']
@@ -2023,9 +2102,9 @@ def copy_file_externals(sbox):
# svn up
# ''')
- X = os.path.join(wc_dir, 'X')
- X_copy = os.path.join(wc_dir, 'X_copy')
- X_xmu = os.path.join(wc_dir, 'X', 'xmu')
+ X = sbox.ospath('X')
+ X_copy = sbox.ospath('X_copy')
+ X_xmu = sbox.ospath('X/xmu')
# svn ci
expected_output = svntest.wc.State(wc_dir, {
@@ -2137,6 +2216,605 @@ def copy_file_externals(sbox):
actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
expected_status, None, None, None, None, None, True, wc_dir)
+def commit_include_externals(sbox):
+ "commit --include-externals"
+ # svntest.factory.make(sbox, """
+ # mkdir Z
+ # echo 'This is the file zeta.' > Z/zeta
+ # svn add Z
+ # svn mkdir --parents Xpegged X/Y
+ # svn ci
+ # svn up
+ # svn ps svn:externals "^/Z xZ" A/D/H
+ # svn ps svn:externals "^/iota@1 Xpegged/xiota" wc_dir
+ # # ^^^ manually set externals to:
+ # # ^/iota@1 Xpegged/xiota
+ # # -r1 ^/A/B/E Xpegged/xE
+ # # ^/A/mu X/xmu
+ # # ^/A/B/lambda X/Y/xlambda
+ # # ^/A/D/G X/xG
+ # # ^/A/D/H X/Y/xH
+ # """)
+ # exit(0)
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ A_D_H = sbox.ospath('A/D/H')
+ X = sbox.ospath('X')
+ X_Y = sbox.ospath('X/Y')
+ Xpegged = sbox.ospath('Xpegged')
+ Z = sbox.ospath('Z')
+ Z_zeta = sbox.ospath('Z/zeta')
+
+ # mkdir Z
+ os.makedirs(Z)
+
+ # echo 'This is the file zeta.' > Z/zeta
+ main.file_write(Z_zeta, 'This is the file zeta.\n')
+
+ # svn add Z
+ expected_stdout = verify.UnorderedOutput([
+ 'A ' + Z + '\n',
+ 'A ' + Z_zeta + '\n',
+ ])
+
+ actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'add', Z)
+
+ # svn mkdir --parents Xpegged X/Y
+ expected_stdout = verify.UnorderedOutput([
+ 'A ' + Xpegged + '\n',
+ 'A ' + X + '\n',
+ 'A ' + X_Y + '\n',
+ ])
+
+ actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'mkdir',
+ '--parents', Xpegged, X_Y)
+
+ # svn ci
+ expected_output = svntest.wc.State(wc_dir, {
+ 'Z' : Item(verb='Adding'),
+ 'Z/zeta' : Item(verb='Adding'),
+ 'X' : Item(verb='Adding'),
+ 'X/Y' : Item(verb='Adding'),
+ 'Xpegged' : Item(verb='Adding'),
+ })
+
+ expected_status = actions.get_virginal_state(wc_dir, 1)
+ expected_status.add({
+ 'Z' : Item(status=' ', wc_rev='2'),
+ 'Z/zeta' : Item(status=' ', wc_rev='2'),
+ 'X' : Item(status=' ', wc_rev='2'),
+ 'X/Y' : Item(status=' ', wc_rev='2'),
+ 'Xpegged' : Item(status=' ', wc_rev='2'),
+ })
+
+ actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+ None, wc_dir)
+
+ # svn up
+ expected_output = svntest.wc.State(wc_dir, {})
+
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.add({
+ 'Z' : Item(),
+ 'Z/zeta' : Item(contents="This is the file zeta.\n"),
+ 'Xpegged' : Item(),
+ 'X' : Item(),
+ 'X/Y' : Item(),
+ })
+
+ expected_status.tweak(wc_rev='2')
+
+ actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
+ expected_status, None, None, None, None, None, False, wc_dir)
+
+ # svn ps svn:externals "^/Z xZ" A/D/H
+ expected_stdout = ["property 'svn:externals' set on '" + A_D_H + "'\n"]
+
+ actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'ps',
+ 'svn:externals', '^/Z xZ', A_D_H)
+
+ # svn ps svn:externals "^/iota@1 Xpegged/xiota" wc_dir
+ expected_stdout = ["property 'svn:externals' set on '" + wc_dir + "'\n"]
+
+ actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'ps',
+ 'svn:externals',
+ '''
+ ^/iota@1 Xpegged/xiota
+ -r1 ^/A/B/E Xpegged/xE
+ ^/A/mu X/xmu
+ ^/A/B/lambda X/Y/xlambda
+ ^/A/D/G X/xG
+ ^/A/D/H X/Y/xH
+ ''', wc_dir)
+
+ # svntest.factory.make(sbox, prev_disk=expected_disk,
+ # prev_status=expected_status,
+ # commands = """
+ # svn ci
+ # svn up
+ # echo mod >> Xpegged/xE/alpha
+ # echo mod >> X/xmu
+ # echo mod >> X/Y/xlambda
+ # echo mod >> X/xG/pi
+ # echo mod >> X/Y/xH/chi
+ # echo mod >> X/Y/xH/xZ/zeta
+ # svn status
+ # # Expect no externals to be committed
+ # svn ci
+ # # Expect no externals to be committed, because pegged
+ # svn ci --include-externals Xpegged
+ # # Expect no externals to be committed, because of depth
+ # svn ci --depth=immediates --include-externals
+ # # Expect only unpegged externals to be committed (those in X/)
+ # svn ci --include-externals
+ # # ### Below, manually add:
+ # # expected_status.tweak('A/D/H/xZ', 'Xpegged/xE', 'X/Y/xH', 'X/xG',
+ # # wc_rev=None)
+ # svn up
+ # # new mods to check more cases
+ # echo mod >> X/xmu
+ # echo mod >> X/Y/xlambda
+ # echo mod >> X/xG/pi
+ # echo mod >> X/Y/xH/chi
+ # echo mod >> X/Y/xH/xZ/zeta
+ # svn status
+ # # Expect no externals to be committed, because of depth
+ # svn ci --include-externals --depth=empty X
+ # # Expect only file external xmu to be committed, because of depth
+ # svn ci --include-externals --depth=files X
+ # svn status
+ # # ### Below, manually add:
+ # # expected_status.tweak('A/D/H/xZ', 'Xpegged/xE', 'X/Y/xH', 'X/xG',
+ # # wc_rev=None)
+ # svn up
+ # echo mod >> X/xG/pi
+ # svn status
+ # # Expect explicit targets to be committed
+ # svn ci X/Y/xlambda X/xG
+ # svn status
+ # """)
+
+ X = sbox.ospath('X')
+ X_xG = sbox.ospath('X/xG')
+ X_xG_pi = sbox.ospath('X/xG/pi')
+ X_xmu = sbox.ospath('X/xmu')
+ X_Y_xH_chi = sbox.ospath('X/Y/xH/chi')
+ X_Y_xH_xZ_zeta = sbox.ospath('X/Y/xH/xZ/zeta')
+ X_Y_xlambda = sbox.ospath('X/Y/xlambda')
+ Xpegged = sbox.ospath('Xpegged')
+ Xpegged_xE_alpha = sbox.ospath('Xpegged/xE/alpha')
+
+ # svn ci
+ expected_output = svntest.wc.State(wc_dir, {
+ '' : Item(verb='Sending'),
+ 'A/D/H' : Item(verb='Sending'),
+ })
+
+ expected_status.tweak('', 'A/D/H', wc_rev='3')
+
+ actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+ None, wc_dir)
+
+ # svn up
+ expected_output = svntest.wc.State(wc_dir, {
+ 'X/xmu' : Item(status='A '),
+ 'X/xG/tau' : Item(status='A '),
+ 'X/xG/rho' : Item(status='A '),
+ 'X/xG/pi' : Item(status='A '),
+ 'X/Y/xH' : Item(status=' U'),
+ 'X/Y/xH/psi' : Item(status='A '),
+ 'X/Y/xH/xZ/zeta' : Item(status='A '),
+ 'X/Y/xH/chi' : Item(status='A '),
+ 'X/Y/xH/omega' : Item(status='A '),
+ 'X/Y/xlambda' : Item(status='A '),
+ 'A/D/H/xZ/zeta' : Item(status='A '),
+ 'Xpegged/xiota' : Item(status='A '),
+ 'Xpegged/xE/alpha' : Item(status='A '),
+ 'Xpegged/xE/beta' : Item(status='A '),
+ })
+
+ expected_disk.add({
+ 'Xpegged/xE' : Item(),
+ 'Xpegged/xE/beta' : Item(contents="This is the file 'beta'.\n"),
+ 'Xpegged/xE/alpha' : Item(contents="This is the file 'alpha'.\n"),
+ 'Xpegged/xiota' : Item(contents="This is the file 'iota'.\n"),
+ 'A/D/H/xZ' : Item(),
+ 'A/D/H/xZ/zeta' : Item(contents="This is the file zeta.\n"),
+ 'X/Y/xlambda' : Item(contents="This is the file 'lambda'.\n"),
+ 'X/Y/xH' : Item(),
+ 'X/Y/xH/chi' : Item(contents="This is the file 'chi'.\n"),
+ 'X/Y/xH/xZ' : Item(),
+ 'X/Y/xH/xZ/zeta' : Item(contents="This is the file zeta.\n"),
+ 'X/Y/xH/psi' : Item(contents="This is the file 'psi'.\n"),
+ 'X/Y/xH/omega' : Item(contents="This is the file 'omega'.\n"),
+ 'X/xmu' : Item(contents="This is the file 'mu'.\n"),
+ 'X/xG' : Item(),
+ 'X/xG/tau' : Item(contents="This is the file 'tau'.\n"),
+ 'X/xG/rho' : Item(contents="This is the file 'rho'.\n"),
+ 'X/xG/pi' : Item(contents="This is the file 'pi'.\n"),
+ })
+
+ expected_status.tweak(wc_rev='3')
+ expected_status.add({
+ 'A/D/H/xZ' : Item(status=' ', prev_status='X ', wc_rev='3'),
+ 'A/D/H/xZ/zeta' : Item(status=' ', wc_rev='3'),
+
+ 'Xpegged/xiota' : Item(status=' ', wc_rev='1', switched='X'),
+ 'Xpegged/xE' : Item(status=' ', prev_status='X ', wc_rev='1'),
+ 'Xpegged/xE/alpha' : Item(status=' ', wc_rev='1'),
+ 'Xpegged/xE/beta' : Item(status=' ', wc_rev='1'),
+
+ 'X/Y/xH' : Item(status=' ', prev_status='X ', wc_rev='3'),
+ 'X/Y/xH/psi' : Item(status=' ', wc_rev='3'),
+ 'X/Y/xH/omega' : Item(status=' ', wc_rev='3'),
+ 'X/Y/xH/chi' : Item(status=' ', wc_rev='3'),
+ 'X/Y/xH/xZ' : Item(status=' ', prev_status='X ', wc_rev='3'),
+ 'X/Y/xH/xZ/zeta' : Item(status=' ', wc_rev='3'),
+
+ 'X/Y/xlambda' : Item(status=' ', wc_rev='3', switched='X'),
+ 'X/xmu' : Item(status=' ', wc_rev='3', switched='X'),
+
+ 'X/xG' : Item(status=' ', prev_status='X ', wc_rev='3'),
+ 'X/xG/rho' : Item(status=' ', wc_rev='3'),
+ 'X/xG/tau' : Item(status=' ', wc_rev='3'),
+ 'X/xG/pi' : Item(status=' ', wc_rev='3'),
+ })
+ expected_status.tweak('Xpegged/xiota', wc_rev='1')
+
+ actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
+ expected_status, None, None, None, None, None, False, wc_dir)
+
+ # echo mod >> Xpegged/xE/alpha
+ main.file_append(Xpegged_xE_alpha, 'mod\n')
+
+ # echo mod >> X/xmu
+ main.file_append(X_xmu, 'mod\n')
+
+ # echo mod >> X/Y/xlambda
+ main.file_append(X_Y_xlambda, 'mod\n')
+
+ # echo mod >> X/xG/pi
+ main.file_append(X_xG_pi, 'mod\n')
+
+ # echo mod >> X/Y/xH/chi
+ main.file_append(X_Y_xH_chi, 'mod\n')
+
+ # echo mod >> X/Y/xH/xZ/zeta
+ main.file_append(X_Y_xH_xZ_zeta, 'mod\n')
+
+ # svn status
+ expected_status.tweak('X/Y/xlambda', 'X/xmu', 'X/Y/xH/chi',
+ 'X/Y/xH/xZ/zeta', 'Xpegged/xE/alpha',
+ 'X/xG/pi', status='M ')
+
+ actions.run_and_verify_unquiet_status(wc_dir, expected_status)
+
+ # Expect no externals to be committed
+ # svn ci
+ expected_output = svntest.wc.State(wc_dir, {})
+
+ actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+ None, wc_dir)
+
+ # Expect no externals to be committed, because pegged
+ # svn ci --include-externals Xpegged
+ expected_output = svntest.wc.State(wc_dir, {})
+
+ actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+ None, '--include-externals', Xpegged)
+
+ # Expect no externals to be committed, because of depth
+ # svn ci --depth=immediates --include-externals
+ expected_output = svntest.wc.State(wc_dir, {})
+
+ actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+ None, '--depth=immediates', '--include-externals', wc_dir)
+
+ # Expect only unpegged externals to be committed (those in X/)
+ # svn ci --include-externals
+ expected_output = svntest.wc.State(wc_dir, {
+ 'X/xmu' : Item(verb='Sending'),
+ 'X/Y/xlambda' : Item(verb='Sending'),
+ 'X/Y/xH/xZ/zeta' : Item(verb='Sending'),
+ 'X/Y/xH/chi' : Item(verb='Sending'),
+ 'X/xG/pi' : Item(verb='Sending'),
+ })
+
+ expected_status.tweak(status=' ')
+ expected_status.tweak('X/xmu', 'X/Y/xlambda', 'X/Y/xH/xZ/zeta',
+ 'X/Y/xH/chi', 'X/xG/pi', wc_rev='4')
+
+ expected_status.tweak('Xpegged/xE/alpha', status='M ')
+
+ actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+ None, '--include-externals', wc_dir)
+
+ # svn up
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/mu' : Item(status='U '),
+ 'A/D/H/chi' : Item(status='U '),
+ 'A/D/H/xZ/zeta' : Item(status='U '),
+ 'A/D/G/pi' : Item(status='U '),
+ 'A/B/lambda' : Item(status='U '),
+ 'Z/zeta' : Item(status='U '),
+ })
+
+ expected_disk.tweak('Xpegged/xE/alpha',
+ contents="This is the file 'alpha'.\nmod\n")
+ expected_disk.tweak('A/D/H/chi', 'X/Y/xH/chi',
+ contents="This is the file 'chi'.\nmod\n")
+ expected_disk.tweak('A/D/H/xZ/zeta', 'X/Y/xH/xZ/zeta', 'Z/zeta',
+ contents='This is the file zeta.\nmod\n')
+ expected_disk.tweak('A/D/G/pi', 'X/xG/pi',
+ contents="This is the file 'pi'.\nmod\n")
+ expected_disk.tweak('A/mu', 'X/xmu',
+ contents="This is the file 'mu'.\nmod\n")
+ expected_disk.tweak('A/B/lambda', 'X/Y/xlambda',
+ contents="This is the file 'lambda'.\nmod\n")
+
+
+ # Assume everything r4, except what is pegged
+ expected_status.tweak(wc_rev='4')
+ expected_status.tweak('Xpegged/xiota', 'Xpegged/xE', 'Xpegged/xE/alpha',
+ 'Xpegged/xE/beta', wc_rev=1)
+
+ actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
+ expected_status, None, None, None, None, None, False, wc_dir)
+
+ # new mods to check more cases
+ # echo mod >> X/xmu
+ main.file_append(X_xmu, 'mod\n')
+
+ # echo mod >> X/Y/xlambda
+ main.file_append(X_Y_xlambda, 'mod\n')
+
+ # echo mod >> X/xG/pi
+ main.file_append(X_xG_pi, 'mod\n')
+
+ # echo mod >> X/Y/xH/chi
+ main.file_append(X_Y_xH_chi, 'mod\n')
+
+ # echo mod >> X/Y/xH/xZ/zeta
+ main.file_append(X_Y_xH_xZ_zeta, 'mod\n')
+
+ # svn status
+ expected_status.tweak('X/Y/xlambda', 'X/xmu', 'X/xG/pi',
+ 'X/Y/xH/chi', 'X/Y/xH/xZ/zeta', status='M ')
+
+ actions.run_and_verify_unquiet_status(wc_dir, expected_status)
+
+ # Expect no externals to be committed, because of depth
+ # svn ci --include-externals --depth=empty X
+ expected_output = svntest.wc.State(wc_dir, {})
+
+ actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+ None, '--include-externals', '--depth=empty', X)
+
+ # Expect only file external xmu to be committed, because of depth
+ # svn ci --include-externals --depth=files X
+ expected_output = svntest.wc.State(wc_dir, {
+ 'X/xmu' : Item(verb='Sending'),
+ })
+
+ expected_status.tweak(status=' ')
+ expected_status.tweak('X/xmu', wc_rev='5')
+ expected_status.tweak('X/Y/xlambda', 'X/xG/pi', 'X/Y/xH/chi',
+ 'X/Y/xH/xZ/zeta', 'Xpegged/xE/alpha', status='M ')
+
+ actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+ None, '--include-externals', '--depth=files', X)
+
+ # svn status
+ actions.run_and_verify_unquiet_status(wc_dir, expected_status)
+
+ # svn up
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/mu' : Item(status='U '),
+ })
+
+ expected_disk.tweak('A/mu', 'X/xmu',
+ contents="This is the file 'mu'.\nmod\nmod\n")
+ expected_disk.tweak('X/Y/xlambda',
+ contents="This is the file 'lambda'.\nmod\nmod\n")
+ expected_disk.tweak('X/Y/xH/chi',
+ contents="This is the file 'chi'.\nmod\nmod\n")
+ expected_disk.tweak('X/Y/xH/xZ/zeta',
+ contents='This is the file zeta.\nmod\nmod\n')
+ expected_disk.tweak('X/xG/pi',
+ contents="This is the file 'pi'.\nmod\nmod\n")
+
+ expected_status.tweak(wc_rev='5')
+ expected_status.tweak('Xpegged/xiota', wc_rev='1')
+ expected_status.tweak('Xpegged/xiota', 'Xpegged/xE', 'Xpegged/xE/alpha',
+ 'Xpegged/xE/beta', wc_rev=1)
+
+ expected_status.tweak('X/Y/xH/chi', status='M ')
+
+ actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
+ expected_status, None, None, None, None, None, False, wc_dir)
+
+ # echo mod >> X/xG/pi
+ main.file_append(X_xG_pi, 'mod\n')
+
+ # svn status
+ actions.run_and_verify_unquiet_status(wc_dir, expected_status)
+
+ # Expect explicit targets to be committed
+ # svn ci X/Y/xlambda X/xG
+ expected_output = svntest.wc.State(wc_dir, {
+ 'X/Y/xlambda' : Item(verb='Sending'),
+ 'X/xG/pi' : Item(verb='Sending'),
+ })
+
+ expected_status.tweak(status=' ')
+ expected_status.tweak('X/Y/xlambda', 'X/xG/pi', wc_rev='6')
+ expected_status.tweak('X/Y/xH/chi', 'X/Y/xH/xZ/zeta', 'Xpegged/xE/alpha',
+ status='M ')
+
+ actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+ None, X_Y_xlambda, X_xG)
+
+ # svn status
+ actions.run_and_verify_unquiet_status(wc_dir, expected_status)
+
+
+@Issue(4252)
+def include_immediate_dir_externals(sbox):
+ "commit --include-externals --depth=immediates"
+ # See also comment in append_externals_as_explicit_targets() in
+ # libsvn_client/commit.c, from r1198765.
+
+ # svntest.factory.make(sbox,"""
+ # svn mkdir X
+ # svn ci
+ # svn up
+ # svn ps svn:externals "^/A/B/E X/XE" wc_dir
+ # svn ci
+ # svn up
+ #
+ # svn ps some change X/XE
+ # echo mod >> X/XE/alpha
+ #
+ # svn st X/XE
+ # # Expect only the propset on X/XE to be committed.
+ # # Should be like 'svn commit --include-externals --depth=empty X/XE'.
+ # svn commit --include-externals --depth=immediates X
+ # """)
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ X = sbox.ospath('X')
+ X_XE = sbox.ospath('X/XE')
+ X_XE_alpha = sbox.ospath('X/XE/alpha')
+
+ # svn mkdir X
+ expected_stdout = ['A ' + X + '\n']
+
+ actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'mkdir', X)
+
+ # svn ci
+ expected_output = svntest.wc.State(wc_dir, {
+ 'X' : Item(verb='Adding'),
+ })
+
+ expected_status = actions.get_virginal_state(wc_dir, 1)
+ expected_status.add({
+ 'X' : Item(status=' ', wc_rev='2'),
+ })
+
+ actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+ None, wc_dir)
+
+ # svn up
+ expected_output = svntest.wc.State(wc_dir, {})
+
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.add({
+ 'X' : Item(),
+ })
+
+ expected_status.tweak(wc_rev='2')
+
+ actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
+ expected_status, None, None, None, None, None, False, wc_dir)
+
+ # svn ps svn:externals "^/A/B/E X/XE" wc_dir
+ expected_stdout = ["property 'svn:externals' set on '" + wc_dir + "'\n"]
+
+ actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'ps',
+ 'svn:externals', '^/A/B/E X/XE', wc_dir)
+
+ # svn ci
+ expected_output = svntest.wc.State(wc_dir, {
+ '' : Item(verb='Sending'),
+ })
+
+ expected_status.tweak('', wc_rev='3')
+
+ actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+ None, wc_dir)
+
+ # svn up
+ expected_output = svntest.wc.State(wc_dir, {
+ 'X/XE/alpha' : Item(status='A '),
+ 'X/XE/beta' : Item(status='A '),
+ })
+
+ expected_disk.add({
+ 'X/XE' : Item(),
+ 'X/XE/alpha' : Item(contents="This is the file 'alpha'.\n"),
+ 'X/XE/beta' : Item(contents="This is the file 'beta'.\n"),
+ })
+
+ expected_status.tweak(wc_rev='3')
+ expected_status.add({
+ 'X/XE' : Item(status=' ', prev_status='X ', wc_rev='3'),
+ 'X/XE/beta' : Item(status=' ', wc_rev='3'),
+ 'X/XE/alpha' : Item(status=' ', wc_rev='3'),
+ })
+
+ actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
+ expected_status, None, None, None, None, None, False, wc_dir)
+
+ sbox.simple_propset('some', 'change', 'X/XE')
+
+ # echo mod >> X/XE/alpha
+ main.file_append(X_XE_alpha, 'mod\n')
+
+ # svn st X/XE
+ expected_status.tweak('X/XE', status=' M')
+ expected_status.tweak('X/XE/alpha', status='M ')
+ actions.run_and_verify_unquiet_status(wc_dir, expected_status)
+
+ # Expect only the propset on X/XE to be committed.
+ # Should be like 'svn commit --include-externals --depth=empty X/XE'.
+ # svn commit --include-externals --depth=immediates X
+ expected_output = svntest.wc.State(wc_dir, {
+ 'X/XE' : Item(verb='Sending'),
+ })
+ expected_status.tweak('X/XE', status=' ', wc_rev=4)
+
+ # Currently this fails because nothing is committed.
+ #
+ # >svn st
+ # X X\XE
+ #
+ # Performing status on external item at 'X\XE':
+ # M C:\SVN\src-trunk\...\externals_tests-37\X\XE
+ # M C:\SVN\src-trunk\...\externals_tests-37\X\XE\alpha
+ #
+ # >svn ci -m "m" --include-externals --depth immediates X
+ #
+ # >
+ actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+ None, '--include-externals', '--depth=immediates', X)
+
+
+@Issue(4085)
+def shadowing(sbox):
+ "external shadows an existing dir"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # Setup external: /A/B/F as 'C' child of /A
+ externals_prop = "^/A/B/F C\n"
+ change_external(sbox.ospath('A'), externals_prop, commit=False)
+
+ # An update errors out because the external is shadowed by an existing dir
+ svntest.main.run_svn("W205011: Error handling externals definition for '%s'"
+ % (sbox.wc_dir) + "/A/C", 'update', wc_dir)
+
+ # Remove the shadowed directory to unblock the external
+ svntest.main.run_svn(None, 'rm', sbox.repo_url + '/A/C', '-m', 'remove A/C')
+
+ # The next update should fetch the external and not error out
+ sbox.simple_update()
+
+
# Test for issue #4093 'remapping a file external can segfault due to
# "deleted" props'.
@Issue(4093)
@@ -2146,8 +2824,8 @@ def remap_file_external_with_prop_del(sbox):
sbox.build()
wc_dir = sbox.wc_dir
- A_path = os.path.join(wc_dir, "A")
- mu_path = os.path.join(wc_dir, "A", "mu")
+ A_path = sbox.ospath('A')
+ mu_path = sbox.ospath('A/mu')
# Add a property to A/mu
svntest.actions.run_and_verify_svn(None, None, [],
@@ -2192,8 +2870,8 @@ def dir_external_with_dash_r_only(sbox):
wc_dir = sbox.wc_dir
url = sbox.repo_url
- A_B_E_alpha = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha')
- E_ext = os.path.join(wc_dir, 'E_ext')
+ A_B_E_alpha = sbox.ospath('A/B/E/alpha')
+ E_ext = sbox.ospath('E_ext')
# echo 'newer alpha' > A/B/E/alpha
main.file_write(A_B_E_alpha, 'newer alpha\n')
@@ -2232,7 +2910,9 @@ def dir_external_with_dash_r_only(sbox):
expected_status.tweak(wc_rev='2')
expected_status.tweak('', status=' M')
expected_status.add({
- 'E_ext' : Item(status='X '),
+ 'E_ext' : Item(status=' ', prev_status='X ', wc_rev=1),
+ 'E_ext/beta' : Item(status=' ', wc_rev='1'),
+ 'E_ext/alpha' : Item(status=' ', wc_rev='1'),
})
actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
@@ -2255,7 +2935,7 @@ def url_to_wc_copy_of_externals(sbox):
# Create an external A/C/external pointing to ^/A/D/G.
svntest.actions.run_and_verify_svn(None, None, [], 'ps',
'svn:externals', '^/A/D/G external',
- os.path.join(wc_dir, 'A', 'C'))
+ sbox.ospath('A/C'))
svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
'create an external', wc_dir)
svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
@@ -2265,7 +2945,7 @@ def url_to_wc_copy_of_externals(sbox):
# Previously this failed with:
# >svn copy ^^/A/C External-WC-to-URL-Copy
# U External-WC-to-URL-Copy
- #
+ #
# Fetching external item into 'External-WC-to-URL-Copy\external':
# A External-WC-to-URL-Copy\external\pi
# A External-WC-to-URL-Copy\external\rho
@@ -2285,7 +2965,7 @@ def url_to_wc_copy_of_externals(sbox):
# svn-F9E2C0EC' to 'C:\SVN\src-trunk-3\Debug\subversion\tests\cmdline\
# svn-test-work\working_copies\externals_tests-41\External-WC-to-URL-Copy':
# Access is denied.
- external_root_path = os.path.join(wc_dir, "External-WC-to-URL-Copy")
+ external_root_path = sbox.ospath('External-WC-to-URL-Copy')
external_ex_path = os.path.join(wc_dir, "External-WC-to-URL-Copy",
"external")
external_pi_path = os.path.join(wc_dir, "External-WC-to-URL-Copy",
@@ -2295,19 +2975,364 @@ def url_to_wc_copy_of_externals(sbox):
external_tau_path = os.path.join(wc_dir, "External-WC-to-URL-Copy",
"external", "tau")
expected_stdout = verify.UnorderedOutput([
- "\n",
" U " + external_root_path + "\n",
+ "\n",
"Fetching external item into '" + external_ex_path + "':\n",
"A " + external_pi_path + "\n",
"A " + external_rho_path + "\n",
"A " + external_tau_path + "\n",
"Checked out external at revision 2.\n",
+ "\n",
"Checked out revision 2.\n",
"A " + external_root_path + "\n"
])
exit_code, stdout, stderr = svntest.actions.run_and_verify_svn2(
"OUTPUT", expected_stdout, [], 0, 'copy', repo_url + '/A/C',
- os.path.join(wc_dir, 'External-WC-to-URL-Copy'))
+ sbox.ospath('External-WC-to-URL-Copy'))
+
+@Issue(4227)
+def duplicate_targets(sbox):
+ "local path appears twice in one svn:external prop"
+
+ if False:
+ svntest.factory.make(sbox, r"""
+ svn ps svn:externals "^/A/B/E barf\n^/A/B/E barf" .
+ svn ps svn:externals "^/A/B/E barf\n^/A/D/G barf" .
+ svn ps svn:externals "^/A/B/E barf/.\n^/A/D/G ./barf" .
+ svn ps svn:externals "^/A/B/E ././barf\n^/A/D/G .//barf" .
+ svn pg svn:externals .
+ svn ps svn:externals "^/A/B/E ok" .
+ svn pg svn:externals .
+ """)
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ abs_wc_dir = os.path.abspath(sbox.wc_dir)
+
+ expected_stderr = verify.RegexOutput(
+ ".*Invalid svn:externals property on '" + re.escape(abs_wc_dir) +
+ "': target 'barf' appears more than once\n",
+ match_all=False)
+
+ # svn ps svn:externals "^/A/B/E barf\n^/A/B/E barf" .
+ actions.run_and_verify_svn2('OUTPUT', [], expected_stderr, 1, 'ps',
+ 'svn:externals', '^/A/B/E barf\n^/A/B/E barf', wc_dir)
+
+ # svn ps svn:externals "^/A/B/E barf\n^/A/D/G barf" .
+ actions.run_and_verify_svn2('OUTPUT', [], expected_stderr, 1, 'ps',
+ 'svn:externals', '^/A/B/E barf\n^/A/D/G barf', wc_dir)
+
+ # svn ps svn:externals "^/A/B/E barf/.\n^/A/D/G ./barf" .
+ actions.run_and_verify_svn2('OUTPUT', [], expected_stderr, 1, 'ps',
+ 'svn:externals', '^/A/B/E barf/.\n^/A/D/G ./barf', wc_dir)
+
+ # svn ps svn:externals "^/A/B/E ././barf\n^/A/D/G .//barf" .
+ actions.run_and_verify_svn2('OUTPUT', [], expected_stderr, 1, 'ps',
+ 'svn:externals', '^/A/B/E ././barf\n^/A/D/G .//barf', wc_dir)
+
+ # svn pg svn:externals .
+ expected_stdout = []
+
+ actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'pg',
+ 'svn:externals', wc_dir)
+
+ # svn ps svn:externals "^/A/B/E ok" .
+ expected_stdout = ["property 'svn:externals' set on '" + wc_dir + "'\n"]
+
+ actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'ps',
+ 'svn:externals', '^/A/B/E ok', wc_dir)
+
+ # svn pg svn:externals .
+ expected_stdout = verify.UnorderedOutput([
+ '^/A/B/E ok\n',
+ '\n'
+ ])
+
+ actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'pg',
+ 'svn:externals', wc_dir)
+
+@Issue(4225)
+def list_include_externals(sbox):
+ "list with --include-externals"
+
+ externals_test_setup(sbox)
+
+ wc_dir = sbox.wc_dir
+ repo_url = sbox.repo_url
+
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'checkout',
+ repo_url, wc_dir)
+
+ B_path = sbox.ospath("A/B")
+ C_path = sbox.ospath("A/C")
+
+ B_url = repo_url + "/A/B"
+ C_url = repo_url + "/A/C"
+
+ def list_external_string(path, url):
+ string = "Listing external" + " '" + path + "' " + "defined on" + " '" + \
+ url + "'" + ":"
+ return string
+
+ expected_stdout = verify.UnorderedOutput([
+ "E/" + "\n",
+ "F/" + "\n",
+ "lambda" + "\n",
+ list_external_string("gamma", B_url ) + "\n",
+ "gamma" + "\n"])
+
+ exit_code, stdout, stderr = svntest.actions.run_and_verify_svn2(
+ "OUTPUT", expected_stdout, [], 0, 'ls', '--include-externals', B_path)
+
+ exit_code, stdout, stderr = svntest.actions.run_and_verify_svn2(
+ "OUTPUT", expected_stdout, [], 0, 'ls', '--include-externals', B_url)
+
+ expected_stdout = verify.UnorderedOutput([
+ list_external_string("exdir_G", C_url)+ "\n",
+ "pi" + "\n",
+ "rho" + "\n",
+ "tau" + "\n",
+ list_external_string("exdir_H", C_url) + "\n",
+ "chi" + "\n",
+ "omega" + "\n",
+ "psi" + "\n"])
+
+ exit_code, stdout, stderr = svntest.actions.run_and_verify_svn2(
+ "OUTPUT", expected_stdout, [], 0, 'ls', '--include-externals', C_path)
+
+ exit_code, stdout, stderr = svntest.actions.run_and_verify_svn2(
+ "OUTPUT", expected_stdout, [], 0, 'ls', '--include-externals', C_url)
+
+@Issue(4293)
+def move_with_file_externals(sbox):
+ "move with file externals"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ repo_url = sbox.repo_url
+
+ sbox.simple_propset('svn:externals', '^/A/mu@1 mu-1\n', 'A/D')
+ sbox.simple_commit()
+
+ sbox.simple_update()
+ sbox.simple_move('A/D', 'A/D_moved')
+ sbox.simple_commit()
+ sbox.simple_update()
+
+@Issue(4185)
+def pinned_externals(sbox):
+ "pinned external"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ repo_url = sbox.repo_url
+
+ # Create X in r2
+ sbox.simple_copy('A', 'X')
+ sbox.simple_mkdir('Z')
+ sbox.simple_commit('')
+
+ repo_X_mu = repo_url + '/X/mu'
+
+ expected_output = verify.RegexOutput(
+ '^ 1 jrandom .* mu$'
+ )
+
+ svntest.actions.run_and_verify_svn(None, expected_output, [],
+ 'list', repo_X_mu, '-v')
+
+ # So, we copied A/mu to X/mu in r2, but its last changed revision is
+ # still r1. It existed as A/mu at r1.
+
+ # In the old format the -r is interpreted like an @1 on checkout.
+
+ sbox.simple_propset('svn:externals',
+ 'old-plain ' + repo_X_mu + '\n' +
+ 'old-rev -r 1 ' + repo_X_mu + '\n' +
+ repo_X_mu + ' new-plain\n' +
+ '-r1 ' + repo_X_mu + ' new-rev\n' +
+ repo_X_mu + '@1 new-peg\n',
+ 'Z')
+
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/D' : Item(status=' U'),
+ 'A/D/exdir_E/beta' : Item(status='A '),
+ 'A/D/exdir_E/alpha' : Item(status='A '),
+ })
+ expected_error = "svn: E205011: Failure.*externals"
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.add({
+ # The interesting values
+ 'Z/old-plain' : Item(contents="This is the file 'mu'.\n"),
+ 'Z/new-plain' : Item(contents="This is the file 'mu'.\n"),
+ 'Z/new-rev' : Item(contents="This is the file 'mu'.\n"),
+
+ # And verifying X
+ 'X/D/H/psi' : Item(contents="This is the file 'psi'.\n"),
+ 'X/D/H/chi' : Item(contents="This is the file 'chi'.\n"),
+ 'X/D/H/omega' : Item(contents="This is the file 'omega'.\n"),
+ 'X/D/G/tau' : Item(contents="This is the file 'tau'.\n"),
+ 'X/D/G/pi' : Item(contents="This is the file 'pi'.\n"),
+ 'X/D/G/rho' : Item(contents="This is the file 'rho'.\n"),
+ 'X/D/gamma' : Item(contents="This is the file 'gamma'.\n"),
+ 'X/B/E/alpha' : Item(contents="This is the file 'alpha'.\n"),
+ 'X/B/E/beta' : Item(contents="This is the file 'beta'.\n"),
+ 'X/B/lambda' : Item(contents="This is the file 'lambda'.\n"),
+ 'X/B/F' : Item(),
+ 'X/C' : Item(),
+ 'X/mu' : Item(contents="This is the file 'mu'.\n"),
+ })
+
+
+ # ### Would be nice if verify update would still verify the result
+ # on exiting with an error. Why would you pass it?
+ svntest.actions.run_and_verify_update(wc_dir, None, None, None,
+ expected_error)
+
+ svntest.actions.verify_disk(wc_dir, expected_disk)
+
+# Test for issue #3741 'externals not removed when working copy is made shallow'
+@Issue(3741)
+def update_dir_external_shallow(sbox):
+ "shallow update should remove externals"
+
+ sbox.build()
+
+ # Create an external in r2
+ sbox.simple_propset('svn:externals', '^/A/D/H X', 'A/B/E')
+ sbox.simple_commit()
+ sbox.simple_update()
+
+ # Now make A/B/E shallow by updating with "--set-depth empty"
+ expected_output = svntest.wc.State(sbox.wc_dir, {
+ 'A/B/E/alpha' : Item(status='D '),
+ 'A/B/E/X' : Item(verb='Removed external'),
+ 'A/B/E/beta' : Item(status='D '),
+ })
+ svntest.actions.run_and_verify_update(sbox.wc_dir,
+ expected_output, None, None,
+ None, None, None, None, None, False,
+ '--set-depth=empty',
+ sbox.ospath('A/B/E'))
+
+ # And bring the external back by updating with "--set-depth infinity"
+ expected_output = svntest.wc.State(sbox.wc_dir, {
+ 'A/B/E/X/psi' : Item(status='A '),
+ 'A/B/E/X/chi' : Item(status='A '),
+ 'A/B/E/X/omega' : Item(status='A '),
+ 'A/B/E/alpha' : Item(status='A '),
+ 'A/B/E/beta' : Item(status='A '),
+ })
+ svntest.actions.run_and_verify_update(sbox.wc_dir,
+ expected_output, None, None,
+ None, None, None, None, None, False,
+ '--set-depth=infinity',
+ sbox.ospath('A/B/E'))
+
+@Issue(4411)
+def switch_parent_relative_file_external(sbox):
+ "switch parent-relative file external"
+
+ sbox.build()
+
+ # Create a parent-relative file external in r2
+ sbox.simple_propset('svn:externals', '../D/gamma gamma-ext', 'A/B')
+ sbox.simple_commit()
+ sbox.simple_update()
+
+ # Create a branch that contains the file external
+ sbox.simple_copy('A', 'A_copy')
+ sbox.simple_commit()
+ sbox.simple_update()
+
+ # Check out A/B_copy to a new working copy
+ branch_wc = sbox.add_wc_path("branch")
+ branch_url = sbox.repo_url + '/A_copy'
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'checkout', branch_url,
+ branch_wc)
+
+ # Rename the branch
+ sbox.simple_move('A_copy', 'A_copy2')
+ sbox.simple_commit()
+
+ # Switch the branch working copy to the new branch URL
+ new_branch_url = sbox.repo_url + '/A_copy2'
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'switch', new_branch_url,
+ branch_wc)
+
+ # Bug: The branch working copy can no longer be updated.
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'update', branch_wc)
+
+def update_deletes_file_external(sbox):
+ "update deletes a file external"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ sbox.simple_propset('svn:externals', '../D/gamma gamma', 'A/C')
+ sbox.simple_commit()
+ sbox.simple_update()
+
+ # Create a branch
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'copy',
+ '-m', 'create branch',
+ sbox.repo_url + '/A',
+ sbox.repo_url + '/A_copy')
+
+ # Update the working copy
+ sbox.simple_commit()
+ sbox.simple_update()
+
+ # Remove the branch
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'rm',
+ '-m', 'remove branch',
+ sbox.repo_url + '/A_copy')
+
+ # As of r1448345, this update fails:
+ # E000002: Can't remove directory '.../A_copy/C': No such file or directory
+ sbox.simple_update()
+
+
+@Issue(4519)
+def switch_relative_externals(sbox):
+ "switch relative externals"
+
+ sbox.build(create_wc=False)
+
+ svntest.actions.run_and_verify_svnmucc(None, None, [],
+ '-U', sbox.repo_url, '-m', 'Q',
+ 'mkdir', 'branches',
+ 'cp', '1', 'A', 'trunk',
+ 'cp', '1', 'A', 'branches/A',
+ 'propset', 'svn:externals',
+ '../C dirExC\n ../mu fileExMu',
+ 'trunk/B',
+ 'propset', 'svn:externals',
+ '../C dirExC\n ../mu fileExMu',
+ 'branches/A/B')
+
+ wc = sbox.add_wc_path('wc')
+
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'co', sbox.repo_url + '/trunk', wc)
+
+ # This forgets to update some externals data
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'switch', sbox.repo_url + '/branches/A', wc)
+
+ # This upgrade makes the following update fail
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'upgrade', wc)
+
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'up', wc)
+
########################################################################
# Run the tests
@@ -2350,9 +3375,20 @@ test_list = [ None,
file_externals_different_url,
file_external_in_unversioned,
copy_file_externals,
+ commit_include_externals,
+ include_immediate_dir_externals,
+ shadowing,
remap_file_external_with_prop_del,
dir_external_with_dash_r_only,
url_to_wc_copy_of_externals,
+ duplicate_targets,
+ list_include_externals,
+ move_with_file_externals,
+ pinned_externals,
+ update_dir_external_shallow,
+ switch_parent_relative_file_external,
+ update_deletes_file_external,
+ switch_relative_externals,
]
if __name__ == '__main__':