Author: brane
Date: Sat May  9 20:12:26 2026
New Revision: 1934006

Log:
On the javahl-1.15 branch: Upgrade the native implementation to use
svn_client_checkout4 and add support for selecting the WC format version
from Java.

A note about the new VersionNumber class: both Version and RuntimeVersion
are global singletons and don't carry version information themselves. Instead
of rewriting their native implementations, we added VersionNumber as a
vehicle to carry version information that's not bound to the native library.

* BRANCH-README: Update TODO and DONE lists.

[in subversion/bindings/javahl/src/org/apache/subversion/javahl]

* ISVNClient.java
  (ISVNClient.checkout) Deprecate current method and add overload that
   accepts additional parameters wcFormatVersion and storePristines.
  (ISVNClient.defaultWcVersion): New method.
* SVNClient.java
  (SVNClient.checkout): Declare new native method and implement a
   compatibility wrapper for the deprecated version.
  (SVNClient.version, SVNClient.versionMajor,
   SVNClient.versionMinor, SVNClient.versionPatch); Deprecate these static
   methods. They return hard-coded version 0.9.0 and are a hold-over from
   ye olden days.
  (SVNClient.defaultWcVersion,
   SVNClient.oldestWcVersion,
   SVNClient.latestWcVersion): Declare new native methods.

* types/Version.java
  (Version.getInstance): New static factory methods.
  (Version.isAtLeast): Update docstring, add new overload.
  (Version.getNumberTag): Update docstring.
* types/RuntimeVersion.java:
  (RuntimeVersion.getNumberTag): Update docstring.
* types/VersionNumber.java: new, package-private subclass of Version.
  Used to pass WC versions to and return them from other methods.

[in subversion/bindings/javahl/src/org/apache/subversion/javahl]
* BasicTests.java
  (BasicTests.testRuntimeVersion): Avoid calling getRunteimVersion() twice.
  (BasicTests.testDefaultWcVersion,
   BasicTests.testOldestWcVersion,
   BasicTests.testLatestWcVersion,
   BasicTests.testWcVersionOrder) New test cases.

[in subversion/bindings/javahl/native/]

* Version.hpp, Version.cpp: New; native wrapper for the Java Version class.
* jniwrapper/jni_object.hpp, jniwrapper/jni_class_cache.cpp: Add new-style
   declarations for the Java Version class.

* SVNClient.h: Include jniwrapper/jni_env.hpp.
  (SVNClient::checkout): Add parameters wcFormatVersion and storePristines.
  (SVNClient::defaultWcVersion): Declare new method.
* SVNClient.cpp: Include Version.hpp.
  (SVNClient::checkout): Update to use svn_client_checkout4.
  (SVNClient::defaultWcVersion): Implement.

* org_apache_subversion_javahl_SVNClient.cpp: Include svn_client.h,
   Version.hpp, jniwrapper/jni_env.hpp; remove "svn_version.h".
  (Java_org_apache_subversion_javahl_SVNClient_checkout): Update the native
   method implementation, handle wcFormatVersion and storePristines.
  (Java_org_apache_subversion_javahl_SVNClient_defaultWcVersion,
   Java_org_apache_subversion_javahl_SVNClient_oldestWcVersion,
   Java_org_apache_subversion_javahl_SVNClient_latestWcVersion): implement.

Added:
   
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/Version.cpp   
(contents, props changed)
   
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/Version.hpp   
(contents, props changed)
   
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/VersionNumber.java
   (contents, props changed)
Modified:
   subversion/branches/javahl-1.15/BRANCH-README
   
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/SVNClient.cpp
   subversion/branches/javahl-1.15/subversion/bindings/javahl/native/SVNClient.h
   
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/jniwrapper/jni_class_cache.cpp
   
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/jniwrapper/jni_object.hpp
   
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
   
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
   
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
   
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/RuntimeVersion.java
   
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/Version.java
   
subversion/branches/javahl-1.15/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java

