Author: dsahlberg
Date: Sun May 17 18:22:26 2026
New Revision: 1934310

Log:
On the javahl-1.15 branch:

Catchup merge with trunk (to simplify review).

Added:
   subversion/branches/javahl-1.15/build/cmake/FindCURSES.cmake
      - copied unchanged from r1934309, 
subversion/trunk/build/cmake/FindCURSES.cmake
Modified:
   subversion/branches/javahl-1.15/   (props changed)
   subversion/branches/javahl-1.15/.github/workflows/autoconf.yml
   subversion/branches/javahl-1.15/.github/workflows/cmake.yml
   
subversion/branches/javahl-1.15/.github/workflows/detect-backport-conflicts.yml
   subversion/branches/javahl-1.15/CMakeLists.txt
   subversion/branches/javahl-1.15/COMMITTERS
   subversion/branches/javahl-1.15/INSTALL
   subversion/branches/javahl-1.15/build/cmake/FindHttpd.cmake
   subversion/branches/javahl-1.15/build/generator/templates/targets.cmake.ezt
   subversion/branches/javahl-1.15/subversion/libsvn_subr/config_file.c
   subversion/branches/javahl-1.15/subversion/libsvn_subr/utf.c
   subversion/branches/javahl-1.15/subversion/svnbrowse/model.c
   subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.c
   subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.h
   subversion/branches/javahl-1.15/subversion/tests/libsvn_subr/utf-test.c
   subversion/branches/javahl-1.15/tools/dist/detect-conflicting-backports.py

Modified: subversion/branches/javahl-1.15/.github/workflows/autoconf.yml
==============================================================================
--- subversion/branches/javahl-1.15/.github/workflows/autoconf.yml      Sun May 
17 17:52:52 2026        (r1934309)
+++ subversion/branches/javahl-1.15/.github/workflows/autoconf.yml      Sun May 
17 18:22:26 2026        (r1934310)
@@ -100,7 +100,7 @@ jobs:
 
       - name: Archive test logs
         if: always()
-        uses: actions/upload-artifact@v4
+        uses: actions/upload-artifact@v7
         with:
           name: tests-${{matrix.os}}-${{matrix.check-target}}-${{matrix.httpd}}
           path: |

Modified: subversion/branches/javahl-1.15/.github/workflows/cmake.yml
==============================================================================
--- subversion/branches/javahl-1.15/.github/workflows/cmake.yml Sun May 17 
17:52:52 2026        (r1934309)
+++ subversion/branches/javahl-1.15/.github/workflows/cmake.yml Sun May 17 
18:22:26 2026        (r1934310)
@@ -42,27 +42,27 @@ jobs:
       matrix:
         include:
           - name: Windows, shared, x64, with tests
-            os: windows-latest
+            os: windows-2022
             build_shared: ON
             cmake_generator: Ninja
             vcpkg_triplet: x64-windows
             arch: x64
             run_tests: true
           - name: Windows, shared, x64, vs2022, with tests
-            os: windows-latest
+            os: windows-2022
             build_shared: ON
             cmake_generator: 'Visual Studio 17 2022'
             vcpkg_triplet: x64-windows
             arch: x64
             run_tests: true
           - name: Windows, shared, x86
-            os: windows-latest
+            os: windows-2022
             build_shared: ON
             cmake_generator: Ninja
             vcpkg_triplet: x86-windows
             arch: x86
           - name: Windows, static, x64, with tests
-            os: windows-latest
+            os: windows-2022
             build_shared: OFF
             cmake_generator: Ninja
             vcpkg_triplet: x64-windows-static-md
@@ -115,7 +115,7 @@ jobs:
 
       - name: Restore vcpkg archives (Windows, vcpkg)
         if: runner.os == 'Windows'
-        uses: actions/cache/restore@v4
+        uses: actions/cache/restore@v5
         with:
           path: vcpkg-archives
           key: vcpkg/${{ runner.os }}/${{ matrix.vcpkg_triplet }}/${{ 
steps.vcpkg-sha.outputs.sha }}
@@ -130,13 +130,13 @@ jobs:
             New-Item $env:VCPKG_DEFAULT_BINARY_CACHE -ItemType Directory | 
Out-Null
           }
           C:\vcpkg\vcpkg.exe install --triplet ${{ matrix.vcpkg_triplet }} `
-            apr apr-util serf expat zlib sqlite3
+            apr apr-util serf expat zlib sqlite3 gettext[tools] pdcurses
 
           "CMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" >> 
$env:GITHUB_ENV
 
       - name: Save vcpkg archives (Windows, vcpkg)
         if: runner.os == 'Windows'
-        uses: actions/cache/save@v4
+        uses: actions/cache/save@v5
         with:
           path: vcpkg-archives
           key: vcpkg/${{ runner.os }}/${{ matrix.vcpkg_triplet }}/${{ 
steps.vcpkg-sha.outputs.sha }}
@@ -154,14 +154,18 @@ jobs:
           libexpat1-dev
           zlib1g-dev
           libsqlite3-dev
+          apache2-dev
+          gettext
+          libncurses-dev
           ninja-build
           ${{ matrix.extra_packages }}
 
       - name: Install dependencies (Mac OS, homebrew)
         if: runner.os == 'macOS'
         run: |
-          $packages = @('apr', 'apr-util', 'expat', 'sqlite', 'apache-serf')
-          brew install ninja $packages
+          $packages = @('apr', 'apr-util', 'expat', 'sqlite', 'apache-serf',
+                        'gettext', 'ncurses')
+          brew install ninja apache2 $packages
           $PKG_CONFIG_PATH = `
             $packages | `
             % { "$(& brew --prefix $_)/lib/pkgconfig" } | `
@@ -180,10 +184,16 @@ jobs:
 
       - name: Configure CMake
         run: >
+          if ($env:RUNNER_OS -eq 'Windows') {
+            $env:PATH += ";${env:VCPKG_ROOT}\installed\${{ 
matrix.vcpkg_triplet }}\bin";
+          };
           cmake -B out
           -DBUILD_SHARED_LIBS=${{ matrix.build_shared }}
           -DSVN_ENABLE_TESTS=ON
           -DSVN_ENABLE_RA_SERF=ON
+          -DSVN_ENABLE_NLS=ON
+          -DSVN_ENABLE_APACHE_MODULES=${{ runner.os != 'Windows' && 'ON' || 
'OFF' }}
+          -DSVN_ENABLE_TUI=ON
           -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/installdir
           -DVCPKG_TARGET_TRIPLET=${{ matrix.vcpkg_triplet }}
           -DSVN_TEST_CONFIGURE_FOR_PARALLEL=ON

Modified: 
subversion/branches/javahl-1.15/.github/workflows/detect-backport-conflicts.yml
==============================================================================
--- 
subversion/branches/javahl-1.15/.github/workflows/detect-backport-conflicts.yml 
    Sun May 17 17:52:52 2026        (r1934309)
+++ 
subversion/branches/javahl-1.15/.github/workflows/detect-backport-conflicts.yml 
    Sun May 17 18:22:26 2026        (r1934310)
@@ -24,9 +24,7 @@ name: backportbot
 
 on:
   push:
-    branches: ["1.14.x"]
-  pull_request:
-    branches: ["1.14.x"]
+    branches: ["1.14.x", "1.15.x"]
 
 concurrency:
   group: ${{ github.workflow }}-${{ github.ref }}
@@ -43,10 +41,13 @@ jobs:
           sudo apt-get update &&
           sudo apt-get install
           subversion
-          
+
+      - name: Obtain tools/dist
+        run: svn export 
https://svn.apache.org/repos/asf/subversion/trunk/tools/dist tools-dist
+
       - name: Checkout backport branch
-        run: svn co https://svn.apache.org/repos/asf/subversion/branches/1.14.x
+        run: svn co https://svn.apache.org/repos/asf/subversion/branches/${{ 
github.ref_name }} branch-wc
 
       - name: Detect conflicting backports
-        run: cd 1.14.x && ./tools/dist/detect-conflicting-backports.py
+        run: cd branch-wc && ../tools-dist/detect-conflicting-backports.py
 

Modified: subversion/branches/javahl-1.15/CMakeLists.txt
==============================================================================
--- subversion/branches/javahl-1.15/CMakeLists.txt      Sun May 17 17:52:52 
2026        (r1934309)
+++ subversion/branches/javahl-1.15/CMakeLists.txt      Sun May 17 18:22:26 
2026        (r1934310)
@@ -298,6 +298,88 @@ if (NOT EXISTS "${CMAKE_SOURCE_DIR}/buil
   )
 endif()
 
+### Intl
+
+if(SVN_ENABLE_NLS)
+  # Note: when installing these dependecies with vcpkg, you will need to
+  # install 'gettext' package with 'tools' feature. Use the following command
+  # for this: `./vcpkg install gettext[tools]`. This package contains both,
+  # Gettext and Intl dependecies.
+  find_package(Gettext REQUIRED)
+  find_package(Intl REQUIRED)
+
+  # If using CMake of version < 3.20, FindIntl would not define IMPORTED 
target.
+  # https://cmake.org/cmake/help/latest/module/FindIntl.html
+  if(NOT TARGET Intl::Intl)
+    add_library(Intl::Intl INTERFACE IMPORTED)
+    include_directories("${Intl_INCLUDE_DIRS}")
+    set_target_properties(Intl::Intl PROPERTIES
+      INTERFACE_LINK_LIBRARIES "${Intl_LIBRARIES}"
+    )
+  endif()
+
+  add_library(external-intl ALIAS Intl::Intl)
+
+  add_private_config_definition(
+    "Define to 1 if translation of program messages to the user's native 
language is requested."
+    "ENABLE_NLS" "1"
+  )
+
+  if (NOT WIN32)
+    add_private_config_definition(
+      "Defined to be the path to the installed locale dirs"
+      "SVN_LOCALE_DIR" "\"${CMAKE_INSTALL_PREFIX}/share/locale\""
+    )
+  endif()
+
+  add_custom_target(locale ALL)
+
+  file(GLOB SVN_PO_FILES "subversion/po/*.po")
+
+  foreach(po_file ${SVN_PO_FILES})
+    get_filename_component(lang ${po_file} NAME_WLE)
+    set(mo_file "${CMAKE_BINARY_DIR}/${lang}.mo")
+
+    add_custom_command(
+      DEPENDS
+        "${po_file}"
+      OUTPUT
+        "${mo_file}"
+      COMMAND
+        "${GETTEXT_MSGFMT_EXECUTABLE}" -c -o ${mo_file} ${po_file}
+    )
+
+    target_sources(locale PRIVATE ${mo_file})
+
+    install(
+      FILES "${mo_file}"
+      DESTINATION "share/locale/${lang}/LC_MESSAGES"
+      RENAME "subversion.mo"
+    )
+  endforeach()
+else()
+  # Declare empty target for Intl if we don't use it.
+  add_library(external-intl INTERFACE)
+endif()
+
+# Link all targets with Intl library. The 'external-intl' target is always,
+# even if we don't use NLS functionality.
+#
+# Following the CMake documentation [1], the link_libraries affects only on
+# the targets declared later, so it should be here.
+#
+# [1] https://cmake.org/cmake/help/latest/command/link_libraries.html
+#     -- "Link libraries to all targets added later."
+link_libraries(external-intl)
+
+### Httpd
+
+if(SVN_ENABLE_APACHE_MODULES)
+  find_package(Httpd REQUIRED)
+  add_library(external-libhttpd ALIAS httpd::httpd)
+  add_library(external-mod_dav ALIAS httpd::mod_dav)
+endif()
+
 add_library(ra-libs INTERFACE)
 add_library(fs-libs INTERFACE)
 
@@ -497,14 +579,6 @@ elseif(SVN_ENABLE_TESTS)
   )
 endif()
 
-### Httpd
-
-if(SVN_ENABLE_APACHE_MODULES)
-  find_package(Httpd REQUIRED)
-  add_library(external-libhttpd ALIAS httpd::httpd)
-  add_library(external-mod_dav ALIAS httpd::mod_dav)
-endif()
-
 ### KWallet
 
 if(SVN_ENABLE_AUTH_KWALLET)
@@ -560,7 +634,8 @@ if (SVN_ENABLE_TUI)
     pkg_check_modules(ncurses REQUIRED IMPORTED_TARGET ncurses)
     target_link_libraries(external-ncurses INTERFACE PkgConfig::ncurses)
   else()
-    message(SEND_ERROR "not supported")
+    find_package(CURSES REQUIRED)
+    target_link_libraries(external-ncurses INTERFACE CURSES::CURSES)
   endif()
 endif()
 
@@ -788,78 +863,6 @@ if (MSVC)
   )
 endif()
 
-if(SVN_ENABLE_NLS)
-  # Note: when installing these dependecies with vcpkg, you will need to
-  # install 'gettext' package with 'tools' feature. Use the following command
-  # for this: `./vcpkg install gettext[tools]`. This package contains both,
-  # Gettext and Intl dependecies.
-  find_package(Gettext REQUIRED)
-  find_package(Intl REQUIRED)
-
-  # If using CMake of version < 3.20, FindIntl would not define IMPORTED 
target.
-  # https://cmake.org/cmake/help/latest/module/FindIntl.html
-  if(NOT TARGET Intl::Intl)
-    add_library(Intl::Intl INTERFACE IMPORTED)
-    set_target_properties(Intl::Intl PROPERTIES
-      INTERFACE_INCLUDE_DIRECTORIES "${Intl_INCLUDE_DIRS}"
-      INTERFACE_LINK_LIBRARIES "${Intl_LIBRARIES}"
-    )
-  endif()
-
-  add_library(external-intl ALIAS Intl::Intl)
-
-  add_private_config_definition(
-    "Define to 1 if translation of program messages to the user's native 
language is requested."
-    "ENABLE_NLS" "1"
-  )
-
-  if (NOT WIN32)
-    add_private_config_definition(
-      "Defined to be the path to the installed locale dirs"
-      "SVN_LOCALE_DIR" "\"${CMAKE_INSTALL_PREFIX}/share/locale\""
-    )
-  endif()
-
-  add_custom_target(locale ALL)
-
-  file(GLOB SVN_PO_FILES "subversion/po/*.po")
-
-  foreach(po_file ${SVN_PO_FILES})
-    get_filename_component(lang ${po_file} NAME_WLE)
-    set(mo_file "${CMAKE_BINARY_DIR}/${lang}.mo")
-
-    add_custom_command(
-      DEPENDS
-        "${po_file}"
-      OUTPUT
-        "${mo_file}"
-      COMMAND
-        "${GETTEXT_MSGFMT_EXECUTABLE}" -c -o ${mo_file} ${po_file}
-    )
-
-    target_sources(locale PRIVATE ${mo_file})
-
-    install(
-      FILES "${mo_file}"
-      DESTINATION "share/locale/${lang}/LC_MESSAGES"
-      RENAME "subversion.mo"
-    )
-  endforeach()
-else()
-  # Declare empty target for Intl if we don't use it.
-  add_library(external-intl INTERFACE)
-endif()
-
-# Link all targets with Intl library. The 'external-intl' target is always,
-# even if we don't use NLS functionality.
-#
-# Following the CMake documentation [1], the link_libraries affects only on
-# the targets declared later, so it should be here.
-#
-# [1] https://cmake.org/cmake/help/latest/command/link_libraries.html
-#     -- "Link libraries to all targets added later."
-link_libraries(external-intl)
-
 # Build shared libraries and theirs implibs with 'lib' prefix, for example
 # libsvn_subr-1.[lib|a] and libsvn_subr-1.[dll|so]
 set(CMAKE_SHARED_LIBRARY_PREFIX "lib")

Modified: subversion/branches/javahl-1.15/COMMITTERS
==============================================================================
--- subversion/branches/javahl-1.15/COMMITTERS  Sun May 17 17:52:52 2026        
(r1934309)
+++ subversion/branches/javahl-1.15/COMMITTERS  Sun May 17 18:22:26 2026        
(r1934310)
@@ -46,7 +46,6 @@ Blanket commit access:
       arfrever   Arfrever Frehtes Taifersar Arahesis <[email protected]>
           stsp   Stefan Sperling <[email protected]>
            kou   Kouhei Sutou <[email protected]>
-      danielsh   Daniel Shahaf <[email protected]>
         peters   Peter Samuelson <[email protected]>
       rhuijben   Bert Huijben <[email protected]>
       stylesen   Senthil Kumaran S <[email protected]>
@@ -87,6 +86,7 @@ Full committers who have asked to be lis
          naked   Nuutti Kotivuori <[email protected]>
      ringstrom   Tobias Ringström <[email protected]>
       luke1410   Stefan Hett <[email protected]>
+      danielsh   Daniel Shahaf <[email protected]>
 
 
 Partial committers who have asked to be listed as dormant:

