[prev in list] [next in list] [prev in thread] [next in thread] 

List:       subversion-commits
Subject:    svn commit: r1847678 [21/25] - in /subversion/branches/swig-py3: ./ build/ build/ac-macros/ build/ge
From:       cmpilato () apache ! org
Date:       2018-11-28 21:25:35
Message-ID: 20181128212540.8D37D3A2F29 () svn01-us-west ! apache ! org
[Download RAW message or body]

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/merge_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/merge_tests.py Wed Nov 28 \
21:25:32 2018 @@ -697,7 +697,7 @@ def simple_property_merges(sbox):
 def merge_similar_unrelated_trees(sbox):
   "merging similar trees ancestrally unrelated"
 
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=1249. ##
+  ## See https://issues.apache.org/jira/browse/SVN-1249. ##
 
   sbox.build()
   wc_dir = sbox.wc_dir
@@ -3939,7 +3939,7 @@ def avoid_repeated_merge_on_subtree_with
                                        check_props=True)
 
   # Test for part of Issue #2821, see
-  # http://subversion.tigris.org/issues/show_bug.cgi?id=2821#desc22
+  # https://issues.apache.org/jira/browse/SVN-2821#desc22
   #
   # Revert all local changes.
   svntest.actions.run_and_verify_svn(None, [], 'revert', '-R', wc_dir)
@@ -4966,11 +4966,11 @@ def merge_to_switched_path(sbox):
   A_COPY_D_G_rho_path = sbox.ospath('A_COPY/D/G/rho')
 
   expected = svntest.verify.UnorderedOutput(
-         ["A    " + os.path.join(G_COPY_path, "pi") + "\n",
-          "A    " + os.path.join(G_COPY_path, "rho") + "\n",
-          "A    " + os.path.join(G_COPY_path, "tau") + "\n",
-          "Checked out revision 6.\n",
-          "A         " + G_COPY_path + "\n"])
+         ["A         " + G_COPY_path + "\n",
+          "A         " + os.path.join(G_COPY_path, "pi") + "\n",
+          "A         " + os.path.join(G_COPY_path, "rho") + "\n",
+          "A         " + os.path.join(G_COPY_path, "tau") + "\n",
+          ])
 
   # r7 - Copy A/D/G to A/D/G_COPY and commit.
   svntest.actions.run_and_verify_svn(expected, [], 'copy',
@@ -6007,7 +6007,7 @@ def foreign_repos_does_not_update_mergei
 def avoid_reflected_revs(sbox):
   "avoid repeated merges for cyclic merging"
 
-  # See <http://subversion.tigris.org/issues/show_bug.cgi?id=2897>.
+  # See <https://issues.apache.org/jira/browse/SVN-2897>.
   #
   # This test cherry-picks some changes (all of them, in fact) from the
   # parent branch 'A' to the child branch 'A_COPY', and then tries to
@@ -8294,7 +8294,7 @@ def cherry_picking(sbox):
 def propchange_of_subdir_raises_conflict(sbox):
   "merge of propchange on subdir raises conflict"
 
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2969. ##
+  ## See https://issues.apache.org/jira/browse/SVN-2969. ##
 
   # Create a WC with a single branch
   sbox.build()
@@ -8515,7 +8515,7 @@ def reverse_merge_prop_add_on_child(sbox
 def merge_target_with_non_inheritable_mergeinfo(sbox):
   "merge target with non inheritable mergeinfo"
 
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2970. ##
+  ## See https://issues.apache.org/jira/browse/SVN-2970. ##
 
   # Create a WC with a single branch
   sbox.build()
@@ -8547,7 +8547,7 @@ def merge_target_with_non_inheritable_me
   expected_output = wc.State(A_COPY_B_path, {
     'lambda' : Item(status='U '),
     })
-  # Issue #3642 http://subversion.tigris.org/issues/show_bug.cgi?id=3642
+  # Issue #3642 https://issues.apache.org/jira/browse/SVN-3642
   #
   # We don't expect A_COPY/B/F to have mergeinfo recorded on it because
   # not only is it unaffected by the merge at depth immediates, it could
@@ -8820,7 +8820,7 @@ def merge_from_renamed_branch_fails_whil
   #Merge r4 from A/RENAMED_C to A/C
   #Merge r2:5 from A/RENAMED_C to A/C <-- This fails tracked via #3032.
 
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3032. ##
+  ## See https://issues.apache.org/jira/browse/SVN-3032. ##
 
   # Create a WC with a single branch
   sbox.build()
@@ -9250,7 +9250,7 @@ def new_subtrees_should_not_break_merge(
   # so we expect only subtree merges on A_COPY/D, A_COPY_D_H, and
   # A_COPY/D/H/nu.  The fact that A/D/H/nu doesn't exist at r6 should not cause
   # the merge to fail -- see
-  # http://subversion.tigris.org/issues/show_bug.cgi?id=3067#desc7.
+  # https://issues.apache.org/jira/browse/SVN-3067#desc7.
   expected_output = wc.State(A_COPY_path, {
     'D/H/omega': Item(status='U '),
     })
@@ -10495,7 +10495,7 @@ def reverse_merge_away_all_mergeinfo(sbo
 # Another test for issue #3067: 'subtrees with intersecting mergeinfo,
 # that don't exist at the start of a merge range shouldn't break the
 # merge'.  Specifically see
-# http://subversion.tigris.org/issues/show_bug.cgi?id=3067#desc5
+# https://issues.apache.org/jira/browse/SVN-3067#desc5
 @SkipUnless(server_has_mergeinfo)
 @Issues(3138,3067,4217)
 def dont_merge_revs_into_subtree_that_predate_it(sbox):
@@ -10614,7 +10614,7 @@ def dont_merge_revs_into_subtree_that_pr
   # Cherry harvest all eligible revisions from 'A/D/H' to 'H_COPY'.
   #
   # This is where we see the problem described in
-  # http://subversion.tigris.org/issues/show_bug.cgi?id=3067#desc5.
+  # https://issues.apache.org/jira/browse/SVN-3067#desc5.
   #
   # Use run_and_verify_svn() because run_and_verify_merge*() require
   # explicit revision ranges.
@@ -11786,7 +11786,7 @@ def subtree_source_missing_in_requested_
 # Another test for issue #3067: 'subtrees that don't exist at the start
 # or end of a merge range shouldn't break the merge'
 #
-# See http://subversion.tigris.org/issues/show_bug.cgi?id=3067#desc34
+# See https://issues.apache.org/jira/browse/SVN-3067#desc34
 @Issue(3067)
 @SkipUnless(server_has_mergeinfo)
 def subtrees_with_empty_mergeinfo(sbox):
@@ -12848,6 +12848,39 @@ def natural_history_filtering(sbox):
   #      the revisions on 'trunk' which occurred after 'branch2' was copied as
   #      these are not part of 'branch2's natural history.
 
+  def path_join(head, tail):
+    if not head: return tail
+    if not tail: return head
+    return head + '/' + tail
+
+  def greek_file_item(path):
+    if path[-1:].islower():
+      basename = re.sub('.*/', '', path)
+      return Item("This is the file '" + basename + "'.\n")
+    return Item()
+
+  A_paths = [
+    "",
+    "B",
+    "B/lambda",
+    "B/E",
+    "B/E/alpha",
+    "B/E/beta",
+    "B/F",
+    "mu",
+    "C",
+    "D",
+    "D/gamma",
+    "D/G",
+    "D/G/pi",
+    "D/G/rho",
+    "D/G/tau",
+    "D/H",
+    "D/H/chi",
+    "D/H/omega",
+    "D/H/psi",
+    ]
+
   sbox.build()
   wc_dir = sbox.wc_dir
 
@@ -12861,68 +12894,16 @@ def natural_history_filtering(sbox):
 
   # r7: Make a second 'branch': Copy A to A_COPY_2
   expected = svntest.verify.UnorderedOutput(
-    ["A    " + os.path.join(A_COPY_2_path, "B") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "B", "lambda") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "B", "E") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "B", "E", "alpha") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "B", "E", "beta") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "B", "F") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "mu") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "C") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "D") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "D", "gamma") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "D", "G") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "D", "G", "pi") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "D", "G", "rho") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "D", "G", "tau") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "D", "H") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "D", "H", "chi") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "D", "H", "omega") + "\n",
-     "A    " + os.path.join(A_COPY_2_path, "D", "H", "psi") + "\n",
-     "Checked out revision 6.\n",
-     "A         " + A_COPY_2_path + "\n"])
-  wc_status.add({
-    "A_COPY_2" + "/B"         : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/B/lambda"  : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/B/E"       : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/B/E/alpha" : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/B/E/beta"  : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/B/F"       : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/mu"        : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/C"         : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/D"         : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/D/gamma"   : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/D/G"       : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/D/G/pi"    : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/D/G/rho"   : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/D/G/tau"   : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/D/H"       : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/D/H/chi"   : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/D/H/omega" : Item(status='  ', wc_rev=7),
-    "A_COPY_2" + "/D/H/psi"   : Item(status='  ', wc_rev=7),
-    "A_COPY_2"                : Item(status='  ', wc_rev=7),
-    })
-  wc_disk.add({
-    "A_COPY_2"                : Item(),
-    "A_COPY_2" + '/B'         : Item(),
-    "A_COPY_2" + '/B/lambda'  : Item("This is the file 'lambda'.\n"),
-    "A_COPY_2" + '/B/E'       : Item(),
-    "A_COPY_2" + '/B/E/alpha' : Item("This is the file 'alpha'.\n"),
-    "A_COPY_2" + '/B/E/beta'  : Item("New content"),
-    "A_COPY_2" + '/B/F'       : Item(),
-    "A_COPY_2" + '/mu'        : Item("This is the file 'mu'.\n"),
-    "A_COPY_2" + '/C'         : Item(),
-    "A_COPY_2" + '/D'         : Item(),
-    "A_COPY_2" + '/D/gamma'   : Item("This is the file 'gamma'.\n"),
-    "A_COPY_2" + '/D/G'       : Item(),
-    "A_COPY_2" + '/D/G/pi'    : Item("This is the file 'pi'.\n"),
-    "A_COPY_2" + '/D/G/rho'   : Item("New content"),
-    "A_COPY_2" + '/D/G/tau'   : Item("This is the file 'tau'.\n"),
-    "A_COPY_2" + '/D/H'       : Item(),
-    "A_COPY_2" + '/D/H/chi'   : Item("New content"),
-    "A_COPY_2" + '/D/H/omega' : Item("This is the file 'omega'.\n"),
-    "A_COPY_2" + '/D/H/psi'   : Item("New content"),
-    })
+    [ "A         " + sbox.ospath(path_join("A_COPY_2", p)) + "\n"
+      for p in A_paths ])
+  wc_status.add(
+    { path_join("A_COPY_2", p) : Item(status='  ', wc_rev=7)
+      for p in A_paths })
+  wc_disk.add(
+    { path_join("A_COPY_2", p) :
+        Item("New content") if p in ['B/E/beta', 'D/G/rho', 'D/H/chi', 'D/H/psi']
+                            else greek_file_item(p)
+      for p in A_paths })
   svntest.actions.run_and_verify_svn(expected, [], 'copy',
                                      sbox.repo_url + "/A",
                                      A_COPY_2_path)
