tree_conflict_tests.py [plain text]
import sys, re, os, traceback
import svntest
from svntest import main, wc, verify
from svntest.actions import run_and_verify_svn
from svntest.actions import run_and_verify_commit
from svntest.actions import run_and_verify_resolved
from svntest.actions import run_and_verify_update
from svntest.actions import run_and_verify_status
from svntest.actions import run_and_verify_info
from svntest.actions import get_virginal_state
import shutil
Skip = svntest.testcase.Skip_deco
SkipUnless = svntest.testcase.SkipUnless_deco
XFail = svntest.testcase.XFail_deco
Issues = svntest.testcase.Issues_deco
Issue = svntest.testcase.Issue_deco
Wimp = svntest.testcase.Wimp_deco
Item = svntest.wc.StateItem
AnyOutput = svntest.verify.AnyOutput
def verbose_print(line):
if main.options.verbose:
print(line)
def verbose_printlines(lines):
if main.options.verbose:
for line in lines:
sys.stdout.write(line)
def incoming_paths(root_dir, parent_dir):
"""Create a set of paths in which the victims of tree conflicts are
children of PARENT_DIR. ROOT_DIR should be a shallower directory
in which items "F1" and "D1" can pre-exist and be shared across
multiple parent dirs."""
return {
'F1' : os.path.join(root_dir, "F1"),
'F' : os.path.join(parent_dir, "F"),
'F2' : os.path.join(parent_dir, "F2-in"),
'F3' : os.path.join(root_dir, "F3"),
'D1' : os.path.join(root_dir, "D1"),
'D' : os.path.join(parent_dir, "D"),
'D2' : os.path.join(parent_dir, "D2-in"),
}
def localmod_paths(root_dir, parent_dir):
"""Create a set of paths in which the victims of tree conflicts are
children of PARENT_DIR. ROOT_DIR should be a shallower directory
in which items "F1" and "D1" can pre-exist and be shared across
multiple parent dirs."""
return {
'F1' : os.path.join(root_dir, "F1"),
'F' : os.path.join(parent_dir, "F"),
'F2' : os.path.join(parent_dir, "F2-local"),
'F3' : os.path.join(root_dir, "F3"),
'D1' : os.path.join(root_dir, "D1"),
'D' : os.path.join(parent_dir, "D"),
'D2' : os.path.join(parent_dir, "D2-local"),
}
def modify(modaction, paths, is_init=True):
F1 = paths['F1'] F3 = paths['F3'] F = paths['F'] F2 = paths['F2'] D1 = paths['D1'] D = paths['D'] D2 = paths['D2']
if modaction == 'ft': assert os.path.exists(F)
main.file_append(F, "This is a text-mod of file F.\n")
elif modaction == 'fP': assert os.path.exists(F)
main.run_svn(None, 'pset', 'fprop1', 'A prop set on file F.', F)
elif modaction == 'dP': assert os.path.exists(D)
main.run_svn(None, 'pset', 'dprop1', 'A prop set on dir D.', D)
elif modaction == 'fD': assert os.path.exists(F)
main.run_svn(None, 'del', F)
elif modaction == 'dD': assert os.path.exists(D)
main.run_svn(None, 'del', D)
elif modaction == 'fA': assert os.path.exists(F)
main.run_svn(None, 'add', F)
main.run_svn(None, 'pset', 'fprop2', 'A prop of added file F.', F)
elif modaction == 'dA': assert os.path.exists(D)
main.run_svn(None, 'add', D)
main.run_svn(None, 'pset', 'dprop2', 'A prop of added dir D.', D)
elif modaction == 'fC': if is_init:
main.run_svn(None, 'copy', F1, F)
else:
main.run_svn(None, 'copy', F3, F)
elif modaction == 'dC': main.run_svn(None, 'copy', D1, D)
elif modaction == 'fM': main.run_svn(None, 'rename', F, F2)
elif modaction == 'dM': main.run_svn(None, 'rename', D, D2)
elif modaction == 'fa': assert not os.path.exists(F)
main.file_write(F, "This is file F.\n")
elif modaction == 'da': assert not os.path.exists(D)
os.mkdir(D)
elif modaction == 'fd': assert os.path.exists(F)
os.remove(F)
elif modaction == 'dd': assert os.path.exists(D)
os.remove(D)
else:
raise Exception("unknown modaction: '" + modaction + "'")
absent_f = []
absent_d = []
create_f = ['fa','fA']
create_d = ['da','dA']
f_adds = [
( absent_f, ['fC'] ),
( absent_f, ['fC','ft'] ), ]
d_adds = [
( absent_d, ['dC'] ),
]
f_dels = [
( create_f, ['fD'] ),
( create_f, ['fM'] ),
]
d_dels = [
( create_d, ['dD'] ),
( create_d, ['dM'] ),
]
f_rpls = [
]
d_rpls = [
]
f_rpl_d = [
]
d_rpl_f = [
]
f_mods = [
( create_f, ['ft'] ),
( create_f, ['fP'] ),
]
d_mods = [
( create_d, ['dP'] ),
]
def set_up_repos(wc_dir, br_dir, scenarios):
if not os.path.exists(br_dir):
main.run_svn(None, "mkdir", "--parents", br_dir)
paths = incoming_paths(wc_dir, wc_dir) F1 = paths['F1'] F3 = paths['F3'] main.file_write(F1, "This is initially file F1.\n")
main.file_write(F3, "This is initially file F3.\n")
main.run_svn(None, 'add', F1, F3)
D1 = paths['D1'] main.run_svn(None, 'mkdir', D1)
for init_mods, action_mods in scenarios:
path = "_".join(action_mods)
P = os.path.join(br_dir, path) main.run_svn(None, 'mkdir', '--parents', P)
for modaction in init_mods:
modify(modaction, incoming_paths(wc_dir, P))
run_and_verify_svn(None, AnyOutput, [],
'commit', '-m', 'Initial set-up.', wc_dir)
init_rev = 2
for _path, action_mods in scenarios:
path = "_".join(action_mods)
P = os.path.join(br_dir, path) for modaction in action_mods:
modify(modaction, incoming_paths(wc_dir, P))
run_and_verify_svn(None, AnyOutput, [],
'commit', '-m', 'Action.', wc_dir)
changed_rev = 3
return (init_rev, changed_rev)
def ensure_tree_conflict(sbox, operation,
incoming_scenarios, localmod_scenarios,
commit_local_mods):
sbox.build()
wc_dir = sbox.wc_dir
def url_of(repo_relative_path):
return sbox.repo_url + '/' + repo_relative_path
verbose_print("")
verbose_print("=== Starting a set of '" + operation + "' tests.")
source_br = "branch1"
verbose_print("--- Creating changes in repos")
source_wc_dir = os.path.join(wc_dir, source_br)
source_left_rev, source_right_rev = set_up_repos(wc_dir, source_wc_dir,
incoming_scenarios)
head_rev = source_right_rev
for _loc_init_mods, loc_action in localmod_scenarios:
if operation == 'update':
target_br = source_br
target_start_rev = source_left_rev
else: target_br = "branch2"
run_and_verify_svn(None, AnyOutput, [],
'copy', '-r', str(source_left_rev), url_of(source_br),
url_of(target_br),
'-m', 'Create target branch.')
head_rev += 1
target_start_rev = head_rev
main.run_svn(None, 'checkout', '-r', str(target_start_rev), sbox.repo_url,
wc_dir)
saved_cwd = os.getcwd()
os.chdir(wc_dir)
for _inc_init_mods, inc_action in incoming_scenarios:
scen_name = "_".join(inc_action)
source_url = url_of(source_br + '/' + scen_name)
target_path = os.path.join(target_br, scen_name)
verbose_print("=== " + str(inc_action) + " onto " + str(loc_action))
verbose_print("--- Making local mods")
for modaction in loc_action:
modify(modaction, localmod_paths(".", target_path), is_init=False)
if commit_local_mods:
run_and_verify_svn(None, AnyOutput, [],
'commit', target_path,
'-m', 'Mods in target branch.')
head_rev += 1
if operation == 'update':
verbose_print("--- Trying to commit (expecting 'out-of-date' error)")
run_and_verify_commit(".", None, None, "Commit failed",
target_path)
if modaction.startswith('f'):
victim_name = 'F'
else:
victim_name = 'D'
victim_path = os.path.join(target_path, victim_name)
expected_stdout = svntest.verify.ExpectedOutput(" C " + victim_path
+ "\n",
match_all=False)
if operation == 'update':
verbose_print("--- Updating")
run_and_verify_svn(None, expected_stdout, [],
'update', target_path)
elif operation == 'switch':
verbose_print("--- Switching")
run_and_verify_svn(None, expected_stdout, [],
'switch', source_url, target_path)
elif operation == 'merge':
verbose_print("--- Merging")
run_and_verify_svn(None, expected_stdout, [],
'merge', '--ignore-ancestry',
'--allow-mixed-revisions',
'-r', str(source_left_rev) + ':' + str(source_right_rev),
source_url, target_path)
else:
raise Exception("unknown operation: '" + operation + "'")
verbose_print("--- Checking that 'info' reports the conflict")
if operation == 'update' or operation == 'switch':
incoming_left_rev = target_start_rev
else:
incoming_left_rev = source_left_rev
if operation == 'update' or operation == 'merge':
incoming_right_rev = source_right_rev
else:
incoming_right_rev = head_rev
expected_info = { 'Tree conflict' : '.* upon ' + operation +
r'.* \((none|(file|dir).*' +
re.escape(victim_name + '@' + str(incoming_left_rev)) + r')' +
r'.* \((none|(file|dir).*' +
re.escape(victim_name + '@' + str(incoming_right_rev)) + r')' }
run_and_verify_info([expected_info], victim_path)
verbose_print("--- Trying to commit (expecting 'conflict' error)")
run_and_verify_commit(".", None, None, ".*conflict.*", victim_path)
verbose_print("--- Checking that 'status' reports the conflict")
expected_stdout = svntest.verify.RegexOutput("^......C.* " +
re.escape(victim_path) + "$",
match_all=False)
run_and_verify_svn(None, expected_stdout, [],
'status', victim_path)
verbose_print("--- Resolving the conflict")
run_and_verify_resolved([], os.path.dirname(victim_path))
run_and_verify_resolved([victim_path])
verbose_print("--- Checking that 'status' does not report a conflict")
exitcode, stdout, stderr = run_and_verify_svn(None, None, [],
'status', victim_path)
for line in stdout:
if line[6] == 'C': raise svntest.Failure("unexpected status C")
verbose_print("")
os.chdir(saved_cwd)
main.run_svn(None, 'revert', '-R', wc_dir)
main.safe_rmtree(wc_dir)
if operation != 'update':
run_and_verify_svn(None, AnyOutput, [],
'delete', url_of(target_br),
'-m', 'Delete target branch.')
head_rev += 1
def test_tc_up_sw(sbox, incoming_scen, wc_scen):
sbox2 = sbox.clone_dependent()
ensure_tree_conflict(sbox, 'update', incoming_scen, wc_scen, False)
ensure_tree_conflict(sbox2, 'switch', incoming_scen, wc_scen, False)
def test_tc_merge(sbox, incoming_scen, br_scen=None, wc_scen=None):
if br_scen:
ensure_tree_conflict(sbox, 'merge', incoming_scen, br_scen, True)
else:
ensure_tree_conflict(sbox, 'merge', incoming_scen, wc_scen, False)
def up_sw_file_mod_onto_del(sbox):
"up/sw file: modify onto del/rpl/mv"
test_tc_up_sw(sbox, f_mods, f_dels + f_rpls)
def up_sw_file_del_onto_mod(sbox):
"up/sw file: del/rpl/mv onto modify"
test_tc_up_sw(sbox, f_dels + f_rpls, f_mods)
def up_sw_file_del_onto_del(sbox):
"up/sw file: del/rpl/mv onto del/rpl/mv"
test_tc_up_sw(sbox, f_dels + f_rpls, f_dels + f_rpls)
def up_sw_file_add_onto_add(sbox):
"up/sw file: add onto add"
test_tc_up_sw(sbox, f_adds, f_adds)
def up_sw_dir_mod_onto_del(sbox):
"up/sw dir: modify onto del/rpl/mv"
test_tc_up_sw(sbox, d_mods, d_dels + d_rpls)
def up_sw_dir_del_onto_mod(sbox):
"up/sw dir: del/rpl/mv onto modify"
test_tc_up_sw(sbox, d_dels + d_rpls, d_mods)
def up_sw_dir_del_onto_del(sbox):
"up/sw dir: del/rpl/mv onto del/rpl/mv"
test_tc_up_sw(sbox, d_dels + d_rpls, d_dels + d_rpls)
@XFail(svntest.main.is_ra_type_dav)
@Issue(3314)
def up_sw_dir_add_onto_add(sbox):
"up/sw dir: add onto add"
test_tc_up_sw(sbox, d_adds, d_adds)
def merge_file_mod_onto_not_file(sbox):
"merge file: modify onto not-file"
sbox2 = sbox.clone_dependent()
test_tc_merge(sbox, f_mods, br_scen = f_dels + f_rpl_d)
test_tc_merge(sbox2, f_mods, wc_scen = f_dels)
def merge_file_del_onto_not_same(sbox):
"merge file: del/rpl/mv onto not-same"
sbox2 = sbox.clone_dependent()
test_tc_merge(sbox, f_dels + f_rpls, br_scen = f_mods)
test_tc_merge(sbox2, f_dels + f_rpls, wc_scen = f_mods)
def merge_file_del_onto_not_file(sbox):
"merge file: del/rpl/mv onto not-file"
sbox2 = sbox.clone_dependent()
test_tc_merge(sbox, f_dels + f_rpls, br_scen = f_dels + f_rpl_d)
test_tc_merge(sbox2, f_dels + f_rpls, wc_scen = f_dels)
def merge_file_add_onto_not_none(sbox):
"merge file: add onto not-none"
sbox2 = sbox.clone_dependent()
test_tc_merge(sbox, f_adds, br_scen = f_adds) test_tc_merge(sbox2, f_adds, wc_scen = f_adds)
def merge_dir_mod_onto_not_dir(sbox):
"merge dir: modify onto not-dir"
sbox2 = sbox.clone_dependent()
test_tc_merge(sbox, d_mods, br_scen = d_dels + d_rpl_f)
test_tc_merge(sbox2, d_mods, wc_scen = d_dels)
@XFail()
@Issue(3150)
def merge_dir_del_onto_not_same(sbox):
"merge dir: del/rpl/mv onto not-same"
sbox2 = sbox.clone_dependent()
test_tc_merge(sbox, d_dels + d_rpls, br_scen = d_mods)
test_tc_merge(sbox2, d_dels + d_rpls, wc_scen = d_mods)
def merge_dir_del_onto_not_dir(sbox):
"merge dir: del/rpl/mv onto not-dir"
sbox2 = sbox.clone_dependent()
test_tc_merge(sbox, d_dels + d_rpls, br_scen = d_dels + d_rpl_f)
test_tc_merge(sbox2, d_dels + d_rpls, wc_scen = d_dels)
def merge_dir_add_onto_not_none(sbox):
"merge dir: add onto not-none"
sbox2 = sbox.clone_dependent()
test_tc_merge(sbox, d_adds, br_scen = d_adds) test_tc_merge(sbox2, d_adds, wc_scen = d_adds)
@Issue(3805)
def force_del_tc_inside(sbox):
"--force del on dir with TCs inside"
sbox.build()
wc_dir = sbox.wc_dir
C = os.path.join(wc_dir, "A", "C")
dir = os.path.join(wc_dir, "A", "C", "dir")
file = os.path.join(wc_dir, "A", "C", "file")
main.run_svn(None, 'mkdir', dir)
content = "This is the file 'file'.\n"
main.file_append(file, content)
main.run_svn(None, 'add', file)
main.run_svn(None, 'commit', '-m', 'Add dir and file', wc_dir)
main.run_svn(None, 'delete', dir, file)
main.run_svn(None, 'commit', '-m', 'Remove dir and file', wc_dir)
main.run_svn(None, 'update', '-r2', wc_dir)
run_and_verify_svn(None,
["property 'propname' set on '" + dir + "'\n"],
[], 'ps', 'propname', 'propval', dir)
run_and_verify_svn(None,
["property 'propname' set on '" + file + "'\n"],
[], 'ps', 'propname', 'propval', file)
expected_output = wc.State(wc_dir, {
'A/C/dir' : Item(status=' ', treeconflict='C'),
'A/C/file' : Item(status=' ', treeconflict='C'),
})
expected_disk = main.greek_state.copy()
expected_disk.add({
'A/C/dir' : Item(props={'propname' : 'propval'}),
'A/C/file' : Item(contents=content, props={'propname' : 'propval'}),
})
expected_status = get_virginal_state(wc_dir, 2)
expected_status.tweak(wc_rev='3')
expected_status.add({
'A/C/dir' : Item(status='A ', wc_rev='-', copied='+', treeconflict='C'),
'A/C/file' : Item(status='A ', wc_rev='-', copied='+', treeconflict='C'),
})
run_and_verify_update(wc_dir,
expected_output, expected_disk, expected_status,
None, None, None, None, None, 1,
wc_dir)
run_and_verify_svn(None,
verify.UnorderedOutput(['D ' + C + '\n',
'D ' + dir + '\n',
'D ' + file + '\n']),
[], 'delete', C, '--force')
expected_status.tweak('A/C', status='D ')
expected_status.remove('A/C/dir', 'A/C/file')
run_and_verify_status(wc_dir, expected_status)
expected_output = wc.State(wc_dir, { 'A/C' : Item(verb='Deleting') })
expected_status.remove('A/C')
run_and_verify_commit(wc_dir,
expected_output, expected_status, None,
wc_dir)
@Issue(3805)
def force_del_tc_is_target(sbox):
"--force del on tree-conflicted targets"
sbox.build()
wc_dir = sbox.wc_dir
C = os.path.join(wc_dir, "A", "C")
dir = os.path.join(wc_dir, "A", "C", "dir")
file = os.path.join(wc_dir, "A", "C", "file")
main.run_svn(None, 'mkdir', dir)
content = "This is the file 'file'.\n"
main.file_append(file, content)
main.run_svn(None, 'add', file)
main.run_svn(None, 'commit', '-m', 'Add dir and file', wc_dir)
main.run_svn(None, 'delete', dir, file)
main.run_svn(None, 'commit', '-m', 'Remove dir and file', wc_dir)
main.run_svn(None, 'update', '-r2', wc_dir)
run_and_verify_svn(None,
["property 'propname' set on '" + dir + "'\n"],
[], 'ps', 'propname', 'propval', dir)
run_and_verify_svn(None,
["property 'propname' set on '" + file + "'\n"],
[], 'ps', 'propname', 'propval', file)
expected_output = wc.State(wc_dir, {
'A/C/dir' : Item(status=' ', treeconflict='C'),
'A/C/file' : Item(status=' ', treeconflict='C'),
})
expected_disk = main.greek_state.copy()
expected_disk.add({
'A/C/dir' : Item(props={'propname' : 'propval'}),
'A/C/file' : Item(contents=content, props={'propname' : 'propval'}),
})
expected_status = get_virginal_state(wc_dir, 2)
expected_status.tweak(wc_rev='3')
expected_status.add({
'A/C/dir' : Item(status='A ', wc_rev='-', copied='+', treeconflict='C'),
'A/C/file' : Item(status='A ', wc_rev='-', copied='+', treeconflict='C'),
})
run_and_verify_update(wc_dir,
expected_output, expected_disk, expected_status,
None, None, None, None, None, 1,
wc_dir)
run_and_verify_svn(None,
['D ' + dir + '\n',
'D ' + file + '\n'],
[],
'delete', dir, file, '--force')
expected_status.remove('A/C/dir', 'A/C/file')
run_and_verify_status(wc_dir, expected_status)
expected_output = wc.State(wc_dir, {})
run_and_verify_commit(wc_dir,
expected_output, expected_status, None,
wc_dir)
def query_absent_tree_conflicted_dir(sbox):
"query an unversioned tree-conflicted dir"
sbox.build()
wc_dir = sbox.wc_dir
C_path = os.path.join(wc_dir, "A", "C")
C_C_path = os.path.join(wc_dir, "A", "C", "C")
main.run_svn(None, 'mkdir', C_C_path)
main.run_svn(None, 'commit', '-m', 'Add directory A/C/C', wc_dir)
main.run_svn(None, 'delete', C_C_path)
main.run_svn(None, 'commit', '-m', 'Remove directory A/C/C', wc_dir)
main.run_svn(None, 'update', '-r2', wc_dir)
run_and_verify_svn(None,
["property 'propname' set on '" + C_C_path + "'\n"],
[], 'ps', 'propname', 'propval', C_C_path)
expected_output = wc.State(wc_dir, {
'A/C/C' : Item(status=' ', treeconflict='C'),
})
expected_disk = main.greek_state.copy()
expected_disk.add({'A/C/C' : Item(props={'propname' : 'propval'})})
expected_status = get_virginal_state(wc_dir, 1)
expected_status.tweak(wc_rev='3')
expected_status.add({'A/C/C' : Item(status='A ',
wc_rev='-',
copied='+',
treeconflict='C')})
run_and_verify_update(wc_dir,
expected_output, expected_disk, expected_status,
None, None, None, None, None, 1,
wc_dir)
run_and_verify_svn(None,
verify.UnorderedOutput(['D ' + C_C_path + '\n',
'D ' + C_path + '\n']),
[],
'delete', C_path, '--keep-local')
expected_status.tweak('A/C', status='D ')
expected_status.remove('A/C/C')
run_and_verify_status(wc_dir, expected_status)
expected_output = wc.State(wc_dir, {
})
run_and_verify_status(C_C_path, expected_output)
run_and_verify_svn(None, None, ".*W155010.*The node.*was not found.*",
'info', C_C_path)
@Issue(3608)
def up_add_onto_add_revert(sbox):
"issue #3608: reverting an add onto add conflict"
sbox.build()
wc_dir = sbox.wc_dir
wc2_dir = sbox.add_wc_path('wc2')
svntest.actions.run_and_verify_svn(None, None, [], 'checkout',
sbox.repo_url, wc2_dir)
file1 = os.path.join(wc_dir, 'newfile')
file2 = os.path.join(wc2_dir, 'newfile')
dir1 = os.path.join(wc_dir, 'NewDir')
dir2 = os.path.join(wc2_dir, 'NewDir')
main.run_svn(None, 'cp', os.path.join(wc_dir, 'iota'), file1)
main.run_svn(None, 'cp', os.path.join(wc2_dir, 'iota'), file2)
main.run_svn(None, 'cp', os.path.join(wc_dir, 'A/C'), dir1)
main.run_svn(None, 'cp', os.path.join(wc2_dir, 'A/C'), dir2)
main.run_svn(None, 'ci', wc_dir, '-m', 'Added file')
expected_disk = main.greek_state.copy()
expected_disk.add({
'newfile' : Item(contents="This is the file 'iota'.\n"),
'NewDir' : Item(),
})
expected_status = get_virginal_state(wc2_dir, 2)
expected_status.add({
'newfile' : Item(status='R ', copied='+', treeconflict='C', wc_rev='-'),
'NewDir' : Item(status='R ', copied='+', treeconflict='C', wc_rev='-'),
})
run_and_verify_update(wc2_dir,
None, expected_disk, expected_status,
None, None, None, None, None, 1,
wc2_dir)
main.run_svn(None, 'revert', file2)
main.run_svn(None, 'revert', dir2)
expected_status = get_virginal_state(wc2_dir, 2)
expected_status.add({
'newfile' : Item(status=' ', wc_rev='2'),
'NewDir' : Item(status=' ', wc_rev='2'),
})
run_and_verify_update(wc2_dir,
None, expected_disk, expected_status,
None, None, None, None, None, 1,
wc2_dir)
@Issues(3525,3533)
def lock_update_only(sbox):
"lock status update shouldn't flag tree conflict"
sbox.build()
wc_dir = sbox.wc_dir
wc_b = sbox.add_wc_path('_b')
svntest.actions.duplicate_dir(wc_dir, wc_b)
fname = 'iota'
file_path = os.path.join(sbox.wc_dir, fname)
file_path_b = os.path.join(wc_b, fname)
svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
'-m', '', file_path)
svntest.main.run_svn(None, 'delete', file_path)
svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
'-m', '', '--force', file_path)
expected_disk = main.greek_state.copy()
expected_disk.remove('iota')
expected_status = get_virginal_state(wc_dir, 1)
expected_status.tweak('iota', status='D ', writelocked='K')
run_and_verify_update(wc_dir,
None, expected_disk, expected_status,
None, None, None, None, None, 1,
wc_dir)
@Issue(3469)
def at_directory_external(sbox):
"tree conflict at directory external"
sbox.build()
wc_dir = sbox.wc_dir
svntest.main.run_svn(None, 'ps', 'svn:externals', '^/A E', wc_dir)
svntest.main.run_svn(None, 'commit', '-m', 'ps', wc_dir)
svntest.main.run_svn(None, 'update', wc_dir)
open(sbox.ospath('A/B/E/alpha'), 'a').write('This is still A/B/E/alpha.\n')
svntest.main.run_svn(None, 'commit', '-m', 'file mod', wc_dir)
svntest.main.run_svn(None, 'update', wc_dir)
merge_rev = svntest.main.youngest(sbox.repo_dir)
open(sbox.ospath('A/B/E/alpha2'), 'a').write("This is the file 'alpha2'.\n")
svntest.main.run_svn(None, 'add', sbox.ospath('A/B/E/alpha2'))
svntest.main.run_svn(None, 'commit', '-m', 'file add', wc_dir)
svntest.main.run_svn(None, 'update', wc_dir)
merge_rev2 = svntest.main.youngest(sbox.repo_dir)
svntest.main.run_svn(None, "merge", '-c', merge_rev, '^/A/B', wc_dir)
svntest.main.run_svn(None, "merge", '-c', merge_rev2, '^/A/B', wc_dir)
@Issue(3779)
def actual_only_node_behaviour(sbox):
"test behaviour with actual-only nodes"
sbox.build()
A_url = sbox.repo_url + '/A'
A_copy_url = sbox.repo_url + '/A_copy'
wc_dir = sbox.wc_dir
foo_path = sbox.ospath('A/foo', wc_dir)
sbox.simple_repo_copy('A', 'A_copy')
wc2_dir = sbox.add_wc_path('wc2')
foo2_path = sbox.ospath('foo', wc2_dir)
svntest.main.run_svn(None, "checkout", A_copy_url, wc2_dir)
svntest.main.file_write(foo2_path, "This is initially file foo.\n")
svntest.main.run_svn(None, "add", foo2_path)
svntest.main.run_svn(None, "commit", '-m', svntest.main.make_log_msg(),
foo2_path)
svntest.main.file_append(foo2_path, "This is a new line in file foo.\n")
svntest.main.run_svn(None, "commit", '-m', svntest.main.make_log_msg(),
wc2_dir)
sbox.simple_update()
svntest.main.run_svn(None, "merge", '-c', '4', A_copy_url,
os.path.join(wc_dir, 'A'))
expected_stdout = None
expected_stderr = ".*foo.*is an existing item in conflict.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"add", foo_path)
svntest.main.file_write(foo_path, "This is an obstruction of foo.\n")
expected_stdout = None
expected_stderr = ".*foo.*is an existing item in conflict.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"add", foo_path)
os.remove(foo_path)
expected_stdout = None
expected_stderr = ".*foo.*not found.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"blame", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*not under version control.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"cat", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*not under version control.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"cat", "-r", "BASE", foo_path)
expected_stdout = None
expected_stderr = ".*svn: warning: W155010: The node '.*foo' was not found."
run_and_verify_svn(None, expected_stdout, expected_stderr,
"changelist", "my_changelist", foo_path)
expected_stdout = None
expected_stderr = []
run_and_verify_svn(None, expected_stdout, expected_stderr,
"checkout", A_copy_url, foo_path)
shutil.rmtree(foo_path)
expected_stdout = None
expected_stderr = ".*foo.*is not a working copy directory"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"cleanup", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*remains in conflict.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"commit", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*does not exist.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"copy", foo_path, foo_path + ".copy")
expected_stdout = None
expected_stderr = ".*foo.*is not under version control.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"delete", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*is not under version control.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"diff", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*was not found.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"export", foo_path, sbox.get_tempname())
expected_stdout = None
expected_stderr = ".*foo.*does not exist.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"import", '-m', svntest.main.make_log_msg(),
foo_path, sbox.repo_url + '/foo_imported')
expected_info = {
'Tree conflict': 'local missing, incoming edit upon merge.*',
'Name': 'foo',
'Schedule': 'normal',
'Node Kind': 'none',
'Path': re.escape(sbox.ospath('A/foo')),
}
run_and_verify_info([expected_info], foo_path)
expected_stdout = None
expected_stderr = ".*foo.*was not found.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"list", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*was not found.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"lock", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*was not found.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"log", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*does not exist.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"merge", '--ignore-ancestry', '-c', '4',
A_copy_url + '/mu', foo_path)
expected_stdout = None
expected_stderr = ".*foo.*was not found.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"mergeinfo", A_copy_url + '/foo', foo_path)
expected_stdout = None
expected_stderr = ".*foo.*is an existing item in conflict.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"mkdir", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*does not exist.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"move", foo_path, foo_path + ".moved")
expected_stdout = None
expected_stderr = ".*foo.*does not exist.*"
patch_path = sbox.get_tempname()
f = open(patch_path, 'w')
patch_data = [
"--- foo (revision 2)\n"
"+++ foo (working copy)\n"
"@@ -1 +1,2 @@\n"
" foo\n"
" +foo\n"
]
for line in patch_data:
f.write(line)
f.close()
run_and_verify_svn(None, expected_stdout, expected_stderr,
"patch", patch_path, sbox.ospath("A/foo"))
expected_stdout = None
expected_stderr = ".*foo.*was not found.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"propdel", "svn:eol-style", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*is not under version control.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"propget", "svn:eol-style", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*is not under version control.*"
svntest.actions.run_and_verify_svn(None, expected_stdout, expected_stderr,
"proplist", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*was not found.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"propset", "svn:eol-style", "native", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*was not found.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"relocate", A_copy_url + "/foo", foo_path)
expected_stdout = "Resolved conflicted state of.*foo.*"
expected_stderr = []
run_and_verify_svn(None, expected_stdout, expected_stderr,
"resolve", "--accept", "working", foo_path)
svntest.main.run_svn(None, "revert", "-R", wc_dir)
svntest.main.run_svn(None, "merge", '-c', '4', A_copy_url,
os.path.join(wc_dir, 'A'))
expected_stdout = "Reverted.*foo.*"
expected_stderr = []
run_and_verify_svn(None, expected_stdout, expected_stderr,
"revert", foo_path)
svntest.main.run_svn(None, "revert", "-R", wc_dir)
svntest.main.run_svn(None, "merge", '-c', '4', A_copy_url,
os.path.join(wc_dir, 'A'))
expected_status = wc.State(foo_path, {
'' : Item(status='! ', treeconflict='C'),
})
run_and_verify_status(foo_path, expected_status)
expected_stdout = None
expected_stderr = ".*foo.*was not found.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"switch", A_copy_url + "/foo", foo_path)
expected_stdout = None
expected_stderr = ".*foo.*was not found.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"unlock", foo_path)
expected_stdout = [
"Skipped '%s' -- Node remains in conflict\n" % sbox.ospath('A/foo'),
"Summary of conflicts:\n",
" Skipped paths: 1\n",
]
expected_stderr = []
run_and_verify_svn(None, expected_stdout, expected_stderr,
"update", foo_path)
expected_stdout = None
expected_stderr = ".*Can't upgrade.*foo.*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"upgrade", foo_path)
@Issues(3526)
def update_dir_with_not_present(sbox):
"lock status update shouldn't flag tree conflict"
sbox.build()
wc_dir = sbox.wc_dir
newtxt = sbox.ospath('A/B/new.txt')
main.file_write(newtxt, 'new.txt')
sbox.simple_add('A/B/new.txt')
sbox.simple_commit()
sbox.simple_move('A/B/new.txt', 'A/C/newer.txt')
sbox.simple_commit()
sbox.simple_rm('A/B')
run_and_verify_svn(None, None, "svn: (E155011|E160028): Dir.*B.*out of date",
'ci', '-m', '', wc_dir)
run_and_verify_svn(None, None, [],
'up', wc_dir)
run_and_verify_svn(None, None, [],
'ci', '-m', '', wc_dir)
test_list = [ None,
up_sw_file_mod_onto_del,
up_sw_file_del_onto_mod,
up_sw_file_del_onto_del,
up_sw_file_add_onto_add,
up_sw_dir_mod_onto_del,
up_sw_dir_del_onto_mod,
up_sw_dir_del_onto_del,
up_sw_dir_add_onto_add,
merge_file_mod_onto_not_file,
merge_file_del_onto_not_same,
merge_file_del_onto_not_file,
merge_file_add_onto_not_none,
merge_dir_mod_onto_not_dir,
merge_dir_del_onto_not_same,
merge_dir_del_onto_not_dir,
merge_dir_add_onto_not_none,
force_del_tc_inside,
force_del_tc_is_target,
query_absent_tree_conflicted_dir,
up_add_onto_add_revert,
lock_update_only,
at_directory_external,
actual_only_node_behaviour,
update_dir_with_not_present,
]
if __name__ == '__main__':
svntest.main.run_tests(test_list)