Modified: subversion/branches/javahl-1.15/BRANCH-README
==============================================================================
--- subversion/branches/javahl-1.15/BRANCH-README       Sat May  9 20:10:04 
2026        (r1934005)
+++ subversion/branches/javahl-1.15/BRANCH-README       Sat May  9 20:12:26 
2026        (r1934006)
@@ -5,10 +5,19 @@ This is a temporary working branch to up
 
 TODO:
   * Update use of deprecated Subversion APIs:
-    - svn_client_checkout3 -> svn_client_checkout4
     - svn_client_upgrade -> svn_client_upgrade2
     - svn_client_diff6 -> svn_client_diff7
     - svn_client_diff_peg6 -> svn_client_diff_peg7
     - svn_client_revert3 -> svn_client_revert4
   * Add Java wrappers for some new functionality
   * Fix Java warnings where possible without breaking the JRE ABI
+
+DONE:
+  * Update use of deprecated Subversion APIs:
+    - svn_client_checkout3 -> svn_client_checkout4
+  * Add Java wrappers for some new functionality
+    + .types.VersionNumber extends Version (package scope)
+    + .types.Version::getInstance(int major, int minor, int patch)
+    + SVNClient.defaultWcVersion()
+    + SVNClient.oldestWcVersion()
+    + SVNClient.latestWcVersion()

Modified: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/SVNClient.cpp
==============================================================================
--- 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/SVNClient.cpp 
    Sat May  9 20:10:04 2026        (r1934005)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/SVNClient.cpp 
    Sat May  9 20:12:26 2026        (r1934006)
@@ -60,6 +60,7 @@
 #include "DiffOptions.h"
 #include "CreateJ.h"
 #include "JNIStringHolder.h"
+#include "Version.hpp"
 
 #include "svn_auth.h"
 #include "svn_dso.h"
@@ -302,7 +303,9 @@ void SVNClient::logMessages(const char *
 jlong SVNClient::checkout(const char *moduleName, const char *destPath,
                           Revision &revision, Revision &pegRevision,
                           svn_depth_t depth, bool ignoreExternals,
-                          bool allowUnverObstructions)
+                          bool allowUnverObstructions,
+                          const svn_version_t *wcFormatVersion,
+                          svn_tristate_t storePristines)
 {
     SVN::Pool subPool;
 
@@ -319,13 +322,15 @@ jlong SVNClient::checkout(const char *mo
     if (ctx == NULL)
         return -1;
 
-    SVN_JNI_ERR(svn_client_checkout3(&rev, url.c_str(),
+    SVN_JNI_ERR(svn_client_checkout4(&rev, url.c_str(),
                                      path.c_str(),
                                      pegRevision.revision(),
                                      revision.revision(),
                                      depth,
                                      ignoreExternals,
                                      allowUnverObstructions,
+                                     wcFormatVersion,
+                                     storePristines,
                                      ctx,
                                      subPool.getPool()),
                 -1);
@@ -1586,6 +1591,21 @@ void SVNClient::vacuum(const char *path,
                                   ctx, subPool.getPool()), );
 }
 
+jobject SVNClient::defaultWcVersion(::Java::Env env)
+{
+    SVN::Pool subPool(pool);
+    svn_client_ctx_t *ctx = context.getContext(NULL, subPool);
+    if (ctx == NULL)
+        return NULL;
+
+    apr_pool_t *pool = subPool.getPool();
+    const svn_version_t *version = NULL;
+    SVN_JNI_ERR(svn_client_default_wc_version(&version, ctx,
+                                              pool, pool),
+                NULL);
+    return JavaHL::Version::getInstance(env, *version);
+}
+
 jobject
 SVNClient::openRemoteSession(const char* path, int retryAttempts)
 {

Modified: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/SVNClient.h
==============================================================================
--- 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/SVNClient.h   
    Sat May  9 20:10:04 2026        (r1934005)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/SVNClient.h   
    Sat May  9 20:12:26 2026        (r1934006)
@@ -58,6 +58,7 @@ class DiffOptions;
 #include "svn_types.h"
 #include "svn_client.h"
 #include "SVNBase.h"
+#include "jniwrapper/jni_env.hpp"
 
 class SVNClient :public SVNBase
 {
@@ -168,7 +169,9 @@ class SVNClient :public SVNBase
               CommitCallback *callback);
   jlong checkout(const char *moduleName, const char *destPath,
                  Revision &revision, Revision &pegRevsion, svn_depth_t depth,
-                 bool ignoreExternals, bool allowUnverObstructions);
+                 bool ignoreExternals, bool allowUnverObstructions,
+                 const svn_version_t *wcFormatVersion,
+                 svn_tristate_t storePristines);
   void logMessages(const char *path, Revision &pegRevision,
                    std::vector<RevisionRange> &ranges, bool stopOnCopy,
                    bool discoverPaths, bool includeMergedRevisions,
@@ -224,6 +227,7 @@ class SVNClient :public SVNBase
                      Revision &startRevision, Revision &endRevision,
                      svn_depth_t depth, StringArray &changelists,
                      bool ignoreAncestry, DiffSummaryReceiver &receiver);
+  jobject defaultWcVersion(::Java::Env env);
 
   ClientContext &getClientContext();
 

Added: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/Version.cpp
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/Version.cpp   
    Sat May  9 20:12:26 2026        (r1934006)
@@ -0,0 +1,70 @@
+/**
+ * @copyright
+ * ====================================================================
+ *    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.
+ * ====================================================================
+ * @endcopyright
+ */
+
+#include "Version.hpp"
+
+#include "JNIUtil.h"
+
+namespace JavaHL {
+
+// Class JavaHL::Version
+const char* const Version::m_class_name =
+  JAVAHL_CLASS("/types/Version");
+
+Version::ClassImpl::ClassImpl(::Java::Env env, jclass cls)
+  : ::Java::Object::ClassImpl(env, cls),
+    m_mid_get_instance(
+        env.GetStaticMethodID(cls, "getInstance",
+                              "(III)" JAVAHL_ARG("/types/Version") ";")),
+    m_mid_get_major(env.GetMethodID(cls, "getMajor", "()I")),
+    m_mid_get_minor(env.GetMethodID(cls, "getMinor", "()I")),
+    m_mid_get_patch(env.GetMethodID(cls, "getPatch", "()I"))
+{}
+
+Version::ClassImpl::~ClassImpl() {}
+
+
+jobject Version::getInstance(::Java::Env env,
+                             const svn_version_t &version)
+{
+  const ClassImpl &impl =
+    *dynamic_cast<const ClassImpl*>(::Java::ClassCache::get_version(env));
+
+  return env.CallStaticObjectMethod(
+      impl.get_class(), impl.m_mid_get_instance,
+      version.major, version.minor, version.patch);
+}
+
+void Version::getVersion(svn_version_t &version) const
+{
+  jint major = m_env.CallIntMethod(m_jthis, impl().m_mid_get_major);
+  jint minor = m_env.CallIntMethod(m_jthis, impl().m_mid_get_minor);
+  jint patch = m_env.CallIntMethod(m_jthis, impl().m_mid_get_patch);
+
+  version.major = major;
+  version.minor = minor;
+  version.patch = patch;
+  version.tag = "";
+}
+
+} // namespace JavaHL

Added: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/Version.hpp
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/Version.hpp   
    Sat May  9 20:12:26 2026        (r1934006)
@@ -0,0 +1,90 @@
+/**
+ * @copyright
+ * ====================================================================
+ *    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.
+ * ====================================================================
+ * @endcopyright
+ */
+
+#ifndef SVN_JAVAHL_VERSION_HPP
+#define SVN_JAVAHL_VERSION_HPP
+
+#include "jniwrapper/jni_object.hpp"
+
+#include "svn_version.h"
+
+namespace JavaHL {
+
+/**
+ * Object wrapper for @c org.apache.subversion.javahl.types.Version.
+ *
+ * @since New in 1.15.
+ */
+class Version : public ::Java::Object
+{
+public:
+  /**
+   * Constructs a wrapper around @a jthis.
+   * The constructor does not verify the class of the wrapped object.
+   */
+  explicit Version(::Java::Env env, jobject jthis)
+    : ::Java::Object(env, ::Java::ClassCache::get_version(env), jthis)
+    {}
+
+  /**
+   * Constructs a new Version object from an svn_version_t.
+   */
+  static jobject getInstance(::Java::Env env, const svn_version_t &version);
+
+  /**
+   * Fills an svn_version_t from this object.
+   */
+  void getVersion(svn_version_t &version) const;
+
+private:
+  /**
+   * This object's implementation details.
+   */
+  class ClassImpl : public Object::ClassImpl
+  {
+    friend class ::Java::ClassCacheImpl;
+
+  protected:
+    explicit ClassImpl(::Java::Env env, jclass cls);
+
+  public:
+    virtual ~ClassImpl();
+
+    const ::Java::MethodID m_mid_get_instance;
+    const ::Java::MethodID m_mid_get_major;
+    const ::Java::MethodID m_mid_get_minor;
+    const ::Java::MethodID m_mid_get_patch;
+  };
+
+  const ClassImpl& impl() const
+    {
+      return *dynamic_cast<const ClassImpl*>(m_impl);
+    }
+
+  friend class ::Java::ClassCacheImpl;
+  static const char* const m_class_name;
+};
+
+} // namespace JavaHL
+
+#endif // SVN_JAVAHL_VERSION_HPP

Modified: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/jniwrapper/jni_class_cache.cpp
==============================================================================
--- 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/jniwrapper/jni_class_cache.cpp
    Sat May  9 20:10:04 2026        (r1934005)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/jniwrapper/jni_class_cache.cpp
    Sat May  9 20:12:26 2026        (r1934006)
@@ -38,6 +38,7 @@
 #include "jni_string_map.hpp"
 
 #include "../SubversionException.hpp"
+#include "../Version.hpp"
 #include "../AuthnCallback.hpp"
 #include "../Credential.hpp"
 #include "../ExternalItem.hpp"
@@ -188,6 +189,9 @@ class ClassCacheImpl
   JNIWRAPPER_DEFINE_CACHED_CLASS(subversion_exception,
                                  ::JavaHL::SubversionException);
 
+  JNIWRAPPER_DEFINE_CACHED_CLASS(version,
+                                 ::JavaHL::Version);
+
   JNIWRAPPER_DEFINE_CACHED_CLASS(authn_cb,
                                  ::JavaHL::AuthnCallback);
   JNIWRAPPER_DEFINE_CACHED_CLASS(authn_result,
@@ -305,6 +309,8 @@ JNIWRAPPER_IMPL_CLASS_CACHE_ACCESSOR(byt
 
 JNIWRAPPER_IMPL_CLASS_CACHE_ACCESSOR(subversion_exception);
 
+JNIWRAPPER_IMPL_CLASS_CACHE_ACCESSOR(version);
+
 JNIWRAPPER_IMPL_CLASS_CACHE_ACCESSOR(authn_cb);
 JNIWRAPPER_IMPL_CLASS_CACHE_ACCESSOR(authn_result);
 JNIWRAPPER_IMPL_CLASS_CACHE_ACCESSOR(authn_ssl_server_cert_failures);

Modified: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/jniwrapper/jni_object.hpp
==============================================================================
--- 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/jniwrapper/jni_object.hpp
 Sat May  9 20:10:04 2026        (r1934005)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/jniwrapper/jni_object.hpp
 Sat May  9 20:12:26 2026        (r1934006)
@@ -190,6 +190,8 @@ public:
 
   JNIWRAPPER_DECLARE_CACHED_CLASS_ACCESSOR(subversion_exception);
 
+  JNIWRAPPER_DECLARE_CACHED_CLASS_ACCESSOR(version);
+
   JNIWRAPPER_DECLARE_CACHED_CLASS_ACCESSOR(authn_cb);
   JNIWRAPPER_DECLARE_CACHED_CLASS_ACCESSOR(authn_result);
   JNIWRAPPER_DECLARE_CACHED_CLASS_ACCESSOR(authn_ssl_server_cert_failures);

Modified: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
==============================================================================
--- 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
        Sat May  9 20:10:04 2026        (r1934005)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
        Sat May  9 20:12:26 2026        (r1934006)
@@ -52,11 +52,13 @@
 #include "StringArray.h"
 #include "PropertyTable.h"
 #include "CreateJ.h"
+#include "Version.hpp"
 #include "VersionExtended.h"
 #include "DiffOptions.h"
-#include "svn_version.h"
+#include "svn_client.h"
 #include "svn_private_config.h"
 #include "version.h"
+#include "jniwrapper/jni_env.hpp"
 #include <iostream>
 
 JNIEXPORT jlong JNICALL
@@ -382,7 +384,8 @@ JNIEXPORT jlong JNICALL
 Java_org_apache_subversion_javahl_SVNClient_checkout
 (JNIEnv *env, jobject jthis, jstring jmoduleName, jstring jdestPath,
  jobject jrevision, jobject jpegRevision, jobject jdepth,
- jboolean jignoreExternals, jboolean jallowUnverObstructions)
+ jboolean jignoreExternals, jboolean jallowUnverObstructions,
+ jobject jwcFormatVersion, jobject jstorePristines)
 {
   JNIEntry(SVNClient, checkout);
   SVNClient *cl = SVNClient::getCppObject(jthis);
@@ -407,10 +410,22 @@ Java_org_apache_subversion_javahl_SVNCli
   if (JNIUtil::isExceptionThrown())
     return -1;
 
+  svn_version_t version_data;
+  const svn_version_t *version_ptr = NULL;
+  if (jwcFormatVersion != 0)
+    {
+      JavaHL::Version wcFormatVersion(::Java::Env(env), jwcFormatVersion);
+      if (JNIUtil::isExceptionThrown())
+        return -1;
+      wcFormatVersion.getVersion(version_data);
+      version_ptr = &version_data;
+    }
+
   return cl->checkout(moduleName, destPath, revision, pegRevision,
                       EnumMapper::toDepth(jdepth),
                       jignoreExternals ? true : false,
-                      jallowUnverObstructions ? true : false);
+                      jallowUnverObstructions ? true : false,
+                      version_ptr, EnumMapper::toTristate(jstorePristines));
 }
 
 JNIEXPORT void JNICALL
@@ -1994,6 +2009,43 @@ Java_org_apache_subversion_javahl_SVNCli
 }
 
 JNIEXPORT jobject JNICALL
+Java_org_apache_subversion_javahl_SVNClient_defaultWcVersion
+(JNIEnv *env, jobject jthis)
+{
+  JNIEntry(SVNClient, defaultWcVersion);
+  SVNClient *cl = SVNClient::getCppObject(jthis);
+  if (cl == NULL)
+    {
+      JNIUtil::throwError("bad C++ this");
+      return NULL;
+    }
+
+  return cl->defaultWcVersion(::Java::Env(env));
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_apache_subversion_javahl_SVNClient_oldestWcVersion
+(JNIEnv *env, jclass jclazz)
+{
+  JNIEntryStatic(SVNClient, oldestWcVersion);
+  SVN::Pool tmpPool;
+  return JavaHL::Version::getInstance(
+      ::Java::Env(env),
+      *svn_client_oldest_wc_version(tmpPool.getPool()));
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_apache_subversion_javahl_SVNClient_latestWcVersion
+(JNIEnv *env, jclass jclazz)
+{
+  JNIEntryStatic(SVNClient, latestWcVersion);
+  SVN::Pool tmpPool;
+  return JavaHL::Version::getInstance(
+      ::Java::Env(env),
+      *svn_client_latest_wc_version(tmpPool.getPool()));
+}
+
+JNIEXPORT jobject JNICALL
 Java_org_apache_subversion_javahl_SVNClient_nativeOpenRemoteSession
 (JNIEnv *env, jobject jthis, jstring jpath, jint jretryAttempts)
 {

Modified: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
==============================================================================
--- 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
 Sat May  9 20:10:04 2026        (r1934005)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
 Sat May  9 20:12:26 2026        (r1934006)
@@ -237,6 +237,19 @@ public interface ISVNClient
 
     /**
      * Executes a revision checkout.
+     * <p>
+     * Behaves like the 1.15 version with <code>wcFormatVersion = null</code>
+     * and <code>storePristines = Tristate.Unknown</code>
+     * @deprecated
+     */
+    @Deprecated
+    long checkout(String moduleName, String destPath, Revision revision,
+                  Revision pegRevision, Depth depth,
+                  boolean ignoreExternals,
+                  boolean allowUnverObstructions) throws ClientException;
+
+    /**
+     * Executes a revision checkout.
      * @param moduleName name of the module to checkout.
      * @param destPath destination directory for checkout.
      * @param revision the revision to checkout.
@@ -244,12 +257,16 @@ public interface ISVNClient
      * @param depth how deep to checkout files recursively.
      * @param ignoreExternals if externals are ignored during checkout
      * @param allowUnverObstructions allow unversioned paths that obstruct adds
+     * @param wcFormatVersion desired WC compatibiliy version or NULL default
+     * @param storePristines whether to store pristine files
      * @throws ClientException
      */
     long checkout(String moduleName, String destPath, Revision revision,
                   Revision pegRevision, Depth depth,
                   boolean ignoreExternals,
-                  boolean allowUnverObstructions) throws ClientException;
+                  boolean allowUnverObstructions,
+                  Version wcFormatVersion,
+                  Tristate storePristines) throws ClientException;
 
     /**
      * Sets the notification callback used to send processing information back
@@ -1656,6 +1673,8 @@ public interface ISVNClient
                 boolean includeExternals)
             throws ClientException;
 
+    Version defaultWcVersion() throws ClientException;
+
     /**
      * Open a persistent session to a repository.
      * <p>

Modified: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
==============================================================================
--- 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
  Sat May  9 20:10:04 2026        (r1934005)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
  Sat May  9 20:12:26 2026        (r1934006)
@@ -204,11 +204,28 @@ public class SVNClient implements ISVNCl
                                    long limit, LogMessageCallback callback)
             throws ClientException;
 
-    public native long checkout(String moduleName, String destPath,
+    @Deprecated
+    @Override
+    public long checkout(String moduleName, String destPath,
                                 Revision revision, Revision pegRevision,
                                 Depth depth, boolean ignoreExternals,
                                 boolean allowUnverObstructions)
-            throws ClientException;
+            throws ClientException
+    {
+        return checkout(moduleName, destPath,
+                        revision, pegRevision, depth,
+                        ignoreExternals, allowUnverObstructions,
+                        null, Tristate.Unknown);
+    }
+
+    @Override
+    public native long checkout(String moduleName, String destPath,
+                                Revision revision, Revision pegRevision,
+                                Depth depth, boolean ignoreExternals,
+                                boolean allowUnverObstructions,
+                                Version wcFormatVersion,
+                                Tristate storePristines)
+        throws ClientException;
 
     public void notification2(ClientNotifyCallback notify)
     {
@@ -805,28 +822,36 @@ public class SVNClient implements ISVNCl
     /**
      * Returns version information of subversion and the javahl binding
      * @return version information
+     * @deprecated
      */
+    @Deprecated
     public static native String version();
 
     /**
      * Returns the major version of the javahl binding. Same version of the
      * javahl support the same interfaces
      * @return major version number
+     * @deprecated
      */
+    @Deprecated
     public static native int versionMajor();
 
     /**
      * Returns the minor version of the javahl binding. Same version of the
      * javahl support the same interfaces
      * @return minor version number
+     * @deprecated
      */
+    @Deprecated
     public static native int versionMinor();
 
     /**
      * Returns the micro (patch) version of the javahl binding. Same version of
      * the javahl support the same interfaces
      * @return micro version number
+     * @deprecated
      */
+    @Deprecated
     public static native int versionMicro();
 
     public native void lock(Set<String> paths, String comment, boolean force)
@@ -867,6 +892,10 @@ public class SVNClient implements ISVNCl
                               boolean includeExternals)
             throws ClientException;
 
+    public native Version defaultWcVersion() throws ClientException;
+    public static native Version oldestWcVersion();
+    public static native Version latestWcVersion();
+
     public ISVNRemote openRemoteSession(String pathOrUrl)
             throws ClientException, SubversionException
     {

Modified: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/RuntimeVersion.java
==============================================================================
--- 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/RuntimeVersion.java
       Sat May  9 20:10:04 2026        (r1934005)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/RuntimeVersion.java
       Sat May  9 20:12:26 2026        (r1934006)
@@ -65,7 +65,7 @@ public class RuntimeVersion extends Vers
 
     /**
      * @return Some text further describing the library version
-     * (e.g. "r1234", "Alpha 1", "dev build", etc.).
+     * (e.g. "-r1234", "-alpha1", "-dev", etc.).
      */
     private native String getNumberTag();
 }

Modified: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/Version.java
==============================================================================
--- 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/Version.java
      Sat May  9 20:10:04 2026        (r1934005)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/Version.java
      Sat May  9 20:12:26 2026        (r1934006)
@@ -39,6 +39,15 @@ public class Version
     }
 
     /**
+     * Return a Version instance for the given version numbers.
+     * @since 1.15
+     */
+    public static Version getInstance(int major, int minor, int patch)
+    {
+        return new VersionNumber(major, minor, patch);
+    }
+
+    /**
      * @return The full version string for the loaded JavaHL library,
      * as defined by <code>MAJOR.MINOR.PATCH INFO</code>.
      */
@@ -70,8 +79,8 @@ public class Version
     public native int getPatch();
 
     /**
-     * @return Whether the JavaHL native library version is at least
-     * of <code>major.minor.patch</code> level.
+     * @return Whether the version is at least
+     * <code>major.minor.patch</code>.
      */
     public boolean isAtLeast(int major, int minor, int patch)
     {
@@ -84,6 +93,18 @@ public class Version
     }
 
     /**
+     * @return Whether version is at least <code>other</code>.
+     * @since 1.15
+     */
+    public boolean isAtLeast(Version other)
+    {
+        return isAtLeast(other.getMajor(),
+                         other.getMinor(),
+                         other.getPatch());
+    }
+
+
+    /**
      * @return Some text further describing the library version
      * (e.g. <code>" (r1234)"</code>, <code>" (Alpha 1)"</code>,
      * <code>" (dev build)"</code>, etc.).
@@ -92,7 +113,7 @@ public class Version
 
     /**
      * @return Some text further describing the library version
-     * (e.g. "r1234", "Alpha 1", "dev build", etc.).
+     * (e.g. "-r1234", "-alpha1", "-dev", etc.).
      */
     private native String getNumberTag();
 }