@@ -13305,7 +13286,7 @@ def no_self_referential_filtering_on_add
   # how can any prop changes be merged to it?  The answer is that
   # the merge code does some quiet housekeeping, merging C_MOVED's
   # inherited mergeinfo into its incoming mergeinfo, see
-  # http://subversion.tigris.org/issues/show_bug.cgi?id=4309
+  # https://issues.apache.org/jira/browse/SVN-4309
   # This test is not covering issue #4309 so we let the current
   # behavior pass.
   expected_mergeinfo_output = wc.State(A_COPY_2_path, {
@@ -13374,7 +13355,7 @@ def no_self_referential_filtering_on_add
 
 #----------------------------------------------------------------------
 # Test for issue #3324
-# http://subversion.tigris.org/issues/show_bug.cgi?id=3324
+# https://issues.apache.org/jira/browse/SVN-3324
 @Issue(3324)
 @SkipUnless(server_has_mergeinfo)
 def merge_range_prior_to_rename_source_existence(sbox):
@@ -13881,7 +13862,7 @@ def dont_merge_gaps_in_history(sbox):
 
 #----------------------------------------------------------------------
 # Test for issue #3432 'Merge can record mergeinfo from natural history
-# gaps'.  See http://subversion.tigris.org/issues/show_bug.cgi?id=3432
+# gaps'.  See https://issues.apache.org/jira/browse/SVN-3432
 @Issue(3432)
 @SkipUnless(server_has_mergeinfo)
 def handle_gaps_in_implicit_mergeinfo(sbox):
@@ -15122,7 +15103,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
+# mergeinfo'. See https://issues.apache.org/jira/browse/SVN-3642
 @Issue(3642)
 def immediate_depth_merge_creates_minimal_subtree_mergeinfo(sbox):
   "no spurious mergeinfo from immediate depth merges"
@@ -15817,7 +15798,7 @@ def subtree_merges_inherit_invalid_worki
 
 #----------------------------------------------------------------------
 # Test for issue #3686 'executable flag not correctly set on merge'
-# See http://subversion.tigris.org/issues/show_bug.cgi?id=3686
+# See https://issues.apache.org/jira/browse/SVN-3686
 @Issue(3686)
 @SkipUnless(server_has_mergeinfo)
 @SkipUnless(svntest.main.is_posix_os)

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/merge_tree_conflict_tests.py
                
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/merge_tree_conflict_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/merge_tree_conflict_tests.py \
                (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/merge_tree_conflict_tests.py \
Wed Nov 28 21:25:32 2018 @@ -540,7 +540,7 @@ def merge_add_over_versioned_file_confli
 def mergeinfo_recording_in_skipped_merge(sbox):
   "mergeinfo recording in skipped merge"
 
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2829. ##
+  ## See https://issues.apache.org/jira/browse/SVN-2829. ##
 
   # Create a WC with a single branch
   sbox.build()
@@ -705,7 +705,7 @@ def del_differing_file(sbox):
 def tree_conflicts_and_obstructions(sbox):
   "tree conflicts and obstructions"
 
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3146. ##
+  ## See https://issues.apache.org/jira/browse/SVN-3146. ##
 
   sbox.build()
   wc_dir = sbox.wc_dir

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/mergeinfo_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/mergeinfo_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/mergeinfo_tests.py \
                (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/mergeinfo_tests.py Wed Nov \
28 21:25:32 2018 @@ -196,7 +196,7 @@ def mergeinfo_on_unknown_url(sbox):
 
 # Test for issue #3126 'svn mergeinfo shows too few or too many
 # eligible revisions'.  Specifically
-# http://subversion.tigris.org/issues/show_bug.cgi?id=3126#desc5.
+# https://issues.apache.org/jira/browse/SVN-3126#desc5.
 @SkipUnless(server_has_mergeinfo)
 @Issue(3126)
 def non_inheritable_mergeinfo(sbox):

Propchange: subversion/branches/swig-py3/subversion/tests/cmdline/mod_dav_svn_tests.py
                
------------------------------------------------------------------------------
    svn:executable = *

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/move_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/move_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/move_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/move_tests.py Wed Nov 28 \
21:25:32 2018 @@ -1261,7 +1261,7 @@ def nested_replaces(sbox):
     '   D /A/B/C/Y',
   ]))
   expected_output = svntest.verify.UnorderedRegexListOutput(escaped
-                    + [ '^-', '^r2', '^-', '^Changed paths:', ])
+                    + [ '^--*', '^r2.*', '^--*', '^Changed paths:', ])
   svntest.actions.run_and_verify_svn(expected_output, [],
                                      'log', '-qvr2', repo_url)
 

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/patch_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/patch_tests.py Wed Nov 28 \
21:25:32 2018 @@ -4246,7 +4246,7 @@ def patch_git_with_index_line(sbox):
     "+++ b/src/tools/ConsoleRunner/hi.txt\n",
     "@@ -0,0 +1 @@\n",
     "+hihihihihihi\n",
-    "\ No newline at end of file\n",
+    "\\ No newline at end of file\n",
   ]
 
   svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
@@ -4413,7 +4413,7 @@ def patch_replace_dir_with_file_and_vv(s
     "+++ A/D\t(working copy)\n",
     "@@ -0,0 +1 @@\n",
     "+New file\n",
-    "\ No newline at end of file\n",
+    "\\ No newline at end of file\n",
 
   # Add iota as directory
     "Index: iota\n",
@@ -4426,7 +4426,7 @@ def patch_replace_dir_with_file_and_vv(s
     "Added: k\n",
     "## -0,0 +1 ##\n",
     "+v\n",
-    "\ No newline at end of property\n",
+    "\\ No newline at end of property\n",
   ]))
 
   expected_output = wc.State(wc_dir, {
@@ -6541,7 +6541,7 @@ def patch_prop_madness(sbox):
                                        "Property: del_n\n"
                                        "## -1,1 +0,0 ##\n"
                                        "-no-eol\n"
-                                       "\ No newline at end of property\n"
+                                       "\\ No newline at end of property\n"
                                        % (sbox.path('iota'),
                                           sbox.path('iota'))),
   })
@@ -7853,6 +7853,163 @@ def patch_mergeinfo_in_regular_prop_form
                                        [], True, True,
                                        '--strip', strip_count)
 
+@XFail()
+def patch_empty_prop(sbox):
+  "patch empty prop"
+  sbox.build(empty=True)
+  was_cwd = os.getcwd()
+  os.chdir(sbox.wc_dir)
+  sbox.wc_dir = ''
+  wc_dir = ''
+
+  # start with a file with an empty prop
+  sbox.simple_add_text('', 'f')
+  sbox.simple_propset('p', '', 'f')
+  sbox.simple_commit()
+
+  # a patch that modifies the prop to a non-empty value
+  unidiff_patch = [
+    "--- f\n",
+    "+++ f\n",
+    "\n",
+    "Property changes on: f\n",
+    "___________________________________________________________________\n",
+    "Modified: p\n",
+    "## -0,0 +1 ##\n",
+    "+v\n",
+  ]
+
+  trailing_eol = False
+  if trailing_eol:
+    value = "v\n"
+  else:
+    value = "v"
+    unidiff_patch += ['\ No newline at end of property\n']
+
+  patch_file_path = sbox.get_tempname('my.patch')
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch), 'wb')
+
+  expected_output = [
+    ' U        %s\n' % sbox.ospath('f'),
+  ]
+
+  expected_disk = svntest.wc.State(wc_dir, {})
+  expected_disk.add({'f': Item(props={'p' : value})})
+  expected_status = svntest.wc.State(wc_dir, {})
+  expected_status.add({'f': Item(status=' M')})
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, patch_file_path,
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       False, # dry-run
+                                       )
+
+  svntest.actions.check_prop('p', wc_dir, [value.encode()])
+
+  os.chdir(was_cwd)
+
+# Test that 'patch' can apply a patch that modifies properties on the root
+# of a WC and/or the root of a repository. This test uses the format of
+# diff output produced by 'svn diff --git' in svn <= 1.10.0: paths are given
+# as 'a/' and 'b/' and 'Property changes on: ' (with no following '.').
+#
+# See dev@ email thread 2018-07-09 from Dmitry Pavlenko,
+# '[PATCH] can't "svn patch" working copy root if the patch is in --git format',
+# https://lists.apache.org/thread.html/d1d9811ca36fac8cabb9339634840099e22811beac505be2ea59f19f@%3Cdev.subversion.apache.org%3E
 +@XFail()
