You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/09/05 08:27:00 UTC

svn commit: r1701348 [1/4] - in /subversion/branches/move-tracking-2: ./ build/ build/ac-macros/ build/generator/ subversion/ subversion/bindings/swig/include/ subversion/include/ subversion/include/private/ subversion/libsvn_auth_kwallet/ subversion/l...

Author: julianfoad
Date: Sat Sep  5 06:26:58 2015
New Revision: 1701348

URL: http://svn.apache.org/r1701348
Log:
On the 'move-tracking-2' branch: catch up to trunk@1701347.

Added:
    subversion/branches/move-tracking-2/subversion/tests/cmdline/svnfsfs_tests.py
      - copied unchanged from r1701347, subversion/trunk/subversion/tests/cmdline/svnfsfs_tests.py
Modified:
    subversion/branches/move-tracking-2/   (props changed)
    subversion/branches/move-tracking-2/CHANGES   (contents, props changed)
    subversion/branches/move-tracking-2/build/   (props changed)
    subversion/branches/move-tracking-2/build/ac-macros/swig.m4
    subversion/branches/move-tracking-2/build/generator/gen_vcnet_vcproj.py
    subversion/branches/move-tracking-2/build/run_tests.py
    subversion/branches/move-tracking-2/subversion/   (props changed)
    subversion/branches/move-tracking-2/subversion/bindings/swig/include/svn_types.swg
    subversion/branches/move-tracking-2/subversion/include/private/svn_atomic.h
    subversion/branches/move-tracking-2/subversion/include/private/svn_io_private.h
    subversion/branches/move-tracking-2/subversion/include/private/svn_ra_svn_private.h
    subversion/branches/move-tracking-2/subversion/include/svn_io.h
    subversion/branches/move-tracking-2/subversion/include/svn_ra_svn.h
    subversion/branches/move-tracking-2/subversion/include/svn_repos.h
    subversion/branches/move-tracking-2/subversion/libsvn_auth_kwallet/kwallet.cpp
    subversion/branches/move-tracking-2/subversion/libsvn_client/copy.c
    subversion/branches/move-tracking-2/subversion/libsvn_client/export.c
    subversion/branches/move-tracking-2/subversion/libsvn_client/externals.c
    subversion/branches/move-tracking-2/subversion/libsvn_client/resolved.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs_init.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/index.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/load-index.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/util.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/   (props changed)
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/lock.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/transaction.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/util.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/serf.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/cram.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/cyrus_auth.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/deprecated.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/internal_auth.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/marshal.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/ra_svn.h
    subversion/branches/move-tracking-2/subversion/libsvn_repos/load-fs-vtable.c
    subversion/branches/move-tracking-2/subversion/libsvn_repos/load.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/atomic.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.h
    subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/config_auth.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/deprecated.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/stream.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/subst.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/xml.c
    subversion/branches/move-tracking-2/subversion/libsvn_wc/copy.c
    subversion/branches/move-tracking-2/subversion/libsvn_wc/node.c
    subversion/branches/move-tracking-2/subversion/libsvn_wc/upgrade.c
    subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db_pristine.c
    subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.c
    subversion/branches/move-tracking-2/subversion/svn/svn.c
    subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c
    subversion/branches/move-tracking-2/subversion/svnfsfs/load-index-cmd.c
    subversion/branches/move-tracking-2/subversion/svnfsfs/stats-cmd.c
    subversion/branches/move-tracking-2/subversion/svnserve/cyrus_auth.c
    subversion/branches/move-tracking-2/subversion/svnserve/serve.c
    subversion/branches/move-tracking-2/subversion/tests/cmdline/svnadmin_tests.py
    subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/actions.py
    subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/main.py
    subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c
    subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c
    subversion/branches/move-tracking-2/subversion/tests/libsvn_repos/repos-test.c
    subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/io-test.c
    subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/stream-test.c
    subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/wc-queries-test.c
    subversion/branches/move-tracking-2/tools/   (props changed)
    subversion/branches/move-tracking-2/tools/buildbot/slaves/bb-openbsd/svnbuild.sh
    subversion/branches/move-tracking-2/tools/buildbot/slaves/bb-openbsd/svncheck-bindings.sh
    subversion/branches/move-tracking-2/tools/buildbot/slaves/svn-x64-macosx/   (props changed)
    subversion/branches/move-tracking-2/tools/buildbot/slaves/svn-x64-macosx/setenv.sh
    subversion/branches/move-tracking-2/tools/client-side/bash_completion
    subversion/branches/move-tracking-2/tools/client-side/svn-mergeinfo-normalizer/   (props changed)
    subversion/branches/move-tracking-2/tools/client-side/svn-mergeinfo-normalizer/missing-branches.c
    subversion/branches/move-tracking-2/tools/dev/unix-build/Makefile.svn
    subversion/branches/move-tracking-2/tools/dist/backport.pl
    subversion/branches/move-tracking-2/tools/dist/templates/rc-news.ezt
    subversion/branches/move-tracking-2/tools/dist/templates/rc-release-ann.ezt
    subversion/branches/move-tracking-2/tools/dist/templates/stable-news.ezt
    subversion/branches/move-tracking-2/tools/dist/templates/stable-release-ann.ezt
    subversion/branches/move-tracking-2/win-tests.py   (contents, props changed)

Propchange: subversion/branches/move-tracking-2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Sep  5 06:26:58 2015
@@ -93,4 +93,4 @@
 /subversion/branches/verify-at-commit:1462039-1462408
 /subversion/branches/verify-keep-going:1439280-1546110
 /subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1606692-1697326
+/subversion/trunk:1606692-1701347

Propchange: subversion/branches/move-tracking-2/
------------------------------------------------------------------------------
    tsvn:projectlanguage = 1033

Modified: subversion/branches/move-tracking-2/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/CHANGES?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/CHANGES (original)
+++ subversion/branches/move-tracking-2/CHANGES Sat Sep  5 06:26:58 2015
@@ -1,3 +1,33 @@
+Version 1.9.1
+(02 Sep 2015, from /branches/1.9.x)
+http://svn.apache.org/repos/asf/subversion/tags/1.9.1
+
+ User-visible changes:
+  - Client-side bugfixes:
+    * Fix crash with GPG-agent with non-canonical $HOME (r1691928, issue #4584)
+    * Fix checkout errors with svn+ssh:// on Windows (r1696222, r1696225)
+    * svn: expose expat and zlib versions in svn --version --verbose (r1696387, r1697664)
+    * svn: improve help text for 'svn info --show-item' (r1698106)
+
+  - Server-side bugfixes:
+    * svnserve: fixed minor typo in help text (r1694023)
+    * Enable caching with memcached on Windows (1674626, r1674785)
+    * Fix an error leak in FSFS verification (r1693886)
+    * Fix incomplete membuffer cache initialization (r1695022)
+    * svnfsfs: fix some bugs and inconsistencies in load-index (r1697381 et al.)
+
+  - Client-side and server-side bugfixes:
+    * Fix alignment fault in ra_svn on 32 bit SPARC machines (r1697914)
+
+  - Bindings bugfixes:
+    * Fix memory corruption in copy source SWIG bindings (r1694929)
+
+ Developer-visible changes:
+  * Better configure-time detection of httpd version and authz fix (r1687304 et al.)
+  * Correct a parameter name in svn_repos_get_fs_build_parser5 (r1694194)
+  * Resolve circular library reference in libsvn_fs_x (r1696695)
+  * Fix Unix build on systems without GPG agent (r1694481, r1697824)
+
 Version 1.9.0
 (5 Aug 2015, from /branches/1.9.x)
 http://svn.apache.org/repos/asf/subversion/tags/1.9.0

Propchange: subversion/branches/move-tracking-2/CHANGES
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Sep  5 06:26:58 2015
@@ -86,4 +86,4 @@
 /subversion/branches/verify-at-commit/CHANGES:1462039-1462408
 /subversion/branches/verify-keep-going/CHANGES:1439280-1546110
 /subversion/branches/wc-collate-path/CHANGES:1402685-1480384
-/subversion/trunk/CHANGES:1606692-1695728
+/subversion/trunk/CHANGES:1606692-1701347

Propchange: subversion/branches/move-tracking-2/build/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Sep  5 06:26:58 2015
@@ -82,4 +82,4 @@
 /subversion/branches/verify-at-commit/build:1462039-1462408
 /subversion/branches/verify-keep-going/build:1439280-1546110
 /subversion/branches/wc-collate-path/build:1402685-1480384
-/subversion/trunk/build:1606692-1697326
+/subversion/trunk/build:1606692-1701347

Modified: subversion/branches/move-tracking-2/build/ac-macros/swig.m4
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/build/ac-macros/swig.m4?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/build/ac-macros/swig.m4 (original)
+++ subversion/branches/move-tracking-2/build/ac-macros/swig.m4 Sat Sep  5 06:26:58 2015
@@ -38,7 +38,7 @@ AC_DEFUN(SVN_CHECK_SWIG,
         SVN_FIND_SWIG(no)
       ;;
       "yes")
-        SVN_FIND_SWIG(check)
+        SVN_FIND_SWIG(required)
       ;;
       *)
         SVN_FIND_SWIG($withval)