Added: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/VersionNumber.java
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/VersionNumber.java
        Sat May  9 20:12:26 2026        (r1934006)
@@ -0,0 +1,81 @@
+/*
+ * ====================================================================
+ *    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.
+ * ====================================================================
+ */
+
+package org.apache.subversion.javahl.types;
+
+/**
+ * A package-level derivation of Version that can hold arbitrary
+ * version numbers used by {@link Version::getInstance}.
+ * @since 1.15
+ */
+class VersionNumber extends Version
+{
+    VersionNumber(int major, int minor, int patch)
+    {
+        this.major = major;
+        this.minor = minor;
+        this.patch = patch;
+    }
+
+    /**
+     * @return The version string <code>MAJOR.MINOR.PATCH</code>.
+     */
+    @Override
+    public String toString()
+    {
+        StringBuffer version = new StringBuffer();
+        version.append(getMajor())
+            .append('.').append(getMinor())
+            .append('.').append(getPatch());
+        return version.toString();
+    }
+
+    /**
+     * @return The major version number..
+     */
+    @Override
+    public int getMajor()
+    {
+        return major;
+    }
+
+    /**
+     * @return The minor version number..
+     */
+    @Override
+    public int getMinor()
+    {
+        return minor;
+    }
+
+    /**
+     * @return The patch-level version number.
+     */
+    @Override
+    public int getPatch()
+    {
+        return patch;
+    }
+
+    private final int major;
+    private final int minor;
+    private final int patch;
+}

