You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2015/11/30 11:24:23 UTC

svn commit: r1717223 [4/50] - in /subversion/branches/ra-git: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/hook-scripts/ notes/ notes/api-errata/1.9/ notes/move-tracking/ subversion/ subversion/bindings/ctypes-python/c...

Modified: subversion/branches/ra-git/build/generator/templates/vcnet_vcxproj.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/build/generator/templates/vcnet_vcxproj.ezt?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/build/generator/templates/vcnet_vcxproj.ezt (original)
+++ subversion/branches/ra-git/build/generator/templates/vcnet_vcxproj.ezt Mon Nov 30 10:24:16 2015
@@ -20,7 +20,7 @@
 ]<?xml version="1.0" encoding="utf-8"?>
 [format "xml"]<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
-[for configs][for platforms]    <ProjectConfiguration Include="[configs.name]|[platforms]">
+[for platforms][for configs]    <ProjectConfiguration Include="[configs.name]|[platforms]">
       <Configuration>[configs.name]</Configuration>
       <Platform>[platforms]</Platform>
     </ProjectConfiguration>
@@ -38,8 +38,10 @@
 [end][end]  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
-[for platforms][for configs]  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='[configs.name]|[platforms]'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+[for platforms][for configs]  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='[configs.name]|[platforms]'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
 [end][end]  <PropertyGroup Label="UserMacros" />
 [for platforms][for configs]  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='[configs.name]|[platforms]'">
@@ -62,13 +64,18 @@
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
       <DisableSpecificWarnings>4100;4127;4206;4512;4701;4706;4800;%(DisableSpecificWarnings)</DisableSpecificWarnings>
-      <TreatSpecificWarningsAsErrors>4002;4003;4013;4020;4022;4024;4028;4029;4030;4031;4033;4047;4089;4113;4115;4204;4715;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>
+      <TreatSpecificWarningsAsErrors>4002;4003;4013;4020;4022;4024;4028;4029;4030;4031;4033;4047;4089;4113;4115;4133;4204;4700;4715;4789;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>
 [if-any configs.forced_include_files]      <ForcedIncludeFiles>[for configs.forced_include_files][configs.forced_include_files];[end]%(ForcedIncludeFiles)</ForcedIncludeFiles>
 [end]    </ClCompile>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>[for configs.includes][configs.includes];[end]%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>SVN_FILE_NAME=[target.output_name];SVN_FILE_DESCRIPTION=[target.desc];[is platforms "x64"]WIN64;[end][for configs.defines][configs.defines];[end]%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
 [is config_type "Application"]    <Link>
       <AdditionalDependencies>[for configs.libs][configs.libs];[end]%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>[for configs.libdirs][configs.libdirs];[end]%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
+      <DelayLoadDLLs>[for depends][if-any depends.delayload][depends.delayload];[end][end]</DelayLoadDLLs>
       <SubSystem>Console</SubSystem>
       <EnableUAC>true</EnableUAC>
       <OptimizeReferences>true</OptimizeReferences>
@@ -79,6 +86,7 @@
       <AdditionalDependencies>[for configs.libs][configs.libs];[end]%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>[for configs.libdirs][configs.libdirs];[end]%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
+      <DelayLoadDLLs>[for depends][if-any depends.delayload][depends.delayload];[end][end]</DelayLoadDLLs>
       <IgnoreSpecificDefaultLibraries>[is configs.name "Debug"]msvcrt.lib[end][is configs.name "Release"]msvcrtd.lib[end]</IgnoreSpecificDefaultLibraries>
 [if-any def_file]      <ModuleDefinitionFile>[def_file]</ModuleDefinitionFile>
 [end]    </Link>
@@ -88,10 +96,7 @@
 [end]    </Lib>
 [end][end][end]  </ItemDefinitionGroup>
 [end][end][if-any target.desc]  <ItemGroup>
-    <ResourceCompile Include="..\svn.rc">
-[for configs][for platforms]      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='[configs.name]|[platforms]'">[for configs.includes][configs.includes];[end]%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='[configs.name]|[platforms]'">SVN_FILE_NAME=[target.output_name];SVN_FILE_DESCRIPTION=[target.desc];[is configs.name "Debug"]_DEBUG[else]NDEBUG[end];%(PreprocessorDefinitions)</PreprocessorDefinitions>
-[end][end]    </ResourceCompile>
+    <ResourceCompile Include="..\svn.rc" />
   </ItemGroup>
 [end]  <ItemGroup>
 [for sources][is sources.extension ".h"][else][is sources.extension ".hpp"][else][if-any sources.custom_build]    <CustomBuild Include="[sources.path]">

Modified: subversion/branches/ra-git/build/generator/templates/vcnet_vcxproj_filters.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/build/generator/templates/vcnet_vcxproj_filters.ezt?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/build/generator/templates/vcnet_vcxproj_filters.ezt (original)
+++ subversion/branches/ra-git/build/generator/templates/vcnet_vcxproj_filters.ezt Mon Nov 30 10:24:16 2015
@@ -1,4 +1,4 @@
-[define COPYRIGHT]
+[#
 <!--
      Licensed to the Apache Software Foundation (ASF) under one
      or more contributor license agreements.  See the NOTICE file
@@ -17,7 +17,7 @@
      specific language governing permissions and limitations
      under the License.
 -->
-[end]<?xml version="1.0" encoding="utf-8"?>
+]<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <Filter Include="Header Files">

Modified: subversion/branches/ra-git/build/run_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/build/run_tests.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/build/run_tests.py (original)
+++ subversion/branches/ra-git/build/run_tests.py Mon Nov 30 10:24:16 2015
@@ -24,7 +24,8 @@
 #
 
 '''usage: python run_tests.py
-            [--verbose] [--log-to-stdout] [--cleanup] [--parallel]
+            [--verbose] [--log-to-stdout] [--cleanup]
+            [--parallel | --parallel=<n>] [--global-scheduler]
             [--url=<base-url>] [--http-library=<http-library>] [--enable-sasl]
             [--fs-type=<fs-type>] [--fsfs-packing] [--fsfs-sharding=<n>]
             [--list] [--milestone-filter=<regex>] [--mode-filter=<type>]
@@ -44,22 +45,26 @@ 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, shutil
+import re
+import logging
+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
+  # Python >=3.0
+  import queue
+except ImportError:
+  # Python <3.0
+  import Queue as queue
 
 # 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'
@@ -81,7 +86,8 @@ def _get_term_width():
   def ioctl_GWINSZ(fd):
     try:
       import fcntl, termios, struct, os
-      cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
+      cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
+                                           struct.pack('hh', 0, 0)))
     except:
       return None
     return cr
@@ -120,107 +126,441 @@ 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'
+  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.set_log_level is not None
+        and self.opts.set_log_level <= logging.DEBUG):
+      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=%d' %
+                     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.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)
+
+    self.py_test_cmdline = cmdline
+
+    # 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']
+
+      svntest.main.parse_options(cmdline, optparse.SUPPRESS_USAGE)
+      svntest.testcase.TextColors.disable()
+    finally:
+      os.chdir(old_cwd)
+
+  class Job:
+    '''A single test or test suite to execute. After execution, the results
+    can be taken from the respective data fields.'''
+
+    def __init__(self, number, is_python, progabs, progdir, progbase):
+      '''number is the test count for C tests and the test nr for Python.'''
+      self.number = number
+      self.is_python = is_python
+      self.progabs = progabs
+      self.progdir = progdir
+      self.progbase = progbase
+      self.result = None
+      self.stdout_lines = []
+      self.stderr_lines = []
+      self.taken = 0
+
+    def test_count(self):
+      if self.is_python:
+        return 1
+      else:
+        return self.number
+
+    def _command_line(self, harness):
+      if self.is_python:
+        cmdline = list(harness.py_test_cmdline)
+        cmdline.insert(0, 'python')
+        cmdline.insert(1, self.progabs)
+        # Run the test apps in "child process" mode,
+        # i.e. w/o cleaning up global directories etc.
+        cmdline.append('-c')
+        cmdline.append(str(self.number))
+      else:
+        cmdline = list(harness.c_test_cmdline)
+        cmdline[0] = self.progabs
+        cmdline[1] = '--srcdir=%s' % os.path.join(harness.srcdir, self.progdir)
+      return cmdline
+
+    def execute(self, harness):
+      start_time = datetime.now()
+      prog = subprocess.Popen(self._command_line(harness),
+                              stdout=subprocess.PIPE,
+                              stderr=subprocess.PIPE,
+                              cwd=self.progdir)
+
+      self.stdout_lines = prog.stdout.readlines()
+      self.stderr_lines = prog.stderr.readlines()
+      prog.wait()
+      self.result = prog.returncode
+      self.taken = datetime.now() - start_time
+
+  class CollectingThread(threading.Thread):
+    '''A thread that lists the individual tests in a given case and creates
+    jobs objects for them.  in  in  test cases in their own processes.
+    Receives test numbers to run from the queue, and saves results into
+    the results field.'''
+    def __init__(self, srcdir, builddir, testcase):
+      threading.Thread.__init__(self)
+      self.srcdir = srcdir
+      self.builddir = builddir
+      self.testcase = testcase
+      self.result = []
+
+    def _count_c_tests(self, progabs, progdir, progbase):
+      'Run a c test, escaping parameters as required.'
+      cmdline = [ progabs, '--list' ]
+      prog = subprocess.Popen(cmdline, stdout=subprocess.PIPE, cwd=progdir)
+      lines = prog.stdout.readlines()
+      self.result.append(TestHarness.Job(len(lines) - 2, False, progabs,
+                                         progdir, progbase))
+      prog.wait()
+
+    def _count_py_tests(self, progabs, progdir, progbase):
+      'Run a c test, escaping parameters as required.'
+      cmdline = [ 'python', progabs, '--list' ]
+      prog = subprocess.Popen(cmdline, stdout=subprocess.PIPE, cwd=progdir)
+      lines = prog.stdout.readlines()
+
+      for i in range(0, len(lines) - 2):
+        self.result.append(TestHarness.Job(i + 1, True, progabs, 
+                                           progdir, progbase))
+      prog.wait()
+
+    def run(self):
+      "Run a single test. Return the test's exit code."
+
+      progdir, progbase, test_nums = self.testcase
+
+      if progbase[-3:] == '.py':
+        progabs = os.path.abspath(os.path.join(self.srcdir, progdir, progbase))
+        self._count_py_tests(progabs, progdir, progbase)
+      else:
+        progabs = os.path.abspath(os.path.join(self.builddir, progdir,
+                                               progbase))
+        self._count_c_tests(progabs, progdir, progbase)
+
+    def get_result(self):
+      return self.result
+
+  class TestSpawningThread(threading.Thread):
+    '''A thread that runs test cases in their own processes.
+    Receives test jobs to run from the queue, and shows some progress
+    indication on stdout.  The detailed test results are stored inside
+    the job objects.'''
+    def __init__(self, queue, harness):
+      threading.Thread.__init__(self)
+      self.queue = queue
+      self.harness = harness
+      self.results = []
+
+    def run(self):
+      while True:
+        try:
+          job = self.queue.get_nowait()
+        except queue.Empty:
+          return
+
+        job.execute(self.harness)
+
+        if job.result:
+          os.write(sys.stdout.fileno(), '!' * job.test_count())
+        else:
+          os.write(sys.stdout.fileno(), '.' * job.test_count())
+
+
+  def _run_global_sheduler(self, testlist, has_py_tests):
+    # Collect all tests to execute (separate jobs for each test in python
+    # test cases, one job for each c test case).  Do that concurrently to
+    # mask latency.  This takes .5s instead of about 3s.
+    threads = [ ]
+    for count, testcase in enumerate(testlist):
+      threads.append(self.CollectingThread(self.srcdir, self.builddir,
+                                           testcase))
+
+    for t in threads:
+      t.start()
+
+    jobs = []
+    for t in threads:
+      t.join()
+      jobs.extend(t.result)
+
+    # Put all jobs into our "todo" queue.
+    # Scramble them for a more even resource utilization.
+    job_queue = queue.Queue()
+    total_count = 0
+    scrambled = list(jobs)
+    scrambled.sort(key=lambda x: x.number)
+    for job in scrambled:
+      total_count += job.test_count()
+      job_queue.put(job)
+
+    # Use the svntest infrastructure to initialize the common test template
+    # wc and repos.
+    if has_py_tests:
+      old_cwd = os.getcwd()
+      os.chdir(jobs[-1].progdir)
+      svntest.main.options.keep_local_tmp = True
+      svntest.main.execute_tests([])
+      os.chdir(old_cwd)
+
+    # Some more prep work
+    if self.log:
+      log = self.log
     else:
-      self.fsfs_version = None
+      log = sys.stdout
+
+    if self.opts.parallel is None:
+      thread_count = 1
+    else:
+      if self.opts.parallel == 1:
+        thread_count = 5
+      else:
+        thread_count = self.opts.parallel
+
+    # Actually run the tests in concurrent sub-processes
+    print('Tests to execute: %d' % total_count)
+
+    threads = [ TestHarness.TestSpawningThread(job_queue, self)
+                for i in range(thread_count) ]
+    for t in threads:
+      t.start()
+    for t in threads:
+      t.join()
+
+    print
+
+    # Aggregate and log the results
+    failed = 0
+    taken = 0
+    last_test_name = ""
+    for job in jobs:
+      if last_test_name != job.progbase:
+        if last_test_name != "":
+          log.write('ELAPSED: %s %s\n' % (last_test_name, str(taken)))
+          log.write('\n')
+        last_test_name = job.progbase
+        taken = job.taken
+      else:
+        taken += job.taken
+
+      log.writelines(job.stderr_lines)
+      for line in job.stdout_lines:
+        self._process_test_output_line(line)
+
+      self._check_for_unknown_failure(log, job.progbase, job.result)
+      failed = job.result or failed
+
+    log.write('ELAPSED: %s %s\n' % (last_test_name, str(taken)))
+    log.write('\n')
 
-  def run(self, list):
-    '''Run all test programs given in LIST. Print a summary of results, if
+    return failed
+
+  def _run_local_schedulers(self, testlist):
+    '''Serial execution of all test suites using their respective internal
+    schedulers.'''
+    testcount = len(testlist)
+
+    failed = 0
+    for count, testcase in enumerate(testlist):
+      failed = self._run_test(testcase, count, testcount) or failed
+
+    return failed
+
+  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)
-
-    for cnt, prog in enumerate(list):
-      failed = self._run_test(prog, cnt, len(list)) or failed
+    # 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])
 
-    if self.log is None:
-      return 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
+    if self.opts.global_scheduler is None:
+      failed = self._run_local_schedulers(testlist)
+    else:
+      failed = self._run_global_sheduler(testlist, len(py_tests) > 0)
 
     # Open the log in binary mode because it can contain binary data
     # from diff_tests.py's testing of svnpatch. This may prevent
@@ -245,26 +585,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)
@@ -282,19 +622,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:
@@ -303,14 +643,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:
@@ -370,63 +710,49 @@ class TestHarness:
       self.log.close()
       self.log = None
 
-  def _run_c_test(self, prog, test_nums, dot_count):
-    'Run a c test, escaping parameters as required.'
-    progdir, progbase = os.path.split(prog)
+  def _process_test_output_line(self, line):
+    if sys.platform == 'win32':
+      # Remove CRs inserted because we parse the output as binary.
+      line = line.replace('\r', '')
 
-    if self.list_tests and self.milestone_filter:
-      print 'WARNING: --milestone-filter option does not currently work with C tests'
+    # If using --log-to-stdout self.log in None.
+    if self.log:
+      self.log.write(line)
 
-    if not os.access(progbase, os.X_OK):
-      print("\nNot an executable file: " + progbase)
-      sys.exit(1)
+    if line.startswith('PASS') or line.startswith('FAIL') \
+        or line.startswith('XFAIL') or line.startswith('XPASS') \
+        or line.startswith('SKIP'):
+      return 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)
+    return 0
 
-    if self.base_url is not None:
-      subdir = 'subversion/tests/cmdline/svn-test-work'
+  def _check_for_unknown_failure(self, log, progbase, test_failed):
+    # We always return 1 for failed tests. Some other failure than 1
+    # probably means the test didn't run at all and probably didn't
+    # output any failure info. In that case, log a generic failure message.
+    # ### Even if failure==1 it could be that the test didn't run at all.
+    if test_failed and test_failed != 1:
+      if self.log:
+        log.write('FAIL:  %s: Unknown test failure; see tests.log.\n' % progbase)
+        log.flush()
+      else:
+        log.write('FAIL:  %s: Unknown test failure.\n' % progbase)
 
-      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')))
+  def _run_c_test(self, progabs, progdir, progbase, test_nums, dot_count):
+    'Run a c test, escaping parameters as required.'
+    if self.opts.list_tests and self.opts.milestone_filter:
+      print 'WARNING: --milestone-filter option does not currently work with C tests'
 
-      # 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')
+    if not os.access(progbase, os.X_OK):
+      print("\nNot an executable file: " + progbase)
+      sys.exit(1)
 
-    # ### 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']
@@ -451,17 +777,7 @@ class TestHarness:
                             stderr=self.log)
     line = prog.stdout.readline()
     while line:
-      if sys.platform == 'win32':
-        # Remove CRs inserted because we parse the output as binary.
-        line = line.replace('\r', '')
-
-      # If using --log-to-stdout self.log in None.
-      if self.log:
-        self.log.write(line)
-
-      if line.startswith('PASS') or line.startswith('FAIL') \
-           or line.startswith('XFAIL') or line.startswith('XPASS') \
-           or line.startswith('SKIP'):
+      if self._process_test_output_line(line):
         tests_completed += 1
         progress_func(tests_completed)
 
@@ -474,90 +790,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()
@@ -589,31 +831,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()
@@ -624,13 +858,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:
@@ -638,13 +866,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, ))
@@ -653,7 +880,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)
@@ -662,7 +889,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 \
@@ -671,27 +898,19 @@ 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
     else:
       os.chdir(old_cwd)
 
-    # We always return 1 for failed tests. Some other failure than 1
-    # probably means the test didn't run at all and probably didn't
-    # output any failure info. In that case, log a generic failure message.
-    # ### Even if failure==1 it could be that the test didn't run at all.
-    if failed and failed != 1:
-      if self.log:
-        log.write('FAIL:  %s: Unknown test failure; see tests.log.\n' % progbase)
-        log.flush()
-      else:
-        log.write('FAIL:  %s: Unknown test failure.\n' % progbase)
+    self._check_for_unknown_failure(log, progbase, failed)
 
-    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)
@@ -702,7 +921,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:
@@ -713,113 +932,95 @@ class TestHarness:
     return failed
 
 
+def create_parser():
+  def set_log_level(option, opt, value, parser, level=None):
+    if level is None:
+      level = value
+    parser.values.set_log_level = getattr(logging, level, None) or int(level)
+
+  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='callback',
+                    callback=set_log_level, callback_args=(logging.DEBUG, ),
+                    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('-g', '--global-scheduler', action='store_true',
+                    help='Run tests from all scripts together')
+  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='callback', type='str',
+                    callback=set_log_level,
+                    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)')
+
+  parser.set_defaults(set_log_level=None)
+  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)

Modified: subversion/branches/ra-git/build/transform_sql.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/build/transform_sql.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/build/transform_sql.py (original)
+++ subversion/branches/ra-git/build/transform_sql.py Mon Nov 30 10:24:16 2015
@@ -31,13 +31,6 @@ import re
 import sys
 
 
-# operator.methodcaller doesn't exist in Python 2.5.
-if not hasattr(operator, 'methodcaller'):
-  def methodcaller(method, *args, **kwargs):
-    return lambda x: getattr(x, method)(*args, **kwargs)
-  operator.methodcaller = methodcaller
-  del methodcaller
-
 DEFINE_END = '  ""\n\n'
 
 

Modified: subversion/branches/ra-git/configure.ac
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/configure.ac?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/configure.ac (original)
+++ subversion/branches/ra-git/configure.ac Mon Nov 30 10:24:16 2015
@@ -1055,7 +1055,7 @@ AS_HELP_STRING([--enable-maintainer-mode
         CFLAGS="$CFLAGS_KEEP"
 
         dnl Add flags that all versions of GCC (should) support
-        CMAINTAINERFLAGS="-Wall -Wpointer-arith -Wwrite-strings -Wshadow -Wformat=2 -Wunused -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wno-multichar -Wredundant-decls -Wnested-externs -Winline -Wno-long-long -Wbad-function-cast $CMAINTAINERFLAGS"
+        CMAINTAINERFLAGS="-Wall -Wpointer-arith -Wwrite-strings -Wshadow -Wformat=2 -Wunused -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wno-multichar -Wredundant-decls -Wnested-externs -Winline -Wno-long-long -Wbad-function-cast $CMAINTAINERFLAGS"
       fi
       if test "$GXX" = "yes"; then
         AC_MSG_NOTICE([maintainer-mode: adding G++ warning flags])
@@ -1276,7 +1276,7 @@ AS_HELP_STRING([--enable-gprof],
 
 PYTHON="`$abs_srcdir/build/find_python.sh`"
 if test -z "$PYTHON"; then
-  AC_MSG_WARN([Python 2.5 or later is required to run the testsuite])
+  AC_MSG_WARN([Python 2.7 or later is required to run the testsuite])
   AC_MSG_WARN([or to use the Subversion Python bindings])
   AC_MSG_WARN([])
   AC_MSG_WARN([If you have a suitable Python installed, but not on the])
@@ -1286,7 +1286,7 @@ fi
 AC_PATH_PROGS(PYTHON, "$PYTHON", none)
 
 # The minimum version for the JVM runtime for our Java bytecode.
-JAVA_OLDEST_WORKING_VER='1.5'
+JAVA_OLDEST_WORKING_VER='1.6'
 # SVN_CHECK_JDK sets $JAVA_CLASSPATH
 SVN_CHECK_JDK($JAVA_OLDEST_WORKING_VER)
 
@@ -1357,6 +1357,19 @@ AS_HELP_STRING([--enable-runtime-module-
       fi
       AC_DEFINE(SVN_USE_DSO, 1,
                 [Defined if svn should try to load DSOs])
+
+      dnl Mac OS X uses libname.MAJOR.SOVERSION.dylib
+      dnl Most other unixes use libname.MAJOR.so.SOVERSION
+      case "$host" in
+        *-*-darwin*)
+          AC_DEFINE(SVN_DSO_SUFFIX_FMT, ["%d.%d.dylib"],
+                    [Shared library file name suffix format])
+          ;;
+        *)
+          AC_DEFINE(SVN_DSO_SUFFIX_FMT, ["%d.so.%d"],
+                    [Shared library file name suffix format])
+          ;;
+      esac
     fi
 ])
 
@@ -1503,7 +1516,7 @@ AC_SUBST(JAVAHL_COMPAT_TESTS_TARGET)
 
 # ==== Miscellaneous bits ====================================================
 
-AC_CHECK_HEADERS([stdbool.h inttypes.h])
+AC_CHECK_HEADERS([stdbool.h stdint.h])
 
 # Strip '-no-cpp-precomp' from CPPFLAGS for the clang compiler
 ### I think we get this flag from APR, so the fix probably belongs there

Modified: subversion/branches/ra-git/contrib/hook-scripts/check-mime-type.pl
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/contrib/hook-scripts/check-mime-type.pl?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/contrib/hook-scripts/check-mime-type.pl (original)
+++ subversion/branches/ra-git/contrib/hook-scripts/check-mime-type.pl Mon Nov 30 10:24:16 2015
@@ -119,17 +119,48 @@ foreach my $path ( @files_added )
 
 		# Parse the complete list of property values of the file $path to extract
 		# the mime-type and eol-style
-		foreach my $prop (&read_from_process($svnlook, 'proplist', $repos, '-t',
-		                  $txn, '--verbose', '--', $path))
+
+		my @output = &read_from_process($svnlook, 'proplist', $repos, '-t',
+					$txn, '--verbose', '--', $path);
+		my $output_line = 0;
+
+		foreach my $prop (@output)
 			{
-				if ($prop =~ /^\s*svn:mime-type : (\S+)/)
+				if ($prop =~ /^\s*svn:mime-type( : (\S+))?/)
 					{
-						$mime_type = $1;
+						$mime_type = $2;
+						# 1.7.8 (r1416637) onwards changed the format of svnloop proplist --verbose
+						# from propname : propvalue format, to values in an indent list on following lines
+						if (not $mime_type)
+							{
+								if ($output_line + 1 >= scalar(@output))
+									{
+										die "$0: Unexpected EOF reading proplist.\n";
+									}
+								my $next_line_pval_indented = $output[$output_line + 1];
+								if ($next_line_pval_indented =~ /^\s{4}(.*)/)
+									{
+										$mime_type = $1;
+									}
+							}
 					}
-				elsif ($prop =~ /^\s*svn:eol-style : (\S+)/)
+				elsif ($prop =~ /^\s*svn:eol-style( : (\S+))?/)
 					{
-						$eol_style = $1;
+						$eol_style = $2;
+						if (not $eol_style)
+							{
+								if ($output_line + 1 >= scalar(@output))
+									{
+										die "$0: Unexpected EOF reading proplist.\n";
+									}
+								my $next_line_pval_indented = $output[$output_line + 1];
+								if ($next_line_pval_indented =~ /^\s{4}(.*)/)
+									{
+										$eol_style = $1;
+									}
+							}
 					}
+				$output_line++;
 			}
 
 		# Detect error conditions and add them to @errors

Modified: subversion/branches/ra-git/gen-make.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/gen-make.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/gen-make.py (original)
+++ subversion/branches/ra-git/gen-make.py Mon Nov 30 10:24:16 2015
@@ -67,6 +67,7 @@ def main(fname, gentype, verfname=None,
   generator.write()
   generator.write_sqlite_headers()
   generator.write_errno_table()
+  generator.write_config_keys()
 
   if ('--debug', '') in other_options:
     for dep_type, target_dict in generator.graph.deps.items():
@@ -205,9 +206,8 @@ def _usage_exit(err=None):
   print("           Use static openssl")
   print("")
   print("  --vsnet-version=VER")
-  print("           generate for VS.NET version VER (2002, 2003, 2005, 2008,")
-  print("           2010, 2012, 2013 or 2015)")
-  print("           [only valid in combination with '-t vcproj']")
+  print("           generate for VS.NET version VER (2005-2015 or 9.0-14.0)")
+  print("           [implies '-t vcproj']")
   print("")
   print(" -D NAME[=value]")
   print("           define NAME macro during compilation")
@@ -303,6 +303,8 @@ if __name__ == '__main__':
       skip = 1
     elif opt == '-t':
       gentype = val
+    elif opt == '--vsnet-version':
+      gentype = 'vcproj'
     else:
       if opt == '--with-httpd':
         rest.add('--with-apr', os.path.join(val, 'srclib', 'apr'),

Propchange: subversion/branches/ra-git/notes/
            ('svn:mergeinfo' removed)

Modified: subversion/branches/ra-git/notes/api-errata/1.9/fs001.txt
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/notes/api-errata/1.9/fs001.txt?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/notes/api-errata/1.9/fs001.txt (original)
+++ subversion/branches/ra-git/notes/api-errata/1.9/fs001.txt Mon Nov 30 10:24:16 2015
@@ -3,9 +3,22 @@ API ERRATA -- $Id$
 Root Cause of Errata: implementation/docstring mismatch
  Library(s) Affected: libsvn_fs_fs, libsvn_fs_base
 Function(s) Affected: svn_fs_props_changed, svn_fs_contents_changed
-     New Behavior in: 1.9
-      Related Issues: n/a
+     New Behavior in: 1.9.0-1.9.2 (only, see note below)
+      Related Issues: 4598
 
+[ Note: This only applies to Subversion 1.9.0-1.9.2; later versions
+        restore the original behavior of svn_fs_props_changed and
+        svn_fs_contents_changed.  The new svn_fs_props_different
+        svn_fs_contents_different functions are available for the
+        API users as well.
+
+        References:
+
+        https://issues.apache.org/jira/browse/SVN-4598
+        https://mail-archives.apache.org/mod_mbox/subversion-dev/201509.mbox/%3CCAB84uBVe8QnEpbPVAb__yQjiDDoYjFn2+M9mPcdBXZCwMCpOLw@mail.gmail.com%3E
+        ("No-op changes no longer dumped by 'svnadmin dump' in 1.9")
+        https://mail-archives.apache.org/mod_mbox/subversion-dev/201302.mbox/%3C510B6AE9.9070106@collab.net%3E
+        ("Re: Reintegrate-like merges and diff_ignore_ancestry") ]
 
 == Details ==
 

Propchange: subversion/branches/ra-git/notes/move-tracking/README
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Nov 30 10:24:16 2015
@@ -1,32 +1,46 @@
 /subversion/branches/1.5.x-r30215/BRANCH-README:870312
+/subversion/branches/1.5.x-r30215/notes/move-tracking/README:870312
 /subversion/branches/1.7.x-fs-verify/BRANCH-README:1146708,1161180
 /subversion/branches/10Gb/BRANCH-README:1388102,1388163-1388190,1388195,1388202,1388205,1388211,1388276,1388362,1388375,1388394,1388636,1388639-1388640,1388643-1388644,1388654,1388720,1388789,1388795,1388801,1388805,1388807,1388810,1388816,1389044,1389276,1389289,1389662,1389867,1390017,1390209,1390216,1390407,1390409,1390414,1390419,1390955
 /subversion/branches/atomic-revprop/BRANCH-README:965046-1000689
 /subversion/branches/authzperf/BRANCH-README:1615360
 /subversion/branches/auto-props-sdc/BRANCH-README:1384106-1401643
 /subversion/branches/bdb-reverse-deltas/BRANCH-README:872050-872529
+/subversion/branches/bdb-reverse-deltas/notes/move-tracking/README:872050-872529
 /subversion/branches/cache-server/BRANCH-README:1458643-1476567
 /subversion/branches/diff-callbacks3/BRANCH-README:870059-870761
+/subversion/branches/diff-callbacks3/notes/move-tracking/README:870059-870761
 /subversion/branches/diff-optimizations/BRANCH-README:1031270-1037352
 /subversion/branches/diff-optimizations-bytes/BRANCH-README:1037353-1067789
 /subversion/branches/dont-save-plaintext-passwords-by-default/BRANCH-README:870728-871118
+/subversion/branches/dont-save-plaintext-passwords-by-default/notes/move-tracking/README:870728-871118
 /subversion/branches/double-delete/BRANCH-README:870511-872970
+/subversion/branches/double-delete/notes/move-tracking/README:870511-872970
 /subversion/branches/dump-load-cross-check/BRANCH-README:1654853-1657295
+/subversion/branches/dump-load-cross-check/notes/move-tracking/README:1654853-1657295
 /subversion/branches/ev2-export/BRANCH-README:1325914,1332738,1413107
 /subversion/branches/explore-wc/BRANCH-README:875486,875493,875497,875507,875511,875514,875559,875580-875581,875584,875587,875611,875627,875647,875667-875668,875711-875712,875733-875734,875736,875744-875748,875751,875758,875782,875795-875796,875830,875836,875838,875842,875852,875855,875864,875870,875873,875880,875885-875888,875890,875897-875898,875905,875907-875909,875935,875943-875944,875946,875979,875982-875983,875985-875986,875990,875997
+/subversion/branches/explore-wc/notes/move-tracking/README:875486,875493,875497,875507,875511,875514,875559,875580-875581,875584,875587,875611,875627,875647,875667-875668,875711-875712,875733-875734,875736,875744-875748,875751,875758,875782,875795-875796,875830,875836,875838,875842,875852,875855,875864,875870,875873,875880,875885-875888,875890,875897-875898,875905,875907-875909,875935,875943-875944,875946,875979,875982-875983,875985-875986,875990,875997
 /subversion/branches/file-externals/BRANCH-README:871779-873302
+/subversion/branches/file-externals/notes/move-tracking/README:871779-873302
 /subversion/branches/fs-rep-sharing/BRANCH-README:869036-873803
+/subversion/branches/fs-rep-sharing/notes/move-tracking/README:869036-873803
 /subversion/branches/fsfs-format7/BRANCH-README:1426304,1430673,1433848,1438408,1438982,1441129,1442051,1442068,1442504,1442910,1443171,1443803,1444690,1444693,1444695,1445040,1445080,1446103,1451129,1453590,1454307,1460579,1461851,1461865,1462837,1462904,1463120,1467362,1467382,1469487,1471208,1477166,1478055,1481447,1489817,1489949,1490673-1490674,1491784,1493042,1498029,1498103,1498155,1500054,1507729-1507731,1507735-1507736
 /subversion/branches/fsfs-improvements/BRANCH-README:1499981-1547039
 /subversion/branches/fsfs-lock-many/BRANCH-README:1571740-1577217
+/subversion/branches/fsfs-lock-many/notes/move-tracking/README:1571740-1577217
 /subversion/branches/fsfs-pack/BRANCH-README:873717-874575
+/subversion/branches/fsfs-pack/notes/move-tracking/README:873717-874575
 /subversion/branches/fsx/BRANCH-README:1507845-1509914
 /subversion/branches/fsx-id/BRANCH-README:1645603-1649011
 /subversion/branches/gnome-keyring/BRANCH-README:870558-871410
+/subversion/branches/gnome-keyring/notes/move-tracking/README:870558-871410
 /subversion/branches/gpg-agent-password-store/BRANCH-README:1005036-1150766
 /subversion/branches/gtest_addition/BRANCH-README:1452117-1502138
 /subversion/branches/http-protocol-v2/BRANCH-README:874395-876041
+/subversion/branches/http-protocol-v2/notes/move-tracking/README:874395-876041
 /subversion/branches/in-memory-cache/BRANCH-README:869829-871452
+/subversion/branches/in-memory-cache/notes/move-tracking/README:869829-871452
 /subversion/branches/in-repo-authz/BRANCH-README:1414342-1424779
 /subversion/branches/inheritable-props/BRANCH-README:1297080-1395089
 /subversion/branches/integrate-cache-item-serialization/BRANCH-README:1068724-1068739
@@ -41,48 +55,75 @@
 /subversion/branches/integrate-txdelta-caching/BRANCH-README:1072541-1078213
 /subversion/branches/issue-2779-dev/BRANCH-README:965496-984198
 /subversion/branches/issue-2843-dev/BRANCH-README:871432-874179
+/subversion/branches/issue-2843-dev/notes/move-tracking/README:871432-874179
 /subversion/branches/issue-3000/BRANCH-README:871713,871716-871719,871721-871726,871728,871734
+/subversion/branches/issue-3000/notes/move-tracking/README:871713,871716-871719,871721-871726,871728,871734
 /subversion/branches/issue-3067-deleted-subtrees/BRANCH-README:873375-874084
+/subversion/branches/issue-3067-deleted-subtrees/notes/move-tracking/README:873375-874084
 /subversion/branches/issue-3148-dev/BRANCH-README:875193-875204
+/subversion/branches/issue-3148-dev/notes/move-tracking/README:875193-875204
 /subversion/branches/issue-3220-dev/BRANCH-README:872210-872226
+/subversion/branches/issue-3220-dev/notes/move-tracking/README:872210-872226
 /subversion/branches/issue-3242-dev/BRANCH-README:879653-896436
+/subversion/branches/issue-3242-dev/notes/move-tracking/README:879653-896436
 /subversion/branches/issue-3334-dirs/BRANCH-README:875156-875867
+/subversion/branches/issue-3334-dirs/notes/move-tracking/README:875156-875867
 /subversion/branches/issue-3975/BRANCH-README:1152931-1160746
 /subversion/branches/issue-4116-dev/BRANCH-README:1424719-1425040
 /subversion/branches/issue-4194-dev/BRANCH-README:1410507-1414880
 /subversion/branches/javahl-ra/BRANCH-README:991978-1494640
 /subversion/branches/kwallet/BRANCH-README:870785-871314
+/subversion/branches/kwallet/notes/move-tracking/README:870785-871314
 /subversion/branches/log-addressing/BRANCH-README:1509279-1546844
 /subversion/branches/log-g-performance/BRANCH-README:870941-871032
+/subversion/branches/log-g-performance/notes/move-tracking/README:870941-871032
 /subversion/branches/merge-skips-obstructions/BRANCH-README:874525-874615
+/subversion/branches/merge-skips-obstructions/notes/move-tracking/README:874525-874615
 /subversion/branches/move-tracking-2/notes/move-tracking/README:1714595-1714632
 /subversion/branches/multi-layer-moves/BRANCH-README:1239019-1300930
 /subversion/branches/nfc-nfd-aware-client/BRANCH-README:870276,870376
+/subversion/branches/nfc-nfd-aware-client/notes/move-tracking/README:870276,870376
 /subversion/branches/node_pool/BRANCH-README:1304828-1305388
 /subversion/branches/performance/BRANCH-README:979193,980118,981087,981090,981189,981194,981287,981684,981827,982043,982355,983398,983406,983430,983474,983488,983490,983760,983764,983766,983770,984927,984973,984984,985014,985037,985046,985472,985477,985482,985487-985488,985493,985497,985500,985514,985601,985603,985606,985669,985673,985695,985697,986453,986465,986485,986491-986492,986517,986521,986605,986608,986817,986832,987865,987868-987869,987872,987886-987888,987893,988319,988898,990330,990533,990535-990537,990541,990568,990572,990574-990575,990600,990759,992899,992904,992911,993127,993141,994956,995478,995507,995603,998012,998858,999098,1001413,1001417,1004291,1022668,1022670,1022676,1022715,1022719,1025660,1025672,1027193,1027203,1027206,1027214,1027227,1028077,1028092,1028094,1028104,1028107,1028111,1028354,1029038,1029042-1029043,1029054-1029055,1029062-1029063,1029078,1029080,1029090,1029092-1029093,1029111,1029151,1029158,1029229-1029230,1029232,1029335-1029336,1029339-1029
 340,1029342,1029344,1030763,1030827,1031203,1031235,1032285,1032333,1033040,1033057,1033294,1035869,1035882,1039511,1043705,1053735,1056015,1066452,1067683,1067697-1078365
 /subversion/branches/pin-externals/BRANCH-README:1643757-1659392
+/subversion/branches/pin-externals/notes/move-tracking/README:1643757-1659392
 /subversion/branches/py-tests-as-modules/BRANCH-README:956579-1033052
 /subversion/branches/ra_serf-digest-authn/BRANCH-README:875693-876404
+/subversion/branches/ra_serf-digest-authn/notes/move-tracking/README:875693-876404
 /subversion/branches/reintegrate-improvements/BRANCH-README:873853-874164
+/subversion/branches/reintegrate-improvements/notes/move-tracking/README:873853-874164
 /subversion/branches/remote-only-status/BRANCH-README:1581845-1586090
 /subversion/branches/revprop-cache/BRANCH-README:1298521-1326293
 /subversion/branches/revprop-caching-ng/BRANCH-README:1620597,1620599
 /subversion/branches/revprop-packing/BRANCH-README:1143907,1143971,1143997,1144017,1144499,1144568,1146145
 /subversion/branches/subtree-mergeinfo/BRANCH-README:876734-878766
+/subversion/branches/subtree-mergeinfo/notes/move-tracking/README:876734-878766
 /subversion/branches/svn-auth-x509/BRANCH-README:1603509-1655900
+/subversion/branches/svn-auth-x509/notes/move-tracking/README:1603509-1655900
 /subversion/branches/svn-info-detail/BRANCH-README:1660035-1662618
 /subversion/branches/svn-mergeinfo-enhancements/BRANCH-README:870119-870195,870197-870288
+/subversion/branches/svn-mergeinfo-enhancements/notes/move-tracking/README:870119-870195,870197-870288
 /subversion/branches/svn-patch-improvements/BRANCH-README:918519-934609
+/subversion/branches/svn-patch-improvements/notes/move-tracking/README:918519-934609
 /subversion/branches/svn_mutex/BRANCH-README:1141683-1182099
 /subversion/branches/svnpatch-diff/BRANCH-README:865738-876477
+/subversion/branches/svnpatch-diff/notes/move-tracking/README:865738-876477
 /subversion/branches/svnraisetc/BRANCH-README:874709-875149
+/subversion/branches/svnraisetc/notes/move-tracking/README:874709-875149
 /subversion/branches/svnserve-logging/BRANCH-README:869828-870893
+/subversion/branches/svnserve-logging/notes/move-tracking/README:869828-870893
 /subversion/branches/tc-issue-3334/BRANCH-README:874697-874773
+/subversion/branches/tc-issue-3334/notes/move-tracking/README:874697-874773
 /subversion/branches/tc-merge-notify/BRANCH-README:874017-874062
+/subversion/branches/tc-merge-notify/notes/move-tracking/README:874017-874062
 /subversion/branches/tc-resolve/BRANCH-README:874191-874239
+/subversion/branches/tc-resolve/notes/move-tracking/README:874191-874239
 /subversion/branches/tc_url_rev/BRANCH-README:874351-874483
+/subversion/branches/tc_url_rev/notes/move-tracking/README:874351-874483
 /subversion/branches/tree-conflicts/BRANCH-README:868291-873154
+/subversion/branches/tree-conflicts/notes/move-tracking/README:868291-873154
 /subversion/branches/tree-conflicts-notify/BRANCH-README:873926-874008
+/subversion/branches/tree-conflicts-notify/notes/move-tracking/README:873926-874008
 /subversion/branches/tristate-chunked-request/BRANCH-README:1502394-1502681
 /subversion/branches/tweak-build-take-two/BRANCH-README:1424288-1425049,1425051-1425613
 /subversion/branches/uris-as-urls/BRANCH-README:1060426-1064427
@@ -90,3 +131,4 @@
 /subversion/branches/verify-keep-going/BRANCH-README:1439280-1546110
 /subversion/branches/wc-collate-path/BRANCH-README:1402685-1480384
 /subversion/trunk/BRANCH-README:1606692-1663280
+/subversion/trunk/notes/move-tracking/README:1583624-1664077,1714640-1717222

Modified: subversion/branches/ra-git/notes/svnsync.txt
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/notes/svnsync.txt?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/notes/svnsync.txt (original)
+++ subversion/branches/ra-git/notes/svnsync.txt Mon Nov 30 10:24:16 2015
@@ -27,14 +27,17 @@ exit 1
 EOF
 $ chmod +x dest/hooks/pre-revprop-change
 
-$ svnsync init --username svnsync file://`pwd`/dest \
-                                  http://svn.example.org/source/repos
+$ svnsync init --sync-username svnsync file://`pwd`/dest \
+               --source-username user  http://svn.example.org/source/repos
 Copied properties for revision 0
 $
 
 Note that the arguments to 'svnsync init' are two arbitrary repository
 URLs.  The first is the destination, which must be empty, and the second
-is the source.
+is the source.  Credentials for the source repository can be provided
+using --source-username/--source-password and for the destination using
+--sync-username/--sync-password.  These credentials are cached in the
+same way other credentials are cached.
 
 Now you can just run the 'svnsync sync' command to synchronize pending
 revisions.  This will copy any revisions that exist in the source repos

Modified: subversion/branches/ra-git/subversion/bindings/ctypes-python/csvn/ext/callback_receiver.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/bindings/ctypes-python/csvn/ext/callback_receiver.py?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/bindings/ctypes-python/csvn/ext/callback_receiver.py (original)
+++ subversion/branches/ra-git/subversion/bindings/ctypes-python/csvn/ext/callback_receiver.py Mon Nov 30 10:24:16 2015
@@ -138,6 +138,7 @@ class _CallbackResultIterator(object):
         finally:
             self.receiver.lock.release()
 
+        # ### TODO: simplify, removing support for Python 2.4
         # Return the first result. Only Python 2.5 supports 'yield'
         # inside a try-finally block, so we jump through some hoops here
         # to avoid that case.

Modified: subversion/branches/ra-git/subversion/bindings/javahl/README
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/bindings/javahl/README?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/bindings/javahl/README (original)
+++ subversion/branches/ra-git/subversion/bindings/javahl/README Mon Nov 30 10:24:16 2015
@@ -5,7 +5,7 @@ JavaHL provides a (mostly native, using
 a high level Java API for Subversion, which was originally targeted for
 implementors of GUI clients and IDE plug-ins for Subversion.  JavaHL
 currently provides a minimal-but-complete set of APIs which expose the
-core Subversion C API to Java.  It requires a JRE 1.5+ (runtime).
+core Subversion C API to Java.  It requires a JRE 1.6+ (runtime).
 
 It is currently quite mature, and can be considered for production use.
 
@@ -13,8 +13,9 @@ It is currently quite mature, and can be
 Build system
 ------------
 
-JavaHL should compile and run under Linux, Win32, and Mac OS X with a
-JDK 1.5+.
+JavaHL should compile and run under Linux, Win32, and Mac OS X with
+JDK 1.6+ and a C++ compiler with a complete implementation of
+C++98 (for example, GCC 3.2 and older cannot compile JavaHL 1.9+).
 
 Its build will produce both a native library (libsvnjavahl-1.so on Unix
 or libsvnjavahl-1.dll on Win32) and a platform independent archive of
@@ -22,26 +23,29 @@ Java bytecode (svn-javahl.jar).
 
 To build JavaHL on non-Win32 platforms, just add "--enable-javahl" to
 the configure script's parameters.  "--with-jdk" can be provided to
-specify the path to a jdk.  "--with-maintainer-mode" will compile Java
-bytecode with debugging information.  Jikes will be the preferred
-compiler if it is auto-detected.  If not auto-detected, you can force
-its use via the "--with-jikes=path" flag to configure.
+specify the path to a jdk.  "--enable-maintainer-mode" will compile
+Java bytecode with debugging information.
 
 The following make targets are provided:
 
-javahl                build javahl
-install-javahl        install javahl
-check-javahl          run javahl tests
+javahl                build JavaHL
+install-javahl        install JavaHL
+check-javahl          run JavaHL tests
+check-all-javahl      run all JavaHL tests, including tests for
+                      deprecated backward-compatibility APIs.
 
 (In order to run check-javahl, you must have specified a path to a JUnit
-jar file with --with-junit when running configure; JUnit version 3.8.1
+jar file with --with-junit when running configure; JUnit version 4.11
 has been tested.  JUnit can be downloaded from http://junit.org/ .)
 
 
 MacOS X:
 
-After building libsvnjavahl.dynlib, you must rename it to
-libsvnjavahl.jnilib.  Additionally, it should probably be installed in
+After building libsvnjavahl.dylib, you must rename it to
+libsvnjavahl.jnilib. Make install-javahl creates a symbolic
+link with the appropriate name.
+
+Additionally, it should probably be installed in
 /Library/Java/Extensions instead of wherever the build system chose to
 install it; patches to our build system to do this automatically are
 welcome.
@@ -60,6 +64,7 @@ Success stories
 ---------------
 
 Subclipse, Eclipse IDE plug-in <http://subclipse.tigris.org/>
+SmartSVN, cross-platform Subversion client (http://www.smartsvn.com/)
 
 
 Why not 100% pure Java?
@@ -86,6 +91,8 @@ as to its compatibility with the officia
 TODO
 ----
 
+o Transition all of the implementation to the new-style jniwrapper.
 o Expose more of Subversion's core libraries through JNI.
 o More JUnit test cases.
+o Refactor the JUnit tests to use the improved features of JUnit 4.
 o Improve JavaDoc and coding style.

Modified: subversion/branches/ra-git/subversion/bindings/javahl/native/AuthnCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/bindings/javahl/native/AuthnCallback.cpp?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/bindings/javahl/native/AuthnCallback.cpp (original)
+++ subversion/branches/ra-git/subversion/bindings/javahl/native/AuthnCallback.cpp Mon Nov 30 10:24:16 2015
@@ -38,39 +38,39 @@ namespace JavaHL {
 
 // Class JavaHL::AuthnCallback
 const char* const AuthnCallback::m_class_name =
-  JAVA_PACKAGE"/callback/AuthnCallback";
+  JAVAHL_CLASS("/callback/AuthnCallback");
 
 AuthnCallback::ClassImpl::ClassImpl(::Java::Env env, jclass cls)
   : ::Java::Object::ClassImpl(env, cls),
     m_mid_username_prompt(
         env.GetMethodID(cls, "usernamePrompt",
                         "(Ljava/lang/String;Z)"
-                        "L"JAVA_PACKAGE"/callback/AuthnCallback"
+                        JAVAHL_ARG("/callback/AuthnCallback")
                         "$UsernameResult;")),
     m_mid_user_password_prompt(
         env.GetMethodID(cls, "userPasswordPrompt",
                         "(Ljava/lang/String;Ljava/lang/String;Z)"
-                        "L"JAVA_PACKAGE"/callback/AuthnCallback"
+                        JAVAHL_ARG("/callback/AuthnCallback")
                         "$UserPasswordResult;")),
     m_mid_ssl_server_trust_prompt(
         env.GetMethodID(cls, "sslServerTrustPrompt",
                         "(Ljava/lang/String;"
-                        "L"JAVA_PACKAGE"/callback/AuthnCallback"
+                        JAVAHL_ARG("/callback/AuthnCallback")
                         "$SSLServerCertFailures;"
-                        "L"JAVA_PACKAGE"/callback/AuthnCallback"
+                        JAVAHL_ARG("/callback/AuthnCallback")
                         "$SSLServerCertInfo;"
                         "Z)"
-                        "L"JAVA_PACKAGE"/callback/AuthnCallback"
+                        JAVAHL_ARG("/callback/AuthnCallback")
                         "$SSLServerTrustResult;")),
     m_mid_ssl_client_cert_prompt(
         env.GetMethodID(cls, "sslClientCertPrompt",
                         "(Ljava/lang/String;Z)"
-                        "L"JAVA_PACKAGE"/callback/AuthnCallback"
+                        JAVAHL_ARG("/callback/AuthnCallback")
                         "$SSLClientCertResult;")),
     m_mid_ssl_client_cert_passphrase_prompt(
         env.GetMethodID(cls, "sslClientCertPassphrasePrompt",
                         "(Ljava/lang/String;Z)"
-                        "L"JAVA_PACKAGE"/callback/AuthnCallback"
+                        JAVAHL_ARG("/callback/AuthnCallback")
                         "$SSLClientCertPassphraseResult;")),
     m_mid_allow_store_plaintext_password(
         env.GetMethodID(cls, "allowStorePlaintextPassword",
@@ -143,7 +143,7 @@ bool AuthnCallback::allow_store_plaintex
 
 // Class JavaHL::AuthnCallback::AuthnResult
 const char* const AuthnCallback::AuthnResult::m_class_name =
-  JAVA_PACKAGE"/callback/AuthnCallback$AuthnResult";
+  JAVAHL_CLASS("/callback/AuthnCallback$AuthnResult");
 
 AuthnCallback::AuthnResult::ClassImpl::ClassImpl(::Java::Env env, jclass cls)
   : ::Java::Object::ClassImpl(env, cls),
@@ -157,7 +157,7 @@ AuthnCallback::AuthnResult::ClassImpl::~
 
 // Class JavaHL::AuthnCallback::SSLServerCertFailures
 const char* const AuthnCallback::SSLServerCertFailures::m_class_name =
-  JAVA_PACKAGE"/callback/AuthnCallback$SSLServerCertFailures";
+  JAVAHL_CLASS("/callback/AuthnCallback$SSLServerCertFailures");
 
 AuthnCallback::SSLServerCertFailures::ClassImpl::ClassImpl(
     ::Java::Env env, jclass cls)
@@ -178,7 +178,7 @@ AuthnCallback::SSLServerCertFailures::SS
 
 // Class JavaHL::AuthnCallback::SSLServerCertInfo
 const char* const AuthnCallback::SSLServerCertInfo::m_class_name =
-  JAVA_PACKAGE"/callback/AuthnCallback$SSLServerCertInfo";
+  JAVAHL_CLASS("/callback/AuthnCallback$SSLServerCertInfo");
 
 AuthnCallback::SSLServerCertInfo::ClassImpl::ClassImpl(
     ::Java::Env env, jclass cls)
@@ -259,7 +259,7 @@ AuthnCallback::SSLServerCertInfo::SSLSer
 
 // Class JavaHL::UserPasswordCallback
 const char* const UserPasswordCallback::m_class_name =
-  JAVA_PACKAGE"/callback/UserPasswordCallback";
+  JAVAHL_CLASS("/callback/UserPasswordCallback");
 
 UserPasswordCallback::ClassImpl::ClassImpl(::Java::Env env, jclass cls)
   : ::Java::Object::ClassImpl(env, cls),

Modified: subversion/branches/ra-git/subversion/bindings/javahl/native/BlameCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/bindings/javahl/native/BlameCallback.cpp?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/bindings/javahl/native/BlameCallback.cpp (original)
+++ subversion/branches/ra-git/subversion/bindings/javahl/native/BlameCallback.cpp Mon Nov 30 10:24:16 2015
@@ -92,7 +92,7 @@ BlameCallback::singleLine(svn_revnum_t s
   static jmethodID mid = 0;
   if (mid == 0)
     {
-      jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/BlameCallback");
+      jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/BlameCallback"));
       if (JNIUtil::isJavaExceptionThrown())
         POP_AND_RETURN(SVN_NO_ERROR);
 
@@ -128,8 +128,6 @@ BlameCallback::singleLine(svn_revnum_t s
   env->CallVoidMethod(m_callback, mid, (jlong)line_no, (jlong)revision,
                       jrevProps, (jlong)mergedRevision, jmergedRevProps,
                       jmergedPath, jline, (jboolean)localChange);
-  // No need to check for an exception here, because we return anyway.
 
-  env->PopLocalFrame(NULL);
-  return SVN_NO_ERROR;
+  POP_AND_RETURN_EXCEPTION_AS_SVNERROR();
 }

Modified: subversion/branches/ra-git/subversion/bindings/javahl/native/ChangelistCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/bindings/javahl/native/ChangelistCallback.cpp?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/bindings/javahl/native/ChangelistCallback.cpp (original)
+++ subversion/branches/ra-git/subversion/bindings/javahl/native/ChangelistCallback.cpp Mon Nov 30 10:24:16 2015
@@ -78,7 +78,7 @@ ChangelistCallback::doChangelist(const c
   // it can be cached.
   if (mid == 0)
     {
-      jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/ChangelistCallback");
+      jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/ChangelistCallback"));
       if (JNIUtil::isJavaExceptionThrown())
         POP_AND_RETURN_NOTHING();
 

Modified: subversion/branches/ra-git/subversion/bindings/javahl/native/ClientContext.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/bindings/javahl/native/ClientContext.cpp?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/bindings/javahl/native/ClientContext.cpp (original)
+++ subversion/branches/ra-git/subversion/bindings/javahl/native/ClientContext.cpp Mon Nov 30 10:24:16 2015
@@ -42,7 +42,7 @@ ClientContext::ClientContext(jobject jsv
     : OperationContext(pool)
 {
     static jfieldID ctxFieldID = 0;
-    attachJavaObject(jsvnclient, "L"JAVA_PACKAGE"/SVNClient$ClientContext;", "clientContext", &ctxFieldID);
+    attachJavaObject(jsvnclient, JAVAHL_ARG("/SVNClient$ClientContext;"), "clientContext", &ctxFieldID);
 
     SVN_JNI_ERR(svn_client_create_context2(&m_context, NULL,
                                            pool.getPool()),
@@ -182,7 +182,7 @@ ClientContext::notify(void *baton,
         return;
 
       mid = env->GetMethodID(clazz, "onNotify",
-                             "(L"JAVA_PACKAGE"/ClientNotifyInformation;)V");
+                             "(" JAVAHL_ARG("/ClientNotifyInformation;") ")V");
       if (JNIUtil::isJavaExceptionThrown() || mid == 0)
         return;
 
@@ -223,8 +223,8 @@ ClientContext::resolve(svn_wc_conflict_r
         POP_AND_RETURN(SVN_NO_ERROR);
 
       mid = env->GetMethodID(clazz, "resolve",
-                             "(L"JAVA_PACKAGE"/ConflictDescriptor;)"
-                             "L"JAVA_PACKAGE"/ConflictResult;");
+                             "(" JAVAHL_ARG("/ConflictDescriptor;") ")"
+                             JAVAHL_ARG("/ConflictResult;"));
       if (JNIUtil::isJavaExceptionThrown() || mid == 0)
         POP_AND_RETURN(SVN_NO_ERROR);
     }
@@ -276,7 +276,7 @@ ClientContext::javaResultToC(jobject jre
   jclass clazz = NULL;
   if (getChoice == 0 || getMergedPath == 0)
     {
-      clazz = env->FindClass(JAVA_PACKAGE "/ConflictResult");
+      clazz = env->FindClass(JAVAHL_CLASS("/ConflictResult"));
       if (JNIUtil::isJavaExceptionThrown())
         POP_AND_RETURN_NULL;
     }
@@ -284,7 +284,7 @@ ClientContext::javaResultToC(jobject jre
   if (getChoice == 0)
     {
       getChoice = env->GetMethodID(clazz, "getChoice",
-                                   "()L"JAVA_PACKAGE"/ConflictResult$Choice;");
+                                   "()" JAVAHL_ARG("/ConflictResult$Choice;"));
       if (JNIUtil::isJavaExceptionThrown() || getChoice == 0)
         POP_AND_RETURN_NULL;
     }