@@ -56,8 +56,11 @@ AC_DEFUN(SVN_FIND_SWIG,
 
   if test $where = no; then
     SWIG=none
-  elif test $where = check; then
+  elif test $where = required || test $where = check; then
     AC_PATH_PROG(SWIG, swig, none)
+    if test "$SWIG" = "none" && test $where = required; then
+      AC_MSG_ERROR([SWIG required, but not found])
+    fi
   else
     if test -f "$where"; then
       SWIG="$where"

Modified: subversion/branches/move-tracking-2/build/generator/gen_vcnet_vcproj.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/build/generator/gen_vcnet_vcproj.py?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/build/generator/gen_vcnet_vcproj.py (original)
+++ subversion/branches/move-tracking-2/build/generator/gen_vcnet_vcproj.py Sat Sep  5 06:26:58 2015
@@ -217,7 +217,8 @@ class Generator(gen_win.WinGeneratorBase
                               dp.fname)
 
         if isinstance(dp, gen_base.TargetLib) and dp.msvc_delayload \
-           and isinstance(target, gen_base.TargetLinked):
+           and isinstance(target, gen_base.TargetLinked) \
+           and not self.disable_shared:
           delayload = self.get_output_name(dp)
         else:
           delayload = None

Modified: subversion/branches/move-tracking-2/build/run_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/build/run_tests.py?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/build/run_tests.py (original)
+++ subversion/branches/move-tracking-2/build/run_tests.py Sat Sep  5 06:26:58 2015
@@ -44,22 +44,18 @@ and filename of a test program, optional
 separated list of test numbers; the default is to run all the tests in it.
 '''
 
-# A few useful constants
-SVN_VER_MINOR = 10
-
-import os, re, subprocess, sys, imp, threading, traceback, exceptions
+import os, sys
+import re
+import optparse, subprocess, imp, threading, traceback, exceptions
 from datetime import datetime
 
-import getopt
-try:
-  my_getopt = getopt.gnu_getopt
-except AttributeError:
-  my_getopt = getopt.getopt
-
 # Ensure the compiled C tests use a known locale (Python tests set the locale
 # explicitly).
 os.environ['LC_ALL'] = 'C'
 
+# Placeholder for the svntest module
+svntest = None
+
 class TextColors:
   '''Some ANSI terminal constants for output color'''
   ENDC = '\033[0;m'
@@ -121,104 +117,220 @@ class TestHarness:
   '''Test harness for Subversion tests.
   '''
 
-  def __init__(self, abs_srcdir, abs_builddir, logfile, faillogfile,
-               base_url=None, fs_type=None, http_library=None,
-               server_minor_version=None, verbose=None,
-               cleanup=None, enable_sasl=None, parallel=None, config_file=None,
-               fsfs_sharding=None, fsfs_packing=None,
-               list_tests=None, svn_bin=None, mode_filter=None,
-               milestone_filter=None, set_log_level=None, ssl_cert=None,
-               http_proxy=None, http_proxy_username=None,
-               http_proxy_password=None, httpd_version=None,
-               exclusive_wc_locks=None,
-               memcached_server=None, skip_c_tests=None,
-               dump_load_cross_check=None):
+  def __init__(self, abs_srcdir, abs_builddir, logfile, faillogfile, opts):
     '''Construct a TestHarness instance.
 
     ABS_SRCDIR and ABS_BUILDDIR are the source and build directories.
     LOGFILE is the name of the log file. If LOGFILE is None, let tests
     print their output to stdout and stderr, and don't print a summary
     at the end (since there's no log file to analyze).
-    BASE_URL is the base url for DAV tests.
-    FS_TYPE is the FS type for repository creation.
-    HTTP_LIBRARY is the HTTP library for DAV-based communications.
-    SERVER_MINOR_VERSION is the minor version of the server being tested.
-    SVN_BIN is the path where the svn binaries are installed.
-    MODE_FILTER restricts the TestHarness to tests with the expected mode
-    XFail, Skip, Pass, or All tests (default).  MILESTONE_FILTER is a
-    string representation of a valid regular expression pattern; when used
-    in conjunction with LIST_TESTS, the only tests that are listed are
-    those with an associated issue in the tracker which has a target
-    milestone that matches the regex.
-    HTTP_PROXY (hostname:port), HTTP_PROXY_USERNAME and HTTP_PROXY_PASSWORD
-    define the params to run the tests over a proxy server.
+    OPTS are the options that will be sent to the tests.
     '''
+
+    # Canonicalize the test base URL
+    if opts.url is not None and opts.url[-1] == '/':
+      opts.url = opts.url[:-1]
+
+    # Make the configfile path absolute
+    if opts.config_file is not None:
+      opts.config_file = os.path.abspath(opts.config_file)
+
+    # Parse out the FSFS version number
+    if (opts.fs_type is not None
+         and opts.fs_type.startswith('fsfs-v')):
+      opts.fsfs_version = int(opts.fs_type[6:])
+      opts.fs_type = 'fsfs'
+    else:
+      opts.fsfs_version = None
+
     self.srcdir = abs_srcdir
     self.builddir = abs_builddir
     self.logfile = logfile
     self.faillogfile = faillogfile
-    self.base_url = base_url
-    self.fs_type = fs_type
-    self.http_library = http_library
-    self.server_minor_version = server_minor_version
-    # If you change the below condition then change in
-    # ../subversion/tests/cmdline/svntest/main.py too.
-    if server_minor_version is not None:
-      if int(server_minor_version) not in range(3, 1+SVN_VER_MINOR):
-        sys.stderr.write("Test harness only supports server minor versions 3-%d\n"
-                         % SVN_VER_MINOR)
-        sys.exit(1)
-    self.verbose = verbose
-    self.cleanup = cleanup
-    self.enable_sasl = enable_sasl
-    self.parallel = parallel
-    self.fsfs_sharding = fsfs_sharding
-    self.fsfs_packing = fsfs_packing
-    if fsfs_packing is not None and fsfs_sharding is None:
-      raise Exception('--fsfs-packing requires --fsfs-sharding')
-    self.config_file = None
-    if config_file is not None:
-      self.config_file = os.path.abspath(config_file)
-    self.list_tests = list_tests
-    self.milestone_filter = milestone_filter
-    self.set_log_level = set_log_level
-    self.svn_bin = svn_bin
-    self.mode_filter = mode_filter
     self.log = None
-    self.ssl_cert = ssl_cert
-    self.http_proxy = http_proxy
-    self.http_proxy_username = http_proxy_username
-    self.http_proxy_password = http_proxy_password
-    self.httpd_version = httpd_version
-    self.exclusive_wc_locks = exclusive_wc_locks
-    self.memcached_server = memcached_server
+    self.opts = opts
+
     if not sys.stdout.isatty() or sys.platform == 'win32':
       TextColors.disable()
-    self.skip_c_tests = (not not skip_c_tests)
-    self.dump_load_cross_check = (not not dump_load_cross_check)
 
-    # Parse out the FSFS version number
-    if self.fs_type is not None and self.fs_type.startswith('fsfs-v'):
-      self.fsfs_version = int(self.fs_type[6:])
-      self.fs_type = 'fsfs'
-    else:
-      self.fsfs_version = None
+  def _init_c_tests(self):
+    cmdline = [None, None]   # Program name and source dir
+
+    if self.opts.config_file is not None:
+      cmdline.append('--config-file=' + self.opts.config_file)
+    elif self.opts.memcached_server is not None:
+      cmdline.append('--memcached-server=' + self.opts.memcached_server)
+
+    if self.opts.url is not None:
+      subdir = 'subversion/tests/cmdline/svn-test-work'
+      cmdline.append('--repos-url=%s' % self.opts.url +
+                        '/svn-test-work/repositories')
+      cmdline.append('--repos-dir=%s'
+                     % os.path.abspath(
+                         os.path.join(self.builddir,
+                                      subdir, 'repositories')))
+
+      # Enable access for http
+      if self.opts.url.startswith('http'):
+        authzparent = os.path.join(self.builddir, subdir)
+        if not os.path.exists(authzparent):
+          os.makedirs(authzparent);
+        open(os.path.join(authzparent, 'authz'), 'w').write('[/]\n'
+                                                            '* = rw\n')
+
+    # ### Support --repos-template
+    if self.opts.list_tests is not None:
+      cmdline.append('--list')
+    if self.opts.verbose is not None:
+      cmdline.append('--verbose')
+    if self.opts.cleanup is not None:
+      cmdline.append('--cleanup')
+    if self.opts.fs_type is not None:
+      cmdline.append('--fs-type=%s' % self.opts.fs_type)
+    if self.opts.fsfs_version is not None:
+      cmdline.append('--fsfs-version=%d' % self.opts.fsfs_version)
+    if self.opts.server_minor_version is not None:
+      cmdline.append('--server-minor-version=' +
+                     self.opts.server_minor_version)
+    if self.opts.mode_filter is not None:
+      cmdline.append('--mode-filter=' + self.opts.mode_filter)
+    if self.opts.parallel is not None:
+      cmdline.append('--parallel')
+
+    self.c_test_cmdline = cmdline
+
+
+  def _init_py_tests(self, basedir):
+    cmdline = ['--srcdir=%s' % self.srcdir]
+    if self.opts.list_tests is not None:
+      cmdline.append('--list')
+    if self.opts.verbose is not None:
+      cmdline.append('--verbose')
+    if self.opts.cleanup is not None:
+      cmdline.append('--cleanup')
+    if self.opts.parallel is not None:
+      if self.opts.parallel == 1:
+        cmdline.append('--parallel')
+      else:
+        cmdline.append('--parallel-instances=%d' % self.opts.parallel)
+    if self.opts.svn_bin is not None:
+      cmdline.append('--bin=%s', self.opts.svn_bin)
+    if self.opts.url is not None:
+      cmdline.append('--url=%s' % self.opts.url)
+    if self.opts.fs_type is not None:
+      cmdline.append('--fs-type=%s' % self.opts.fs_type)
+    if self.opts.http_library is not None:
+      cmdline.append('--http-library=%s' % self.opts.http_library)
+    if self.opts.fsfs_sharding is not None:
+      cmdline.append('--fsfs-sharding=%d' % self.opts.fsfs_sharding)
+    if self.opts.fsfs_packing is not None:
+      cmdline.append('--fsfs-packing')
+    if self.opts.fsfs_version is not None:
+      cmdline.append('--fsfs-version=%d' % self.opts.fsfs_version)
+    if self.opts.server_minor_version is not None:
+      cmdline.append('--server-minor-version=%d' % self.opts.server_minor_version)
+    if self.opts.dump_load_cross_check is not None:
+      cmdline.append('--dump-load-cross-check')
+    if self.opts.enable_sasl is not None:
+      cmdline.append('--enable-sasl')
+    if self.opts.config_file is not None:
+      cmdline.append('--config-file=%s' % self.opts.config_file)
+    if self.opts.milestone_filter is not None:
+      cmdline.append('--milestone-filter=%s' % self.opts.milestone_filter)
+    if self.opts.mode_filter is not None:
+      cmdline.append('--mode-filter=%s' % self.opts.mode_filter)
+    if self.opts.set_log_level is not None:
+      cmdline.append('--set-log-level=%s' % self.opts.set_log_level)
+    if self.opts.ssl_cert is not None:
+      cmdline.append('--ssl-cert=%s' % self.opts.ssl_cert)
+    if self.opts.http_proxy is not None:
+      cmdline.append('--http-proxy=%s' % self.opts.http_proxy)
+    if self.opts.http_proxy_username is not None:
+      cmdline.append('--http-proxy-username=%s' % self.opts.http_proxy_username)
+    if self.opts.http_proxy_password is not None:
+      cmdline.append('--http-proxy-password=%s' % self.opts.http_proxy_password)
+    if self.opts.httpd_version is not None:
+      cmdline.append('--httpd-version=%s' % self.opts.httpd_version)
+    if self.opts.exclusive_wc_locks is not None:
+      cmdline.append('--exclusive-wc-locks')
+    if self.opts.memcached_server is not None:
+      cmdline.append('--memcached-server=%s' % self.opts.memcached_server)
+
+    # The svntest module is very pedantic about the current working directory
+    old_cwd = os.getcwd()
+    try:
+      os.chdir(basedir)
+      sys.path.insert(0, os.path.abspath(os.path.join(self.srcdir, basedir)))
+
+      global svntest
+      __import__('svntest')
+      __import__('svntest.main')
+      __import__('svntest.testcase')
+      svntest = sys.modules['svntest']
+      svntest.main = sys.modules['svntest.main']
+      svntest.testcase = sys.modules['svntest.testcase']
+
+      if svntest.main.logger is None:
+        import logging
+        svntest.main.logger = logging.getLogger()
+      svntest.main.parse_options(cmdline, optparse.SUPPRESS_USAGE)
+
+      svntest.testcase.TextColors.disable()
+    finally:
+      os.chdir(old_cwd)
 
-  def run(self, list):
-    '''Run all test programs given in LIST. Print a summary of results, if
+  def run(self, testlist):
+    '''Run all test programs given in TESTLIST. Print a summary of results, if
        there is a log file. Return zero iff all test programs passed.'''
     self._open_log('w')
     failed = 0
 
-    # If asked to skip C tests, remove non-Python tests from the list
-    if self.skip_c_tests:
-      def is_py_test(prog):
-        progpath, nums = self._split_nums(prog)
-        return progpath.endswith('.py')
-      list = filter(is_py_test, list)
+    # Filter tests into Python and native groups and prepare arguments
+    # for each group. The resulting list will contain tuples of
+    # (program dir, program name, test numbers), where the test
+    # numbers may be None.
+
+    def split_nums(prog):
+      test_nums = []
+      if '#' in prog:
+        prog, test_nums = prog.split('#')
+        if test_nums:
+          test_nums = test_nums.split(',')
+      return prog, test_nums
+
+    py_basedir = set()
+    py_tests = []
+    c_tests = []
+
+    for prog in testlist:
+      progpath, testnums = split_nums(prog)
+      progdir, progbase = os.path.split(progpath)
+      if progpath.endswith('.py'):
+        py_basedir.add(progdir)
+        py_tests.append((progdir, progbase, testnums))
+      elif not self.opts.skip_c_tests:
+        c_tests.append((progdir, progbase, testnums))
+
+    # Initialize svntest.main.options for Python tests. Load the
+    # svntest.main module from the Python test path.
+    if len(py_tests):
+      if len(py_basedir) > 1:
+        sys.stderr.write('The test harness requires all Python tests'
+                         ' to be in the same directory.')
+        sys.exit(1)
+      self._init_py_tests(list(py_basedir)[0])
+      py_tests.sort(key=lambda x: x[1])
 
-    for cnt, prog in enumerate(list):
-      failed = self._run_test(prog, cnt, len(list)) or failed
+    # Create the common command line for C tests
+    if len(c_tests):
+      self._init_c_tests()
+      c_tests.sort(key=lambda x: x[1])
+
+    # Run the tests
+    testlist = c_tests + py_tests
+    testcount = len(testlist)
+    for count, testcase in enumerate(testlist):
+      failed = self._run_test(testcase, count, testcount) or failed
 
     if self.log is None:
       return failed
@@ -246,26 +358,26 @@ class TestHarness:
         sys.stdout.write('%s\n       [[%s'
                          % (x[:wip], x[wip + len(wimptag):]))
 
-    if self.list_tests:
+    if self.opts.list_tests:
       passed = [x for x in log_lines if x[8:13] == '     ']
     else:
       passed = [x for x in log_lines if x[:6] == 'PASS: ']
 
-    if self.list_tests:
+    if self.opts.list_tests:
       skipped = [x for x in log_lines if x[8:12] == 'SKIP']
     else:
       skipped = [x for x in log_lines if x[:6] == 'SKIP: ']
 
-    if skipped and not self.list_tests:
+    if skipped and not self.opts.list_tests:
       print('At least one test was SKIPPED, checking ' + self.logfile)
       for x in skipped:
         sys.stdout.write(x)
 
-    if self.list_tests:
+    if self.opts.list_tests:
       xfailed = [x for x in log_lines if x[8:13] == 'XFAIL']
     else:
       xfailed = [x for x in log_lines if x[:6] == 'XFAIL:']
-    if xfailed and not self.list_tests:
+    if xfailed and not self.opts.list_tests:
       print('At least one test XFAILED, checking ' + self.logfile)
       for x in xfailed:
         printxfail(x)
@@ -283,19 +395,19 @@ class TestHarness:
         sys.stdout.write(x)
 
     # Print summaries, from least interesting to most interesting.
-    if self.list_tests:
+    if self.opts.list_tests:
       print('Summary of test listing:')
     else:
       print('Summary of test results:')
     if passed:
-      if self.list_tests:
+      if self.opts.list_tests:
         print('  %d test%s are set to PASS'
               % (len(passed), 's'*min(len(passed) - 1, 1)))
       else:
         print('  %d test%s PASSED'
               % (len(passed), 's'*min(len(passed) - 1, 1)))
     if skipped:
-      if self.list_tests:
+      if self.opts.list_tests:
         print('  %d test%s are set as SKIP'
               % (len(skipped), 's'*min(len(skipped) - 1, 1)))
       else:
@@ -304,14 +416,14 @@ class TestHarness:
     if xfailed:
       passwimp = [x for x in xfailed if 0 <= x.find(wimptag)]
       if passwimp:
-        if self.list_tests:
+        if self.opts.list_tests:
           print('  %d test%s are set to XFAIL (%d WORK-IN-PROGRESS)'
                 % (len(xfailed), 's'*min(len(xfailed) - 1, 1), len(passwimp)))
         else:
           print('  %d test%s XFAILED (%d WORK-IN-PROGRESS)'
                 % (len(xfailed), 's'*min(len(xfailed) - 1, 1), len(passwimp)))
       else:
-        if self.list_tests:
+        if self.opts.list_tests:
           print('  %d test%s are set as XFAIL'
                 % (len(xfailed), 's'*min(len(xfailed) - 1, 1)))
         else:
@@ -371,65 +483,21 @@ class TestHarness:
       self.log.close()
       self.log = None
 
-  def _run_c_test(self, prog, test_nums, dot_count):
+  def _run_c_test(self, progabs, progdir, progbase, test_nums, dot_count):
     'Run a c test, escaping parameters as required.'
-    progdir, progbase = os.path.split(prog)
-
-    if self.list_tests and self.milestone_filter:
+    if self.opts.list_tests and self.opts.milestone_filter:
       print 'WARNING: --milestone-filter option does not currently work with C tests'
 
     if not os.access(progbase, os.X_OK):
       print("\nNot an executable file: " + progbase)
       sys.exit(1)
 
-    progname = './' + progbase
-    cmdline = [progname,
-               '--srcdir=' + os.path.join(self.srcdir, progdir)]
-    if self.config_file is not None:
-      cmdline.append('--config-file=' + self.config_file)
-    elif self.memcached_server is not None:
-      cmdline.append('--memcached-server=' + self.memcached_server)
-
-    if self.base_url is not None:
-      subdir = 'subversion/tests/cmdline/svn-test-work'
-
-      cmdline.append('--repos-url=%s' % self.base_url +
-                        '/svn-test-work/repositories')
-      cmdline.append('--repos-dir=%s'
-                     % os.path.abspath(
-                         os.path.join(self.builddir, subdir, 'repositories')))
-
-      # Enable access for http
-      if self.base_url.startswith('http'):
-        authzparent = os.path.join(self.builddir, subdir)
-        if not os.path.exists(authzparent):
-          os.makedirs(authzparent);
-        open(os.path.join(authzparent, 'authz'), 'w').write('[/]\n'
-                                                            '* = rw\n')
-
-    # ### Support --repos-template
-    if self.verbose is not None:
-      cmdline.append('--verbose')
-    if self.cleanup is not None:
-      cmdline.append('--cleanup')
-    if self.fs_type is not None:
-      cmdline.append('--fs-type=' + self.fs_type)
-    if self.fsfs_version is not None:
-      cmdline.append('--fsfs-version=%d' % self.fsfs_version)
-    if self.server_minor_version is not None:
-      cmdline.append('--server-minor-version=' + self.server_minor_version)
-    if self.list_tests is not None:
-      cmdline.append('--list')
-    if self.mode_filter is not None:
-      cmdline.append('--mode-filter=' + self.mode_filter)
-    if self.parallel is not None:
-      cmdline.append('--parallel')
+    cmdline = self.c_test_cmdline[:]
+    cmdline[0] = './' + progbase
+    cmdline[1] = '--srcdir=%s' % os.path.join(self.srcdir, progdir)
 
     if test_nums:
-      test_nums = test_nums.split(',')
       cmdline.extend(test_nums)
-
-    if test_nums:
       total = len(test_nums)
     else:
       total_cmdline = [cmdline[0], '--list']
@@ -477,90 +545,16 @@ class TestHarness:
     prog.wait()
     return prog.returncode
 
-  def _run_py_test(self, prog, test_nums, dot_count):
+  def _run_py_test(self, progabs, progdir, progbase, test_nums, dot_count):
     'Run a python test, passing parameters as needed.'
-    progdir, progbase = os.path.split(prog)
-
-    old_path = sys.path[:]
-    sys.path = [progdir] + sys.path
-
     try:
-      prog_mod = imp.load_module(progbase[:-3], open(prog, 'r'), prog,
+      prog_mod = imp.load_module(progbase[:-3], open(progabs, 'r'), progabs,
                                  ('.py', 'U', imp.PY_SOURCE))
     except:
       print("\nError loading test (details in following traceback): " + progbase)
       traceback.print_exc()
       sys.exit(1)
 
-    import svntest.main
-
-    # set up our options
-    svntest.main.create_default_options()
-    if self.base_url is not None:
-      svntest.main.options.test_area_url = self.base_url
-    if self.enable_sasl is not None:
-      svntest.main.options.enable_sasl = True
-    if self.parallel is not None:
-      try:
-        num_parallel = int(self.parallel)
-      except exceptions.ValueError:
-        num_parallel = svntest.main.default_num_threads
-      if num_parallel > 1:
-        svntest.main.options.parallel = num_parallel
-      else:
-        svntest.main.options.parallel = svntest.main.default_num_threads
-    if self.config_file is not None:
-      svntest.main.options.config_file = self.config_file
-    if self.verbose is not None:
-      svntest.main.options.verbose = True
-    if self.cleanup is not None:
-      svntest.main.options.cleanup = True
-    if self.fs_type is not None:
-      svntest.main.options.fs_type = self.fs_type
-    if self.fsfs_version is not None:
-      svntest.main.options.fsfs_version = self.fsfs_version
-    if self.http_library is not None:
-      svntest.main.options.http_library = self.http_library
-    if self.server_minor_version is not None:
-      svntest.main.options.server_minor_version = int(self.server_minor_version)
-    if self.list_tests is not None:
-      svntest.main.options.list_tests = True
-    if self.milestone_filter is not None:
-      svntest.main.options.milestone_filter = self.milestone_filter
-    if self.set_log_level is not None:
-      # Somehow the logger is not setup correctly from win-tests.py, so
-      # setting the log level would fail. ### Please fix
-      if svntest.main.logger is None:
-        import logging
-        svntest.main.logger = logging.getLogger()
-      svntest.main.logger.setLevel(self.set_log_level)
-    if self.svn_bin is not None:
-      svntest.main.options.svn_bin = self.svn_bin
-    if self.fsfs_sharding is not None:
-      svntest.main.options.fsfs_sharding = int(self.fsfs_sharding)
-    if self.fsfs_packing is not None:
-      svntest.main.options.fsfs_packing = self.fsfs_packing
-    if self.mode_filter is not None:
-      svntest.main.options.mode_filter = self.mode_filter
-    if self.ssl_cert is not None:
-      svntest.main.options.ssl_cert = self.ssl_cert
-    if self.http_proxy is not None:
-      svntest.main.options.http_proxy = self.http_proxy
-    if self.http_proxy_username is not None:
-          svntest.main.options.http_proxy_username = self.http_proxy_username
-    if self.http_proxy_password is not None:
-        svntest.main.options.http_proxy_password = self.http_proxy_password
-    if self.httpd_version is not None:
-        svntest.main.options.httpd_version = self.httpd_version
-    if self.exclusive_wc_locks is not None:
-      svntest.main.options.exclusive_wc_locks = self.exclusive_wc_locks
-    if self.memcached_server is not None:
-      svntest.main.options.memcached_server = self.memcached_server
-    if self.dump_load_cross_check is not None:
-      svntest.main.options.dump_load_cross_check = self.dump_load_cross_check
-
-    svntest.main.options.srcdir = self.srcdir
-
     # setup the output pipes
     if self.log:
       sys.stdout.flush()
@@ -592,31 +586,23 @@ class TestHarness:
     serial_only = hasattr(prog_mod, 'serial_only') and prog_mod.serial_only
 
     # run the tests
-    svntest.testcase.TextColors.disable()
-
-    if self.list_tests:
+    if self.opts.list_tests:
       prog_f = None
     else:
       prog_f = progress_func
 
-    if test_nums:
-      test_selection = [test_nums]
-    else:
-      test_selection = []
-
     try:
       failed = svntest.main.execute_tests(prog_mod.test_list,
                                           serial_only=serial_only,
                                           test_name=progbase,
                                           progress_func=prog_f,
-                                          test_selection=test_selection)
+                                          test_selection=test_nums)
     except svntest.Failure:
       if self.log:
         os.write(old_stdout, '.' * dot_count)
       failed = True
 
     # restore some values
-    sys.path = old_path
     if self.log:
       sys.stdout.flush()
       sys.stderr.flush()
@@ -627,13 +613,7 @@ class TestHarness:
 
     return failed
 
-  def _split_nums(self, prog):
-    test_nums = None
-    if '#' in prog:
-      prog, test_nums = prog.split('#')
-    return prog, test_nums
-
-  def _run_test(self, prog, test_nr, total_tests):
+  def _run_test(self, testcase, test_nr, total_tests):
     "Run a single test. Return the test's exit code."
 
     if self.log:
@@ -641,13 +621,12 @@ class TestHarness:
     else:
       log = sys.stdout
 
-    prog, test_nums = self._split_nums(prog)
-    progdir, progbase = os.path.split(prog)
+    progdir, progbase, test_nums = testcase
     if self.log:
       # Using write here because we don't want even a trailing space
       test_info = '[%s/%d] %s' % (str(test_nr + 1).zfill(len(str(total_tests))),
                                   total_tests, progbase)
-      if self.list_tests:
+      if self.opts.list_tests:
         sys.stdout.write('Listing tests in %s' % (test_info, ))
       else:
         sys.stdout.write('%s' % (test_info, ))
@@ -656,7 +635,7 @@ class TestHarness:
       # ### Hack for --log-to-stdout to work (but not print any dots).
       test_info = ''
 
-    if self.list_tests:
+    if self.opts.list_tests:
       log.write('LISTING: %s\n' % progbase)
     else:
       log.write('START: %s\n' % progbase)
@@ -665,7 +644,7 @@ class TestHarness:
 
     start_time = datetime.now()
 
-    progabs = os.path.abspath(os.path.join(self.srcdir, prog))
+    progabs = os.path.abspath(os.path.join(self.srcdir, progdir, progbase))
     old_cwd = os.getcwd()
     line_length = _get_term_width()
     dots_needed = line_length \
@@ -674,9 +653,10 @@ class TestHarness:
     try:
       os.chdir(progdir)
       if progbase[-3:] == '.py':
-        failed = self._run_py_test(progabs, test_nums, dots_needed)
+        testcase = self._run_py_test
       else:
-        failed = self._run_c_test(prog, test_nums, dots_needed)
+        testcase = self._run_c_test
+      failed = testcase(progabs, progdir, progbase, test_nums, dots_needed)
     except:
       os.chdir(old_cwd)
       raise
@@ -694,7 +674,7 @@ class TestHarness:
       else:
         log.write('FAIL:  %s: Unknown test failure.\n' % progbase)
 
-    if not self.list_tests:
+    if not self.opts.list_tests:
       # Log the elapsed time.
       elapsed_time = str(datetime.now() - start_time)
       log.write('END: %s\n' % progbase)
@@ -705,7 +685,7 @@ class TestHarness:
     # If we are only listing the tests just add a newline, otherwise if
     # we printed a "Running all tests in ..." line, add the test result.
     if self.log:
-      if self.list_tests:
+      if self.opts.list_tests:
         print ''
       else:
         if failed:
@@ -716,113 +696,84 @@ class TestHarness:
     return failed
 
 
+def create_parser():
+  parser = optparse.OptionParser(usage=__doc__);
+
+  parser.add_option('-l', '--list', action='store_true', dest='list_tests',
+                    help='Print test doc strings instead of running them')
+  parser.add_option('-v', '--verbose', action='store_true',
+                    help='Print binary command-lines')
+  parser.add_option('-c', '--cleanup', action='store_true',
+                    help='Clean up after successful tests')
+  parser.add_option('-p', '--parallel', action='store', type='int',
+                    help='Run the tests in parallel')
+  parser.add_option('-u', '--url', action='store',
+                    help='Base url to the repos (e.g. svn://localhost)')
+  parser.add_option('-f', '--fs-type', action='store',
+                    help='Subversion file system type (fsfs(-v[46]), bdb or fsx)')
+  parser.add_option('--http-library', action='store',
+                    help="Make svn use this DAV library (neon or serf)")
+  parser.add_option('--bin', action='store', dest='svn_bin',
+                    help='Use the svn binaries installed in this path')
+  parser.add_option('--fsfs-sharding', action='store', type='int',
+                    help='Default shard size (for fsfs)')
+  parser.add_option('--fsfs-packing', action='store_true',
+                    help="Run 'svnadmin pack' automatically")
+  parser.add_option('--server-minor-version', type='int', action='store',
+                    help="Set the minor version for the server")
+  parser.add_option('--skip-c-tests', '--skip-C-tests', action='store_true',
+                    help="Run only the Python tests")
+  parser.add_option('--dump-load-cross-check', action='store_true',
+                    help="After every test, run a series of dump and load " +
+                         "tests with svnadmin, svnrdump and svndumpfilter " +
+                         " on the testcase repositories to cross-check " +
+                         " dump file compatibility.")
+  parser.add_option('--enable-sasl', action='store_true',
+                    help='Whether to enable SASL authentication')
+  parser.add_option('--config-file', action='store',
+                    help="Configuration file for tests.")
+  parser.add_option('--log-to-stdout', action='store_true',
+                    help='Print test progress to stdout instead of a log file')
+  parser.add_option('--milestone-filter', action='store', dest='milestone_filter',
+                    help='Limit --list to those with target milestone specified')
+  parser.add_option('--mode-filter', action='store', dest='mode_filter',
+                    default='ALL',
+                    help='Limit tests to those with type specified (e.g. XFAIL)')
+  parser.add_option('--set-log-level', action='store',
+                    help="Set log level (numerically or symbolically). " +
+                         "Symbolic levels are: CRITICAL, ERROR, WARNING, " +
+                         "INFO, DEBUG")
+  parser.add_option('--ssl-cert', action='store',
+                    help='Path to SSL server certificate.')
+  parser.add_option('--http-proxy', action='store',
+                    help='Use the HTTP Proxy at hostname:port.')
+  parser.add_option('--http-proxy-username', action='store',
+                    help='Username for the HTTP Proxy.')
+  parser.add_option('--http-proxy-password', action='store',
+                    help='Password for the HTTP Proxy.')
+  parser.add_option('--httpd-version', action='store',
+                    help='Assume HTTPD is this version.')
+  parser.add_option('--exclusive-wc-locks', action='store_true',
+                    help='Use sqlite exclusive locking for working copies')
+  parser.add_option('--memcached-server', action='store',
+                    help='Use memcached server at specified URL (FSFS only)')
+  return parser
+
 def main():
-  try:
-    opts, args = my_getopt(sys.argv[1:], 'u:f:vc',
-                           ['url=', 'fs-type=', 'verbose', 'cleanup',
-                            'skip-c-tests', 'skip-C-tests',
-                            'dump-load-cross-check',
-                            'http-library=', 'server-minor-version=',
-                            'fsfs-packing', 'fsfs-sharding=',
-                            'enable-sasl', 'parallel=', 'config-file=',
-                            'log-to-stdout', 'list', 'milestone-filter=',
-                            'mode-filter=', 'set-log-level=', 'ssl-cert=',
-                            'http-proxy=', 'http-proxy-username=',
-                            'http-proxy-password=', 'httpd-version=',
-                            'exclusive-wc-locks',
-                            'memcached-server='])
-  except getopt.GetoptError:
-    args = []
+  (opts, args) = create_parser().parse_args(sys.argv[1:])
 
   if len(args) < 3:
     print(__doc__)
     sys.exit(2)
 
-  base_url, fs_type, verbose, cleanup, skip_c_tests, enable_sasl, \
-    http_library, server_minor_version, fsfs_sharding, fsfs_packing, \
-    parallel, config_file, log_to_stdout, list_tests, mode_filter, \
-    milestone_filter, set_log_level, ssl_cert, http_proxy, \
-    http_proxy_username, http_proxy_password, httpd_version, \
-    exclusive_wc_locks, memcached_server, dump_load_cross_check = \
-            None, None, None, None, None, None, None, None, None, None, \
-            None, None, None, None, None, None, None, None, None, None, \
-            None, None, None, None, None
-  for opt, val in opts:
-    if opt in ['-u', '--url']:
-      base_url = val
-    elif opt in ['-f', '--fs-type']:
-      fs_type = val
-    elif opt in ['--http-library']:
-      http_library = val
-    elif opt in ['--fsfs-sharding']:
-      fsfs_sharding = int(val)
-    elif opt in ['--fsfs-packing']:
-      fsfs_packing = 1
-    elif opt in ['--server-minor-version']:
-      server_minor_version = val
-    elif opt in ['-v', '--verbose']:
-      verbose = 1
-    elif opt in ['-c', '--cleanup']:
-      cleanup = 1
-    elif opt in ['--skip-c-tests', '--skip-C-tests']:
-      skip_c_tests = 1
-    elif opt in ['--dump-load-cross-check']:
-      dump_load_cross_check = 1
-    elif opt in ['--enable-sasl']:
-      enable_sasl = 1
-    elif opt in ['--parallel']:
-      parallel = val
-    elif opt in ['--config-file']:
-      config_file = val
-    elif opt in ['--log-to-stdout']:
-      log_to_stdout = 1
-    elif opt in ['--list']:
-      list_tests = 1
-    elif opt in ['--milestone-filter']:
-      milestone_filter = val
-    elif opt in ['--mode-filter']:
-      mode_filter = val
-    elif opt in ['--set-log-level']:
-      set_log_level = val
-    elif opt in ['--ssl-cert']:
-      ssl_cert = val
-    elif opt in ['--http-proxy']:
-      http_proxy = val
-    elif opt in ['--http-proxy-username']:
-      http_proxy_username = val
-    elif opt in ['--http-proxy-password']:
-      http_proxy_password = val
-    elif opt in ['--httpd-version']:
-      httpd_version = val
-    elif opt in ['--exclusive-wc-locks']:
-      exclusive_wc_locks = 1
-    elif opt in ['--memcached-server']:
-      memcached_server = val
-    else:
-      raise getopt.GetoptError
-
-  if log_to_stdout:
+  if opts.log_to_stdout:
     logfile = None
     faillogfile = None
   else:
     logfile = os.path.abspath('tests.log')
     faillogfile = os.path.abspath('fails.log')
 
-  th = TestHarness(args[0], args[1], logfile, faillogfile,
-                   base_url, fs_type, http_library, server_minor_version,
-                   verbose, cleanup, enable_sasl, parallel, config_file,
-                   fsfs_sharding, fsfs_packing, list_tests,
-                   mode_filter=mode_filter, milestone_filter=milestone_filter,
-                   set_log_level=set_log_level, ssl_cert=ssl_cert,
-                   http_proxy=http_proxy,
-                   http_proxy_username=http_proxy_username,
-                   http_proxy_password=http_proxy_password,
-                   httpd_version=httpd_version,
-                   exclusive_wc_locks=exclusive_wc_locks,
-                   memcached_server=memcached_server,
-                   skip_c_tests=skip_c_tests,
-                   dump_load_cross_check=dump_load_cross_check)
-
+  th = TestHarness(args[0], args[1], logfile, faillogfile, opts)
   failed = th.run(args[2:])
   if failed:
     sys.exit(1)

Propchange: subversion/branches/move-tracking-2/subversion/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Sep  5 06:26:58 2015
@@ -82,4 +82,4 @@
 /subversion/branches/verify-at-commit/subversion:1462039-1462408
 /subversion/branches/verify-keep-going/subversion:1439280-1546110
 /subversion/branches/wc-collate-path/subversion:1402685-1480384
-/subversion/trunk/subversion:1606692-1697326
+/subversion/trunk/subversion:1606692-1701347

Modified: subversion/branches/move-tracking-2/subversion/bindings/swig/include/svn_types.swg
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/bindings/swig/include/svn_types.swg?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/bindings/swig/include/svn_types.swg (original)
+++ subversion/branches/move-tracking-2/subversion/bindings/swig/include/svn_types.swg Sat Sep  5 06:26:58 2015
@@ -69,6 +69,15 @@
 #endif
 }
 
+%typemap(in,warning="901:FIXME: Missing old_value_p typemap") const svn_string_t *const *old_value_p {
+#if defined(SWIGRUBY) && SWIG_VERSION <= 0x010329
+  /* Ruby fails to define $symname. */
+  SWIG_exception(SWIG_ValueError, "Function is not implemented yet");
+#else
+  SWIG_exception(SWIG_ValueError, "$symname is not implemented yet");
+#endif
+}
+
 #ifdef SWIGPYTHON
 %typemap(argout) SWIGTYPE **OUTPARAM {
   %append_output(svn_swig_py_new_pointer_obj(*$1, $*1_descriptor,

Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_atomic.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_atomic.h?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_atomic.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_atomic.h Sat Sep  5 06:26:58 2015
@@ -85,15 +85,15 @@ extern "C" {
  * @return an #svn_error_t if the initialization fails.
  * @since New in 1.10
  */
-typedef svn_error_t *(svn_atomic__err_init_func_t)(void *baton,
-                                                   apr_pool_t *pool);
+typedef svn_error_t *(*svn_atomic__err_init_func_t)(void *baton,
+                                                    apr_pool_t *pool);
 
 /**
  * Callback for svn_atomic__init_no_error().
  * @return a string containing an error message if the initialization fails.
  * @since New in 1.10
  */
-typedef const char *(svn_atomic__str_init_func_t)(void *baton);
+typedef const char *(*svn_atomic__str_init_func_t)(void *baton);
 
 /**
  * Call an initialization function in a thread-safe manner.

Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_io_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_io_private.h?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_io_private.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_io_private.h Sat Sep  5 06:26:58 2015
@@ -171,6 +171,26 @@ svn_error_t*
 svn_io__utf8_to_unicode_longpath(const WCHAR **result,
                                  const char *source,
                                  apr_pool_t *result_pool);
+
+/* This Windows-specific function marks the file to be deleted on close using
+   an existing file handle. It can be used to avoid having to reopen the file
+   as part of the delete handling. Return SVN_ERR_UNSUPPORTED_FEATURE if
+   delete on close operation is not supported by OS. */
+svn_error_t *
+svn_io__win_delete_file_on_close(apr_file_t *file,
+                                 const char *path,
+                                 apr_pool_t *pool);
+
+/* This Windows-specific function renames the file using an existing file
+   handle. It can be used to avoid having to reopen the file as part of the
+   rename operation. Return SVN_ERR_UNSUPPORTED_FEATURE if renaming open
+   file is not supported by OS.*/
+svn_error_t *
+svn_io__win_rename_open_file(apr_file_t *file,
+                             const char *from_path,
+                             const char *to_path,
+                             apr_pool_t *pool);
+
 #endif /* WIN32 */
 
 #ifdef __cplusplus

Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_ra_svn_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_ra_svn_private.h?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_ra_svn_private.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_ra_svn_private.h Sat Sep  5 06:26:58 2015
@@ -34,6 +34,99 @@
 extern "C" {
 #endif /* __cplusplus */
 
+/** Memory representation of an on-the-wire data item. */
+typedef struct svn_ra_svn__item_t svn_ra_svn__item_t;
+
+/* A list of svn_ra_svn__item_t objects. */
+typedef struct svn_ra_svn__list_t
+{
+  /* List contents (array).  May be NULL if NELTS is 0. */
+  struct svn_ra_svn__item_t *items;
+
+  /* Number of elements in ITEMS. */
+  int nelts;
+} svn_ra_svn__list_t;
+
+/* List element access macro. */
+#define SVN_RA_SVN__LIST_ITEM(list, idx) (list)->items[idx]
+
+/** Memory representation of an on-the-wire data item. */
+struct svn_ra_svn__item_t
+{
+  /** Variant indicator. */
+  svn_ra_svn_item_kind_t kind;
+
+  /** Variant data. */
+  union {
+    apr_uint64_t number;
+    svn_string_t string;
+    const char *word;
+    svn_ra_svn__list_t list;
+  } u;
+};
+
+/** Command handler, used by svn_ra_svn__handle_commands(). */
+typedef svn_error_t *(*svn_ra_svn__command_handler)(svn_ra_svn_conn_t *conn,
+                                                    apr_pool_t *pool,
+                                                    svn_ra_svn__list_t *params,
+                                                    void *baton);
+
+/** Command table, used by svn_ra_svn_handle_commands().
+ */
+typedef struct svn_ra_svn__cmd_entry_t
+{
+  /** Name of the command */
+  const char *cmdname;
+
+  /** Handler for the command */
+  svn_ra_svn__command_handler handler;
+
+  /** Only set when used through a deprecated API.
+   * HANDLER is NULL in that case. */
+  svn_ra_svn_command_handler deprecated_handler;
+
+  /** Termination flag.  If set, command-handling will cease after
+   * command is processed. */
+  svn_boolean_t terminate;
+} svn_ra_svn__cmd_entry_t;
+
+
+/* Return a deep copy of the SOURCE array containing private API
+ * svn_ra_svn__item_t SOURCE to public API *TARGET, allocating
+ * sub-structures in RESULT_POOL. */
+apr_array_header_t *
+svn_ra_svn__to_public_array(const svn_ra_svn__list_t *source,
+                            apr_pool_t *result_pool);
+
+/* Deep copy contents from private API *SOURCE to public API *TARGET,
+ * allocating sub-structures in RESULT_POOL. */
+void
+svn_ra_svn__to_public_item(svn_ra_svn_item_t *target,
+                           const svn_ra_svn__item_t *source,
+                           apr_pool_t *result_pool);
+
+svn_ra_svn__list_t *
+svn_ra_svn__to_private_array(const apr_array_header_t *source,
+                             apr_pool_t *result_pool);
+
+/* Deep copy contents from public API *SOURCE to private API *TARGET,
+ * allocating sub-structures in RESULT_POOL. */
+void
+svn_ra_svn__to_private_item(svn_ra_svn__item_t *target,
+                            const svn_ra_svn_item_t *source,
+                            apr_pool_t *result_pool);
+
+/** Add the capabilities in @a list to @a conn's capabilities.
+ * @a list contains svn_ra_svn__item_t entries (which should be of type
+ * SVN_RA_SVN_WORD; a malformed data error will result if any are not).
+ *
+ * This is idempotent: if a given capability was already set for
+ * @a conn, it remains set.
+ */
+svn_error_t *
+svn_ra_svn__set_capabilities(svn_ra_svn_conn_t *conn,
+                             const svn_ra_svn__list_t *list);
+
 
 /**
  * Set the shim callbacks to be used by @a conn to @a shim_callbacks.
@@ -175,7 +268,7 @@ svn_ra_svn__write_tuple(svn_ra_svn_conn_
 svn_error_t *
 svn_ra_svn__read_item(svn_ra_svn_conn_t *conn,
                       apr_pool_t *pool,
-                      svn_ra_svn_item_t **item);
+                      svn_ra_svn__item_t **item);
 
 /** Scan data on @a conn until we find something which looks like the
  * beginning of an svn server greeting (an open paren followed by a
@@ -226,7 +319,7 @@ svn_ra_svn__skip_leading_garbage(svn_ra_
  * 'b' may not appear inside an optional tuple specification; use '3' instead.
  */
 svn_error_t *
-svn_ra_svn__parse_tuple(const apr_array_header_t *list,
+svn_ra_svn__parse_tuple(const svn_ra_svn__list_t *list,
                         apr_pool_t *pool,
                         const char *fmt, ...);
 
@@ -238,13 +331,13 @@ svn_ra_svn__read_tuple(svn_ra_svn_conn_t
                        apr_pool_t *pool,
                        const char *fmt, ...);
 
-/** Parse an array of @c svn_ra_svn_item_t structures as a list of
+/** Parse an array of @c svn_ra_svn__item_t structures as a list of
  * properties, storing the properties in a hash table.
  *
  * @since New in 1.5.
  */
 svn_error_t *
-svn_ra_svn__parse_proplist(const apr_array_header_t *list,
+svn_ra_svn__parse_proplist(const svn_ra_svn__list_t *list,
                            apr_pool_t *pool,
                            apr_hash_t **props);
 
@@ -300,7 +393,7 @@ svn_ra_svn__handle_command(svn_boolean_t
 svn_error_t *
 svn_ra_svn__handle_commands2(svn_ra_svn_conn_t *conn,
                              apr_pool_t *pool,
-                             const svn_ra_svn_cmd_entry_t *commands,
+                             const svn_ra_svn__cmd_entry_t *commands,
                              void *baton,
                              svn_boolean_t error_on_disconnect);
 
@@ -931,7 +1024,7 @@ svn_ra_svn__write_data_log_entry(svn_ra_
  * @see svn_log_changed_path2_t for a description of the output parameters.
  */
 svn_error_t *
-svn_ra_svn__read_data_log_changed_entry(const apr_array_header_t *items,
+svn_ra_svn__read_data_log_changed_entry(const svn_ra_svn__list_t *items,
                                         svn_string_t **cpath,
                                         const char **action,
                                         const char **copy_path,

Modified: subversion/branches/move-tracking-2/subversion/include/svn_io.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_io.h?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_io.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_io.h Sat Sep  5 06:26:58 2015
@@ -1157,6 +1157,18 @@ svn_stream_t *
 svn_stream_from_string(const svn_string_t *str,
                        apr_pool_t *pool);
 
+/** Return a generic read-only stream that forwards data from @a inner but
+ * uses buffering for efficiency.  Allocate the stream in @a result_pool.
+ *
+ * @note The returned stream has no support for writing nor mark and seek
+ * even if @a inner does support those functions.
+ *
+ * @since New in 1.10.
+ */
+svn_stream_t *
+svn_stream_wrap_buffered_read(svn_stream_t *inner,
+                              apr_pool_t *result_pool);
+
 /** Return a generic stream which implements buffered reads and writes.
  *  The stream will preferentially store data in-memory, but may use
  *  disk storage as backup if the amount of data is large.
@@ -2344,9 +2356,26 @@ svn_io_stat(apr_finfo_t *finfo,
  * @a from_path to a new path @a to_path within the same filesystem.
  * In some cases, an existing node at @a to_path will be overwritten.
  *
- * A wrapper for apr_file_rename().  @a from_path and @a to_path are
- * utf8-encoded.
+ * @a from_path and @a to_path are utf8-encoded.  If @a flush_to_disk
+ * is non-zero, do not return until the node has actually been moved on
+ * the disk.
+ *
+ * @note The flush to disk operation can be very expensive on systems
+ * that implement flushing on all IO layers, like Windows. Please use
+ * @a flush_to_disk flag only for critical data.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_io_file_rename2(const char *from_path, const char *to_path,
+                    svn_boolean_t flush_to_disk, apr_pool_t *pool);
+
+/** Similar to svn_io_file_rename2(), but with @a flush_to_disk set
+ * to @c FALSE.
+ *
+ * @deprecated Provided for backward compatibility with the 1.9 API
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_io_file_rename(const char *from_path,
                    const char *to_path,

Modified: subversion/branches/move-tracking-2/subversion/include/svn_ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_ra_svn.h?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_ra_svn.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_ra_svn.h Sat Sep  5 06:26:58 2015
@@ -141,16 +141,21 @@ typedef struct svn_ra_svn_cmd_entry_t
   svn_boolean_t terminate;
 } svn_ra_svn_cmd_entry_t;
 
+/** Data types defined by the svn:// protocol. */
+typedef enum
+{
+  SVN_RA_SVN_NUMBER,
+  SVN_RA_SVN_STRING,
+  SVN_RA_SVN_WORD,
+  SVN_RA_SVN_LIST
+} svn_ra_svn_item_kind_t;
+
 /** Memory representation of an on-the-wire data item. */
 typedef struct svn_ra_svn_item_t
 {
   /** Variant indicator. */
-  enum {
-    SVN_RA_SVN_NUMBER,
-    SVN_RA_SVN_STRING,
-    SVN_RA_SVN_WORD,
-    SVN_RA_SVN_LIST
-  } kind;
+  svn_ra_svn_item_kind_t kind;
+
   /** Variant data. */
   union {
     apr_uint64_t number;

Modified: subversion/branches/move-tracking-2/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_repos.h?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_repos.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_repos.h Sat Sep  5 06:26:58 2015
@@ -3443,6 +3443,9 @@ typedef struct svn_repos_parse_fns3_t
  *     could stop reading entirely after the youngest required rev.
  *
  * @since New in 1.8.
+
+ * @since Starting in 1.10, @a parse_fns may contain #NULL pointers for
+ * those callbacks that the caller is not interested in.
  */
 svn_error_t *
 svn_repos_parse_dumpstream3(svn_stream_t *stream,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_auth_kwallet/kwallet.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_auth_kwallet/kwallet.cpp?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_auth_kwallet/kwallet.cpp (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_auth_kwallet/kwallet.cpp Sat Sep  5 06:26:58 2015
@@ -47,6 +47,7 @@
 #include "svn_auth.h"
 #include "svn_config.h"
 #include "svn_error.h"
+#include "svn_hash.h"
 #include "svn_io.h"
 #include "svn_pools.h"
 #include "svn_string.h"
@@ -135,34 +136,36 @@ get_wid(void)
   return wid;
 }
 
+/* Forward definition */
+static apr_status_t
+kwallet_terminate(void *data);
+
 static KWallet::Wallet *
 get_wallet(QString wallet_name,
            apr_hash_t *parameters)
 {
   KWallet::Wallet *wallet =
-    static_cast<KWallet::Wallet *> (apr_hash_get(parameters,
-                                                 "kwallet-wallet",
-                                                 APR_HASH_KEY_STRING));
-  if (! wallet && ! apr_hash_get(parameters,
-                                 "kwallet-opening-failed",
-                                 APR_HASH_KEY_STRING))
+    static_cast<KWallet::Wallet *> (svn_hash_gets(parameters,
+                                                  "kwallet-wallet"));
+  if (! wallet && ! svn_hash_gets(parameters, "kwallet-opening-failed"))
     {
       wallet = KWallet::Wallet::openWallet(wallet_name, get_wid(),
                                            KWallet::Wallet::Synchronous);
-    }
-  if (wallet)
-    {
-      apr_hash_set(parameters,
-                   "kwallet-wallet",
-                   APR_HASH_KEY_STRING,
-                   wallet);
-    }
-  else
-    {
-      apr_hash_set(parameters,
-                   "kwallet-opening-failed",
-                   APR_HASH_KEY_STRING,
-                   "");
+
+      if (wallet)
+        {
+          svn_hash_sets(parameters, "kwallet-wallet", wallet);
+
+          apr_pool_cleanup_register(apr_hash_pool_get(parameters),
+                                    parameters, kwallet_terminate,
+                                    apr_pool_cleanup_null);
+
+          svn_hash_sets(parameters, "kwallet-initialized", "");
+        }
+      else
+        {
+          svn_hash_sets(parameters, "kwallet-opening-failed", "");
+        }
     }
   return wallet;
 }
@@ -171,14 +174,12 @@ static apr_status_t
 kwallet_terminate(void *data)
 {
   apr_hash_t *parameters = static_cast<apr_hash_t *> (data);
-  if (apr_hash_get(parameters, "kwallet-initialized", APR_HASH_KEY_STRING))
+  if (svn_hash_gets(parameters, "kwallet-initialized"))
     {
       KWallet::Wallet *wallet = get_wallet(NULL, parameters);
       delete wallet;
-      apr_hash_set(parameters,
-                   "kwallet-initialized",
-                   APR_HASH_KEY_STRING,
-                   NULL);
+      svn_hash_sets(parameters, "kwallet-wallet", NULL);
+      svn_hash_sets(parameters, "kwallet-initialized", NULL);
     }
   return APR_SUCCESS;
 }
@@ -236,10 +237,6 @@ kwallet_password_get(svn_boolean_t *done
       KWallet::Wallet *wallet = get_wallet(wallet_name, parameters);
       if (wallet)
         {
-          apr_hash_set(parameters,
-                       "kwallet-initialized",
-                       APR_HASH_KEY_STRING,
-                       "");
           if (wallet->setFolder(folder))
             {
               QString q_password;
@@ -254,9 +251,6 @@ kwallet_password_get(svn_boolean_t *done
         }
     }
 
-  apr_pool_cleanup_register(pool, parameters, kwallet_terminate,
-                            apr_pool_cleanup_null);
-
   return SVN_NO_ERROR;
 }
 
@@ -310,10 +304,6 @@ kwallet_password_set(svn_boolean_t *done
   KWallet::Wallet *wallet = get_wallet(wallet_name, parameters);
   if (wallet)
     {
-      apr_hash_set(parameters,
-                   "kwallet-initialized",
-                   APR_HASH_KEY_STRING,
-                   "");
       if (! wallet->hasFolder(folder))
         {
           wallet->createFolder(folder);
@@ -329,9 +319,6 @@ kwallet_password_set(svn_boolean_t *done
         }
     }
 
-  apr_pool_cleanup_register(pool, parameters, kwallet_terminate,
-                            apr_pool_cleanup_null);
-
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_client/copy.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_client/copy.c Sat Sep  5 06:26:58 2015
@@ -2433,7 +2433,7 @@ repos_to_wc_copy_single(svn_boolean_t *t
                                                        pool));
 
           /* Move the temporary disk tree into place. */
-          SVN_ERR(svn_io_file_rename(tmp_abspath, dst_abspath, pool));
+          SVN_ERR(svn_io_file_rename2(tmp_abspath, dst_abspath, FALSE, pool));
         }
       else
         {
@@ -2562,7 +2562,7 @@ repos_to_wc_copy_single(svn_boolean_t *t
 static svn_error_t *
 repos_to_wc_copy_locked(svn_boolean_t *timestamp_sleep,
                         const apr_array_header_t *copy_pairs,
-                        const char *top_dst_path,
+                        const char *top_dst_abspath,
                         svn_boolean_t ignore_externals,
                         svn_boolean_t pin_externals,
                         const apr_hash_t *externals_to_pin,
@@ -2582,39 +2582,25 @@ repos_to_wc_copy_locked(svn_boolean_t *t
 
   /* Decide whether the two repositories are the same or not. */
   {
-    svn_error_t *src_err, *dst_err;
-    const char *parent;
     const char *parent_abspath;
     const char *src_uuid, *dst_uuid;
 
     /* Get the repository uuid of SRC_URL */
-    src_err = svn_ra_get_uuid2(ra_session, &src_uuid, iterpool);
-    if (src_err && src_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)
-      return svn_error_trace(src_err);
+    SVN_ERR(svn_ra_get_uuid2(ra_session, &src_uuid, iterpool));
 
     /* Get repository uuid of dst's parent directory, since dst may
        not exist.  ### TODO:  we should probably walk up the wc here,
        in case the parent dir has an imaginary URL.  */
     if (copy_pairs->nelts == 1)
-      parent = svn_dirent_dirname(top_dst_path, scratch_pool);
+      parent_abspath = svn_dirent_dirname(top_dst_abspath, scratch_pool);
     else
-      parent = top_dst_path;
+      parent_abspath = top_dst_abspath;
 
-    SVN_ERR(svn_dirent_get_absolute(&parent_abspath, parent, scratch_pool));
-    dst_err = svn_client_get_repos_root(NULL /* root_url */, &dst_uuid,
-                                        parent_abspath, ctx,
-                                        iterpool, iterpool);
-    if (dst_err && dst_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)
-      return dst_err;
-
-    /* If either of the UUIDs are nonexistent, then at least one of
-       the repositories must be very old.  Rather than punish the
-       user, just assume the repositories are different, so no
-       copy-history is attempted. */
-    if (src_err || dst_err || (! src_uuid) || (! dst_uuid))
-      same_repositories = FALSE;
-    else
-      same_repositories = (strcmp(src_uuid, dst_uuid) == 0);
+    SVN_ERR(svn_client_get_repos_root(NULL /* root_url */, &dst_uuid,
+                                      parent_abspath, ctx,
+                                      iterpool, iterpool));
+    /* ### Also check repos_root_url? */
+    same_repositories = (strcmp(src_uuid, dst_uuid) == 0);
   }
 
   /* Perform the move for each of the copy_pairs. */
@@ -2650,7 +2636,7 @@ repos_to_wc_copy(svn_boolean_t *timestam
                  apr_pool_t *pool)
 {
   svn_ra_session_t *ra_session;
-  const char *top_src_url, *top_dst_path;
+  const char *top_src_url, *top_dst_abspath;
   apr_pool_t *iterpool = svn_pool_create(pool);
   const char *lock_abspath;
   int i;
@@ -2675,13 +2661,13 @@ repos_to_wc_copy(svn_boolean_t *timestam
       pair->src_abspath_or_url = apr_pstrdup(pool, src);
     }
 
-  SVN_ERR(get_copy_pair_ancestors(copy_pairs, &top_src_url, &top_dst_path,
+  SVN_ERR(get_copy_pair_ancestors(copy_pairs, &top_src_url, &top_dst_abspath,
                                   NULL, pool));
-  lock_abspath = top_dst_path;
+  lock_abspath = top_dst_abspath;
   if (copy_pairs->nelts == 1)
     {
       top_src_url = svn_uri_dirname(top_src_url, pool);
-      lock_abspath = svn_dirent_dirname(top_dst_path, pool);
+      lock_abspath = svn_dirent_dirname(top_dst_abspath, pool);
     }
 
   /* Open a repository session to the longest common src ancestor.  We do not
@@ -2753,7 +2739,7 @@ repos_to_wc_copy(svn_boolean_t *timestam
 
   SVN_WC__CALL_WITH_WRITE_LOCK(
     repos_to_wc_copy_locked(timestamp_sleep,
-                            copy_pairs, top_dst_path, ignore_externals,
+                            copy_pairs, top_dst_abspath, ignore_externals,
                             pin_externals, externals_to_pin,
                             ra_session, ctx, pool),
     ctx->wc_ctx, lock_abspath, FALSE, pool);

Modified: subversion/branches/move-tracking-2/subversion/libsvn_client/export.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_client/export.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_client/export.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_client/export.c Sat Sep  5 06:26:58 2015
@@ -432,7 +432,7 @@ export_node(void *baton,
                                                              scratch_pool));
 
   /* Now that dst_tmp contains the translated data, do the atomic rename. */
-  SVN_ERR(svn_io_file_rename(dst_tmp, to_abspath, scratch_pool));
+  SVN_ERR(svn_io_file_rename2(dst_tmp, to_abspath, FALSE, scratch_pool));
 
   if (eib->notify_func)
     {
@@ -816,7 +816,7 @@ close_file(void *file_baton,
 
   if ((! fb->eol_style_val) && (! fb->keywords_val) && (! fb->special))
     {
-      SVN_ERR(svn_io_file_rename(fb->tmppath, fb->path, pool));
+      SVN_ERR(svn_io_file_rename2(fb->tmppath, fb->path, FALSE, pool));
     }
   else
     {
@@ -1035,7 +1035,7 @@ add_file_ev2(void *baton,
                                eb->cancel_baton, scratch_pool));
 
       /* Move the file into place. */
-      SVN_ERR(svn_io_file_rename(tmppath, full_path, scratch_pool));
+      SVN_ERR(svn_io_file_rename2(tmppath, full_path, FALSE, scratch_pool));
     }
 
   if (executable_val)

Modified: subversion/branches/move-tracking-2/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_client/externals.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_client/externals.c Sat Sep  5 06:26:58 2015
@@ -120,7 +120,7 @@ relegate_dir_external(svn_wc_context_t *
 
           /* And if it is no longer a working copy, we should just rename
              it */
-          err = svn_io_file_rename(local_abspath, new_path, scratch_pool);
+          err = svn_io_file_rename2(local_abspath, new_path, FALSE, scratch_pool);
         }
 
       /* ### TODO: We should notify the user about the rename */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_client/resolved.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_client/resolved.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_client/resolved.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_client/resolved.c Sat Sep  5 06:26:58 2015
@@ -354,8 +354,7 @@ struct conflict_resolver_baton_t {
   svn_client_conflict_walk_func_t *conflict_walk_func;
   void *conflict_walk_func_baton;
   svn_client_ctx_t *ctx;
-  
-} conflict_walk_baton_t;
+};
 
 /* Implements svn_wc_conflict_resolver_func2_t for now because
  * libsvn_wc does not support our new conflict type yet. */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs_init.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs_init.h?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs_init.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs_init.h Sat Sep  5 06:26:58 2015
@@ -30,4 +30,4 @@ svn_error_t *svn_fs_base__init(const svn
                                fs_library_vtable_t **vtable,
                                apr_pool_t* common_pool);
 
-#endif
\ No newline at end of file
+#endif

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c Sat Sep  5 06:26:58 2015
@@ -2010,7 +2010,7 @@ set_node_origins_for_file(svn_fs_t *fs,
   SVN_ERR(svn_stream_close(stream));
 
   /* Rename the temp file as the real destination */
-  return svn_io_file_rename(path_tmp, node_origins_path, pool);
+  return svn_io_file_rename2(path_tmp, node_origins_path, FALSE, pool);
 }
 
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/index.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/index.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/index.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/index.c Sat Sep  5 06:26:58 2015
@@ -3207,18 +3207,11 @@ svn_fs_fs__l2p_index_from_p2l_entries(co
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   int i;
   svn_revnum_t last_revision = SVN_INVALID_REVNUM;
-  svn_revnum_t revision = SVN_INVALID_REVNUM;
 
   /* L2P index must be written in revision order.
    * Sort ENTRIES accordingly. */
   svn_sort__array(entries, compare_p2l_entry_revision);
 
-  /* Find the first revision in the index
-   * (must exist since no truly empty revs are allowed). */
-  for (i = 0; i < entries->nelts && !SVN_IS_VALID_REVNUM(revision); ++i)
-    revision = APR_ARRAY_IDX(entries, i, const svn_fs_fs__p2l_entry_t *)
-               ->item.revision;
-
   /* Create the temporary proto-rev file. */
   SVN_ERR(svn_io_open_unique_file3(NULL, protoname, NULL,
                                    svn_io_file_del_on_pool_cleanup,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/load-index.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/load-index.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/load-index.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/load-index.c Sat Sep  5 06:26:58 2015
@@ -23,53 +23,152 @@
 #include "svn_pools.h"
 
 #include "private/svn_fs_fs_private.h"
+#include "private/svn_sorts_private.h"
 
 #include "index.h"
 #include "util.h"
 #include "transaction.h"
 
+/* From the ENTRIES array of svn_fs_fs__p2l_entry_t*, sorted by offset,
+ * return the first offset behind the last item. */
+static apr_off_t
+get_max_covered(apr_array_header_t *entries)
+{
+  const svn_fs_fs__p2l_entry_t *entry;
+  if (entries->nelts == 0)
+    return -1;
+
+  entry = APR_ARRAY_IDX(entries, entries->nelts - 1,
+                        const svn_fs_fs__p2l_entry_t *);
+  return entry->offset + entry->size;
+}
+
+/* Make sure that the svn_fs_fs__p2l_entry_t* in ENTRIES are consecutive
+ * and non-overlapping.  Use SCRATCH_POOL for temporaries. */
+static svn_error_t *
+check_all_covered(apr_array_header_t *entries,
+                  apr_pool_t *scratch_pool)
+{
+  int i;
+  apr_off_t expected = 0;
+  for (i = 0; i < entries->nelts; ++i)
+    {
+      const svn_fs_fs__p2l_entry_t *entry
+        = APR_ARRAY_IDX(entries, i, const svn_fs_fs__p2l_entry_t *);
+
+      if (entry->offset < expected)
+        return svn_error_createf(SVN_ERR_INVALID_INPUT, NULL,
+                                 "Overlapping index data for offset %s",
+                                 apr_psprintf(scratch_pool,
+                                              "%" APR_UINT64_T_HEX_FMT,
+                                              (apr_uint64_t)expected));
+
+      if (entry->offset > expected)
+        return svn_error_createf(SVN_ERR_INVALID_INPUT, NULL,
+                                 "Missing index data for offset %s",
+                                 apr_psprintf(scratch_pool,
+                                              "%" APR_UINT64_T_HEX_FMT,
+                                              (apr_uint64_t)expected));
+
+      expected = entry->offset + entry->size;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* A svn_sort__array compatible comparator function, sorting the
+ * svn_fs_fs__p2l_entry_t** given in LHS, RHS by offset. */
+static int
+compare_p2l_entry_revision(const void *lhs,
+                           const void *rhs)
+{
+  const svn_fs_fs__p2l_entry_t *lhs_entry
+    =*(const svn_fs_fs__p2l_entry_t **)lhs;
+  const svn_fs_fs__p2l_entry_t *rhs_entry
+    =*(const svn_fs_fs__p2l_entry_t **)rhs;
+
+  if (lhs_entry->offset < rhs_entry->offset)
+    return -1;
+
+  return lhs_entry->offset == rhs_entry->offset ? 0 : 1;
+}
+
 svn_error_t *
 svn_fs_fs__load_index(svn_fs_t *fs,
                       svn_revnum_t revision,
                       apr_array_header_t *entries,
                       apr_pool_t *scratch_pool)
 {
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  apr_pool_t *subpool = svn_pool_create(scratch_pool);
 
   /* Check the FS format number. */
   if (! svn_fs_fs__use_log_addressing(fs))
     return svn_error_create(SVN_ERR_FS_UNSUPPORTED_FORMAT, NULL, NULL);
 
+  /* P2L index must be written in offset order.
+   * Sort ENTRIES accordingly. */
+  svn_sort__array(entries, compare_p2l_entry_revision);
+
   /* Treat an empty array as a no-op instead error. */
   if (entries->nelts != 0)
     {
       const char *l2p_proto_index;
       const char *p2l_proto_index;
       svn_fs_fs__revision_file_t *rev_file;
+      svn_error_t *err;
+      apr_off_t max_covered = get_max_covered(entries);
+
+      /* Ensure that the index data is complete. */
+      SVN_ERR(check_all_covered(entries, scratch_pool));
 
       /* Open rev / pack file & trim indexes + footer off it. */
       SVN_ERR(svn_fs_fs__open_pack_or_rev_file_writable(&rev_file, fs,
-                                                        revision, iterpool,
-                                                        iterpool));
-      SVN_ERR(svn_fs_fs__auto_read_footer(rev_file));
-      SVN_ERR(svn_io_file_trunc(rev_file->file, rev_file->l2p_offset,
-                                iterpool));
+                                                        revision, subpool,
+                                                        subpool));
+
+      /* Remove the existing index info. */
+      err = svn_fs_fs__auto_read_footer(rev_file);
+      if (err)
+        {
+          /* Even the index footer cannot be read, even less be trusted.
+           * Take the range of valid data from the new index data. */
+          svn_error_clear(err);
+          SVN_ERR(svn_io_file_trunc(rev_file->file, max_covered,
+                                    subpool));
+        }
+      else
+        {
+          /* We assume that the new index data covers all contents.
+           * Error out if it doesn't.  The user can always truncate
+           * the file themselves. */
+          if (max_covered != rev_file->l2p_offset)
+            return svn_error_createf(SVN_ERR_INVALID_INPUT, NULL,
+                       "New index data ends at %s, old index ended at %s",
+                       apr_psprintf(scratch_pool, "%" APR_UINT64_T_HEX_FMT,
+                                    (apr_uint64_t)max_covered),
+                       apr_psprintf(scratch_pool, "%" APR_UINT64_T_HEX_FMT,
+                                    (apr_uint64_t) rev_file->l2p_offset));
+
+          SVN_ERR(svn_io_file_trunc(rev_file->file, rev_file->l2p_offset,
+                                    subpool));
+        }
 
       /* Create proto index files for the new index data
        * (will be cleaned up automatically with iterpool). */
       SVN_ERR(svn_fs_fs__p2l_index_from_p2l_entries(&p2l_proto_index, fs,
                                                     rev_file, entries,
-                                                    iterpool, iterpool));
+                                                    subpool, subpool));
       SVN_ERR(svn_fs_fs__l2p_index_from_p2l_entries(&l2p_proto_index, fs,
-                                                    entries, iterpool,
-                                                    iterpool));
+                                                    entries, subpool,
+                                                    subpool));
 
       /* Combine rev data with new index data. */
       SVN_ERR(svn_fs_fs__add_index_data(fs, rev_file->file, l2p_proto_index,
-                                        p2l_proto_index, revision, iterpool));
+                                        p2l_proto_index,
+                                        rev_file->start_revision, subpool));
     }
 
-  svn_pool_destroy(iterpool);
+  svn_pool_destroy(subpool);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c Sat Sep  5 06:26:58 2015
@@ -230,7 +230,7 @@ write_digest_file(apr_hash_t *children,
     }
 
   SVN_ERR(svn_stream_close(stream));
-  SVN_ERR(svn_io_file_rename(tmp_path, digest_path, pool));
+  SVN_ERR(svn_io_file_rename2(tmp_path, digest_path, FALSE, pool));
   SVN_ERR(svn_io_copy_perms(perms_reference, digest_path, pool));
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c Sat Sep  5 06:26:58 2015
@@ -1167,7 +1167,7 @@ set_txn_proplist(svn_fs_t *fs,
   SVN_ERR(svn_hash_write2(props, tmp_stream, SVN_HASH_TERMINATOR, pool));
   SVN_ERR(svn_stream_close(tmp_stream));
 
-  SVN_ERR(svn_io_file_rename(tmp_path, final_path, pool));
+  SVN_ERR(svn_io_file_rename2(tmp_path, final_path, FALSE, pool));
 
   return SVN_NO_ERROR;
 }