You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/09/06 22:02:24 UTC
svn commit: r993141 [22/25] - in /subversion/branches/performance: ./
build/ac-macros/ build/generator/ contrib/server-side/ notes/ notes/wc-ng/
subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/...
Modified: subversion/branches/performance/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/tests/cmdline/merge_tests.py?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/branches/performance/subversion/tests/cmdline/merge_tests.py Mon Sep 6 20:02:15 2010
@@ -37,10 +37,10 @@ Item = wc.StateItem
XFail = svntest.testcase.XFail
Skip = svntest.testcase.Skip
SkipUnless = svntest.testcase.SkipUnless
+Wimp = svntest.testcase.Wimp
from svntest.main import SVN_PROP_MERGEINFO
from svntest.main import server_has_mergeinfo
-from svntest.main import is_fs_case_insensitive
from svntest.actions import fill_file_with_lines
from svntest.actions import make_conflict_marker_text
from svntest.actions import inject_conflict_into_expected_state
@@ -1639,7 +1639,7 @@ def merge_skips_obstructions(sbox):
expected_status.copy(wc_dir),
expected_skip,
None, None, None, None, None,
- 1, 0, '--ignore-ancestry')
+ 1, 0, '--ignore-ancestry', wc_dir)
#----------------------------------------------------------------------
# At one time, a merge that added items with the same name as missing
@@ -1652,6 +1652,8 @@ def merge_into_missing(sbox):
sbox.build()
wc_dir = sbox.wc_dir
+
+ single_db = svntest.main.wc_is_singledb(wc_dir)
F_path = os.path.join(wc_dir, 'A', 'B', 'F')
F_url = sbox.repo_url + '/A/B/F'
@@ -1715,14 +1717,25 @@ def merge_into_missing(sbox):
'' : Item(status=' ', wc_rev=1),
'foo' : Item(status='! ', wc_rev=2),
'Q' : Item(status='! ', wc_rev='?'),
-# In some intermediate WC-NG state (since r937468) this was:
-# 'Q' : Item(status='! ', wc_rev='2', entry_rev='?'),
-# but the expected value is now back what it was.
})
expected_skip = wc.State(F_path, {
'Q' : Item(),
'foo' : Item(),
})
+
+ if single_db:
+ # Revision not lost
+ expected_status.tweak('Q', wc_rev=2)
+ # Missing data still available
+ expected_status.add({
+ 'Q/R' : Item(status='! ', wc_rev='3'),
+ 'Q/R/bar' : Item(status='! ', wc_rev='3'),
+ 'Q/baz' : Item(status='! ', wc_rev='3'),
+ })
+
+ # Use --ignore-ancestry because merge tracking aware merges raise an
+ # error when the merge target is missing subtrees due to OS-level
+ # deletes.
### Need to real and dry-run separately since real merge notifies Q
### twice!
@@ -1734,20 +1747,26 @@ def merge_into_missing(sbox):
expected_status,
expected_skip,
None, None, None, None, None,
- 0, 0, '--dry-run')
+ 0, 0, '--dry-run',
+ '--ignore-ancestry', F_path)
expected_status = wc.State(F_path, {
- '' : Item(status=' M', wc_rev=1),
- 'foo' : Item(status='!M', wc_rev=2),
+ '' : Item(status=' ', wc_rev=1),
+ 'foo' : Item(status='! ', wc_rev=2),
'Q' : Item(status='! ', wc_rev='?'),
-# In some intermediate WC-NG state (since r937468) this was:
-# 'Q' : Item(status='! ', wc_rev='2', entry_rev='?'),
-# but the expected value is now back what it was.
})
expected_mergeinfo_output = wc.State(F_path, {
- '' : Item(status=' U'),
- 'foo' : Item(status=' U'), # Mergeinfo is set on missing/obstructed files.
})
+
+ if single_db:
+ # Revision is known and we can record mergeinfo
+ expected_status.tweak('Q', wc_rev='2', entry_rev='?')
+ expected_status.add({
+ 'Q/R' : Item(status='! ', wc_rev='3'),
+ 'Q/R/bar' : Item(status='! ', wc_rev='3'),
+ 'Q/baz' : Item(status='! ', wc_rev='3'),
+ })
+
svntest.actions.run_and_verify_merge(F_path, '1', '2', F_url, None,
expected_output,
expected_mergeinfo_output,
@@ -1756,7 +1775,8 @@ def merge_into_missing(sbox):
expected_status,
expected_skip,
None, None, None, None, None,
- 0, 0)
+ 0, 0,
+ '--ignore-ancestry', F_path)
# This merge fails when it attempts to descend into the missing
# directory. That's OK, there is no real need to support merge into
@@ -1771,13 +1791,21 @@ def merge_into_missing(sbox):
# Check working copy is not locked.
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.add({
- 'A/B/F' : Item(status=' M', wc_rev=1),
- 'A/B/F/foo' : Item(status='!M', wc_rev=2),
+ 'A/B/F' : Item(status=' ', wc_rev=1),
+ 'A/B/F/foo' : Item(status='! ', wc_rev=2),
'A/B/F/Q' : Item(status='! ', wc_rev='?'),
-# In some intermediate WC-NG state (since r937468) this was:
-# 'A/B/F/Q' : Item(status='! ', wc_rev='2', entry_rev='?'),
-# but the expected value is now back what it was.
})
+ if single_db:
+ # Revision known and mergeinfo recorded
+ expected_status.tweak('A/B/F/Q', wc_rev='2')
+ # Missing data still available
+ expected_status.add({
+ 'A/B/F/Q' : Item(status='! ', wc_rev='2'),
+ 'A/B/F/Q/baz' : Item(status='! ', wc_rev='3'),
+ 'A/B/F/Q/R' : Item(status='! ', wc_rev='3'),
+ 'A/B/F/Q/R/bar' : Item(status='! ', wc_rev='3'),
+ })
+
svntest.actions.run_and_verify_status(wc_dir, expected_status)
#----------------------------------------------------------------------
@@ -2431,11 +2459,11 @@ def merge_dir_replace(sbox):
expected_status = wc.State(C_path, {
'' : Item(status=' M', wc_rev=3),
'foo' : Item(status='R ', wc_rev='-', copied='+'),
- 'foo/new file 2' : Item(status='D ', wc_rev='-', copied='+'),
- 'foo/file foo' : Item(status='A ', wc_rev='-', copied='+'),
- 'foo/bar' : Item(status='A ', wc_rev='-', copied='+'),
- 'foo/bar/new file 3' : Item(status='A ', wc_rev='-', copied='+'),
- 'foo/new file' : Item(status='D ', wc_rev='-', copied='+'),
+ 'foo/new file 2' : Item(status='D ', wc_rev='3'),
+ 'foo/file foo' : Item(status=' ', wc_rev='-', copied='+'),
+ 'foo/bar' : Item(status=' ', wc_rev='-', copied='+'),
+ 'foo/bar/new file 3' : Item(status=' ', wc_rev='-', copied='+'),
+ 'foo/new file' : Item(status='D ', wc_rev='3'),
})
expected_skip = wc.State(C_path, { })
svntest.actions.run_and_verify_merge(C_path, '2', '5', F_url, None,
@@ -2454,9 +2482,6 @@ def merge_dir_replace(sbox):
expected_output = svntest.wc.State(wc_dir, {
'A/C' : Item(verb='Sending'),
'A/C/foo' : Item(verb='Replacing'),
- 'A/C/foo/file foo' : Item(verb='Adding'),
- 'A/C/foo/bar' : Item(verb='Adding'),
- 'A/C/foo/bar/new file 3' : Item(verb='Adding'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.add({
@@ -3023,7 +3048,7 @@ def property_merge_undo_redo(sbox):
None, None, # no B singleton handler
1, # check props
0, # dry_run
- '--ignore-ancestry')
+ '--ignore-ancestry', wc_dir)
@@ -3407,7 +3432,7 @@ def merge_ignore_whitespace(sbox):
expected_skip,
None, None, None, None, None,
0, 0,
- '-x', '-w')
+ '-x', '-w', wc_dir)
#----------------------------------------------------------------------
# use -x --ignore-eol-style option for ignoring eolstyle during merge
@@ -3489,7 +3514,7 @@ def merge_ignore_eolstyle(sbox):
expected_skip,
None, None, None, None, None,
0, 0,
- '-x', '--ignore-eol-style')
+ '-x', '--ignore-eol-style', wc_dir)
#----------------------------------------------------------------------
# eol-style handling during merge with conflicts, scenario 1:
@@ -4786,6 +4811,11 @@ def mergeinfo_inheritance(sbox):
wc_status,
None,
wc_dir)
+
+ # In single-db mode you can't create a disconnected working copy by just
+ # copying a subdir
+ if svntest.main.wc_is_singledb(wc_dir):
+ return
# Copy the subtree A_COPY/B/E from the working copy, making the
# disconnected WC E_only.
@@ -5028,7 +5058,8 @@ def mergeinfo_elision(sbox):
expected_status,
expected_skip,
None, None, None, None,
- None, 1, 1, '--record-only')
+ None, 1, 1, '--record-only',
+ A_COPY_path)
# Reverse merge r5 out of A_COPY/B/E/beta. The mergeinfo on
# A_COPY/B/E/beta which previously elided will now return,
@@ -6788,6 +6819,8 @@ def merge_loses_mergeinfo(sbox):
'' : Item(status=' U'),
})
expected_disk = wc.State('', {'J': Item()})
+ if svntest.main.wc_is_singledb(wc_dir):
+ expected_disk.remove('J')
expected_status = wc.State(A_C_wc_dir,
{ '' : Item(wc_rev=4, status=' M'),
'J' : Item(wc_rev=4, status='D ')
@@ -6809,6 +6842,8 @@ def merge_loses_mergeinfo(sbox):
'J' : Item(),
'' : Item(props={SVN_PROP_MERGEINFO : '/A/B:3'}),
})
+ if svntest.main.wc_is_singledb(wc_dir):
+ expected_disk.remove('J')
expected_status = wc.State(A_C_wc_dir,
{ '' : Item(wc_rev=4, status=' M'),
'K' : Item(status='A ',
@@ -7098,7 +7133,7 @@ def merge_with_depth_files(sbox):
expected_disk,
expected_status, expected_skip,
None, None, None, None, None, 1, 1,
- '--depth', 'files')
+ '--depth', 'files', Acopy_path)
#----------------------------------------------------------------------
# Test for issue #2976 Subtrees can lose non-inheritable ranges.
@@ -7193,7 +7228,7 @@ def merge_away_subtrees_noninheritable_r
expected_disk,
expected_status, expected_skip,
None, None, None, None, None, 1, 1,
- '--depth', 'immediates')
+ '--depth', 'immediates', D_COPY_path)
# Repeat the previous merge but at default depth of infinity. The change
# to A_COPY/D/H/omega should now happen and the non-inheritable ranges on
@@ -7463,7 +7498,7 @@ def merge_away_subtrees_noninheritable_r
expected_disk,
expected_status, expected_skip,
None, None, None, None, None, 1, 1,
- '--depth', 'empty')
+ '--depth', 'empty', H_COPY_2_path)
svntest.actions.run_and_verify_svn(None, None, [], 'commit', '-m',
'log msg', wc_dir);
svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
@@ -8693,7 +8728,8 @@ def propchange_of_subdir_raises_conflict
expected_status,
expected_skip,
None, None, None, None, None,
- 1, 1, '--depth', 'files')
+ 1, 1, '--depth', 'files',
+ A_COPY_B_path)
# Merge /A/B to /A_COPY/B ie., r1 to r3 with infinite depth
expected_output = wc.State(A_COPY_B_path, {
@@ -8916,7 +8952,8 @@ def merge_target_with_non_inheritable_me
expected_status,
expected_skip,
None, None, None, None, None,
- 1, 1, '--depth', 'immediates')
+ 1, 1, '--depth', 'immediates',
+ A_COPY_B_path)
# Merge /A/B to /A_COPY/B ie., r1 to r3 with infinite depth
expected_output = wc.State(A_COPY_B_path, {
@@ -9137,7 +9174,7 @@ def ignore_ancestry_and_mergeinfo(sbox):
expected_status,
expected_skip,
None, None, None, None, None, 1, 1,
- '--ignore-ancestry')
+ '--ignore-ancestry', A_COPY_B_path)
#----------------------------------------------------------------------
def merge_from_renamed_branch_fails_while_avoiding_repeat_merge(sbox):
@@ -13589,7 +13626,7 @@ def subtree_gets_changes_even_if_ultimat
expected_disk,
expected_status, expected_skip,
None, None, None, None, None, 1, 0,
- '-c3,7')
+ '-c3,7', H_COPY_path)
svntest.actions.run_and_verify_svn(
None,
expected_merge_output([[-7]],
@@ -13775,6 +13812,8 @@ def no_self_referential_filtering_on_add
'D/H/psi' : Item("New content"),
'D/H/omega' : Item("New content"),
})
+ if svntest.main.wc_is_singledb(wc_dir):
+ expected_A_COPY_2_disk.remove('C')
expected_A_COPY_2_skip = wc.State(A_COPY_2_path, { })
svntest.actions.run_and_verify_merge(A_COPY_2_path, None, None,
sbox.repo_url + '/A', None,
@@ -14731,7 +14770,7 @@ def record_only_merge(sbox):
expected_status,
expected_skip,
None, None, None, None, None, 1, 0,
- '--record-only')
+ '--record-only', A2_path)
#----------------------------------------------------------------------
# Test for issue #3514 'svn merge --accept [ base | theirs-full ]
@@ -14827,7 +14866,8 @@ def merge_automatic_conflict_resolution(
svntest.tree.detect_conflict_files,
list(psi_conflict_support_files),
None, None, 1, 1,
- '--accept', 'postpone')
+ '--accept', 'postpone',
+ A_COPY_path)
svntest.actions.run_and_verify_svn(None, None, [],
'revert', '--recursive', wc_dir)
@@ -14845,7 +14885,8 @@ def merge_automatic_conflict_resolution(
expected_skip,
None, None, None,
None, None, 1, 0,
- '--accept', 'mine-conflict')
+ '--accept', 'mine-conflict',
+ A_COPY_path)
svntest.actions.run_and_verify_svn(None, None, [],
'revert', '--recursive', wc_dir)
svntest.actions.run_and_verify_merge(A_COPY_path, '2', '3',
@@ -14858,7 +14899,8 @@ def merge_automatic_conflict_resolution(
expected_skip,
None, None, None,
None, None, 1, 0,
- '--accept', 'mine-full')
+ '--accept', 'mine-full',
+ A_COPY_path)
svntest.actions.run_and_verify_svn(None, None, [],
'revert', '--recursive', wc_dir)
@@ -14876,7 +14918,8 @@ def merge_automatic_conflict_resolution(
expected_skip,
None, None, None,
None, None, 1, 0,
- '--accept', 'theirs-conflict')
+ '--accept', 'theirs-conflict',
+ A_COPY_path)
svntest.actions.run_and_verify_svn(None, None, [],
'revert', '--recursive', wc_dir)
# Issue #3514 fails here with an error similar to:
@@ -14915,7 +14958,8 @@ def merge_automatic_conflict_resolution(
expected_skip,
None, None, None,
None, None, 1, 0,
- '--accept', 'theirs-full')
+ '--accept', 'theirs-full',
+ A_COPY_path)
svntest.actions.run_and_verify_svn(None, None, [],
'revert', '--recursive', wc_dir)
# Test --accept base
@@ -14939,7 +14983,8 @@ def merge_automatic_conflict_resolution(
expected_skip,
None, None, None,
None, None, 1, 0,
- '--accept', 'base')
+ '--accept', 'base',
+ A_COPY_path)
#----------------------------------------------------------------------
# Test for issue #3440 'Skipped paths get incorrect override mergeinfo
@@ -14952,6 +14997,7 @@ def skipped_files_get_correct_mergeinfo(
# Some paths we'll care about
A_COPY_path = os.path.join(wc_dir, "A_COPY")
+ H_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H")
psi_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "psi")
psi_path = os.path.join(wc_dir, "A", "D", "H", "psi")
@@ -14979,15 +15025,21 @@ def skipped_files_get_correct_mergeinfo(
[], 'merge', '-c3', sbox.repo_url + '/A', A_COPY_path)
svntest.main.run_svn(None, 'commit', '-m', 'initial merge', wc_dir)
- # Update WC to uniform revision and then delete, via the OS, A_COPY/D/H/psi
- # and then merge all available revisions from A to A_COPY. A_COPY/D/H/psi
- # should be reported as skipped and get explicit mergeinfo set on it
- # reflecting what it previously inherited from A_COPY after the first
- # merge, i.e. '/A/D/H/psi:3'. Issue #3440 occurred when empty mergeinfo
- # was set on A_COPY/D/H/psi, making it appear that r3 was never merged.
+ # Update WC to uniform revision and then set the depth on A_COPY/D/H to
+ # empty. Then merge all available revisions from A to A_COPY.
+ # A_COPY/D/H/psi and A_COPY/D/H/omega are not present due to their
+ # parent's depth and should be reported as skipped. A_COPY/D/H should
+ # get explicit mergeinfo set on it reflecting what it previously inherited
+ # from A_COPY after the first merge, i.e. '/A/D/H:3', plus non-inheritable
+ # mergeinfo describing what was done during this merge,
+ # i.e. '/A/D/H:2*,4-8*'.
+ #
+ # Issue #3440 occurred when empty mergeinfo was set on A_COPY/D/H, making
+ # it appear that r3 was never merged.
svntest.actions.run_and_verify_svn(None, ["At revision 8.\n"], [],
'up', wc_dir)
- os.remove(psi_COPY_path)
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'up', '--set-depth=empty', H_COPY_path)
expected_status = wc.State(A_COPY_path, {
'' : Item(status=' M'),
'B' : Item(status=' '),
@@ -15004,10 +15056,7 @@ def skipped_files_get_correct_mergeinfo(
'D/G/rho' : Item(status='M '),
'D/G/tau' : Item(status=' '),
'D/gamma' : Item(status=' '),
- 'D/H' : Item(status=' '),
- 'D/H/chi' : Item(status=' '),
- 'D/H/psi' : Item(status='!M'),
- 'D/H/omega' : Item(status='M '),
+ 'D/H' : Item(status=' M'),
})
expected_status.tweak(wc_rev=8)
expected_disk = wc.State('', {
@@ -15026,71 +15075,18 @@ def skipped_files_get_correct_mergeinfo(
'D/G/rho' : Item("New content"),
'D/G/tau' : Item("This is the file 'tau'.\n"),
'D/gamma' : Item("This is the file 'gamma'.\n"),
- 'D/H' : Item(),
- 'D/H/chi' : Item("This is the file 'chi'.\n"),
- #'D/H/psi' : Nothing here, this file was deleted via the OS.
- 'D/H/omega' : Item("New content"),
+ 'D/H' : Item(props={SVN_PROP_MERGEINFO : '/A/D/H:2*,3,4-8*'}),
})
expected_skip = wc.State(A_COPY_path,
- {'D/H/psi' : Item()})
+ {'D/H/psi' : Item(),
+ 'D/H/omega' : Item()})
expected_output = wc.State(A_COPY_path,
{'B/E/beta' : Item(status='U '),
- 'D/G/rho' : Item(status='U '),
- 'D/H/omega' : Item(status='U '),})
- expected_mergeinfo_output = wc.State(A_COPY_path, {
- '' : Item(status=' U'),
- 'D/H/psi' : Item(status=' U'),
- })
- expected_elision_output = wc.State(A_COPY_path, {
- })
- svntest.actions.run_and_verify_merge(A_COPY_path, None, None,
- sbox.repo_url + '/A', None,
- expected_output,
- expected_mergeinfo_output,
- expected_elision_output,
- expected_disk,
- expected_status,
- expected_skip,
- None, None, None, None, None,
- 1, 1)
- # run_and_verify_merge cannot check the properties on A_COPY/D/H/psi
- # since that file is not on disk, so we'll check the file's mergeinfo
- # directly with svn propget.
- svntest.actions.run_and_verify_svn(
- 'Incorrect override mergeinfo set on skipped path',
- ["/A/D/H/psi:3\n"], [], 'pg', 'svn:mergeinfo', psi_COPY_path)
-
- # Now test another aspect of issue #3440, that a skipped path with
- # explicit mergeinfo doesn't get it's mergeinfo updated.
- #
- # First revert all changes to the WC and then merge -r2:6 from A/D/H/psi
- # to A_COPY/D/H/psi, creating explicit mergeinfo of '/A/D/H/psi:3-6' on
- # the latter. Commit this merge as r9 and then update the WC.
- svntest.actions.run_and_verify_svn(None, None, [],
- 'revert', '-R', wc_dir)
- svntest.actions.run_and_verify_svn(
- None,
- expected_merge_output([[3,6]],
- [' U ' + psi_COPY_path + '\n',
- ' G ' + psi_COPY_path + '\n']),
- [], 'merge', '-r2:6', sbox.repo_url + '/A/D/H/psi', psi_COPY_path)
- svntest.main.run_svn(None, 'commit', '-m',
- 'subtree merge to create explicit mergeinfo',
- wc_dir)
- svntest.actions.run_and_verify_svn(None, ["At revision 9.\n"], [],
- 'up', wc_dir)
-
- # Remove A_COPY/D/H/psi again and then merge all available revisions
- # from A to A_COPY. The results should be mostly similar to the
- # previous merge we did above, execept that A_COPY/D/H/psi should not
- # have it's mergeinfo changed.
- os.remove(psi_COPY_path)
- expected_status.tweak(wc_rev=9)
- expected_status.tweak('D/H/psi', status='! ')
- expected_disk.tweak('', props={SVN_PROP_MERGEINFO : '/A:2-9'})
+ 'D/G/rho' : Item(status='U ')})
expected_mergeinfo_output = wc.State(A_COPY_path, {
- '' : Item(status=' U'),
- 'D/H/psi' : Item(status=' U'),
+ '' : Item(status=' U'),
+ 'D/H' : Item(status=' G'), # ' G' because override mergeinfo gets set
+ # on this, the root of a 'missing' subtree.
})
expected_elision_output = wc.State(A_COPY_path, {
})
@@ -15105,16 +15101,6 @@ def skipped_files_get_correct_mergeinfo(
None, None, None, None, None,
1, 1)
- # run_and_verify_merge cannot check the properties on A_COPY/D/H/psi
- # since that file is not on disk, so we'll check the file's mergeinfo
- # directly with svn propget. Issue #3440 also occurred here, when an
- # the missing file's mergeinfo was updated, making it appear that r2
- # and r7-9 were also merged into A_COPY/D/H/psi, which is clearly not
- # the case since psi isn't present.
- svntest.actions.run_and_verify_svn(
- 'Mergeinfo on skipped path altered',
- ["/A/D/H/psi:3-6\n"], [], 'pg', 'svn:mergeinfo', psi_COPY_path)
-
#----------------------------------------------------------------------
# Test for issue #3115 'Case only renames resulting from merges don't
# work or break the WC on case-insensitive file systems'.
@@ -15247,6 +15233,8 @@ def committed_case_only_move_and_revert(
})
expected_disk.tweak('', props={SVN_PROP_MERGEINFO : '/A:3,5'})
expected_disk.add({'c' : Item()})
+ if svntest.main.wc_is_singledb(wc_dir):
+ expected_disk.remove('C')
expected_status.tweak('MU', status=' ', wc_rev=4, copied=None)
expected_status.remove('mu')
expected_status.tweak('C', status='D ')
@@ -15467,7 +15455,7 @@ def foreign_repos_del_and_props(sbox):
# Test for issue #3642 'immediate depth merges don't create proper subtree
# mergeinfo'. See http://subversion.tigris.org/issues/show_bug.cgi?id=3642
def immediate_depth_merge_creates_minimal_subtree_mergeinfo(sbox):
- "no spurious mergeinfo from immediate depth merges "
+ "no spurious mergeinfo from immediate depth merges"
sbox.build()
wc_dir = sbox.wc_dir
@@ -15525,7 +15513,8 @@ def immediate_depth_merge_creates_minima
expected_status,
expected_skip,
None, None, None, None, None,
- 1, 1, '--depth', 'immediates')
+ 1, 1, '--depth', 'immediates',
+ B_COPY_path)
#----------------------------------------------------------------------
# Test for issue #3646 'cyclic --record-only merges create self-referential
@@ -15619,7 +15608,7 @@ def record_only_merge_creates_self_refer
expected_A_status,
expected_A_skip,
None, None, None, None, None, 1, 1,
- '--record-only')
+ '--record-only', A_path)
#----------------------------------------------------------------------
# Test for issue #3657 'phantom svn:eol-style changes cause spurious merge
@@ -15746,6 +15735,194 @@ def copy_causes_phantom_eol_conflict(sbo
expected_skip,
None, None, None, None, None, 1, 1)
+
+#----------------------------------------------------------------------
+def merge_into_locally_added_file(sbox):
+ "merge into locally added file"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # Some paths we'll care about
+ pi_path = sbox.ospath("A/D/G/pi")
+ new_path = sbox.ospath("A/D/G/new")
+
+ shutil.copy(pi_path, new_path)
+ svntest.main.file_append(pi_path, "foo\n")
+ sbox.simple_commit(); # r2
+
+ sbox.simple_add(new_path)
+
+ expected_output = wc.State(wc_dir, {
+ 'A/D/G/new' : Item(status='G '),
+ })
+ expected_mergeinfo_output = wc.State(wc_dir, {
+ 'A/D/G/new' : Item(status=' U'),
+ })
+ expected_elision_output = wc.State(wc_dir, {})
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.add({ 'A/D/G/new' : Item(status='A ', wc_rev=0)})
+ expected_status.tweak('A/D/G/pi', wc_rev=2)
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/D/G/pi', contents="This is the file 'pi'.\nfoo\n")
+ expected_disk.add({'A/D/G/new' : Item("This is the file 'pi'.\nfoo\n",
+ props={SVN_PROP_MERGEINFO : '/A/D/G/pi:2'})})
+ expected_skip = wc.State(wc_dir, {})
+
+ svntest.actions.run_and_verify_merge(wc_dir, '1', '2',
+ sbox.repo_url + '/A/D/G/pi', None,
+ expected_output,
+ expected_mergeinfo_output,
+ expected_elision_output,
+ expected_disk,
+ expected_status,
+ expected_skip,
+ None, None, None, None, None,
+ True, True, new_path)
+ sbox.simple_commit()
+
+#----------------------------------------------------------------------
+def merge_into_locally_added_directory(sbox):
+ "merge into locally added directory"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # Some paths we'll care about
+ G_path = sbox.ospath("A/D/G")
+ pi_path = sbox.ospath("A/D/G/pi")
+ new_dir_path = sbox.ospath("A/D/new_dir")
+
+ svntest.main.file_append_binary(pi_path, "foo\n")
+ sbox.simple_commit(); # r2
+
+ os.mkdir(new_dir_path)
+ svntest.main.file_append_binary(os.path.join(new_dir_path, 'pi'),
+ "This is the file 'pi'.\n")
+ svntest.main.file_append_binary(os.path.join(new_dir_path, 'rho'),
+ "This is the file 'rho'.\n")
+ svntest.main.file_append_binary(os.path.join(new_dir_path, 'tau'),
+ "This is the file 'tau'.\n")
+ sbox.simple_add(new_dir_path)
+
+ expected_output = wc.State(wc_dir, {
+ 'A/D/new_dir/pi' : Item(status='G '),
+ })
+ expected_mergeinfo_output = wc.State(wc_dir, {
+ 'A/D/new_dir' : Item(status=' U'),
+ })
+ expected_elision_output = wc.State(wc_dir, {})
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.add({ 'A/D/new_dir' : Item(status='A ', wc_rev=0)})
+ expected_status.add({ 'A/D/new_dir/pi' : Item(status='A ', wc_rev=0)})
+ expected_status.add({ 'A/D/new_dir/rho' : Item(status='A ', wc_rev=0)})
+ expected_status.add({ 'A/D/new_dir/tau' : Item(status='A ', wc_rev=0)})
+ expected_status.tweak('A/D/G/pi', wc_rev=2)
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/D/G/pi', contents="This is the file 'pi'.\nfoo\n")
+ expected_disk.add({'A/D/new_dir' :
+ Item(props={SVN_PROP_MERGEINFO : '/A/D/G:2'})})
+ expected_disk.add({'A/D/new_dir/pi' :
+ Item(contents="This is the file 'pi'.\nfoo\n")})
+ expected_disk.add({'A/D/new_dir/rho' :
+ Item(contents="This is the file 'rho'.\n")})
+ expected_disk.add({'A/D/new_dir/tau' :
+ Item(contents="This is the file 'tau'.\n")})
+ expected_skip = wc.State(wc_dir, {})
+
+ svntest.actions.run_and_verify_merge(wc_dir, '1', '2',
+ sbox.repo_url + '/A/D/G', None,
+ expected_output,
+ expected_mergeinfo_output,
+ expected_elision_output,
+ expected_disk,
+ expected_status,
+ expected_skip,
+ None, None, None, None, None,
+ True, True, new_dir_path)
+ sbox.simple_commit()
+
+#----------------------------------------------------------------------
+# Test for issue #2915 'Handle mergeinfo for subtrees missing due to removal
+# by non-svn command'
+def merge_with_os_deleted_subtrees(sbox):
+ "merge tracking fails if target missing subtrees"
+
+ # r1: Create a greek tree.
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # r2 - r6: Copy A to A_COPY and then make some text changes under A.
+ set_up_branch(sbox)
+
+ # Some paths we'll care about
+ A_COPY_path = os.path.join(wc_dir, "A_COPY")
+ C_COPY_path = os.path.join(wc_dir, "A_COPY", "C")
+ psi_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "psi")
+ mu_COPY_path = os.path.join(wc_dir, "A_COPY", "mu")
+ G_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "G")
+
+ # Remove several subtrees from disk.
+ svntest.main.safe_rmtree(C_COPY_path)
+ svntest.main.safe_rmtree(G_COPY_path)
+ os.remove(psi_COPY_path)
+ os.remove(mu_COPY_path)
+
+ # Be sure the regex paths are properly escaped on Windows, see the
+ # note about "The Backslash Plague" in expected_merge_output().
+ if sys.platform == 'win32':
+ re_sep = '\\\\'
+ else:
+ re_sep = os.sep
+
+ # Common part of the expected error message for all cases we will test.
+ err_re = "svn: Merge tracking not allowed with missing subtrees; " + \
+ "try restoring these items first:" + \
+ "|(\n)" + \
+ "|(.*apr_err.*\n)" # In case of debug build
+
+ # Case 1: Infinite depth merge into infinite depth WC target.
+ # Every missing subtree under the target should be reported as missing.
+ missing = "|(.*A_COPY" + re_sep + "mu\n)" + \
+ "|(.*A_COPY" + re_sep + "D" + re_sep + "G\n)" + \
+ "|(.*A_COPY" + re_sep + "C\n)" + \
+ "|(.*A_COPY" + re_sep + "D" + re_sep + "H" + re_sep + "psi\n)"
+ exit_code, out, err = svntest.actions.run_and_verify_svn(
+ "Missing subtrees should raise error", [], svntest.verify.AnyOutput,
+ 'merge', sbox.repo_url + '/A', A_COPY_path)
+ svntest.verify.verify_outputs("Merge failed but not in the way expected",
+ err, None, err_re + missing, None,
+ True) # Match *all* lines of stderr
+
+ # Case 2: Immediates depth merge into infinite depth WC target.
+ # Only the two immediate children of the merge target should be reported
+ # as missing.
+ missing = "|(.*A_COPY" + re_sep + "mu\n)" + \
+ "|(.*A_COPY" + re_sep + "C\n)"
+ exit_code, out, err = svntest.actions.run_and_verify_svn(
+ "Missing subtrees should raise error", [], svntest.verify.AnyOutput,
+ 'merge', sbox.repo_url + '/A', A_COPY_path, '--depth=immediates')
+ svntest.verify.verify_outputs("Merge failed but not in the way expected",
+ err, None, err_re + missing, None, True)
+
+ # Case 3: Files depth merge into infinite depth WC target.
+ # Only the single file child of the merge target should be reported
+ # as missing.
+ missing = "|(.*A_COPY" + re_sep + "mu\n)"
+ exit_code, out, err = svntest.actions.run_and_verify_svn(
+ "Missing subtrees should raise error", [], svntest.verify.AnyOutput,
+ 'merge', sbox.repo_url + '/A', A_COPY_path, '--depth=files')
+ svntest.verify.verify_outputs("Merge failed but not in the way expected",
+ err, None, err_re + missing, None, True)
+
+ # Case 4: Empty depth merge into infinite depth WC target.
+ # Only the...oh, wait, the target is present and that is as deep
+ # as the merge goes, so this merge should succeed!
+ svntest.actions.run_and_verify_svn(
+ "Depth empty merge should succeed as long at the target is present",
+ svntest.verify.AnyOutput, [], 'merge', sbox.repo_url + '/A',
+ A_COPY_path, '--depth=empty')
+
########################################################################
# Run the tests
@@ -15796,8 +15973,8 @@ test_list = [ None,
SkipUnless(cherry_pick_text_conflict,
server_has_mergeinfo),
merge_file_replace,
- XFail(SkipUnless(merge_dir_replace,
- server_has_mergeinfo)),
+ SkipUnless(merge_dir_replace,
+ server_has_mergeinfo),
merge_dir_and_file_replace,
merge_file_replace_to_mixed_rev_wc,
SkipUnless(merge_ignore_whitespace,
@@ -15926,13 +16103,15 @@ test_list = [ None,
server_has_mergeinfo),
XFail(merge_automatic_conflict_resolution),
skipped_files_get_correct_mergeinfo,
- XFail(committed_case_only_move_and_revert,
- is_fs_case_insensitive),
+ committed_case_only_move_and_revert,
merge_into_wc_for_deleted_branch,
foreign_repos_del_and_props,
immediate_depth_merge_creates_minimal_subtree_mergeinfo,
record_only_merge_creates_self_referential_mergeinfo,
copy_causes_phantom_eol_conflict,
+ merge_into_locally_added_file,
+ merge_into_locally_added_directory,
+ merge_with_os_deleted_subtrees,
]
if __name__ == '__main__':
Modified: subversion/branches/performance/subversion/tests/cmdline/merge_tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/tests/cmdline/merge_tree_conflict_tests.py?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/tests/cmdline/merge_tree_conflict_tests.py (original)
+++ subversion/branches/performance/subversion/tests/cmdline/merge_tree_conflict_tests.py Mon Sep 6 20:02:15 2010
@@ -623,6 +623,9 @@ def mergeinfo_recording_in_skipped_merge
'D/H/omega': Item("This is the file 'omega'.\n"),
'D/H/psi' : Item("This is the file 'psi'.\n"),
})
+ if svntest.main.wc_is_singledb(sbox.wc_dir):
+ # Delete removes directories in single-db
+ expected_disk.remove('B/E')
expected_skip = wc.State(A_COPY_path, {})
svntest.actions.run_and_verify_merge(A_COPY_path, None, None,
A_url, None,
@@ -796,9 +799,11 @@ leaf_edit = svntest.actions.deep_trees_l
tree_del = svntest.actions.deep_trees_tree_del
leaf_del = svntest.actions.deep_trees_leaf_del
-state_after_leaf_edit = svntest.actions.deep_trees_after_leaf_edit
-state_after_leaf_del = svntest.actions.deep_trees_after_leaf_del
-state_after_tree_del = svntest.actions.deep_trees_after_tree_del
+disk_after_leaf_edit = svntest.actions.deep_trees_after_leaf_edit
+disk_after_leaf_del = svntest.actions.deep_trees_after_leaf_del
+disk_after_tree_del = svntest.actions.deep_trees_after_tree_del
+disk_after_leaf_del_no_ci = svntest.actions.deep_trees_after_leaf_del_no_ci
+disk_after_tree_del_no_ci = svntest.actions.deep_trees_after_tree_del_no_ci
deep_trees_conflict_output = svntest.actions.deep_trees_conflict_output
@@ -821,7 +826,7 @@ def tree_conflicts_on_merge_local_ci_4_1
expected_output = deep_trees_conflict_output
- expected_disk = state_after_tree_del
+ expected_disk = disk_after_tree_del
expected_status = svntest.wc.State('', {
'' : Item(status=' M', wc_rev='3'),
@@ -858,7 +863,7 @@ def tree_conflicts_on_merge_local_ci_4_2
expected_output = deep_trees_conflict_output
- expected_disk = state_after_tree_del
+ expected_disk = disk_after_tree_del
expected_status = svntest.wc.State('', {
'' : Item(status=' M', wc_rev='3'),
@@ -897,7 +902,7 @@ def tree_conflicts_on_merge_local_ci_5_1
expected_output = deep_trees_conflict_output
- expected_disk = state_after_leaf_edit
+ expected_disk = disk_after_leaf_edit
# We should detect 6 tree conflicts, and nothing should be deleted (when
# we skip tree conflict victims).
@@ -947,14 +952,7 @@ def tree_conflicts_on_merge_local_ci_5_2
expected_output = deep_trees_conflict_output
- expected_disk = svntest.wc.State('', {
- 'F' : Item(),
- 'D' : Item(),
- 'DF/D1' : Item(),
- 'DD/D1' : Item(),
- 'DDF/D1/D2' : Item(),
- 'DDD/D1/D2' : Item(),
- })
+ expected_disk = disk_after_leaf_del
expected_status = svntest.wc.State('', {
'' : Item(status=' M', wc_rev='3'),
@@ -995,7 +993,7 @@ def tree_conflicts_on_merge_local_ci_6(s
expected_output = deep_trees_conflict_output
- expected_disk = state_after_tree_del
+ expected_disk = disk_after_tree_del
expected_status = svntest.wc.State('', {
'' : Item(status=' M', wc_rev='3'),
@@ -1029,19 +1027,14 @@ def tree_conflicts_on_merge_local_ci_6(s
def tree_conflicts_on_merge_no_local_ci_4_1(sbox):
"tree conflicts 4.1: tree del (no ci), leaf edit"
+ sbox.build()
+
# use case 4, as in notes/tree-conflicts/use-cases.txt
# 4.1) local tree delete, incoming leaf edit
expected_output = deep_trees_conflict_output
- expected_disk = svntest.wc.State('', {
- 'F' : Item(),
- 'D/D1' : Item(),
- 'DF/D1' : Item(),
- 'DD/D1/D2' : Item(),
- 'DDF/D1/D2' : Item(),
- 'DDD/D1/D2/D3' : Item(),
- })
+ expected_disk = disk_after_tree_del_no_ci(sbox.wc_dir)
expected_status = svntest.wc.State('', {
'' : Item(status=' M', wc_rev='3'),
@@ -1083,18 +1076,13 @@ def tree_conflicts_on_merge_no_local_ci_
def tree_conflicts_on_merge_no_local_ci_4_2(sbox):
"tree conflicts 4.2: tree del (no ci), leaf del"
+ sbox.build()
+
# 4.2) local tree delete, incoming leaf delete
expected_output = deep_trees_conflict_output
- expected_disk = svntest.wc.State('', {
- 'F' : Item(),
- 'D/D1' : Item(),
- 'DF/D1' : Item(),
- 'DD/D1/D2' : Item(),
- 'DDF/D1/D2' : Item(),
- 'DDD/D1/D2/D3' : Item(),
- })
+ expected_disk = disk_after_tree_del_no_ci(sbox.wc_dir)
expected_status = svntest.wc.State('', {
'' : Item(status=' M', wc_rev='3'),
@@ -1142,7 +1130,7 @@ def tree_conflicts_on_merge_no_local_ci_
expected_output = deep_trees_conflict_output
- expected_disk = state_after_leaf_edit
+ expected_disk = disk_after_leaf_edit
expected_status = svntest.wc.State('', {
'' : Item(status=' M', wc_rev='3'),
@@ -1150,23 +1138,23 @@ def tree_conflicts_on_merge_no_local_ci_
'D/D1' : Item(status=' M', treeconflict='C', wc_rev='3'),
'D/D1/delta' : Item(status='A ', wc_rev='0'),
'DD' : Item(status=' ', wc_rev='3'),
- 'DD/D1' : Item(status=' M', treeconflict='C', wc_rev='3'),
- 'DD/D1/D2' : Item(status=' ', wc_rev='3'),
+ 'DD/D1' : Item(status=' ', treeconflict='C', wc_rev='3'),
+ 'DD/D1/D2' : Item(status=' M', wc_rev='3'),
'DD/D1/D2/epsilon' : Item(status='A ', wc_rev='0'),
'DDD' : Item(status=' ', wc_rev='3'),
- 'DDD/D1' : Item(status=' M', treeconflict='C', wc_rev='3'),
+ 'DDD/D1' : Item(status=' ', treeconflict='C', wc_rev='3'),
'DDD/D1/D2' : Item(status=' ', wc_rev='3'),
- 'DDD/D1/D2/D3' : Item(status=' ', wc_rev='3'),
+ 'DDD/D1/D2/D3' : Item(status=' M', wc_rev='3'),
'DDD/D1/D2/D3/zeta' : Item(status='A ', wc_rev='0'),
'DDF' : Item(status=' ', wc_rev='3'),
- 'DDF/D1' : Item(status=' M', treeconflict='C', wc_rev='3'),
+ 'DDF/D1' : Item(status=' ', treeconflict='C', wc_rev='3'),
'DDF/D1/D2' : Item(status=' ', wc_rev='3'),
- 'DDF/D1/D2/gamma' : Item(status='M ', wc_rev='3'),
+ 'DDF/D1/D2/gamma' : Item(status='MM', wc_rev='3'),
'DF' : Item(status=' ', wc_rev='3'),
- 'DF/D1' : Item(status=' M', treeconflict='C', wc_rev='3'),
- 'DF/D1/beta' : Item(status='M ', wc_rev='3'),
+ 'DF/D1' : Item(status=' ', treeconflict='C', wc_rev='3'),
+ 'DF/D1/beta' : Item(status='MM', wc_rev='3'),
'F' : Item(status=' ', wc_rev='3'),
- 'F/alpha' : Item(status='M ', treeconflict='C', wc_rev='3'),
+ 'F/alpha' : Item(status='MM', treeconflict='C', wc_rev='3'),
})
expected_skip = svntest.wc.State('', {
@@ -1191,14 +1179,7 @@ def tree_conflicts_on_merge_no_local_ci_
expected_output = deep_trees_conflict_output
- expected_disk = svntest.wc.State('', {
- 'F' : Item(),
- 'D/D1' : Item(),
- 'DF/D1' : Item(),
- 'DD/D1/D2' : Item(),
- 'DDF/D1/D2' : Item(),
- 'DDD/D1/D2/D3' : Item(),
- })
+ expected_disk = disk_after_leaf_del_no_ci(sbox.wc_dir)
expected_status = svntest.wc.State('', {
'' : Item(status=' M', wc_rev='3'),
@@ -1240,19 +1221,14 @@ def tree_conflicts_on_merge_no_local_ci_
def tree_conflicts_on_merge_no_local_ci_6(sbox):
"tree conflicts 6: tree del (no ci), tree del"
+ sbox.build()
+
# use case 6, as in notes/tree-conflicts/use-cases.txt
# local tree delete, incoming tree delete
expected_output = deep_trees_conflict_output
- expected_disk = svntest.wc.State('', {
- 'F' : Item(),
- 'D/D1' : Item(),
- 'DF/D1' : Item(),
- 'DD/D1/D2' : Item(),
- 'DDF/D1/D2' : Item(),
- 'DDD/D1/D2/D3' : Item(),
- })
+ expected_disk = disk_after_tree_del_no_ci(sbox.wc_dir)
expected_status = svntest.wc.State('', {
'' : Item(status=' M', wc_rev='3'),
@@ -1296,15 +1272,28 @@ def tree_conflicts_merge_edit_onto_missi
# local tree missing (via shell delete), incoming leaf edit
+ # Note: In 1.7 merge tracking aware merges raise an error if the
+ # merge target has subtrees missing due to a shell delete. To
+ # preserve the original intent of this test we'll run the merge
+ # with the --ignore-ancestry option, which neither considers nor
+ # records mergeinfo. With this option the merge should "succeed"
+ # while skipping the missing paths. Of course with no mergeinfo
+ # recorded and everything skipped, there is nothing to commit, so
+ # unlike most of the tree conflict tests we don't bother with the
+ # final commit step.
+
+ sbox.build()
expected_output = wc.State('', {
})
- expected_disk = state_after_tree_del
+ expected_disk = disk_after_tree_del
+ # Don't expect any mergeinfo property changes because we run
+ # the merge with the --ignore-ancestry option.
expected_status = svntest.wc.State('', {
- '' : Item(status=' M', wc_rev=3),
+ '' : Item(status=' ', wc_rev=3),
'F' : Item(status=' ', wc_rev=3),
- 'F/alpha' : Item(status='!M', wc_rev=3),
+ 'F/alpha' : Item(status='! ', wc_rev=3),
'D' : Item(status=' ', wc_rev=3),
'D/D1' : Item(status='! ', wc_rev='?'),
'DF' : Item(status=' ', wc_rev=3),
@@ -1323,6 +1312,19 @@ def tree_conflicts_merge_edit_onto_missi
'DDD/D1/D2/D3' : Item(status=' '),
})
+ if svntest.main.wc_is_singledb(sbox.wc_dir):
+ expected_status.tweak('D/D1', wc_rev=3, entry_rev='?')
+ expected_status.tweak('DF/D1', wc_rev=3, entry_rev='?')
+ expected_status.tweak('DF/D1/beta', wc_rev=3, status='! ')
+ expected_status.tweak('DD/D1', wc_rev=3, entry_rev='?')
+ expected_status.tweak('DD/D1/D2', wc_rev=3, status='! ')
+ expected_status.tweak('DDF/D1', wc_rev=3, entry_rev='?')
+ expected_status.tweak('DDF/D1/D2', wc_rev=3, status='! ')
+ expected_status.tweak('DDF/D1/D2/gamma', wc_rev=3, status='! ')
+ expected_status.tweak('DDD/D1', wc_rev=3, entry_rev='?')
+ expected_status.tweak('DDD/D1/D2', wc_rev=3, status='! ')
+ expected_status.tweak('DDD/D1/D2/D3', wc_rev=3, status='! ')
+
expected_skip = svntest.wc.State('', {
'F/alpha' : Item(),
})
@@ -1337,18 +1339,7 @@ def tree_conflicts_merge_edit_onto_missi
expected_disk,
expected_status,
expected_skip,
-
- ### This should not be happening!
- ### The commit succeeds (it only commits mergeinfo).
- ### But then the work queue freaks out while trying to install
- ### F/alpha into the WC, because F/alpha is missing from disk.
- ### We end up with a working copy that cannot be cleaned up.
- ### To make this test pass for now we'll expect this error.
- ### When the problem is fixed this test will start to fail
- ### and should be adjusted.
- commit_block_string=".*Error bumping revisions post-commit",
-
- ) ], False)
+ ) ], False, do_commit_conflicts=False, ignore_ancestry=True)
#----------------------------------------------------------------------
def tree_conflicts_merge_del_onto_missing(sbox):
@@ -1356,15 +1347,28 @@ def tree_conflicts_merge_del_onto_missin
# local tree missing (via shell delete), incoming leaf edit
+ # Note: In 1.7 merge tracking aware merges raise an error if the
+ # merge target has subtrees missing due to a shell delete. To
+ # preserve the original intent of this test we'll run the merge
+ # with the --ignore-ancestry option, which neither considers nor
+ # records mergeinfo. With this option the merge should "succeed"
+ # while skipping the missing paths. Of course with no mergeinfo
+ # recorded and everything skipped, there is nothing to commit, so
+ # unlike most of the tree conflict tests we don't bother with the
+ # final commit step.
+
+ sbox.build()
expected_output = wc.State('', {
})
- expected_disk = state_after_tree_del
+ expected_disk = disk_after_tree_del
+ # Don't expect any mergeinfo property changes because we run
+ # the merge with the --ignore-ancestry option.
expected_status = svntest.wc.State('', {
- '' : Item(status=' M', wc_rev=3),
+ '' : Item(status=' ', wc_rev=3),
'F' : Item(status=' ', wc_rev=3),
- 'F/alpha' : Item(status='!M', wc_rev=3),
+ 'F/alpha' : Item(status='! ', wc_rev=3),
'D' : Item(status=' ', wc_rev=3),
'D/D1' : Item(status='! ', wc_rev='?'),
'DF' : Item(status=' ', wc_rev=3),
@@ -1383,6 +1387,19 @@ def tree_conflicts_merge_del_onto_missin
'DDD/D1/D2/D3' : Item(status=' '),
})
+ if svntest.main.wc_is_singledb(sbox.wc_dir):
+ expected_status.tweak('D/D1', wc_rev=3)
+ expected_status.tweak('DF/D1', wc_rev=3)
+ expected_status.tweak('DF/D1/beta', wc_rev=3, status='! ')
+ expected_status.tweak('DD/D1', wc_rev=3)
+ expected_status.tweak('DD/D1/D2', wc_rev=3, status='! ')
+ expected_status.tweak('DDF/D1', wc_rev=3)
+ expected_status.tweak('DDF/D1/D2', wc_rev=3, status='! ')
+ expected_status.tweak('DDF/D1/D2/gamma', wc_rev=3, status='! ')
+ expected_status.tweak('DDD/D1', wc_rev=3)
+ expected_status.tweak('DDD/D1/D2', wc_rev=3, status='! ')
+ expected_status.tweak('DDD/D1/D2/D3', wc_rev=3, status='! ')
+
expected_skip = svntest.wc.State('', {
'F/alpha' : Item(),
'D/D1' : Item(),
@@ -1397,18 +1414,7 @@ def tree_conflicts_merge_del_onto_missin
expected_disk,
expected_status,
expected_skip,
-
- ### This should not be happening!
- ### The commit succeeds (it only commits mergeinfo).
- ### But then the work queue freaks out while trying to install
- ### F/alpha into the WC, because F/alpha is missing from disk.
- ### We end up with a working copy that cannot be cleaned up.
- ### To make this test pass for now we'll expect this error.
- ### When the problem is fixed this test will start to fail
- ### and should be adjusted.
- commit_block_string=".*Error bumping revisions post-commit",
-
- ) ], False)
+ ) ], False, do_commit_conflicts=False, ignore_ancestry=True)
#----------------------------------------------------------------------
def merge_replace_setup(sbox):
@@ -1891,7 +1897,7 @@ test_list = [ None,
tree_conflicts_on_merge_local_ci_6,
tree_conflicts_on_merge_no_local_ci_4_1,
tree_conflicts_on_merge_no_local_ci_4_2,
- XFail(tree_conflicts_on_merge_no_local_ci_5_1),
+ tree_conflicts_on_merge_no_local_ci_5_1,
XFail(tree_conflicts_on_merge_no_local_ci_5_2),
tree_conflicts_on_merge_no_local_ci_6,
tree_conflicts_merge_edit_onto_missing,
Modified: subversion/branches/performance/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/tests/cmdline/patch_tests.py?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/performance/subversion/tests/cmdline/patch_tests.py Mon Sep 6 20:02:15 2010
@@ -935,9 +935,10 @@ def patch_add_new_dir(sbox):
patch_file_path = make_patch_path(sbox)
# The first diff is adding 'new' with two missing dirs. The second is
- # adding 'new' with one missing dir to a 'A' that is locally deleted
- # (should be skipped). The third is adding 'new' with a directory that
- # is unversioned (should be skipped as well).
+ # adding 'new' with one missing dir to a 'A/B/E' that is locally deleted
+ # (should be skipped). The third is adding 'new' to 'A/C' that is locally
+ # deleted (should be skipped too). The fourth is adding 'new' with a
+ # directory that is unversioned (should be skipped as well).
unidiff_patch = [
"Index: new\n",
"===================================================================\n",
@@ -947,8 +948,14 @@ def patch_add_new_dir(sbox):
"+new\n",
"Index: new\n",
"===================================================================\n",
- "--- A/C/Y/new\t(revision 0)\n",
- "+++ A/C/Y/new\t(revision 0)\n",
+ "--- A/B/E/Y/new\t(revision 0)\n",
+ "+++ A/B/E/Y/new\t(revision 0)\n",
+ "@@ -0,0 +1 @@\n",
+ "+new\n",
+ "Index: new\n",
+ "===================================================================\n",
+ "--- A/C/new\t(revision 0)\n",
+ "+++ A/C/new\t(revision 0)\n",
"@@ -0,0 +1 @@\n",
"+new\n",
"Index: new\n",
@@ -960,37 +967,55 @@ def patch_add_new_dir(sbox):
]
C_path = os.path.join(wc_dir, 'A', 'C')
+ E_path = os.path.join(wc_dir, 'A', 'B', 'E')
svntest.actions.run_and_verify_svn("Deleting C failed", None, [],
'rm', C_path)
+ svntest.actions.run_and_verify_svn("Deleting E failed", None, [],
+ 'rm', E_path)
svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
- A_C_Y_new_path = os.path.join(wc_dir, 'A', 'C', 'Y', 'new')
+ A_B_E_Y_new_path = os.path.join(wc_dir, 'A', 'B', 'E', 'Y', 'new')
+ A_C_new_path = os.path.join(wc_dir, 'A', 'C', 'new')
A_Z_new_path = os.path.join(wc_dir, 'A', 'Z', 'new')
expected_output = [
'A %s\n' % os.path.join(wc_dir, 'X'),
'A %s\n' % os.path.join(wc_dir, 'X', 'Y'),
'A %s\n' % os.path.join(wc_dir, 'X', 'Y', 'new'),
- 'Skipped missing target: \'%s\'\n' % A_C_Y_new_path,
+ 'Skipped missing target: \'%s\'\n' % A_B_E_Y_new_path,
+ 'Skipped missing target: \'%s\'\n' % A_C_new_path,
'Skipped missing target: \'%s\'\n' % A_Z_new_path,
'Summary of conflicts:\n',
- ' Skipped paths: 2\n',
+ ' Skipped paths: 3\n',
]
# Create the unversioned obstructing directory
os.mkdir(os.path.dirname(A_Z_new_path))
expected_disk = svntest.main.greek_state.copy()
- expected_disk.add({'X/Y/new': Item(contents='new\n')})
- expected_disk.add({'A/Z': Item()})
+ expected_disk.add({
+ 'X/Y/new' : Item(contents='new\n'),
+ 'A/Z' : Item()
+ })
+ expected_disk.remove('A/B/E/alpha')
+ expected_disk.remove('A/B/E/beta')
+ if svntest.main.wc_is_singledb(wc_dir):
+ expected_disk.remove('A/B/E')
+ expected_disk.remove('A/C')
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
- expected_status.add({'X' : Item(status='A ', wc_rev=0)})
- expected_status.add({'X/Y' : Item(status='A ', wc_rev=0)})
- expected_status.add({'X/Y/new' : Item(status='A ', wc_rev=0)})
- expected_status.add({'A/C' : Item(status='D ', wc_rev=1)})
-
- expected_skip = wc.State('', {A_C_Y_new_path : Item(),
- A_Z_new_path : Item() })
+ expected_status.add({
+ 'X' : Item(status='A ', wc_rev=0),
+ 'X/Y' : Item(status='A ', wc_rev=0),
+ 'X/Y/new' : Item(status='A ', wc_rev=0),
+ 'A/B/E' : Item(status='D ', wc_rev=1),
+ 'A/B/E/alpha': Item(status='D ', wc_rev=1),
+ 'A/B/E/beta': Item(status='D ', wc_rev=1),
+ 'A/C' : Item(status='D ', wc_rev=1),
+ })
+
+ expected_skip = wc.State('', {A_Z_new_path : Item(),
+ A_B_E_Y_new_path : Item(),
+ A_C_new_path : Item()})
svntest.actions.run_and_verify_patch(wc_dir,
os.path.abspath(patch_file_path),
@@ -1081,6 +1106,10 @@ def patch_remove_empty_dirs(sbox):
expected_disk.remove('A/B/lambda')
expected_disk.remove('A/B/E/alpha')
expected_disk.remove('A/B/E/beta')
+ if svntest.main.wc_is_singledb(wc_dir):
+ expected_disk.remove('A/B/E')
+ expected_disk.remove('A/B/F')
+ expected_disk.remove('A/B')
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
expected_status.add({'A/D/H/chi' : Item(status='! ', wc_rev=1)})
@@ -2162,7 +2191,6 @@ def patch_no_eol_at_eof(sbox):
1, # check-props
1) # dry-run
-### We need to add deletes and adds of properties to this test.
def patch_with_properties(sbox):
"patch with properties"
@@ -2172,10 +2200,13 @@ def patch_with_properties(sbox):
patch_file_path = make_patch_path(sbox)
iota_path = os.path.join(wc_dir, 'iota')
- iota_prop_contents = "This is the property 'iota_prop'.\n"
+ modified_prop_contents = "This is the property 'modified'.\n"
+ deleted_prop_contents = "This is the property 'deleted'.\n"
- # Set iota contents
- svntest.main.run_svn(None, 'propset', 'prop', iota_prop_contents,
+ # Set iota prop contents
+ svntest.main.run_svn(None, 'propset', 'modified', modified_prop_contents,
+ iota_path)
+ svntest.main.run_svn(None, 'propset', 'deleted', deleted_prop_contents,
iota_path)
expected_output = svntest.wc.State(wc_dir, {
'iota' : Item(verb='Sending'),
@@ -2193,24 +2224,32 @@ def patch_with_properties(sbox):
"+++ iota\t(working copy)\n",
"Property changes on: iota\n",
"-------------------------------------------------------------------\n",
- "Modified: prop\n",
- "## -1 +1 ""\n",
- "-This is the property 'iota_prop'.\n",
- "+This is the property 'prop'.\n",
+ "Modified: modified\n",
+ "## -1 +1 ##\n",
+ "-This is the property 'modified'.\n",
+ "+The property 'modified' has changed.\n",
+ "Added: added\n",
+ "## -0,0 +1 ##\n",
+ "+This is the property 'added'.\n",
+ "Deleted: deleted\n",
+ "## -1 +0,0 ##\n",
+ "-This is the property 'deleted'.\n",
]
svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
- iota_prop_contents = "This is the property 'prop'.\n"
+ modified_prop_contents = "The property 'modified' has changed.\n"
+ added_prop_contents = "This is the property 'added'.\n"
expected_output = [
- 'U %s\n' % os.path.join(wc_dir, 'iota'),
+ ' U %s\n' % os.path.join(wc_dir, 'iota'),
]
expected_disk = svntest.main.greek_state.copy()
- expected_disk.tweak('iota', props={'prop' : iota_prop_contents})
+ expected_disk.tweak('iota', props={'modified' : modified_prop_contents,
+ 'added' : added_prop_contents})
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
- expected_status.tweak('iota', status=' M')
+ expected_status.tweak('iota', status=' M', wc_rev='2')
expected_skip = wc.State('', { })
@@ -2419,6 +2458,524 @@ def patch_same_twice(sbox):
1, # check-props
1) # dry-run
+def patch_dir_properties(sbox):
+ "patch with dir properties"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ patch_file_path = make_patch_path(sbox)
+ B_path = os.path.join(wc_dir, 'A', 'B')
+
+ modified_prop_contents = "This is the property 'modified'.\n"
+ deleted_prop_contents = "This is the property 'deleted'.\n"
+
+ # Set the properties
+ svntest.main.run_svn(None, 'propset', 'modified', modified_prop_contents,
+ wc_dir)
+ svntest.main.run_svn(None, 'propset', 'deleted', deleted_prop_contents,
+ B_path)
+ expected_output = svntest.wc.State(wc_dir, {
+ '.' : Item(verb='Sending'),
+ 'A/B' : Item(verb='Sending'),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('', wc_rev=2)
+ expected_status.tweak('A/B', wc_rev=2)
+ svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+ expected_status, None, wc_dir)
+ # Apply patch
+
+ unidiff_patch = [
+ "Index: .\n",
+ "===================================================================\n",
+ "--- .\t(revision 1)\n",
+ "+++ .\t(working copy)\n",
+ "\n",
+ "Property changes on: .\n",
+ "-------------------------------------------------------------------\n",
+ "Modified: modified\n",
+ "## -1 +1 ##\n",
+ "-This is the property 'modified'.\n",
+ "+The property 'modified' has changed.\n",
+ "Added: svn:ignore\n",
+ "## -0,0 +1,3 ##\n",
+ "+*.o\n",
+ "+.libs\n",
+ "+*.lo\n",
+ "Index: A/B\n",
+ "===================================================================\n",
+ "--- A/B\t(revision 1)\n",
+ "+++ A/B\t(working copy)\n",
+ "\n",
+ "Property changes on: A/B\n",
+ "-------------------------------------------------------------------\n",
+ "Deleted: deleted\n",
+ "## -1 +0,0 ##\n",
+ "-This is the property 'deleted'.\n",
+ "Added: svn:executable\n",
+ "## -0,0 +1 ##\n",
+ "+*\n",
+ ]
+
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ modified_prop_contents = "The property 'modified' has changed.\n"
+ ignore_prop_contents = "*.o\n.libs\n*.lo\n"
+
+ ### The output for properties set on illegal targets (i.e. svn:excutable
+ ### on a dir) is still subject to change. We might just want to bail out
+ ### directly instead of catching the error and use the notify mechanism.
+ expected_output = [
+ ' U %s\n' % wc_dir,
+ ' U %s\n' % os.path.join(wc_dir, 'A', 'B'),
+ 'Skipped missing target \'svn:executable\' on (\'%s\')' % B_path,
+ 'Summary of conflicts:\n',
+ ' Skipped paths: 1\n',
+ ]
+
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.add({
+ '' : Item(props={'modified' : modified_prop_contents,
+ 'svn:ignore' : ignore_prop_contents})
+ })
+ expected_disk.tweak('A/B', props={})
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('', status=' M')
+ expected_status.tweak('A/B', status=' M')
+
+ expected_skip = wc.State('', { })
+
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output,
+ expected_disk,
+ expected_status,
+ expected_skip,
+ None, # expected err
+ 1, # check-props
+ 1) # dry-run
+
+def patch_add_path_with_props(sbox):
+ "patch that adds paths with props"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ patch_file_path = make_patch_path(sbox)
+ iota_path = os.path.join(wc_dir, 'iota')
+
+ # Apply patch that adds a file and a dir.
+
+ unidiff_patch = [
+ "Index: new\n",
+ "===================================================================\n",
+ "--- new\t(revision 0)\n",
+ "+++ new\t(working copy)\n",
+ "@@ -0,0 +1 @@\n",
+ "+This is the file 'new'\n",
+ "\n",
+ "Property changes on: new\n",
+ "-------------------------------------------------------------------\n",
+ "Added: added\n",
+ "## -0,0 +1 ##\n",
+ "+This is the property 'added'.\n",
+ "Index: X\n",
+ "===================================================================\n",
+ "--- X\t(revision 0)\n",
+ "+++ X\t(working copy)\n",
+ "\n",
+ "Property changes on: X\n",
+ "-------------------------------------------------------------------\n",
+ "Added: added\n",
+ "## -0,0 +1 ##\n",
+ "+This is the property 'added'.\n",
+ ]
+
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ added_prop_contents = "This is the property 'added'.\n"
+
+ expected_output = [
+ 'A %s\n' % os.path.join(wc_dir, 'new'),
+ 'A %s\n' % os.path.join(wc_dir, 'X'),
+ ]
+
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.add({'new': Item(contents="This is the file 'new'\n",
+ props={'added' : added_prop_contents})})
+ expected_disk.add({'X': Item(contents="",
+ props={'added' : added_prop_contents})})
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.add({'new': Item(status='A ', wc_rev='0')})
+ expected_status.add({'X': Item(status='A ', wc_rev='0')})
+
+ expected_skip = wc.State('', { })
+
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output,
+ expected_disk,
+ expected_status,
+ expected_skip,
+ None, # expected err
+ 1, # check-props
+ 1) # dry-run
+
+def patch_prop_offset(sbox):
+ "property patch with offset searching"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ patch_file_path = make_patch_path(sbox)
+ iota_path = os.path.join(wc_dir, 'iota')
+
+ prop1_content = ''.join([
+ "Dear internet user,\n",
+ # The missing line here will cause the first hunk to match early
+ "We wish to congratulate you over your email success in our computer\n",
+ "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+ "in which email addresses were used. All participants were selected\n",
+ "through a computer ballot system drawn from over 100,000 company\n",
+ "and 50,000,000 individual email addresses from all over the world.\n",
+ "\n",
+ "Your email address drew and have won the sum of 750,000 Euros\n",
+ "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+ "file with\n",
+ " REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+ "These extra lines will cause the second hunk to match late\n",
+ "These extra lines will cause the second hunk to match late\n",
+ "These extra lines will cause the second hunk to match late\n",
+ "These extra lines will cause the second hunk to match late\n",
+ "These extra lines will cause the second hunk to match late\n",
+ " WINNING NUMBER : 14-17-24-34-37-45-16\n",
+ " BATCH NUMBERS :\n",
+ " EULO/1007/444/606/08;\n",
+ " SERIAL NUMBER: 45327\n",
+ "and PROMOTION DATE: 13th June. 2009\n",
+ "\n",
+ "To claim your winning prize, you are to contact the appointed\n",
+ "agent below as soon as possible for the immediate release of your\n",
+ "winnings with the below details.\n",
+ "\n",
+ "Again, we wish to congratulate you over your email success in our\n"
+ "computer Balloting.\n",
+ ])
+
+ # prop2's content will make both a late and early match possible.
+ # The hunk to be applied is replicated here for reference:
+ # ## -5,6 +5,7 ##
+ # property
+ # property
+ # property
+ # +x
+ # property
+ # property
+ # property
+ #
+ # This hunk wants to be applied at line 5, but that isn't
+ # possible because line 8 ("zzz") does not match "property".
+ # The early match happens at line 2 (offset 3 = 5 - 2).
+ # The late match happens at line 9 (offset 4 = 9 - 5).
+ # Subversion will pick the early match in this case because it
+ # is closer to line 5.
+ prop2_content = ''.join([
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "zzz\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n"
+ ])
+
+ # Set iota prop contents
+ svntest.main.run_svn(None, 'propset', 'prop1', prop1_content,
+ iota_path)
+ svntest.main.run_svn(None, 'propset', 'prop2', prop2_content,
+ iota_path)
+ expected_output = svntest.wc.State(wc_dir, {
+ 'iota' : Item(verb='Sending'),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('iota', wc_rev=2)
+ svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+ expected_status, None, wc_dir)
+
+ # Apply patch
+
+ unidiff_patch = [
+ "Index: iota\n",
+ "===================================================================\n",
+ "--- iota (revision XYZ)\n",
+ "+++ iota (working copy)\n",
+ "\n",
+ "Property changes on: iota\n",
+ "-------------------------------------------------------------------\n",
+ "Modified: prop1\n",
+ "## -6,6 +6,9 ##\n",
+ " through a computer ballot system drawn from over 100,000 company\n",
+ " and 50,000,000 individual email addresses from all over the world.\n",
+ " \n",
+ "+It is a promotional program aimed at encouraging internet users;\n",
+ "+therefore you do not need to buy ticket to enter for it.\n",
+ "+\n",
+ " Your email address drew and have won the sum of 750,000 Euros\n",
+ " ( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+ " file with\n",
+ "## -14,11 +17,8 ##\n",
+ " BATCH NUMBERS :\n",
+ " EULO/1007/444/606/08;\n",
+ " SERIAL NUMBER: 45327\n",
+ "-and PROMOTION DATE: 13th June. 2009\n",
+ "+and PROMOTION DATE: 14th June. 2009\n",
+ " \n",
+ " To claim your winning prize, you are to contact the appointed\n",
+ " agent below as soon as possible for the immediate release of your\n",
+ " winnings with the below details.\n",
+ "-\n",
+ "-Again, we wish to congratulate you over your email success in our\n",
+ "-computer Balloting.\n",
+ "Modified: prop2\n",
+ "## -5,6 +5,7 ##\n",
+ " property\n",
+ " property\n",
+ " property\n",
+ "+x\n",
+ " property\n",
+ " property\n",
+ " property\n",
+ ]
+
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ prop1_content = ''.join([
+ "Dear internet user,\n",
+ "We wish to congratulate you over your email success in our computer\n",
+ "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+ "in which email addresses were used. All participants were selected\n",
+ "through a computer ballot system drawn from over 100,000 company\n",
+ "and 50,000,000 individual email addresses from all over the world.\n",
+ "\n",
+ "It is a promotional program aimed at encouraging internet users;\n",
+ "therefore you do not need to buy ticket to enter for it.\n",
+ "\n",
+ "Your email address drew and have won the sum of 750,000 Euros\n",
+ "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+ "file with\n",
+ " REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+ "These extra lines will cause the second hunk to match late\n",
+ "These extra lines will cause the second hunk to match late\n",
+ "These extra lines will cause the second hunk to match late\n",
+ "These extra lines will cause the second hunk to match late\n",
+ "These extra lines will cause the second hunk to match late\n",
+ " WINNING NUMBER : 14-17-24-34-37-45-16\n",
+ " BATCH NUMBERS :\n",
+ " EULO/1007/444/606/08;\n",
+ " SERIAL NUMBER: 45327\n",
+ "and PROMOTION DATE: 14th June. 2009\n",
+ "\n",
+ "To claim your winning prize, you are to contact the appointed\n",
+ "agent below as soon as possible for the immediate release of your\n",
+ "winnings with the below details.\n",
+ ])
+
+ prop2_content = ''.join([
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "x\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "zzz\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ "property\n",
+ ])
+
+ os.chdir(wc_dir)
+
+ expected_output = [
+ ' U iota\n',
+ '> applied hunk ## -6,6 +6,9 ## with offset -1 (prop1)\n',
+ '> applied hunk ## -14,11 +17,8 ## with offset 4 (prop1)\n',
+ '> applied hunk ## -5,6 +5,7 ## with offset -3 (prop2)\n',
+ ]
+
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('iota', props = {'prop1' : prop1_content,
+ 'prop2' : prop2_content})
+
+ expected_status = svntest.actions.get_virginal_state('.', 1)
+ expected_status.tweak('iota', status=' M', wc_rev=2)
+
+ expected_skip = wc.State('', { })
+
+ svntest.actions.run_and_verify_patch('.', os.path.abspath(patch_file_path),
+ expected_output,
+ expected_disk,
+ expected_status,
+ expected_skip,
+ None, # expected err
+ 1, # check-props
+ 1) # dry-run
+
+def patch_prop_with_fuzz(sbox):
+ "property patch with fuzz"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ patch_file_path = make_patch_path(sbox)
+
+ mu_path = os.path.join(wc_dir, 'A', 'mu')
+
+ # We have replaced a couple of lines to cause fuzz. Those lines contains
+ # the word fuzz
+ prop_contents = ''.join([
+ "Line replaced for fuzz = 1\n",
+ "\n",
+ "We wish to congratulate you over your email success in our computer\n",
+ "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+ "in which email addresses were used. All participants were selected\n",
+ "through a computer ballot system drawn from over 100,000 company\n",
+ "and 50,000,000 individual email addresses from all over the world.\n",
+ "Line replaced for fuzz = 2 with only the second context line changed\n",
+ "Your email address drew and have won the sum of 750,000 Euros\n",
+ "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+ "file with\n",
+ " REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+ " WINNING NUMBER : 14-17-24-34-37-45-16\n",
+ " BATCH NUMBERS :\n",
+ " EULO/1007/444/606/08;\n",
+ " SERIAL NUMBER: 45327\n",
+ "and PROMOTION DATE: 13th June. 2009\n",
+ "\n",
+ "This line is inserted to cause an offset of +1\n",
+ "To claim your winning prize, you are to contact the appointed\n",
+ "agent below as soon as possible for the immediate release of your\n",
+ "winnings with the below details.\n",
+ "\n",
+ "Line replaced for fuzz = 2\n",
+ "Line replaced for fuzz = 2\n",
+ ])
+
+ # Set mu prop contents
+ svntest.main.run_svn(None, 'propset', 'prop', prop_contents,
+ mu_path)
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/mu' : Item(verb='Sending'),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', wc_rev=2)
+ svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+ expected_status, None, wc_dir)
+
+ unidiff_patch = [
+ "Index: mu\n",
+ "===================================================================\n",
+ "--- A/mu\t(revision 0)\n",
+ "+++ A/mu\t(revision 0)\n",
+ "\n",
+ "Property changes on: mu\n",
+ "Modified: prop\n",
+ "## -1,6 +1,7 ##\n",
+ " Dear internet user,\n",
+ " \n",
+ " We wish to congratulate you over your email success in our computer\n",
+ "+A new line here\n",
+ " Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+ " in which email addresses were used. All participants were selected\n",
+ " through a computer ballot system drawn from over 100,000 company\n",
+ "## -7,7 +8,9 ##\n",
+ " and 50,000,000 individual email addresses from all over the world.\n",
+ " \n",
+ " Your email address drew and have won the sum of 750,000 Euros\n",
+ "+Another new line\n",
+ " ( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+ "+A third new line\n",
+ " file with\n",
+ " REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+ " WINNING NUMBER : 14-17-24-34-37-45-16\n",
+ "## -19,6 +20,7 ##\n",
+ " To claim your winning prize, you are to contact the appointed\n",
+ " agent below as soon as possible for the immediate release of your\n",
+ " winnings with the below details.\n",
+ "+A fourth new line\n",
+ " \n",
+ " Again, we wish to congratulate you over your email success in our\n"
+ " computer Balloting. [No trailing newline here]"
+ ]
+
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ prop_contents = ''.join([
+ "Line replaced for fuzz = 1\n",
+ "\n",
+ "We wish to congratulate you over your email success in our computer\n",
+ "A new line here\n",
+ "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+ "in which email addresses were used. All participants were selected\n",
+ "through a computer ballot system drawn from over 100,000 company\n",
+ "and 50,000,000 individual email addresses from all over the world.\n",
+ "Line replaced for fuzz = 2 with only the second context line changed\n",
+ "Your email address drew and have won the sum of 750,000 Euros\n",
+ "Another new line\n",
+ "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+ "A third new line\n",
+ "file with\n",
+ " REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+ " WINNING NUMBER : 14-17-24-34-37-45-16\n",
+ " BATCH NUMBERS :\n",
+ " EULO/1007/444/606/08;\n",
+ " SERIAL NUMBER: 45327\n",
+ "and PROMOTION DATE: 13th June. 2009\n",
+ "\n",
+ "This line is inserted to cause an offset of +1\n",
+ "To claim your winning prize, you are to contact the appointed\n",
+ "agent below as soon as possible for the immediate release of your\n",
+ "winnings with the below details.\n",
+ "A fourth new line\n",
+ "\n",
+ "Line replaced for fuzz = 2\n",
+ "Line replaced for fuzz = 2\n",
+ ])
+
+ expected_output = [
+ ' U %s\n' % os.path.join(wc_dir, 'A', 'mu'),
+ '> applied hunk ## -1,6 +1,7 ## with fuzz 1 (prop)\n',
+ '> applied hunk ## -7,7 +8,9 ## with fuzz 2 (prop)\n',
+ '> applied hunk ## -19,6 +20,7 ## with offset 1 and fuzz 2 (prop)\n',
+ ]
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/mu', props = {'prop' : prop_contents})
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', status=' M', wc_rev=2)
+
+ expected_skip = wc.State('', { })
+
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output,
+ expected_disk,
+ expected_status,
+ expected_skip,
+ None, # expected err
+ 1, # check-props
+ 1) # dry-run
+
########################################################################
#Run the tests
@@ -2442,8 +2999,12 @@ test_list = [ None,
patch_with_ignore_whitespace,
patch_replace_locally_deleted_file,
patch_no_eol_at_eof,
- XFail(patch_with_properties),
+ patch_with_properties,
patch_same_twice,
+ XFail(patch_dir_properties),
+ patch_add_path_with_props,
+ patch_prop_offset,
+ patch_prop_with_fuzz,
]
if __name__ == '__main__':
Modified: subversion/branches/performance/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/tests/cmdline/prop_tests.py?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/performance/subversion/tests/cmdline/prop_tests.py Mon Sep 6 20:02:15 2010
@@ -1944,20 +1944,32 @@ def obstructed_subdirs(sbox):
expected_disk.old_tree())
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
- expected_status.tweak('A/C', status='! ', wc_rev='?')
+ if svntest.main.wc_is_singledb(wc_dir):
+ expected_status.tweak('A/C', status='! ', wc_rev='1')
+ else:
+ expected_status.tweak('A/C', status='! ', wc_rev='?')
+
svntest.actions.run_and_verify_status(wc_dir, expected_status)
# Drop an empty file there to obstruct the now-deleted subdir
open(C_path, 'w')
- expected_disk.add({'A/C': Item(contents='')})
+ # Single-DB doesn't lose properties
+ if svntest.main.wc_is_singledb(wc_dir):
+ expected_disk.add({'A/C': Item(contents='', props={'red': 'blue'})})
+ expected_status.tweak('A/C', status='~ ', wc_rev='1')
+ else:
+ expected_disk.add({'A/C': Item(contents='')})
+
+ # NOTE: r943346 fixes a problem with reporter processing, which
+ # is necessary for this status to complete properly.
+ expected_status.tweak('A/C', status='~ ', wc_rev='?')
+
actual_disk_tree = svntest.tree.build_tree_from_wc(wc_dir, load_props=True)
svntest.tree.compare_trees("disk", actual_disk_tree,
expected_disk.old_tree())
- # NOTE: r943346 fixes a problem with reporter processing, which
- # is necessary for this status to complete properly.
- expected_status.tweak('A/C', status='~ ', wc_rev='?')
+
svntest.actions.run_and_verify_status(wc_dir, expected_status)
Modified: subversion/branches/performance/subversion/tests/cmdline/resolved_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/tests/cmdline/resolved_tests.py?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/tests/cmdline/resolved_tests.py (original)
+++ subversion/branches/performance/subversion/tests/cmdline/resolved_tests.py Mon Sep 6 20:02:15 2010
@@ -112,6 +112,8 @@ def resolved_on_wc_root(sbox):
'A/B/lambda',
'A/B/E/alpha', 'A/B/E/beta',
'A/D/gamma')
+ if svntest.main.wc_is_singledb(sbox.wc_dir):
+ expected_disk.remove('A/B/E', 'A/B/F', 'A/B')
expected_status = svntest.actions.get_virginal_state(wc, 2)
expected_status.tweak('iota', 'A/B', 'A/D/gamma',