+def patch_git_wcroot(sbox):
+  "patch working copy root"
+  sbox.build(empty=True)
+  wc_dir = sbox.wc_dir
+
+  git_patch = [ "Index: .\n",
+                "===================================================================\n",
 +                "diff --git a/ b/\n",
+                "--- a/	(revision 0)\n",
+                "+++ b/	(working copy)\n",
+                "Property changes on: \n",
+                "___________________________________________________________________\n",
 +                "Added: p\n",
+                "## -0,0 +1 ##\n",
+                "+v\n",
+                "\\ No newline at end of property\n",
+  ]
+  value = 'v'
+
+  patch_file_path = sbox.get_tempname('my.patch')
+  svntest.main.file_write(patch_file_path, ''.join(git_patch), 'wb')
+
+  expected_output = wc.State(wc_dir, {
+    '.'                 : Item(status=' U'),
+  })
+  expected_disk = svntest.wc.State('', {})
+  expected_disk.add({'': Item(props={'p' : value })})
+  expected_status = svntest.wc.State(wc_dir, {})
+  expected_status.add({'': Item(status=' M', wc_rev='0')})
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, patch_file_path,
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       True, # check-props
+                                       False, # dry-run
+                                       )
+
+  svntest.actions.check_prop('p', wc_dir, [value.encode()])
+
+# Test that 'patch' can apply a patch that modifies properties on the root
+# of a WC and/or the root of a repository. This test performs a round-trip
+# through 'diff --git' and 'patch' rather than assuming any particular
+# variant of the patch format.
+#
+# See dev@ email thread 2018-07-09 from Dmitry Pavlenko,
+# '[PATCH] can't "svn patch" working copy root if the patch is in --git format',
+# https://lists.apache.org/thread.html/d1d9811ca36fac8cabb9339634840099e22811beac505be2ea59f19f@%3Cdev.subversion.apache.org%3E
 +@XFail()
+def patch_git_wcroot2(sbox):
+  "patch working copy root"
+  sbox.build(empty=True)
+  wc_dir = sbox.wc_dir
+
+  value = 'v'
+  sbox.simple_propset('p', value, '')
+  exit_code, git_patch, err_output = svntest.main.run_svn(None, 'diff',
+                                                          '--git', wc_dir)
+
+  patch_file_path = sbox.get_tempname('my.patch')
+  svntest.main.file_write(patch_file_path, ''.join(git_patch), 'wb')
+
+  sbox.simple_revert('')
+
+  expected_output = wc.State(wc_dir, {
+    '.'                 : Item(status=' U'),
+  })
+  expected_disk = svntest.wc.State('', {})
+  expected_disk.add({'': Item(props={'p' : value })})
+  expected_status = svntest.wc.State(wc_dir, {})
+  expected_status.add({'': Item(status=' M', wc_rev='0')})
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, patch_file_path,
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       True, # check-props
+                                       False, # dry-run
+                                       )
+
+  svntest.actions.check_prop('p', wc_dir, [value.encode()])
+
 ########################################################################
 #Run the tests
 