Modified: 
subversion/branches/javahl-1.15/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
==============================================================================
--- 
subversion/branches/javahl-1.15/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
       Sat May  9 20:10:04 2026        (r1934005)
+++ 
subversion/branches/javahl-1.15/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
       Sat May  9 20:12:26 2026        (r1934006)
@@ -238,9 +238,10 @@ public class BasicTests extends SVNTests
      */
     public void testRuntimeVersion() throws Throwable
     {
+        RuntimeVersion runtimeVersion = null;
         try
         {
-            RuntimeVersion runtimeVersion = client.getRuntimeVersion();
+            runtimeVersion = client.getRuntimeVersion();
             String versionString = runtimeVersion.toString();
             if (versionString == null || versionString.trim().length() == 0)
             {
@@ -253,7 +254,7 @@ public class BasicTests extends SVNTests
                  "native libraries failed to initialize: " + e);
         }
 
-        RuntimeVersion runtimeVersion = client.getRuntimeVersion();
+        assertNotNull(runtimeVersion);
         Version version = client.getVersion();
         assertTrue(runtimeVersion.getMajor() > version.getMajor()
                    || (runtimeVersion.getMajor() == version.getMajor()
@@ -261,6 +262,98 @@ public class BasicTests extends SVNTests
     }
 
     /**
+     * Test defaultWcVersion
+     * @throws Throwable
+     */
+    public void testDefaultWcVersion() throws Throwable
+    {
+        try
+        {
+            Version defaultWcVersion = client.defaultWcVersion();
+            String versionString = defaultWcVersion.toString();
+            if (versionString == null || versionString.trim().length() == 0)
+            {
+                throw new Exception("Version string empty");
+            }
+        }
+        catch (Exception e)
+        {
+            fail("defaultWcVersion should always be available unless " +
+                 "the native libraries failed to initialize: " + e);
+        }
+    }
+
+    /**
+     * Test oldestWcVersion
+     */
+    public void testOldestWcVersion()
+    {
+        try
+        {
+            Version oldestWcVersion = SVNClient.oldestWcVersion();
+            String versionString = oldestWcVersion.toString();
+            if (versionString == null || versionString.trim().length() == 0)
+            {
+                throw new Exception("Version string empty");
+            }
+        }
+        catch (Exception e)
+        {
+            fail("oldestWcVersion should always be available unless " +
+                 "the native libraries failed to initialize: " + e);
+        }
+    }
+
+    /**
+     * Test latestWcVersion
+     */
+    public void testLatestWcVersion()
+    {
+        try
+        {
+            Version latestWcVersion = SVNClient.latestWcVersion();
+            String versionString = latestWcVersion.toString();
+            if (versionString == null || versionString.trim().length() == 0)
+            {
+                throw new Exception("Version string empty");
+            }
+        }
+        catch (Exception e)
+        {
+            fail("latestWcVersion should always be available unless " +
+                 "the native libraries failed to initialize: " + e);
+        }
+
+    }
+
+    /**
+     * Test relationships between WC versions
+     * @throws Throwable
+     */
+    public void testWcVersionOrder() throws Throwable
+    {
+        Version defaultWcVersion = client.defaultWcVersion();
+        Version oldestWcVersion = SVNClient.oldestWcVersion();
+        Version latestWcVersion = SVNClient.latestWcVersion();
+
+        assertNotEquals(0, defaultWcVersion.getMajor());
+        assertNotEquals(0, defaultWcVersion.getMinor());
+        assertEquals(0, defaultWcVersion.getPatch());
+
+        assertNotEquals(0, oldestWcVersion.getMajor());
+        assertNotEquals(0, oldestWcVersion.getMinor());
+        assertEquals(0, oldestWcVersion.getPatch());
+
+        assertNotEquals(0, latestWcVersion.getMajor());
+        assertNotEquals(0, latestWcVersion.getMinor());
+        assertEquals(0, latestWcVersion.getPatch());
+
+        assertTrue(latestWcVersion.isAtLeast(oldestWcVersion));
+        assertTrue(latestWcVersion.isAtLeast(defaultWcVersion));
+        assertTrue(defaultWcVersion.isAtLeast(oldestWcVersion));
+    }
+
+    /**
      * Test the JNIError class functionality
      * @throws Throwable
      */


Reply via email to