Modified: subversion/branches/javahl-1.15/INSTALL
==============================================================================
--- subversion/branches/javahl-1.15/INSTALL     Sun May 17 17:52:52 2026        
(r1934309)
+++ subversion/branches/javahl-1.15/INSTALL     Sun May 17 18:22:26 2026        
(r1934310)
@@ -848,6 +848,11 @@ II.   INSTALLATION
   E.  Building the Latest Source under Windows
       ----------------------------------------
 
+      Windows users may find it easier to build Subversion using CMake and
+      vcpkg (see section F below).
+
+      The following procedure does not use CMake or vcpkg.
+
   E.1 Prerequisites
 
       * Microsoft Visual Studio. Any recent (2005+) version containing the
@@ -1194,9 +1199,8 @@ II.   INSTALLATION
   F.  Building using CMake
       --------------------
 
-      Get the sources, either a release tarball or by checking out the
-      official repository. The CMake build system currently only exists in
-      /trunk and it will be included in the 1.15 release.
+      Get the sources, either from a release tarball or by checking out the
+      official repository.
 
       The process for building on Unix and Windows is the same.
 
@@ -1204,11 +1208,14 @@ II.   INSTALLATION
           $ cmake -B out [build options]
           $ cmake --build out
 
+      Note: If you're using the tarball distribution, the first gen-make step
+      can be skipped.
+
       "out" in the commands above is the build directory used by CMake.
 
       Build options can be added, for example:
 
-          $ cmake -B out -DCMAKE_INSTALL_PREFIX=/usr/local/subversion 
-DSVN_ENABLE_RA_SERF=ON
+          $ cmake -B out -DCMAKE_INSTALL_PREFIX=/usr/local/subversion 
-DSVN_ENABLE_TESTS=ON
 
       Build options can be listed using:
 

Copied: subversion/branches/javahl-1.15/build/cmake/FindCURSES.cmake (from 
r1934309, subversion/trunk/build/cmake/FindCURSES.cmake)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ subversion/branches/javahl-1.15/build/cmake/FindCURSES.cmake        Sun May 
17 18:22:26 2026        (r1934310, copy of r1934309, 
subversion/trunk/build/cmake/FindCURSES.cmake)
@@ -0,0 +1,52 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# FindCURSES.cmake -- Find the curses library
+#
+
+find_path(CURSES_INCLUDE_DIR
+  NAMES curses.h
+  PATH_SUFFIXES
+    include
+)
+
+find_library(CURSES_LIBRARY
+  NAMES ncurses pdcurses curses 
+  PATH_SUFFIXES lib
+)
+
+mark_as_advanced(
+  CURSES_INCLUDE_DIR
+  CURSES_LIBRARY
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+  CURSES
+  REQUIRED_VARS
+    CURSES_LIBRARY
+    CURSES_INCLUDE_DIR
+)
+
+if (CURSES_FOUND)
+  add_library(CURSES::CURSES IMPORTED STATIC)
+  set_target_properties(CURSES::CURSES PROPERTIES
+    IMPORTED_LOCATION ${CURSES_LIBRARY}
+    INTERFACE_INCLUDE_DIRECTORIES ${CURSES_INCLUDE_DIR}
+  )
+endif()

Modified: subversion/branches/javahl-1.15/build/cmake/FindHttpd.cmake
==============================================================================
--- subversion/branches/javahl-1.15/build/cmake/FindHttpd.cmake Sun May 17 
17:52:52 2026        (r1934309)
+++ subversion/branches/javahl-1.15/build/cmake/FindHttpd.cmake Sun May 17 
18:22:26 2026        (r1934310)
@@ -1,62 +1,123 @@
-find_path(HTTPD_INCLUDE_DIR
-  NAMES httpd.h
-  PATH_SUFFIXES
-    include
-)
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# FindHttpd.cmake -- CMake module for Httpd library
+#
+
+include(GNUInstallDirs)
+
+if(WIN32)
+  find_path(HTTPD_INCLUDE_DIR
+    NAMES httpd.h
+    PATH_SUFFIXES
+      include
+  )
 
-find_library(HTTPD_LIBRARY
-  NAMES libhttpd
-  PATH_SUFFIXES lib
-)
+  find_library(HTTPD_LIBRARY
+    NAMES libhttpd
+    PATH_SUFFIXES lib
+  )
 
-find_file(HTTPD_DLL
-  NAMES libhttpd.dll
-  PATH_SUFFIXES bin
-)
+  find_library(MOD_DAV_LIBRARY
+    NAMES mod_dav
+    PATH_SUFFIXES lib
+  )
 
-find_library(MOD_DAV_LIBRARY
-  NAMES mod_dav
-  PATH_SUFFIXES lib
-)
+  if (HTTPD_INCLUDE_DIR AND EXISTS "${HTTPD_INCLUDE_DIR}/ap_release.h")
+    file(
+      STRINGS "${HTTPD_INCLUDE_DIR}/ap_release.h" VERSION_STRINGS
+      REGEX "#define 
(AP_SERVER_MAJORVERSION_NUMBER|AP_SERVER_MINORVERSION_NUMBER|AP_SERVER_PATCHLEVEL_NUMBER)"
+    )
 
-if (HTTPD_INCLUDE_DIR AND EXISTS "${HTTPD_INCLUDE_DIR}/ap_release.h")
-  file(
-    STRINGS "${HTTPD_INCLUDE_DIR}/ap_release.h" VERSION_STRINGS
-    REGEX "#define 
(AP_SERVER_MAJORVERSION_NUMBER|AP_SERVER_MINORVERSION_NUMBER|AP_SERVER_PATCHLEVEL_NUMBER)"
-  )
+    string(REGEX REPLACE ".*AP_SERVER_MAJORVERSION_NUMBER +([0-9]+).*" "\\1" 
HTTPD_VERSION_MAJOR ${VERSION_STRINGS})
+    string(REGEX REPLACE ".*AP_SERVER_MINORVERSION_NUMBER +([0-9]+).*" "\\1" 
HTTPD_VERSION_MINOR ${VERSION_STRINGS})
+    string(REGEX REPLACE ".*AP_SERVER_PATCHLEVEL_NUMBER +([0-9]+).*" "\\1" 
HTTPD_VERSION_PATCH ${VERSION_STRINGS})
 
-  string(REGEX REPLACE ".*AP_SERVER_MAJORVERSION_NUMBER +([0-9]+).*" "\\1" 
HTTPD_VERSION_MAJOR ${VERSION_STRINGS})
-  string(REGEX REPLACE ".*AP_SERVER_MINORVERSION_NUMBER +([0-9]+).*" "\\1" 
HTTPD_VERSION_MINOR ${VERSION_STRINGS})
-  string(REGEX REPLACE ".*AP_SERVER_PATCHLEVEL_NUMBER +([0-9]+).*" "\\1" 
HTTPD_VERSION_PATCH ${VERSION_STRINGS})
+    set(HTTPD_VERSION 
"${HTTPD_VERSION_MAJOR}.${HTTPD_VERSION_MINOR}.${HTTPD_VERSION_PATCH}")
+  endif()
+  set(_httpd_modules_dir "${CMAKE_INSTALL_BINDIR}")
+
+else()
+  find_program(APXS_EXECUTABLE
+               NAMES apxs2 apxs
+               PATH /usr/local/apache2/bin /usr/local/apache/bin /usr/bin 
/usr/sbin)
+
+  function(_APXS_CONFIG_VAR VARNAME OUTVAR)
+    execute_process(COMMAND "${APXS_EXECUTABLE}" -q ${VARNAME}
+                    RESULT_VARIABLE _APXS_SUCCESS
+                    OUTPUT_VARIABLE _APXS_OUTPUT
+                    OUTPUT_STRIP_TRAILING_WHITESPACE
+                    ERROR_QUIET)
+    set(${OUTVAR} "${_APXS_OUTPUT}" PARENT_SCOPE)
+  endfunction()
+
+  if(APXS_EXECUTABLE)
+    _APXS_CONFIG_VAR("HTTPD_VERSION" HTTPD_VERSION)
+    _APXS_CONFIG_VAR("INCLUDEDIR" HTTPD_INCLUDE_DIR)
+    set(_httpd_modules_dir "${CMAKE_INSTALL_LIBEXECDIR}")
+    set(HTTPD_FOUND TRUE)
+  endif()
 
-  set(HTTPD_VERSION 
"${HTTPD_VERSION_MAJOR}.${HTTPD_VERSION_MINOR}.${HTTPD_VERSION_PATCH}")
 endif()
 
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(
+set(HTTPD_MODULES_DIR "${_httpd_modules_dir}"
+    CACHE PATH "Install directory for Apache modules")
+
+find_package_handle_standard_args(
   Httpd
   REQUIRED_VARS
-    HTTPD_LIBRARY
     HTTPD_INCLUDE_DIR
-    MOD_DAV_LIBRARY
+    HTTPD_MODULES_DIR
   VERSION_VAR
     HTTPD_VERSION
 )
 
 if(HTTPD_FOUND)
   if(NOT TARGET httpd::httpd)
-    add_library(httpd::httpd SHARED IMPORTED)
+    add_library(httpd::httpd INTERFACE IMPORTED)
     set_target_properties(httpd::httpd PROPERTIES
       INTERFACE_INCLUDE_DIRECTORIES ${HTTPD_INCLUDE_DIR}
-      IMPORTED_LOCATION ${HTTPD_DLL}
-      IMPORTED_IMPLIB ${HTTPD_LIBRARY}
     )
+    if(WIN32)
+      set_target_properties(httpd::httpd PROPERTIES
+        INTERFACE_LINK_LIBRARIES ${HTTPD_LIBRARY}
+      )
+    elseif(APPLE)
+      target_link_options(httpd::httpd INTERFACE
+        "-Wl,-undefined,dynamic_lookup"
+      )
+    endif()
   endif()
 
   if(NOT TARGET httpd::mod_dav)
-    add_library(httpd::mod_dav STATIC IMPORTED)
+    add_library(httpd::mod_dav INTERFACE IMPORTED)
     set_target_properties(httpd::mod_dav PROPERTIES
       INTERFACE_INCLUDE_DIRECTORIES ${HTTPD_INCLUDE_DIR}
-      IMPORTED_LOCATION ${MOD_DAV_LIBRARY}
     )
+    if(WIN32)
+      set_target_properties(httpd::mod_dav PROPERTIES
+        INTERFACE_LINK_LIBRARIES ${MOD_DAV_LIBRARY}
+      )
+    elseif(APPLE)
+      target_link_options(httpd::mod_dav INTERFACE
+        "-Wl,-undefined,dynamic_lookup"
+      )
+    endif()
   endif()
+
 endif()

Modified: 
subversion/branches/javahl-1.15/build/generator/templates/targets.cmake.ezt
==============================================================================
--- subversion/branches/javahl-1.15/build/generator/templates/targets.cmake.ezt 
Sun May 17 17:52:52 2026        (r1934309)
+++ subversion/branches/javahl-1.15/build/generator/templates/targets.cmake.ezt 
Sun May 17 18:22:26 2026        (r1934310)
@@ -49,7 +49,10 @@ if ([targets.enable_condition])[is targe
     [targets.msvc_export][end]
   )[end]
   set_target_properties([targets.name] PROPERTIES OUTPUT_NAME 
"[targets.output_name]")[if-any targets.is_apache_mod]
-  set_target_properties([targets.name] PROPERTIES PREFIX "" SUFFIX ".so")[else]
+  set_target_properties([targets.name] PROPERTIES PREFIX "" SUFFIX ".so")
+  if(WIN32)
+    set_target_properties([targets.name] PROPERTIES IMPORT_PREFIX "")
+  endif()[else]
   set_target_properties([targets.name] PROPERTIES SOVERSION "${SVN_SOVERSION}" 
VERSION "${SVN_SOVERSION}.${SVN_VER_MINOR}.${SVN_VER_PATCH}")[end]
   target_include_directories([targets.name] PUBLIC
     "${CMAKE_CURRENT_SOURCE_DIR}/subversion/include"
@@ -91,6 +94,8 @@ if ([targets.enable_condition])[is targe
   if (WIN32)
     target_sources([targets.name] PRIVATE build/win32/svn.rc)
   endif()[if-any targets.install_target]
-  install(TARGETS [targets.name])[end][end]
+  install(TARGETS [targets.name][if-any targets.is_apache_mod]
+    LIBRARY DESTINATION "${HTTPD_MODULES_DIR}"
+  [end])[end][end]
 endif()
 [end]

Modified: subversion/branches/javahl-1.15/subversion/libsvn_subr/config_file.c
==============================================================================
--- subversion/branches/javahl-1.15/subversion/libsvn_subr/config_file.c        
Sun May 17 17:52:52 2026        (r1934309)
+++ subversion/branches/javahl-1.15/subversion/libsvn_subr/config_file.c        
Sun May 17 18:22:26 2026        (r1934310)
@@ -610,7 +610,7 @@ svn_config__sys_config_path(const char *
   {
     char folder[B_PATH_NAME_LENGTH];
 
-    status_t error = find_directory(B_COMMON_SETTINGS_DIRECTORY, -1, false,
+    status_t error = find_directory(B_SYSTEM_SETTINGS_DIRECTORY, -1, false,
                                     folder, sizeof(folder));
     if (error)
       return SVN_NO_ERROR;

Modified: subversion/branches/javahl-1.15/subversion/libsvn_subr/utf.c
==============================================================================
--- subversion/branches/javahl-1.15/subversion/libsvn_subr/utf.c        Sun May 
17 17:52:52 2026        (r1934309)
+++ subversion/branches/javahl-1.15/subversion/libsvn_subr/utf.c        Sun May 
17 18:22:26 2026        (r1934310)
@@ -1048,7 +1048,8 @@ membuf_insert_ucs4(svn_membuf_t *buf, ap
   ((apr_int32_t*)buf->data)[offset] = value;
 }
 
-/* TODO: Use compiler intrinsics for byte swaps. */
+/* Modern compilers with -O2 optimise it out and replace these with special
+ * instructions (bswap or rev). */
 #define SWAP_SHORT(x)  ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
 #define SWAP_LONG(x)   ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8)    \
                         | (((x) >> 8) & 0xff00) | (((x) >> 24) & 0xff))

Modified: subversion/branches/javahl-1.15/subversion/svnbrowse/model.c
==============================================================================
--- subversion/branches/javahl-1.15/subversion/svnbrowse/model.c        Sun May 
17 17:52:52 2026        (r1934309)
+++ subversion/branches/javahl-1.15/subversion/svnbrowse/model.c        Sun May 
17 18:22:26 2026        (r1934310)
@@ -85,12 +85,12 @@ sort_item_comparison_func(const void *le
 }
 
 svn_error_t *
-svn_browse__state_create(svn_browse__state_t **state_p,
-                         svn_ra_session_t *session,
-                         const char *relpath,
-                         svn_revnum_t revision,
-                         apr_pool_t *result_pool,
-                         apr_pool_t *scratch_pool)
+state_from_dir(svn_browse__state_t **state_p,
+               svn_ra_session_t *session,
+               const char *relpath,
+               svn_revnum_t revision,
+               apr_pool_t *result_pool,
+               apr_pool_t *scratch_pool)
 {
   svn_browse__state_t *state = apr_pcalloc(result_pool, sizeof(*state));
   svn_revnum_t fetched_revnum;
@@ -100,6 +100,7 @@ svn_browse__state_create(svn_browse__sta
   SVN_ERR(svn_ra_get_dir2(session, &dirents, &fetched_revnum, NULL, relpath,
                           revision, SVN_DIRENT_ALL, scratch_pool));
 
+  state->type = svn_browse__state_dir;
   state->relpath = apr_pstrdup(result_pool, relpath);
   state->revision = fetched_revnum;
   state->selection = 0;
@@ -129,6 +130,51 @@ svn_browse__state_create(svn_browse__sta
 }
 
 svn_error_t *
+state_from_file(svn_browse__state_t **state_p,
+                svn_ra_session_t *session,
+                const char *relpath,
+                svn_revnum_t revision,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
+{
+  svn_browse__state_t *state = apr_pcalloc(result_pool, sizeof(*state));
+  svn_revnum_t fetched_revnum;
+  apr_hash_index_t *hi;
+  svn_dirent_t *dirent;
+
+  SVN_ERR(svn_ra_stat(session, relpath, revision, &dirent, scratch_pool));
+
+  state->type = svn_browse__state_file;
+  state->relpath = apr_pstrdup(result_pool, relpath);
+  state->revision = fetched_revnum;
+  state->this_dirent = svn_dirent_dup(dirent, result_pool);
+  state->pool = result_pool;
+
+  *state_p = state;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_browse__state_create(svn_browse__state_t **state_p,
+                         svn_ra_session_t *session,
+                         const char *relpath,
+                         svn_revnum_t revision,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
+{
+  svn_error_t *err;
+
+  err = state_from_dir(state_p, session, relpath, revision, result_pool,
+                       scratch_pool);
+
+  if (err && err->apr_err == SVN_ERR_FS_NOT_DIRECTORY)
+    return svn_error_trace(state_from_file(state_p, session, relpath, revision,
+                                           result_pool, scratch_pool));
+  else
+    return svn_error_trace(err);
+}
+
+svn_error_t *
 svn_browse__model_enter_path(svn_browse__model_t *ctx, const char *relpath,
                  apr_pool_t *scratch_pool)
 {

Modified: subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.c
==============================================================================
--- subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.c    Sun May 
17 17:52:52 2026        (r1934309)
+++ subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.c    Sun May 
17 18:22:26 2026        (r1934310)
@@ -37,6 +37,7 @@
 #include <curses.h>
 
 #include "svn_private_config.h"
+#include "svn_time.h"
 #include "svnbrowse.h"
 
 /* Option codes and descriptions for the command line client.
@@ -263,22 +264,9 @@ view_on_event(svn_browse__view_t *view,
    * 3. The rest of keys remain as their equivalents on the current layout.
    * 4. If shift is held, they just become uppercased.
    */
+
   switch (ch)
     {
-      case KEY_UP:
-      case 'k':
-      case CTRL('p'):
-        SVN_ERR(svn_browse__model_move_selection(view->model, -1));
-        break;
-      case KEY_DOWN:
-      case 'j':
-      case CTRL('n'):
-        SVN_ERR(svn_browse__model_move_selection(view->model, 1));
-        break;
-      case '\n':
-      case '\r':
-        SVN_ERR(svn_browse__model_go_enter(view->model, scratch_pool));
-        break;
       case KEY_BACKSPACE:
       case '-':
       case 'u':
@@ -286,45 +274,72 @@ view_on_event(svn_browse__view_t *view,
         view->model->current->scroller_offset =
             view->model->current->selection - scrollsize / 2;
         break;
-      case CTRL('e'):
-        view->model->current->scroller_offset += 1;
-        break;
-      case CTRL('y'):
-        view->model->current->scroller_offset -= 1;
-        break;
-      case CTRL('d'):
-        SVN_ERR(svn_browse__model_move_selection(view->model, scrollsize / 2));
-        break;
-      case CTRL('f'):
-      case KEY_NPAGE:
-        SVN_ERR(svn_browse__model_move_selection(view->model, scrollsize));
-        break;
-      case CTRL('u'):
-        SVN_ERR(svn_browse__model_move_selection(view->model, -scrollsize / 
2));
-        break;
-      case CTRL('b'):
-      case KEY_PPAGE:
-        SVN_ERR(svn_browse__model_move_selection(view->model, -scrollsize));
-        break;
-      case 'g':
-      case KEY_HOME:
-        view->model->current->selection = 0;
-        break;
-      case 'G':
-      case KEY_END:
-        view->model->current->selection =
-            view->model->current->list->nelts - 1;
-        break;
-      case 'z':
-        view->model->current->scroller_offset =
-            view->model->current->selection - scrollsize / 2;
-        break;
       case 'q':
       case KEY_ESC:
         return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
+      default:
+        break;
     }
 
-  SVN_ERR(svn_browse__model_scroll_in_view(view->model, scrollsize));
+  if (view->model->current->type == svn_browse__state_dir)
+    {
+      switch (ch)
+        {
+          case KEY_UP:
+          case 'k':
+          case CTRL('p'):
+            SVN_ERR(svn_browse__model_move_selection(view->model, -1));
+            break;
+          case KEY_DOWN:
+          case 'j':
+          case CTRL('n'):
+            SVN_ERR(svn_browse__model_move_selection(view->model, 1));
+            break;
+          case '\n':
+          case '\r':
+            SVN_ERR(svn_browse__model_go_enter(view->model, scratch_pool));
+            break;
+          case CTRL('e'):
+            view->model->current->scroller_offset += 1;
+            break;
+          case CTRL('y'):
+            view->model->current->scroller_offset -= 1;
+            break;
+          case CTRL('d'):
+            SVN_ERR(svn_browse__model_move_selection(view->model,
+                                                     scrollsize / 2));
+            break;
+          case CTRL('f'):
+          case KEY_NPAGE:
+            SVN_ERR(svn_browse__model_move_selection(view->model,
+                                                     scrollsize));
+            break;
+          case CTRL('u'):
+            SVN_ERR(svn_browse__model_move_selection(view->model,
+                                                     -scrollsize / 2));
+            break;
+          case CTRL('b'):
+          case KEY_PPAGE:
+            SVN_ERR(svn_browse__model_move_selection(view->model,
+                                                     -scrollsize));
+            break;
+          case 'g':
+          case KEY_HOME:
+            view->model->current->selection = 0;
+            break;
+          case 'G':
+          case KEY_END:
+            view->model->current->selection =
+                view->model->current->list->nelts - 1;
+            break;
+          case 'z':
+            view->model->current->scroller_offset =
+                view->model->current->selection - scrollsize / 2;
+            break;
+        }
+
+      SVN_ERR(svn_browse__model_scroll_in_view(view->model, scrollsize));
+    }
 
   return SVN_NO_ERROR;
 }
@@ -494,6 +509,15 @@ format_percentage_scroll(int scroll, int
     }
 }
 
+static int
+view_get_list_height(const svn_browse__state_t *state)
+{
+  if (state->type == svn_browse__state_dir)
+    return state->list->nelts;
+  else
+    return 0;
+}
+
 static void
 view_draw_footer(svn_browse__view_t *view, WINDOW *win,
                  apr_pool_t *scratch_pool)
@@ -508,26 +532,24 @@ view_draw_footer(svn_browse__view_t *vie
                         getmaxx(win) - 4 - strlen(brand) - 16,
                         scratch_pool));
   waddstr(win, brand);
+
   waddstr(win, leftpad(apr_psprintf(scratch_pool, "%d/%d",
-                                    state->selection + 1, state->list->nelts),
+                                    state->selection + 1,
+                                    view_get_list_height(state)),
                        8, scratch_pool));
   waddstr(win, leftpad(format_percentage_scroll(state->scroller_offset,
-                                                state->list->nelts,
+                                                view_get_list_height(state),
                                                 getmaxy(view->list),
                                                 scratch_pool),
                        8, scratch_pool));
   waddstr(win, "  ");
 }
 
-
 static void
-view_draw(svn_browse__view_t *view, apr_pool_t *pool)
+dir_draw(svn_browse__view_t *view, apr_pool_t *pool)
 {
   int i;
 
-  view_draw_header(view, view->header, pool);
-  view_draw_footer(view, view->footer, pool);
-
   for (i = 0; i < view->model->current->list->nelts; i++)
     {
       svn_browse__item_t *item = APR_ARRAY_IDX(view->model->current->list, i,
@@ -540,6 +562,39 @@ view_draw(svn_browse__view_t *view, apr_
     }
 }
 
+static void
+file_draw(svn_browse__view_t *view, apr_pool_t *pool)
+{
+  const svn_browse__state_t *state = view->model->current;
+
+  mvwprintw(view->list, 0, 0, " File: %s",
+            svn_relpath_basename(state->relpath, pool));
+
+  mvwprintw(view->list, 1, 0, " Last Changed Rev: %ld",
+            state->this_dirent->created_rev);
+  mvwprintw(view->list, 2, 0, " Last Changed Author: %s",
+            state->this_dirent->last_author);
+  mvwprintw(view->list, 3, 0, " Last Changed Date: %s",
+            svn_time_to_human_cstring(state->this_dirent->time, pool));
+}
+
+static void
+view_draw(svn_browse__view_t *view, apr_pool_t *pool)
+{
+  view_draw_header(view, view->header, pool);
+  view_draw_footer(view, view->footer, pool);
+
+  switch (view->model->current->type)
+    {
+      case svn_browse__state_dir:
+        dir_draw(view, pool);
+        break;
+      case svn_browse__state_file:
+        file_draw(view, pool);
+        break;
+    }
+}
+
 static svn_error_t *
 show_usage(apr_pool_t *scratch_pool)
 {

Modified: subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.h
==============================================================================
--- subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.h    Sun May 
17 17:52:52 2026        (r1934309)
+++ subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.h    Sun May 
17 18:22:26 2026        (r1934310)
@@ -68,15 +68,26 @@ typedef struct svn_browse__item_t {
   const svn_dirent_t *dirent;
 } svn_browse__item_t;
 
+typedef enum svn_browse__state_type_e {
+  svn_browse__state_dir,
+  svn_browse__state_file,
+} svn_browse__state_type_e;
+
 /* a state of a single directory */
 typedef struct svn_browse__state_t {
+  svn_browse__state_type_e type;
+
   /* information about this node */
   const char *relpath;
   svn_revnum_t revision;
 
-  /* stores the list of nodes in this state; an array of svn_browse__item_t */
+  /* stores the list of nodes in this state; an array of svn_browse__item_t or
+   * NULL if 'type' is set to svn_browse__state_file */
   apr_array_header_t *list;
 
+  /* only available for files */
+  const svn_dirent_t *this_dirent;
+
   /* the index of hovered item */
   int selection;
   int scroller_offset;

Modified: 
subversion/branches/javahl-1.15/subversion/tests/libsvn_subr/utf-test.c
==============================================================================
--- subversion/branches/javahl-1.15/subversion/tests/libsvn_subr/utf-test.c     
Sun May 17 17:52:52 2026        (r1934309)
+++ subversion/branches/javahl-1.15/subversion/tests/libsvn_subr/utf-test.c     
Sun May 17 18:22:26 2026        (r1934310)
@@ -228,7 +228,8 @@ test_utf_cstring_to_utf8_ex2(apr_pool_t
       const char *from_page;
   } tests[] = {
       {"ascii text\n", "ascii text\n", "unexistent-page"},
-      {"Edelwei\xdf", "Edelwei\xc3\x9f", "ISO-8859-1"}
+      {"Edelwei\xdf", "Edelwei\xc3\x9f", "ISO-8859-1"},
+      {"abc\xF0\x9F\x98\x80", "abc\xF0\x9F\x98\x80", "UTF-8"}
   };
 
   for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
@@ -268,7 +269,8 @@ test_utf_cstring_from_utf8_ex2(apr_pool_
       const char *to_page;
   } tests[] = {
       {"ascii text\n", "ascii text\n", "unexistent-page"},
-      {"Edelwei\xc3\x9f", "Edelwei\xdf", "ISO-8859-1"}
+      {"Edelwei\xc3\x9f", "Edelwei\xdf", "ISO-8859-1"},
+      {"abc\xF0\x9F\x98\x80", "abc\xF0\x9F\x98\x80", "UTF-8"}
   };
 
   for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)

Modified: 
subversion/branches/javahl-1.15/tools/dist/detect-conflicting-backports.py
==============================================================================
--- subversion/branches/javahl-1.15/tools/dist/detect-conflicting-backports.py  
Sun May 17 17:52:52 2026        (r1934309)
+++ subversion/branches/javahl-1.15/tools/dist/detect-conflicting-backports.py  
Sun May 17 18:22:26 2026        (r1934310)
@@ -86,7 +86,7 @@ for entry_para in sf.entries_paras():
     if backport.merger.svn_version() < (1,6):
       output = re.compile('^(......)', re.MULTILINE).sub(r'\1 ', output)
 
-    pattern = re.compile(r'(?:C......|.C.....|......C)\s(.*)', re.MULTILINE)
+    pattern = re.compile(r'^(?:C......|.C.....|......C)\s(.*)$', re.MULTILINE)
     conflicts = pattern.findall(output)
     if conflicts and not entry.depends:
       if len(conflicts) == 1:


Reply via email to