@@ -7937,6 +8094,9 @@ test_list = [ None,
               patch_missed_trail,
               patch_merge,
               patch_mergeinfo_in_regular_prop_format,
+              patch_empty_prop,
+              patch_git_wcroot,
+              patch_git_wcroot2,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/prop_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/prop_tests.py Wed Nov 28 \
21:25:32 2018 @@ -1768,7 +1768,7 @@ def rm_of_replaced_file(sbox):
                                                    'proplist', '-v',
                                                    mu_path + '@base')
   expected_output = svntest.verify.UnorderedRegexListOutput([
-      'Properties on',
+      'Properties on.*',
       '  yellow',
       '    submarine',
       '  orange',

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/revert_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/revert_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/revert_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/revert_tests.py Wed Nov 28 \
21:25:32 2018 @@ -1550,11 +1550,14 @@ def revert_with_unversioned_targets(sbox
   psi_contents = "modified psi\n"
 
   # touch delta
-  open(delta_path, 'w').write(delta_contents)
+  with open(delta_path, 'w') as f:
+    f.write(delta_contents)
 
   # modify chi psi
-  open(chi_path, 'w').write(chi_contents)
-  open(psi_path, 'w').write(psi_contents)
+  with open(chi_path, 'w') as f:
+    f.write(chi_contents)
+  with open(psi_path, 'w') as f:
+    f.write(psi_contents)
 
   # revert
   expected_output = svntest.verify.UnorderedOutput([

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/shelf_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/shelf_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/shelf_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/shelf_tests.py Wed Nov 28 \
21:25:32 2018 @@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-#  shelve_tests.py:  testing shelving
+#  shelf_tests.py:  testing shelving
 #
 #  Subversion is a tool for revision control.
 #  See http://subversion.apache.org for more information.
@@ -32,6 +32,10 @@ logger = logging.getLogger()
 # Our testing module
 import svntest
 from svntest import wc
+from svntest.verify import make_diff_header, make_no_diff_deleted_header, \
+                           make_git_diff_header, make_diff_prop_header, \
+                           make_diff_prop_val, make_diff_prop_deleted, \
+                           make_diff_prop_added, make_diff_prop_modified
 
 # (abbreviation)
 Skip = svntest.testcase.Skip_deco
@@ -44,45 +48,103 @@ Item = wc.StateItem
 
 #----------------------------------------------------------------------
 
-def shelve_unshelve_verify(sbox):
+def state_from_status(wc_dir,
+                      v=True, u=True, q=True):
+  opts = ()
+  if v:
+    opts += ('-v',)
+  if u:
+    opts += ('-u',)
+  if q:
+    opts += ('-q',)
+  _, output, _ = svntest.main.run_svn(None, 'status', wc_dir, *opts)
+  return svntest.wc.State.from_status(output, wc_dir)
+
+def get_wc_state(wc_dir):
+  """Return a description of the WC state. Include as much info as shelving
+     should be capable of restoring.
+  """
+  return (state_from_status(wc_dir),
+          svntest.wc.State.from_wc(wc_dir, load_props=True),
+          )
+
+def check_wc_state(wc_dir, expected):
+  """Check a description of the WC state. Include as much info as shelving
+     should be capable of restoring.
+  """
+  expect_st, expect_wc = expected
+  actual_st, actual_wc = get_wc_state(wc_dir)
+
+  # Verify actual status against expected status.
+  try:
+    expect_st.compare_and_display('status', actual_st)
+  except svntest.tree.SVNTreeError:
+    svntest.actions._log_tree_state("EXPECT STATUS TREE:", expect_st.old_tree(),
+                                    wc_dir)
+    svntest.actions._log_tree_state("ACTUAL STATUS TREE:", actual_st.old_tree(),
+                                    wc_dir)
+    raise
+
+  # Verify actual WC against expected WC.
+  try:
+    expect_wc.compare_and_display('status', actual_wc)
+  except svntest.tree.SVNTreeError:
+    svntest.actions._log_tree_state("EXPECT WC TREE:", expect_wc.old_tree(),
+                                    wc_dir)
+    svntest.actions._log_tree_state("ACTUAL WC TREE:", actual_wc.old_tree(),
+                                    wc_dir)
+    raise
+
+def shelve_unshelve_verify(sbox, modifier, cannot_shelve=False):
   """Round-trip: shelve; verify all changes are reverted;
      unshelve; verify all changes are restored.
   """
 
   wc_dir = sbox.wc_dir
+  virginal_state = get_wc_state(wc_dir)
+
+  # Make some changes to the working copy
+  modifier(sbox)
 
   # Save the modified state
-  _, output, _ = svntest.main.run_svn(None, 'status', '-v', '-u', '-q',
-                                      wc_dir)
-  modified_state = svntest.wc.State.from_status(output, wc_dir)
+  modified_state = get_wc_state(wc_dir)
+
+  if cannot_shelve:
+    svntest.actions.run_and_verify_svn(None, '.* could not be shelved.*',
+                                       'x-shelve', 'foo')
+    return
 
   # Shelve; check there are no longer any modifications
   svntest.actions.run_and_verify_svn(None, [],
-                                     'shelve', 'foo')
-  virginal_state = svntest.actions.get_virginal_state(wc_dir, 1)
-  svntest.actions.run_and_verify_status(wc_dir, virginal_state)
+                                     'x-shelve', 'foo')
+  check_wc_state(wc_dir, virginal_state)
+
+  # List; ensure the shelf is listed
+  expected_output = svntest.verify.RegexListOutput(
+    [r'foo\s*version \d+.*',
+     r' ',
+    ])
+  svntest.actions.run_and_verify_svn(expected_output, [], 'x-shelves')
 
   # Unshelve; check the original modifications are here again
   svntest.actions.run_and_verify_svn(None, [],
-                                     'unshelve', 'foo')
-  svntest.actions.run_and_verify_status(wc_dir, modified_state)
+                                     'x-unshelve', 'foo')
+  check_wc_state(wc_dir, modified_state)
 
 #----------------------------------------------------------------------
 
-def shelve_unshelve(sbox, modifier):
+def shelve_unshelve(sbox, modifier, cannot_shelve=False):
   """Round-trip: build 'sbox'; apply changes by calling 'modifier(sbox)';
      shelve and unshelve; verify changes are fully reverted and restored.
   """
 
-  sbox.build()
+  if not sbox.is_built():
+    sbox.build()
   was_cwd = os.getcwd()
   os.chdir(sbox.wc_dir)
   sbox.wc_dir = ''
 
-  # Make some changes to the working copy
-  modifier(sbox)
-
-  shelve_unshelve_verify(sbox)
+  shelve_unshelve_verify(sbox, modifier, cannot_shelve)
 
   os.chdir(was_cwd)
 
@@ -116,10 +178,8 @@ def shelve_adds(sbox):
   "shelve adds"
 
   def modifier(sbox):
-    sbox.simple_append('A/new', 'A new file\n')
-    sbox.simple_add('A/new')
-    sbox.simple_append('A/new2', 'A new file\n')
-    sbox.simple_add('A/new2')
+    sbox.simple_add_text('A new file\n', 'A/new')
+    sbox.simple_add_text('A new file\n', 'A/new2')
     sbox.simple_propset('p', 'v', 'A/new2')
 
   shelve_unshelve(sbox, modifier)
@@ -137,6 +197,46 @@ def shelve_deletes(sbox):
 
 #----------------------------------------------------------------------
 
+def shelve_replace(sbox):
+  "shelve replace"
+
+  def modifier(sbox):
+    sbox.simple_rm('A/mu')
+    sbox.simple_add_text('Replacement\n', 'A/mu')
+    sbox.simple_propset('p', 'v', 'A/mu')
+
+  shelve_unshelve(sbox, modifier)
+
+#----------------------------------------------------------------------
+
+def shelve_empty_adds(sbox):
+  "shelve empty adds"
+  sbox.build(empty=True)
+
+  def modifier(sbox):
+    sbox.simple_add_text('', 'empty')
+    sbox.simple_add_text('', 'empty-with-prop')
+    sbox.simple_propset('p', 'v', 'empty-with-prop')
+
+  shelve_unshelve(sbox, modifier)
+
+#----------------------------------------------------------------------
+
+def shelve_empty_deletes(sbox):
+  "shelve empty deletes"
+  sbox.build(empty=True)
+  sbox.simple_add_text('', 'empty')
+  sbox.simple_add_text('', 'empty-with-prop')
+  sbox.simple_propset('p', 'v', 'empty-with-prop')
+  sbox.simple_commit()
+
+  def modifier(sbox):
+    sbox.simple_rm('empty', 'empty-with-prop')
+
+  shelve_unshelve(sbox, modifier)
+
+#----------------------------------------------------------------------
+
 def shelve_from_inner_path(sbox):
   "shelve from inner path"
 
@@ -148,18 +248,12 @@ def shelve_from_inner_path(sbox):
   os.chdir(sbox.ospath('A'))
   sbox.wc_dir = '..'
 
-  modifier(sbox)
-  shelve_unshelve_verify(sbox)
+  shelve_unshelve_verify(sbox, modifier)
 
   os.chdir(was_cwd)
 
 #----------------------------------------------------------------------
 
-def state_from_status(wc_dir):
-  _, output, _ = svntest.main.run_svn(None, 'status', '-v', '-u', '-q',
-                                      wc_dir)
-  return svntest.wc.State.from_status(output, wc_dir)
-
 def save_revert_restore(sbox, modifier1, modifier2):
   "Save 2 checkpoints; revert; restore 1st"
 
@@ -169,34 +263,35 @@ def save_revert_restore(sbox, modifier1,
   sbox.wc_dir = ''
   wc_dir = ''
 
+  initial_state = get_wc_state(wc_dir)
+
   # Make some changes to the working copy
   modifier1(sbox)
 
   # Remember the modified state
-  modified_state1 = state_from_status(wc_dir)
+  modified_state1 = get_wc_state(wc_dir)
 
   # Save a checkpoint; check nothing changed
   svntest.actions.run_and_verify_svn(None, [],
-                                     'shelf-save', 'foo')
-  svntest.actions.run_and_verify_status(wc_dir, modified_state1)
+                                     'x-shelf-save', 'foo')
+  check_wc_state(wc_dir, modified_state1)
 
   # Modify again; remember the state; save a checkpoint
   modifier2(sbox)
-  modified_state2 = state_from_status(wc_dir)
+  modified_state2 = get_wc_state(wc_dir)
   svntest.actions.run_and_verify_svn(None, [],
-                                     'shelf-save', 'foo')
-  svntest.actions.run_and_verify_status(wc_dir, modified_state2)
+                                     'x-shelf-save', 'foo')
+  check_wc_state(wc_dir, modified_state2)
 
   # Revert
   svntest.actions.run_and_verify_svn(None, [],
                                      'revert', '-R', '.')
-  virginal_state = svntest.actions.get_virginal_state(wc_dir, 1)
-  svntest.actions.run_and_verify_status(wc_dir, virginal_state)
+  check_wc_state(wc_dir, initial_state)
 
   # Restore; check the original modifications are here again
   svntest.actions.run_and_verify_svn(None, [],
-                                     'unshelve', 'foo', '1')
-  svntest.actions.run_and_verify_status(wc_dir, modified_state1)
+                                     'x-unshelve', 'foo', '1')
+  check_wc_state(wc_dir, modified_state1)
 
   os.chdir(was_cwd)
 
@@ -226,6 +321,633 @@ def shelve_mergeinfo(sbox):
 
   shelve_unshelve(sbox, modifier)
 
+#----------------------------------------------------------------------
+
+def unshelve_refuses_if_conflicts(sbox):
+  "unshelve refuses if conflicts"
+
+  def modifier1(sbox):
+    sbox.simple_append('alpha', 'A-mod1\nB\nC\nD\n', truncate=True)
+    sbox.simple_append('beta', 'A-mod1\nB\nC\nD\n', truncate=True)
+
+  def modifier2(sbox):
+    sbox.simple_append('beta', 'A-mod2\nB\nC\nD\n', truncate=True)
+
+  sbox.build(empty=True)
+  was_cwd = os.getcwd()
+  os.chdir(sbox.wc_dir)
+  sbox.wc_dir = ''
+  wc_dir = ''
+
+  sbox.simple_add_text('A\nB\nC\nD\n', 'alpha')
+  sbox.simple_add_text('A\nB\nC\nD\n', 'beta')
+  sbox.simple_commit()
+  initial_state = get_wc_state(wc_dir)
+
+  # Make initial mods; remember this modified state
+  modifier1(sbox)
+  modified_state1 = get_wc_state(wc_dir)
+  assert modified_state1 != initial_state
+
+  # Shelve; check there are no longer any local mods
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'x-shelve', 'foo')
+  check_wc_state(wc_dir, initial_state)
+
+  # Make a different local mod that will conflict with the shelf
+  modifier2(sbox)
+  modified_state2 = get_wc_state(wc_dir)
+
+  # Try to unshelve; check it fails with an error about a conflict
+  svntest.actions.run_and_verify_svn(None, '.*[Cc]onflict.*',
+                                     'x-unshelve', 'foo')
+  # Check nothing changed in the attempt
+  check_wc_state(wc_dir, modified_state2)
+
+#----------------------------------------------------------------------
+
+def shelve_binary_file_mod(sbox):
+  "shelve binary file mod"
+
+  sbox.build(empty=True)
+
+  existing_files = ['A/B/existing']
+  mod_files = ['bin', 'A/B/bin']
+
+  sbox.simple_mkdir('A', 'A/B')
+  for f in existing_files + mod_files:
+    sbox.simple_add_text('\0\1\2\3\4\5', f)
+  sbox.simple_commit()
+
+  def modifier(sbox):
+    for f in mod_files:
+      sbox.simple_append(f, '\6\5\4\3\2\1\0', truncate=True)
+
+  shelve_unshelve(sbox, modifier)
+
+#----------------------------------------------------------------------
+
+def shelve_binary_file_add(sbox):
+  "shelve binary file add"
+
+  sbox.build(empty=True)
+
+  existing_files = ['A/B/existing']
+  mod_files = ['bin', 'A/B/bin']
+
+  sbox.simple_mkdir('A', 'A/B')
+  for f in existing_files:
+    sbox.simple_add_text('\0\1\2\3\4\5', f)
+  sbox.simple_commit()
+
+  def modifier(sbox):
+    for f in mod_files:
+      sbox.simple_add_text('\0\1\2\3\4\5', f)
+
+  shelve_unshelve(sbox, modifier)
+
+#----------------------------------------------------------------------
+
+def shelve_binary_file_del(sbox):
+  "shelve binary file del"
+
+  sbox.build(empty=True)
+
+  existing_files = ['A/B/existing']
+  mod_files = ['bin', 'A/B/bin']
+
+  sbox.simple_mkdir('A', 'A/B')
+  for f in existing_files + mod_files:
+    sbox.simple_add_text('\0\1\2\3\4\5', f)
+  sbox.simple_commit()
+
+  def modifier(sbox):
+    for f in mod_files:
+      sbox.simple_rm(f)
+
+  shelve_unshelve(sbox, modifier)
+
+#----------------------------------------------------------------------
+
+def shelve_binary_file_replace(sbox):
+  "shelve binary file replace"
+
+  sbox.build(empty=True)
+
+  existing_files = ['A/B/existing']
+  mod_files = ['bin', 'A/B/bin']
+
+  sbox.simple_mkdir('A', 'A/B')
+  for f in existing_files + mod_files:
+    sbox.simple_add_text('\0\1\2\3\4\5', f)
+  sbox.simple_commit()
+
+  def modifier(sbox):
+    for f in mod_files:
+      sbox.simple_rm(f)
+      sbox.simple_add_text('\6\5\4\3\2\1\0', f)
+
+  shelve_unshelve(sbox, modifier)
+
+#----------------------------------------------------------------------
+
+def shelve_with_log_message(sbox):
+  "shelve with log message"
+
+  sbox.build(empty=True)
+  was_cwd = os.getcwd()
+  os.chdir(sbox.wc_dir)
+  sbox.wc_dir = ''
+
+  sbox.simple_add_text('New file', 'f')
+  log_message = 'Log message for foo'
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'x-shelve', 'foo', '-m', log_message)
+  expected_output = svntest.verify.RegexListOutput(
+    ['foo .*',
+     ' ' + log_message
+    ])
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'x-shelf-list')
+
+  os.chdir(was_cwd)
+
+#----------------------------------------------------------------------
+
+def run_and_verify_status(wc_dir_name, status_tree, changelists=[]):
+  """Run 'status' on WC_DIR_NAME and compare it with the
+  expected STATUS_TREE.
+  Returns on success, raises on failure."""
+
+  if not isinstance(status_tree, wc.State):
+    raise TypeError('wc.State tree expected')
+
+  cl_opts = ('--cl=' + cl for cl in changelists)
+  exit_code, output, errput = svntest.main.run_svn(None, 'status', '-q',
+                                                   wc_dir_name, *cl_opts)
+
+  actual_status = svntest.wc.State.from_status(output, wc_dir=wc_dir_name)
+
+  # Verify actual output against expected output.
+  try:
+    status_tree.compare_and_display('status', actual_status)
+  except svntest.tree.SVNTreeError:
+    svntest.actions._log_tree_state("ACTUAL STATUS TREE:", actual_status.old_tree(),
+                                    wc_dir_name)
+    raise
+
+def run_and_verify_shelf_status(wc_dir, expected_status, shelf):
+  run_and_verify_status(wc_dir, expected_status,
+                        changelists=['svn:shelf:' + shelf])
+
+def shelf_status(sbox):
+  "shelf status"
+
+  sbox.build()
+  was_cwd = os.getcwd()
+  os.chdir(sbox.wc_dir)
+  sbox.wc_dir = ''
+
+  sbox.simple_add_text('New file', 'f')
+  sbox.simple_append('iota', 'New text')
+  sbox.simple_propset('p', 'v', 'A/mu')
+  sbox.simple_rm('A/B/lambda')
+  # Not yet supported:
+  #sbox.simple_rm('A/B/E')
+  expected_status = state_from_status(sbox.wc_dir, v=False, u=False, q=False)
+  run_and_verify_status(sbox.wc_dir, expected_status)
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'x-shelve', 'foo')
+  run_and_verify_shelf_status(sbox.wc_dir, expected_status, shelf='foo')
+
+  os.chdir(was_cwd)
+
+#----------------------------------------------------------------------
+
+def shelve_mkdir(sbox):
+  "shelve mkdir"
+
+  sbox.build()
+
+  def modifier(sbox):
+    sbox.simple_mkdir('D', 'D/D2')
+    sbox.simple_propset('p', 'v', 'D', 'D/D2')
+
+  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+
+#----------------------------------------------------------------------
+
+def shelve_rmdir(sbox):
+  "shelve rmdir"
+
+  sbox.build()
+  sbox.simple_propset('p', 'v', 'A/C')
+  sbox.simple_commit()
+
+  def modifier(sbox):
+    sbox.simple_rm('A/C', 'A/D/G')
+
+  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+
+#----------------------------------------------------------------------
+
+def shelve_replace_dir(sbox):
+  "shelve replace dir"
+
+  sbox.build()
+  sbox.simple_propset('p', 'v', 'A/C')
+  sbox.simple_commit()
+
+  def modifier(sbox):
+    sbox.simple_rm('A/C', 'A/D/G')
+    sbox.simple_mkdir('A/C', 'A/C/D2')
+
+  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+
+#----------------------------------------------------------------------
+
+def shelve_file_copy(sbox):
+  "shelve file copy"
+
+  sbox.build()
+
+  def modifier(sbox):
+    sbox.simple_copy('iota', 'A/ii')
+    sbox.simple_propset('p', 'v', 'A/ii')
+
+  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+
+#----------------------------------------------------------------------
+
+def shelve_dir_copy(sbox):
+  "shelve dir copy"
+
+  sbox.build()
+
+  def modifier(sbox):
+    sbox.simple_copy('A/B', 'BB')
+    sbox.simple_propset('p', 'v', 'BB')
+
+  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+
+#----------------------------------------------------------------------
+
+def list_shelves(sbox):
+  "list_shelves"
+
+  sbox.build()
+  was_cwd = os.getcwd()
+  os.chdir(sbox.wc_dir)
+  sbox.wc_dir = ''
+
+  # an empty list
+  svntest.actions.run_and_verify_svn([], [],
+                                     'x-shelf-list', '-q')
+
+  # make two shelves
+  sbox.simple_append('A/mu', 'appended mu text')
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'x-shelf-save', 'foo')
+  sbox.simple_append('A/mu', 'appended more text')
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'x-shelf-save', 'foo', '-m', 'log msg')
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'x-shelf-save', 'bar', '-m', 'log msg')
+
+  # We don't check for time-ordering of the shelves. If we want to do so, we
+  # would need to sleep for timestamps to differ, between creating them.
+
+  # a quiet list
+  expected_out = svntest.verify.UnorderedRegexListOutput(['foo', 'bar'])
+  svntest.actions.run_and_verify_svn(expected_out, [],
+                                     'x-shelf-list', '-q')
+
+  # a detailed list
+  expected_out = svntest.verify.UnorderedRegexListOutput(['foo .* 1 path.*',
+                                                          ' log msg',
+                                                          'bar .* 1 path.*',
+                                                          ' log msg'])
+  svntest.actions.run_and_verify_svn(expected_out, [],
+                                     'x-shelf-list')
+
+  os.chdir(was_cwd)
+
+#----------------------------------------------------------------------
+
+def refuse_to_shelve_conflict(sbox):
+  "refuse to shelve conflict"
+
+  sbox.build(empty=True)
+  was_cwd = os.getcwd()
+  os.chdir(sbox.wc_dir)
+  sbox.wc_dir = ''
+
+  # create a tree conflict victim at an unversioned path
+  sbox.simple_mkdir('topdir')
+  sbox.simple_commit()
+  sbox.simple_mkdir('topdir/subdir')
+  sbox.simple_commit()
+  sbox.simple_update()
+  sbox.simple_rm('topdir')
+  sbox.simple_commit()
+  sbox.simple_update()
+  svntest.actions.run_and_verify_svn(
+    None, [],
+    'merge', '-c2', '.', '--ignore-ancestry', '--accept', 'postpone')
+  svntest.actions.run_and_verify_svn(
+    None, 'svn: E155015:.*existing.*conflict.*',
+    'merge', '-c1', '.', '--ignore-ancestry', '--accept', 'postpone')
+
+  # attempt to shelve
+  expected_out = svntest.verify.RegexListOutput([
+    r'--- .*',
+    r'--- .*',
+    r'\?     C topdir',
+    r'      > .*',
+    r'      >   not shelved'])
+  svntest.actions.run_and_verify_svn(expected_out,
+                                     '.* 1 path could not be shelved',
+                                     'x-shelf-save', 'foo')
+
+  os.chdir(was_cwd)
+
+#----------------------------------------------------------------------
+
+def unshelve_with_merge(sbox, setup, modifier1, modifier2, tweak_expected_state):
+  """Run a test scenario in which 'unshelve' needs to merge some shelved
+     changes made by modifier1() with some committed changes made by
+     modifier2(). tweak_expected_state() must produce the expected WC state.
+  """
+  sbox.build()
+  was_cwd = os.getcwd()
+  os.chdir(sbox.wc_dir)
+  sbox.wc_dir = ''
+  wc_dir = sbox.wc_dir
+
+  setup(sbox)
+  sbox.simple_commit()
+  initial_state = get_wc_state(wc_dir)
+
+  # Make some changes to the working copy
+  modifier1(sbox)
+  modified_state = get_wc_state(wc_dir)
+
+  # Shelve; check there are no longer any modifications
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'x-shelve', 'foo')
+  check_wc_state(wc_dir, initial_state)
+
+  # Make a different change, with which we shall merge
+  modifier2(sbox)
+  sbox.simple_commit()
+  modified_state[0].tweak('A/mu', wc_rev='3')
+
+  # Unshelve; check the expected result of the merge
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'x-unshelve', 'foo')
+  tweak_expected_state(modified_state)
+  check_wc_state(wc_dir, modified_state)
+
+  os.chdir(was_cwd)
+
+def unshelve_text_mod_merge(sbox):
+  "unshelve text mod merge"
+
+  orig_contents='A\nB\nC\nD\nE\n'
+  mod1_contents='A\nBB\nC\nD\nE\n'
+  mod2_contents='A\nB\nC\nDD\nE\n'
+  merged_contents='A\nBB\nC\nDD\nE\n'
+
+  def setup(sbox):
+    sbox.simple_append('A/mu', orig_contents, truncate=True)
+
+  def modifier1(sbox):
+    sbox.simple_append('A/mu', mod1_contents, truncate=True)
+
+  def modifier2(sbox):
+    sbox.simple_append('A/mu', mod2_contents, truncate=True)
+
+  def tweak_expected_state(modified_state):
+    modified_state[1].tweak('A/mu', contents=merged_contents)
+
+  unshelve_with_merge(sbox, setup, modifier1, modifier2, tweak_expected_state)
+
+#----------------------------------------------------------------------
+
+def unshelve_text_mod_conflict(sbox):
+  "unshelve text mod conflict"
+
+  orig_contents='A\nB\nC\nD\nE\n'
+  mod1_contents='A\nBB\nC\nD\nE\n'
+  mod2_contents='A\nBCD\nC\nD\nE\n'
+  merged_contents = 'A\n<<<<<<< .working\nBCD\n||||||| \
.merge-left\nB\n=======\nBB\n>>>>>>> .merge-right\nC\nD\nE\n' +
+  def setup(sbox):
+    sbox.simple_append('A/mu', orig_contents, truncate=True)
+
+  def modifier1(sbox):
+    sbox.simple_append('A/mu', mod1_contents, truncate=True)
+
+  def modifier2(sbox):
+    sbox.simple_append('A/mu', mod2_contents, truncate=True)
+
+  def tweak_expected_state(modified_state):
+    modified_state[0].tweak('A/mu', status='C ')
+    modified_state[1].tweak('A/mu', contents=merged_contents)
+    modified_state[1].add({
+      'A/mu.merge-left':  Item(contents=orig_contents),
+      'A/mu.merge-right': Item(contents=mod1_contents),
+      'A/mu.working':     Item(contents=mod2_contents),
+      })
+
+  unshelve_with_merge(sbox, setup, modifier1, modifier2, tweak_expected_state)
+
+#----------------------------------------------------------------------
+
+def unshelve_undeclared_binary_mod_conflict(sbox):
+  "unshelve undeclared binary mod conflict"
+
+  orig_contents='\1\2\3\4\5'
+  mod1_contents='\1\2\2\3\4\5'
+  mod2_contents='\1\2\3\4\3\4\5'
+  merged_contents = '<<<<<<< .working\n' + mod2_contents + '||||||| .merge-left\n' + \
orig_contents + '=======\n' + mod1_contents + '>>>>>>> .merge-right\n' +
+  def setup(sbox):
+    sbox.simple_append('A/mu', orig_contents, truncate=True)
+
+  def modifier1(sbox):
+    sbox.simple_append('A/mu', mod1_contents, truncate=True)
+
+  def modifier2(sbox):
+    sbox.simple_append('A/mu', mod2_contents, truncate=True)
+
+  def tweak_expected_state(modified_state):
+    modified_state[0].tweak('A/mu', status='C ')
+    modified_state[1].tweak('A/mu', contents=merged_contents)
+    modified_state[1].add({
+      'A/mu.merge-left':  Item(contents=orig_contents),
+      'A/mu.merge-right': Item(contents=mod1_contents),
+      'A/mu.working':     Item(contents=mod2_contents),
+      })
+
+  unshelve_with_merge(sbox, setup, modifier1, modifier2, tweak_expected_state)
+
+#----------------------------------------------------------------------
+
+def unshelve_binary_mod_conflict(sbox):
+  "unshelve binary mod conflict"
+
+  orig_contents='\1\2\3\4\5'
+  mod1_contents='\1\2\2\3\4\5'
+  mod2_contents='\1\2\3\4\3\4\5'
+
+  def setup(sbox):
+    sbox.simple_append('A/mu', orig_contents, truncate=True)
+    sbox.simple_propset('svn:mime-type', 'application/octet-stream', 'A/mu')
+
+  def modifier1(sbox):
+    sbox.simple_append('A/mu', mod1_contents, truncate=True)
+
+  def modifier2(sbox):
+    sbox.simple_append('A/mu', mod2_contents, truncate=True)
+
+  def tweak_expected_state(modified_state):
+    modified_state[0].tweak('A/mu', status='C ')
+    modified_state[1].tweak('A/mu', contents=mod2_contents)
+    modified_state[1].add({
+      'A/mu.merge-left':  Item(contents=orig_contents),
+      'A/mu.merge-right': Item(contents=mod1_contents),
+      })
+
+  unshelve_with_merge(sbox, setup, modifier1, modifier2, tweak_expected_state)
+
+#----------------------------------------------------------------------
+
+def unshelve_text_prop_merge(sbox):
+  "unshelve text prop merge"
+
+  def setup(sbox):
+    sbox.simple_propset('p1', 'v', 'A/mu')
+    sbox.simple_propset('p2', 'v', 'A/mu')
+
+  def modifier1(sbox):
+    sbox.simple_propset('p1', 'changed', 'A/mu')
+
+  def modifier2(sbox):
+    sbox.simple_propset('p2', 'changed', 'A/mu')
+
+  def tweak_expected_state(wc_state):
+    wc_state[1].tweak('A/mu', props={'p1':'changed',
+                                     'p2':'changed'})
+
+  unshelve_with_merge(sbox, setup, modifier1, modifier2, tweak_expected_state)
+
+#----------------------------------------------------------------------
+
+def unshelve_text_prop_conflict(sbox):
+  "unshelve text prop conflict"
+
+  orig_contents='A'
+  mod1_contents='B'
+  mod2_contents='C'
+  merged_contents='C'
+  prej_contents='''Trying to change property 'p'
+but the local property value conflicts with the incoming change.
+<<<<<<< (local property value)
+C||||||| (incoming 'changed from' value)
+A=======
+B>>>>>>> (incoming 'changed to' value)
+'''
+
+  def setup(sbox):
+    sbox.simple_propset('p', orig_contents, 'A/mu')
+
+  def modifier1(sbox):
+    sbox.simple_propset('p', mod1_contents, 'A/mu')
+
+  def modifier2(sbox):
+    sbox.simple_propset('p', mod2_contents, 'A/mu')
+
+  def tweak_expected_state(wc_state):
+    wc_state[0].tweak('A/mu', status=' C')
+    wc_state[1].tweak('A/mu', props={'p':merged_contents})
+    wc_state[1].add({
+      'A/mu.prej':     Item(contents=prej_contents),
+      })
+
+  unshelve_with_merge(sbox, setup, modifier1, modifier2, tweak_expected_state)
+
+#----------------------------------------------------------------------
+
+def run_and_verify_shelf_diff_summarize(output_tree, shelf, *args):
+  """Run 'svn shelf-diff --summarize' with the arguments *ARGS.
+
+  The subcommand output will be verified against OUTPUT_TREE.  Returns
+  on success, raises on failure.
+  """
+
+  if isinstance(output_tree, wc.State):
+    output_tree = output_tree.old_tree()
+
+  exit_code, output, errput = svntest.actions.run_and_verify_svn(
+                                None, [],
+                                'x-shelf-diff', '--summarize', shelf, *args)
+
+  actual = svntest.tree.build_tree_from_diff_summarize(output)
+
+  # Verify actual output against expected output.
+  try:
+    svntest.tree.compare_trees("output", actual, output_tree)
+  except svntest.tree.SVNTreeError:
+    svntest.verify.display_trees(None, 'DIFF OUTPUT TREE', output_tree, actual)
+    raise
+
+# Exercise a very basic case of shelf-diff.
+def shelf_diff_simple(sbox):
+  "shelf diff simple"
+
+  sbox.build()
+  was_cwd = os.getcwd()
+  os.chdir(sbox.wc_dir)
+  sbox.wc_dir = ''
+  wc_dir = sbox.wc_dir
+
+  def setup(sbox):
+    sbox.simple_propset('p1', 'v', 'A/mu')
+    sbox.simple_propset('p2', 'v', 'A/mu')
+
+  def modifier1(sbox):
+    sbox.simple_append('A/mu', 'New line.\n')
+    sbox.simple_propset('p1', 'changed', 'A/mu')
+
+  setup(sbox)
+  sbox.simple_commit()
+  initial_state = get_wc_state(wc_dir)
+
+  # Make some changes to the working copy
+  modifier1(sbox)
+  modified_state = get_wc_state(wc_dir)
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'x-shelf-save', 'foo')
+
+  # basic svn-style diff
+  expected_output = make_diff_header('A/mu', 'revision 2', 'working copy') + [
+                      "@@ -1 +1,2 @@\n",
+                      " This is the file 'mu'.\n",
+                      "+New line.\n",
+                    ] + make_diff_prop_header('A/mu') \
+                    + make_diff_prop_modified('p1', 'v', 'changed')
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'x-shelf-diff', 'foo')
+
+  # basic summary diff
+  expected_diff = svntest.wc.State(wc_dir, {
+    'A/mu':           Item(status='MM'),
+  })
+  run_and_verify_shelf_diff_summarize(expected_diff, 'foo')
+
 
 ########################################################################
 # Run the tests
