svn commit: r1934006 - in subversion/branches/javahl-1.15: . subversion/bindings/javahl/native subversion/bindings/javahl/native/jniwrapper subversion/bindings/javahl/src/org/apache/subversion/javahl subversion/bindings/javahl/src/org/apache/subversion...

[email protected]
Newsgroups gmane.comp.version-control.subversion.svn
Message-ID <177835754642.656630.16759353252148637377@svn03-he-fi>
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
      */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.