@@ -236,9 +958,33 @@ test_list = [ None,
               shelve_prop_changes,
               shelve_adds,
               shelve_deletes,
+              shelve_replace,
+              shelve_empty_adds,
+              shelve_empty_deletes,
               shelve_from_inner_path,
               checkpoint_basic,
               shelve_mergeinfo,
+              unshelve_refuses_if_conflicts,
+              shelve_binary_file_mod,
+              shelve_binary_file_add,
+              shelve_binary_file_del,
+              shelve_binary_file_replace,
+              shelve_with_log_message,
+              shelf_status,
+              shelve_mkdir,
+              shelve_rmdir,
+              shelve_replace_dir,
+              shelve_file_copy,
+              shelve_dir_copy,
+              list_shelves,
+              refuse_to_shelve_conflict,
+              unshelve_text_mod_merge,
+              unshelve_text_mod_conflict,
+              unshelve_undeclared_binary_mod_conflict,
+              unshelve_binary_mod_conflict,
+              unshelve_text_prop_merge,
+              unshelve_text_prop_conflict,
+              shelf_diff_simple,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/special_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/special_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/special_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/special_tests.py Wed Nov 28 \
21:25:32 2018 @@ -535,7 +535,7 @@ def diff_symlink_to_dir(sbox):
     "+++ link\t(working copy)\n",
     "@@ -0,0 +1 @@\n",
     "+link A/D\n",
-    "\ No newline at end of file\n",
+    "\\ No newline at end of file\n",
     "\n",
     "Property changes on: link\n",
     "___________________________________________________________________\n",
@@ -730,7 +730,8 @@ def unrelated_changed_special_status(sbo
 
   os.chdir(os.path.join(sbox.wc_dir, 'A/D/H'))
 
-  open('chi', 'a').write('random local mod')
+  with open('chi', 'a') as f:
+    f.write('random local mod')
   os.unlink('psi')
   os.symlink('omega', 'psi') # omega is versioned!
   svntest.main.run_svn(None, 'changelist', 'chi cl', 'chi')

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/stat_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/stat_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/stat_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/stat_tests.py Wed Nov 28 \
21:25:32 2018 @@ -1949,7 +1949,8 @@ def modified_modulo_translation(sbox):
   sbox.simple_commit()
 
   # CRLF it.
-  open(sbox.ospath('iota'), 'wb').write("This is the file 'iota'.\r\n")
+  with open(sbox.ospath('iota'), 'wb') as f:
+    f.write("This is the file 'iota'.\r\n")
 
   # Run status.  Expect some output.
   # TODO: decide how such files should show in the output; whether they

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/svnadmin_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/svnadmin_tests.py \
                (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/svnadmin_tests.py Wed Nov \
28 21:25:32 2018 @@ -53,6 +53,24 @@ Wimp = svntest.testcase.Wimp_deco
 SkipDumpLoadCrossCheck = svntest.testcase.SkipDumpLoadCrossCheck_deco
 Item = svntest.wc.StateItem
 
+def read_rep_cache(repo_dir):
+  """Return the rep-cache contents as a dict {hash: (rev, index, ...)}.
+  """
+  db_path = os.path.join(repo_dir, 'db', 'rep-cache.db')
+  db1 = svntest.sqlite3.connect(db_path)
+  schema1 = db1.execute("pragma user_version").fetchone()[0]
+  # Can't test newer rep-cache schemas with an old built-in SQLite; see the
+  # documentation of STMT_CREATE_SCHEMA_V2 in ../../libsvn_fs_fs/rep-cache-db.sql
+  if schema1 >= 2 and svntest.sqlite3.sqlite_version_info < (3, 8, 2):
+    raise svntest.Failure("Can't read rep-cache schema %d using old "
+                          "Python-SQLite version %s < (3,8,2)" %
+                           (schema1,
+                            svntest.sqlite3.sqlite_version_info))
+
+  content = { row[0]: row[1:] for row in
+              db1.execute("select * from rep_cache") }
+  return content
+
 def check_hotcopy_bdb(src, dst):
   "Verify that the SRC BDB repository has been correctly copied to DST."
   ### TODO: This function should be extended to verify all hotcopied files,
@@ -256,7 +274,8 @@ def patch_format(repo_dir, shard_size):
 
   new_contents = b"\n".join(processed_lines)
   os.chmod(format_path, svntest.main.S_ALL_RW)
-  open(format_path, 'wb').write(new_contents)
+  with open(format_path, 'wb') as f:
+    f.write(new_contents)
 
 def is_sharded(repo_dir):
   """Return whether the FSFS repository REPO_DIR is sharded."""
@@ -777,9 +796,13 @@ def verify_windows_paths_in_repos(sbox):
 def fsfs_file(repo_dir, kind, rev):
   if svntest.main.options.server_minor_version >= 5:
     if svntest.main.options.fsfs_sharding is None:
+      if svntest.main.is_fs_type_fsx():
+        rev = 'r' + rev
       return os.path.join(repo_dir, 'db', kind, '0', rev)
     else:
       shard = int(rev) // svntest.main.options.fsfs_sharding
+      if svntest.main.is_fs_type_fsx():
+        rev = 'r' + rev
       path = os.path.join(repo_dir, 'db', kind, str(shard), rev)
 
       if svntest.main.options.fsfs_packing is None or kind == 'revprops':
@@ -1043,7 +1066,7 @@ def fsfs_recover_old_db_current(sbox):
 def load_with_parent_dir(sbox):
   "'svnadmin load --parent-dir' reparents mergeinfo"
 
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2983. ##
+  ## See https://issues.apache.org/jira/browse/SVN-2983. ##
   sbox.build(empty=True)
 
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
@@ -1134,7 +1157,7 @@ def set_uuid(sbox):
 def reflect_dropped_renumbered_revs(sbox):
   "reflect dropped renumbered revs in svn:mergeinfo"
 
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3020. ##
+  ## See https://issues.apache.org/jira/browse/SVN-3020. ##
 
   sbox.build(empty=True)
 
@@ -1326,7 +1349,7 @@ def verify_with_invalid_revprops(sbox):
 #   2) Dump 'SOURCE-REPOS' in a series of incremental dumps and load
 #      each of them to 'TARGET-REPOS'.
 #
-# See http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc13
+# See https://issues.apache.org/jira/browse/SVN-3020#desc13
 @Issue(3020)
 def dont_drop_valid_mergeinfo_during_incremental_loads(sbox):
   "don't filter mergeinfo revs from incremental dump"
@@ -1512,7 +1535,7 @@ def dont_drop_valid_mergeinfo_during_inc
 
   # Check the resulting mergeinfo.  We expect the exact same results
   # as Part 3.
-  # See http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16.
+  # See https://issues.apache.org/jira/browse/SVN-3020#desc16.
   svntest.actions.run_and_verify_svn(expected_output, [],
                                      'propget', 'svn:mergeinfo', '-R',
                                      sbox.repo_url)
@@ -1523,7 +1546,7 @@ def dont_drop_valid_mergeinfo_during_inc
 def hotcopy_symlink(sbox):
   "'svnadmin hotcopy' replicates symlink"
 
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2591. ##
+  ## See https://issues.apache.org/jira/browse/SVN-2591. ##
 
   # Create a repository.
   sbox.build(create_wc=False, empty=True)
@@ -1629,9 +1652,9 @@ text
   sbox.build(empty=True)
 
   # Try to load the dumpstream, expecting a failure (because of mixed EOLs).
-  exp_err = svntest.verify.RegexListOutput(['svnadmin: E125005',
-                                            'svnadmin: E125005',
-                                            'svnadmin: E125017'],
+  exp_err = svntest.verify.RegexListOutput(['svnadmin: E125005:.*',
+                                            'svnadmin: E125005:.*',
+                                            'svnadmin: E125017:.*'],
                                            match_all=False)
   load_and_verify_dumpstream(sbox, [], exp_err, dumpfile_revisions,
                              False, dump_str, '--ignore-uuid')
@@ -1760,10 +1783,10 @@ def test_lslocks_and_rmlocks(sbox):
   def expected_output_list(path):
     return [
       "Path: " + path,
-      "UUID Token: opaquelocktoken",
+      "UUID Token: opaquelocktoken:.*",
       "Owner: jrandom",
-      "Created:",
-      "Expires:",
+      "Created:.*",
+      "Expires:.*",
       "Comment \(1 line\):",
       "Locking files",
       "\n", # empty line
@@ -1814,7 +1837,7 @@ def test_lslocks_and_rmlocks(sbox):
 def load_ranges(sbox):
   "'svnadmin load --revision X:Y'"
 
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3734. ##
+  ## See https://issues.apache.org/jira/browse/SVN-3734. ##
   sbox.build(empty=True)
 
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
@@ -2165,7 +2188,7 @@ def verify_keep_going(sbox):
                                                         sbox.repo_dir)
 
   if (svntest.main.is_fs_log_addressing()):
-    exp_out = svntest.verify.RegexListOutput([".*Verifying metadata at revision 0"])
+    exp_out = svntest.verify.RegexListOutput([".*Verifying metadata at revision \
0.*"])  else:
     exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.",
                                               ".*Verified revision 1."])
@@ -2856,10 +2879,7 @@ def verify_quickly(sbox):
   "verify quickly using metadata"
 
   sbox.build(create_wc = False)
-  if svntest.main.is_fs_type_fsfs():
-    rev_file = open(fsfs_file(sbox.repo_dir, 'revs', '1'), 'r+b')
-  else:
-    rev_file = open(fsfs_file(sbox.repo_dir, 'revs', 'r1'), 'r+b')
+  rev_file = open(fsfs_file(sbox.repo_dir, 'revs', '1'), 'r+b')
 
   # set new contents
   rev_file.seek(8)
@@ -3458,7 +3478,8 @@ def load_from_file(sbox):
   sbox.build(empty=True)
 
   file = sbox.get_tempname()
-  open(file, 'wb').writelines(clean_dumpfile())
+  with open(file, 'wb') as f:
+    f.writelines(clean_dumpfile())
   svntest.actions.run_and_verify_svnadmin2(None, [],
                                            0, 'load', '--file', file,
                                            '--ignore-uuid', sbox.repo_dir)
@@ -3762,7 +3783,7 @@ def dump_exclude_all_rev_changes(sbox):
   # Check log. Revision properties ('svn:log' etc.) should be empty for r2.
   expected_output = svntest.verify.RegexListOutput([
     '-+\\n',
-    'r3\ |\ jrandom\ |\ .*\ |\ 1\ line\\n',
+    'r3 | jrandom | .* | 1 line\\n',
     re.escape('Changed paths:'),
     re.escape('   A /r3a'),
     re.escape('   A /r3b'),
@@ -3774,7 +3795,7 @@ def dump_exclude_all_rev_changes(sbox):
     '',
     '',
     '-+\\n',
-    'r1\ |\ jrandom\ |\ .*\ |\ 1\ line\\n',
+    'r1 | jrandom | .* | 1 line\\n',
     re.escape('Changed paths:'),
     re.escape('   A /r1a'),
     re.escape('   A /r1b'),
@@ -3801,6 +3822,104 @@ def dump_invalid_filtering_option(sbox):
                                           '--include', '/A/B/E',
                                           sbox.repo_dir)
 
+@Issue(4725)
+def load_issue4725(sbox):
+  """load that triggers issue 4725"""
+
+  sbox.build(empty=True)
+
+  sbox.simple_mkdir('subversion')
+  sbox.simple_commit()
+  sbox.simple_mkdir('subversion/trunk')
+  sbox.simple_mkdir('subversion/branches')
+  sbox.simple_commit()
+  sbox.simple_mkdir('subversion/trunk/src')
+  sbox.simple_commit()
+
+  _, dump, _ = svntest.actions.run_and_verify_svnadmin(None, [],
+                                                       'dump', '-q',
+                                                       sbox.repo_dir)
+
+  sbox2 = sbox.clone_dependent()
+  sbox2.build(create_wc=False, empty=True)
+  load_and_verify_dumpstream(sbox2, None, [], None, False, dump, '-M100')
+
+@Issue(4767)
+def dump_no_canonicalize_svndate(sbox):
+  "svnadmin dump shouldn't canonicalize svn:date"
+
+  sbox.build(create_wc=False, empty=True)
+  svntest.actions.enable_revprop_changes(sbox.repo_dir)
+
+  # set svn:date in a non-canonical format (not six decimal places)
+  propval = "2015-01-01T00:00:00.0Z"
+  svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [],
+                                     "propset", "--revprop", "-r0", "svn:date",
+                                     propval,
+                                     sbox.repo_url)
+
+  dump_lines = svntest.actions.run_and_verify_dump(sbox.repo_dir)
+  assert propval + '\n' in dump_lines
+
+def check_recover_prunes_rep_cache(sbox, enable_rep_sharing):
+  """Check 'recover' prunes the rep-cache while enable-rep-sharing is
+     true/false.
+  """
+  # Remember the initial rep cache content.
+  rep_cache_r1 = read_rep_cache(sbox.repo_dir)
+  #print '\n'.join([h + ": " + repr(ref) for h, ref in rep_cache_r1.items()])
+
+  # Commit one new rep and check the rep-cache is extended.
+  sbox.simple_append('iota', 'New line.\n')
+  sbox.simple_commit()
+  rep_cache_r2 = read_rep_cache(sbox.repo_dir)
+  if not (len(rep_cache_r2) == len(rep_cache_r1) + 1):
+    raise svntest.Failure
+
+  fsfs_conf = svntest.main.get_fsfs_conf_file_path(sbox.repo_dir)
+  svntest.main.file_append(fsfs_conf,
+                           # Add a newline in case the existing file doesn't
+                           # end with one.
+                           "\n"
+                           "[rep-sharing]\n"
+                           "enable-rep-sharing = %s\n"
+                           % (('true' if enable_rep_sharing else 'false'),))
+
+  # Break r2 in such a way that 'recover' will discard it
+  head_rev_path = fsfs_file(sbox.repo_dir, 'revs', '2')
+  os.remove(head_rev_path)
+  current_path = os.path.join(sbox.repo_dir, 'db', 'current')
+  svntest.main.file_write(current_path, '1\n')
+
+  # Recover back to r1.
+  svntest.actions.run_and_verify_svnadmin(None, [],
+                                          "recover", sbox.repo_dir)
+  svntest.actions.run_and_verify_svnlook(['1\n'], [], 'youngest',
+                                         sbox.repo_dir)
+
+  # Check the rep-cache is pruned.
+  rep_cache_recovered = read_rep_cache(sbox.repo_dir)
+  if not (rep_cache_recovered == rep_cache_r1):
+    raise svntest.Failure
+
+@Issue(4077)
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+@SkipUnless(svntest.main.python_sqlite_can_read_without_rowid)
+def recover_prunes_rep_cache_when_enabled(sbox):
+  "recover prunes rep cache when enabled"
+  sbox.build()
+
+  check_recover_prunes_rep_cache(sbox, enable_rep_sharing=True)
+
+@Issue(4077)
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+@SkipUnless(svntest.main.python_sqlite_can_read_without_rowid)
+def recover_prunes_rep_cache_when_disabled(sbox):
+  "recover prunes rep cache when disabled"
+  sbox.build()
+
+  check_recover_prunes_rep_cache(sbox, enable_rep_sharing=False)
+
 ########################################################################
 # Run the tests
 
@@ -3873,7 +3992,11 @@ test_list = [ None,
               dump_exclude_by_pattern,
               dump_include_by_pattern,
               dump_exclude_all_rev_changes,
-              dump_invalid_filtering_option
+              dump_invalid_filtering_option,
+              load_issue4725,
+              dump_no_canonicalize_svndate,
+              recover_prunes_rep_cache_when_enabled,
+              recover_prunes_rep_cache_when_disabled,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/svnauthz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/svnauthz_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/svnauthz_tests.py \
                (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/svnauthz_tests.py Wed Nov \
28 21:25:32 2018 @@ -197,9 +197,8 @@ def svnauthz_validate_txn_test(sbox):
   svntest.main.create_python_hook_script(pre_commit_hook, hook_instance)
   svntest.main.file_append(authz_path, 'x')
   expected_status.tweak('A/authz', status='  ', wc_rev=4)
-  if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
-                                           expected_status):
-    raise svntest.Failure
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status)
   expected_data = svntest.verify.ExpectedOutput("Exit 2\n", match_all=False)
   verify_logfile(logfilepath, expected_data)
 
@@ -275,9 +274,8 @@ def svnauthz_accessof_repo_test(sbox):
   expected_status.add({
     'A/authz'            :  Item(status='  ', wc_rev=2),
   })
-  if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
-                                           expected_status):
-    raise svntest.Failure
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status)
 
   # Anonymous access with no path, and no repository should be rw
   # since it returns the highest level of access granted anywhere.

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/svndumpfilter_tests.py
                
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/svndumpfilter_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/svndumpfilter_tests.py \
                (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/svndumpfilter_tests.py Wed \
Nov 28 21:25:32 2018 @@ -83,7 +83,7 @@ def filter_and_return_output(dump, bufsi
 def reflect_dropped_renumbered_revs(sbox):
   "reflect dropped renumbered revs in svn:mergeinfo"
 
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2982. ##
+  ## See https://issues.apache.org/jira/browse/SVN-2982. ##
 
   # Test svndumpfilter with include option
   sbox.build(empty=True)
@@ -134,7 +134,7 @@ def svndumpfilter_loses_mergeinfo(sbox):
   "svndumpfilter loses mergeinfo"
   #svndumpfilter loses mergeinfo if invoked without --renumber-revs
 
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3181. ##
+  ## See https://issues.apache.org/jira/browse/SVN-3181. ##
 
   sbox.build(empty=True)
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
@@ -217,7 +217,7 @@ def _simple_dumpfilter_test(sbox, dumpfi
 @Issue(2697)
 def dumpfilter_with_targets(sbox):
   "svndumpfilter --targets blah"
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2697. ##
+  ## See https://issues.apache.org/jira/browse/SVN-2697. ##
 
   sbox.build(empty=True)
 
@@ -677,7 +677,7 @@ def accepts_deltas(sbox):
 @Issue(4234)
 def dumpfilter_targets_expect_leading_slash_prefixes(sbox):
   "dumpfilter targets expect leading '/' in prefixes"
-  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=4234. ##
+  ## See https://issues.apache.org/jira/browse/SVN-4234. ##
 
   sbox.build(empty=True)
 

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/svnfsfs_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/svnfsfs_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/svnfsfs_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/svnfsfs_tests.py Wed Nov 28 \
21:25:32 2018 @@ -94,7 +94,8 @@ def patch_format(repo_dir, shard_size):
 
   new_contents = b"\n".join(processed_lines)
   os.chmod(format_path, svntest.main.S_ALL_RW)
-  open(format_path, 'wb').write(new_contents)
+  with open(format_path, 'wb') as f:
+    f.write(new_contents)
 
 ######################################################################
 # Tests

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/svnmover_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/svnmover_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/svnmover_tests.py \
                (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/svnmover_tests.py Wed Nov \
28 21:25:32 2018 @@ -469,7 +469,7 @@ rm A/B/C/Y
     '   D /top0/A/B/C/Y',
   ]))
   expected_output = svntest.verify.UnorderedRegexListOutput(escaped
-                          + ['^-', '^r2', '^-', '^Changed paths:',])
+                          + ['^--*', '^r2.*', '^--*', '^Changed paths:',])
   svntest.actions.run_and_verify_svn(expected_output, [],
                                      'log', '-qvr2', repo_url)
 
@@ -755,7 +755,7 @@ def simple_moves_within_a_branch(sbox):
                 'mv lib/foo/y2 y2')
   # move and rename, dir with children
   test_svnmover2(sbox, '/trunk',
-                 reported_br_diff('') +
+                 reported_br_diff('trunk') +
                  reported_add('subdir') +
                  reported_move('lib', 'subdir/lib2'),
                 'mkdir subdir',
@@ -765,7 +765,7 @@ def simple_moves_within_a_branch(sbox):
   # moves and renames together
   # (put it all back to how it was, in one commit)
   test_svnmover2(sbox, '/trunk',
-                 reported_br_diff('') +
+                 reported_br_diff('trunk') +
                  reported_move('subdir/lib2/README.txt', 'README') +
                  reported_move('subdir/lib2', 'lib') +
                  reported_move('y2', 'lib/foo/y') +

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/svnmucc_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/svnmucc_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
 ==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/svnmucc_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/svnmucc_tests.py Wed Nov 28 \
21:25:32 2018 @@ -458,7 +458,7 @@ rm A/B/C/Y
     '   D /A/B/C/Y',
   ]))
   expected_output = svntest.verify.UnorderedRegexListOutput(excaped
-                    + ['^-', '^r3', '^-', '^Changed paths:',])
+                    + ['^--*', '^r3.*', '^--*', '^Changed paths:',])
   svntest.actions.run_and_verify_svn(expected_output, [],
                                      'log', '-qvr3', repo_url)
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic