Author: julianfoad
Date: Fri Feb 18 15:27:02 2022
New Revision: 1898187

URL: http://svn.apache.org/viewvc?rev=1898187&view=rev
Log:
Merge the 'multi-wc-format' branch to trunk.

Modified:
    subversion/trunk/   (props changed)
    subversion/trunk/CHANGES
    subversion/trunk/Makefile.in
    subversion/trunk/build.conf
    subversion/trunk/build/run_tests.py
    subversion/trunk/subversion/include/private/svn_wc_private.h
    subversion/trunk/subversion/include/svn_client.h
    subversion/trunk/subversion/include/svn_wc.h
    subversion/trunk/subversion/libsvn_client/checkout.c
    subversion/trunk/subversion/libsvn_client/client.h
    subversion/trunk/subversion/libsvn_client/copy.c
    subversion/trunk/subversion/libsvn_client/deprecated.c
    subversion/trunk/subversion/libsvn_client/externals.c
    subversion/trunk/subversion/libsvn_client/shelf.c
    subversion/trunk/subversion/libsvn_client/upgrade.c
    subversion/trunk/subversion/libsvn_fs_x/   (props changed)
    subversion/trunk/subversion/libsvn_subr/utf8proc/   (props changed)
    subversion/trunk/subversion/libsvn_wc/adm_files.c
    subversion/trunk/subversion/libsvn_wc/deprecated.c
    subversion/trunk/subversion/libsvn_wc/info.c
    subversion/trunk/subversion/libsvn_wc/lock.c
    subversion/trunk/subversion/libsvn_wc/upgrade.c
    subversion/trunk/subversion/libsvn_wc/wc-metadata.sql
    subversion/trunk/subversion/libsvn_wc/wc.h
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h
    subversion/trunk/subversion/libsvn_wc/wc_db_private.h
    subversion/trunk/subversion/libsvn_wc/wc_db_wcroot.c
    subversion/trunk/subversion/svn/checkout-cmd.c
    subversion/trunk/subversion/svn/cl.h
    subversion/trunk/subversion/svn/help-cmd.c
    subversion/trunk/subversion/svn/info-cmd.c
    subversion/trunk/subversion/svn/svn.c
    subversion/trunk/subversion/svn/upgrade-cmd.c
    subversion/trunk/subversion/tests/cmdline/basic_tests.py
    subversion/trunk/subversion/tests/cmdline/getopt_tests.py
    
subversion/trunk/subversion/tests/cmdline/getopt_tests_data/svn--version--verbose_stdout
    
subversion/trunk/subversion/tests/cmdline/getopt_tests_data/svn--version_stdout
    subversion/trunk/subversion/tests/cmdline/svntest/main.py
    subversion/trunk/subversion/tests/cmdline/upgrade_tests.py
    subversion/trunk/subversion/tests/libsvn_client/client-test.c
    subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c
    subversion/trunk/subversion/tests/libsvn_wc/db-test.c
    subversion/trunk/subversion/tests/libsvn_wc/entries-compat.c
    subversion/trunk/subversion/tests/libsvn_wc/utils.c
    subversion/trunk/subversion/tests/libsvn_wc/utils.h
    subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c
    subversion/trunk/subversion/tests/svn_test.h
    subversion/trunk/subversion/tests/svn_test_main.c
    subversion/trunk/tools/buildbot/slaves/win32-vcpkg/   (props changed)

Propchange: subversion/trunk/
------------------------------------------------------------------------------
  Merged /subversion/branches/better-pristines:r1807118-1843075
  Merged /subversion/branches/multi-wc-format:r1843076-1898186

Modified: subversion/trunk/CHANGES
URL: 
http://svn.apache.org/viewvc/subversion/trunk/CHANGES?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/CHANGES (original)
+++ subversion/trunk/CHANGES Fri Feb 18 15:27:02 2022
@@ -7,6 +7,9 @@
 Version 1.15.0
 (?? ??? 20XX, from /branches/1.15.x)
 https://svn.apache.org/repos/asf/subversion/tags/1.15.0
+ User-visible changes:
+  - Client-side improvements and bugfixes:
+    * Support multiple working copy formats (1.8-onward, 1.15) (issue #????)
 
 Version 1.14.1
 (10 Feb 2021, from /branches/1.14.x)

Modified: subversion/trunk/Makefile.in
URL: 
http://svn.apache.org/viewvc/subversion/trunk/Makefile.in?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/Makefile.in (original)
+++ subversion/trunk/Makefile.in Fri Feb 18 15:27:02 2022
@@ -576,6 +576,9 @@ check: bin @TRANSFORM_LIBTOOL_SCRIPTS@ $
          if test "$(SERVER_MINOR_VERSION)" != ""; then                      \
            flags="--server-minor-version $(SERVER_MINOR_VERSION) $$flags";  \
          fi;                                                                \
+         if test "$(WC_FORMAT_VERSION)" != ""; then                         \
+           flags="--wc-format-version $(WC_FORMAT_VERSION) $$flags";        \
+         fi;                                                                \
          if test "$(ENABLE_SASL)" != ""; then                               \
            flags="--enable-sasl $$flags";                                   \
          fi;                                                                \

Modified: subversion/trunk/build.conf
URL: 
http://svn.apache.org/viewvc/subversion/trunk/build.conf?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/build.conf (original)
+++ subversion/trunk/build.conf Fri Feb 18 15:27:02 2022
@@ -768,7 +768,7 @@ link-cmd = $(LINK_SVNXX_TEST)
 type = lib
 path = subversion/tests
 install = test
-libs = libsvn_repos libsvn_fs libsvn_delta libsvn_subr aprutil apriconv apr
+libs = libsvn_repos libsvn_fs libsvn_delta libsvn_wc libsvn_subr aprutil 
apriconv apr
 msvc-static = yes
 undefined-lib-symbols = yes
 
@@ -781,7 +781,7 @@ type = exe
 path = subversion/tests/libsvn_fs_base
 sources = fs-base-test.c
 install = bdb-test
-libs = libsvn_test libsvn_fs libsvn_fs_base libsvn_delta
+libs = libsvn_test libsvn_wc libsvn_fs libsvn_fs_base libsvn_delta
        libsvn_fs_util libsvn_subr apriconv apr
 msvc-force-static = yes
 
@@ -791,7 +791,7 @@ type = exe
 path = subversion/tests/libsvn_fs_base
 sources = strings-reps-test.c
 install = bdb-test
-libs = libsvn_test libsvn_fs libsvn_fs_base libsvn_delta
+libs = libsvn_test libsvn_wc libsvn_fs libsvn_fs_base libsvn_delta
        libsvn_subr apriconv apr
 msvc-force-static = yes
 
@@ -801,7 +801,7 @@ type = exe
 path = subversion/tests/libsvn_fs_base
 sources = changes-test.c
 install = bdb-test
-libs = libsvn_test libsvn_fs libsvn_fs_base libsvn_delta
+libs = libsvn_test libsvn_wc libsvn_fs libsvn_fs_base libsvn_delta
        libsvn_subr apriconv apr
 msvc-force-static = yes
 
@@ -813,7 +813,7 @@ type = exe
 path = subversion/tests/libsvn_fs_fs
 sources = fs-fs-pack-test.c
 install = test
-libs = libsvn_test libsvn_fs libsvn_fs_fs libsvn_delta
+libs = libsvn_test libsvn_wc libsvn_fs libsvn_fs_fs libsvn_delta
        libsvn_subr apriconv apr
 msvc-force-static = yes
 
@@ -823,7 +823,7 @@ type = exe
 path = subversion/tests/libsvn_fs_fs
 sources = fs-fs-fuzzy-test.c
 install = sub-test
-libs = libsvn_test libsvn_fs libsvn_fs_fs libsvn_delta
+libs = libsvn_test libsvn_wc libsvn_fs libsvn_fs_fs libsvn_delta
        libsvn_repos libsvn_subr apriconv apr
 msvc-force-static = yes
 
@@ -833,7 +833,7 @@ type = exe
 path = subversion/tests/libsvn_fs_fs
 sources = fs-fs-private-test.c
 install = test
-libs = libsvn_test libsvn_fs libsvn_fs_fs libsvn_delta
+libs = libsvn_test libsvn_wc libsvn_fs libsvn_fs_fs libsvn_delta
        libsvn_repos libsvn_subr apriconv apr
 msvc-force-static = yes
 
@@ -845,7 +845,7 @@ type = exe
 path = subversion/tests/libsvn_fs_x
 sources = fs-x-pack-test.c
 install = test
-libs = libsvn_test libsvn_fs libsvn_fs_x libsvn_delta
+libs = libsvn_test libsvn_wc libsvn_fs libsvn_fs_x libsvn_delta
        libsvn_subr apriconv apr
 msvc-force-static = yes
 
@@ -855,7 +855,7 @@ type = exe
 path = subversion/tests/libsvn_fs_x
 sources = string-table-test.c
 install = test
-libs = libsvn_test libsvn_fs_x libsvn_subr apr
+libs = libsvn_test libsvn_wc libsvn_fs_x libsvn_subr apr
 msvc-force-static = yes
 
 # ----------------------------------------------------------------------------
@@ -867,7 +867,7 @@ type = exe
 path = subversion/tests/libsvn_fs
 sources = locks-test.c
 install = test
-libs = libsvn_test libsvn_fs libsvn_delta libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_fs libsvn_delta libsvn_subr apriconv apr
 msvc-force-static = yes
 
 [fs-test]
@@ -876,7 +876,7 @@ type = exe
 path = subversion/tests/libsvn_fs
 sources = fs-test.c
 install = test
-libs = libsvn_test libsvn_fs libsvn_delta
+libs = libsvn_test libsvn_wc libsvn_fs libsvn_delta
        libsvn_fs_util libsvn_subr aprutil apriconv apr
 
 [fs-sequential-test]
@@ -885,7 +885,7 @@ type = exe
 path = subversion/tests/libsvn_fs
 sources = fs-sequential-test.c
 install = test
-libs = libsvn_test libsvn_fs libsvn_delta
+libs = libsvn_test libsvn_wc libsvn_fs libsvn_delta
        libsvn_fs_util libsvn_subr aprutil apriconv apr
 
 # ----------------------------------------------------------------------------
@@ -897,7 +897,7 @@ type = exe
 path = subversion/tests/libsvn_repos
 sources = authz-test.c
 install = test
-libs = libsvn_test libsvn_repos libsvn_fs libsvn_delta libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_repos libsvn_fs libsvn_delta libsvn_subr 
apriconv apr
 
 [repos-test]
 description = Test delta editor in libsvn_repos
@@ -905,7 +905,7 @@ type = exe
 path = subversion/tests/libsvn_repos
 sources = repos-test.c dir-delta-editor.c
 install = test
-libs = libsvn_test libsvn_repos libsvn_fs libsvn_delta libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_repos libsvn_fs libsvn_delta libsvn_subr 
apriconv apr
 
 [dump-load-test]
 description = Test dumping/loading repositories in libsvn_repos
@@ -913,7 +913,7 @@ type = exe
 path = subversion/tests/libsvn_repos
 sources = dump-load-test.c
 install = test
-libs = libsvn_test libsvn_repos libsvn_fs libsvn_delta libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_repos libsvn_fs libsvn_delta libsvn_subr 
apriconv apr
 
 # ----------------------------------------------------------------------------
 # Tests for libsvn_subr
@@ -924,7 +924,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = auth-test.c
 install = test
-libs = libsvn_test libsvn_subr apr
+libs = libsvn_test libsvn_wc libsvn_subr apr
 
 [bit-array-test]
 description = Test packed bit arrays
@@ -932,7 +932,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = bit-array-test.c
 install = test
-libs = libsvn_test libsvn_subr apr
+libs = libsvn_test libsvn_wc libsvn_subr apr
 
 [cache-test]
 description = Test in-memory cache
@@ -940,7 +940,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = cache-test.c
 install = test
-libs = libsvn_test libsvn_subr apr
+libs = libsvn_test libsvn_wc libsvn_subr apr
 
 [checksum-test]
 description = Test checksum functions
@@ -948,7 +948,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = checksum-test.c
 install = test
-libs = libsvn_test libsvn_subr apr zlib
+libs = libsvn_test libsvn_wc libsvn_subr apr zlib
 msvc-force-static = yes
 
 [compat-test]
@@ -957,7 +957,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = compat-test.c
 install = test
-libs = libsvn_test libsvn_subr apr
+libs = libsvn_test libsvn_wc libsvn_subr apr
 
 [config-test]
 description = Test svn_config utilities
@@ -965,7 +965,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = config-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [crypto-test]
 description = Test svn_crypto utilities
@@ -973,7 +973,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = crypto-test.c
 install = test
-libs = libsvn_test libsvn_subr aprutil apr
+libs = libsvn_test libsvn_wc libsvn_subr aprutil apr
 msvc-force-static = yes
 
 [dirent_uri-test]
@@ -982,7 +982,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = dirent_uri-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [error-test]
 description = Test error library
@@ -990,7 +990,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = error-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [error-code-test]
 description = Test error library
@@ -998,7 +998,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = error-code-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [hashdump-test]
 description = Test hashfile format for props
@@ -1006,7 +1006,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = hashdump-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [io-test]
 description = Test I/O Operations
@@ -1014,7 +1014,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = io-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [opt-test]
 description = Test options library
@@ -1022,7 +1022,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = opt-test.c
 install = test
-libs = libsvn_test libsvn_subr apr
+libs = libsvn_test libsvn_wc libsvn_subr apr
 
 [mergeinfo-test]
 description = Test mergeinfo library
@@ -1030,7 +1030,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = mergeinfo-test.c
 install = test
-libs = libsvn_test libsvn_subr apr
+libs = libsvn_test libsvn_wc libsvn_subr apr
 
 [packed-data-test]
 description = Test path library
@@ -1038,7 +1038,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = packed-data-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [path-test]
 description = Test path library
@@ -1046,7 +1046,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = path-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [prefix-string-test]
 description = Test path library
@@ -1054,7 +1054,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = prefix-string-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [priority-queue-test]
 description = Test path library
@@ -1062,7 +1062,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = priority-queue-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [revision-test]
 description = Test revision library
@@ -1070,7 +1070,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = revision-test.c
 install = test
-libs = libsvn_test libsvn_subr apr
+libs = libsvn_test libsvn_wc libsvn_subr apr
 
 [root-pools-test]
 description = Test time functions
@@ -1078,7 +1078,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = root-pools-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [skel-test]
 description = Test skels in libsvn_subr
@@ -1086,7 +1086,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = skel-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [spillbuf-test]
 description = Test spillbuf in libsvn_subr
@@ -1094,7 +1094,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = spillbuf-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [stream-test]
 description = Test stream library
@@ -1102,7 +1102,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = stream-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [string-test]
 description = Test svn_stringbuf_t utilities
@@ -1110,7 +1110,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = string-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [sqlite-test]
 description = Test stream library
@@ -1118,7 +1118,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = sqlite-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [task-test]
 description = Test concurrent tasks
@@ -1126,7 +1126,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = task-test.c
 install = test
-libs = libsvn_test libsvn_subr apr
+libs = libsvn_test libsvn_wc libsvn_subr apr
 
 [time-test]
 description = Test time functions
@@ -1134,7 +1134,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = time-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [utf-test]
 description = Test UTF-8 functions
@@ -1142,7 +1142,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = utf-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [subst_translate-test]
 description = Test the svn_subst_translate* functions
@@ -1150,7 +1150,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = subst_translate-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [translate-test]
 description = Test eol conversion and keyword substitution routines
@@ -1158,7 +1158,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = translate-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [x509-test]
 description = Test x509 parser
@@ -1166,7 +1166,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = x509-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [xml-test]
 description = Test XML parser in libsvn_subr
@@ -1174,7 +1174,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = xml-test.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr
 
 [compress-test]
 description = Test compression functions
@@ -1182,7 +1182,7 @@ type = exe
 path = subversion/tests/libsvn_subr
 sources = compress-test.c
 install = test
-libs = libsvn_test libsvn_subr apr
+libs = libsvn_test libsvn_wc libsvn_subr apr
 
 # ----------------------------------------------------------------------------
 # Tests for libsvn_delta
@@ -1193,7 +1193,7 @@ type = exe
 path = subversion/tests/libsvn_delta
 sources = random-test.c
 install = test
-libs = libsvn_test libsvn_delta libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_delta libsvn_subr apriconv apr
 
 [window-test]
 description = Test delta window generation
@@ -1201,7 +1201,7 @@ type = exe
 path = subversion/tests/libsvn_delta
 sources = window-test.c
 install = test
-libs = libsvn_test libsvn_delta libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_delta libsvn_subr apriconv apr
 
 [svndiff-stream-test]
 description = Test svndiff streams
@@ -1209,7 +1209,7 @@ type = exe
 path = subversion/tests/libsvn_delta
 sources = svndiff-stream-test.c
 install = test
-libs = libsvn_test libsvn_delta libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_delta libsvn_subr apriconv apr
 
 # ----------------------------------------------------------------------------
 # Tests for libsvn_client
@@ -1249,7 +1249,7 @@ type = exe
 path = subversion/tests/libsvn_diff
 sources = diff-diff3-test.c
 install = test
-libs = libsvn_test libsvn_diff libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_diff libsvn_subr apriconv apr
 
 [parse-diff-test]
 description = Test unidiff parsing
@@ -1257,7 +1257,7 @@ type = exe
 path = subversion/tests/libsvn_diff
 sources = parse-diff-test.c
 install = test
-libs = libsvn_test libsvn_diff libsvn_subr apriconv apr
+libs = libsvn_test libsvn_wc libsvn_diff libsvn_subr apriconv apr
 
 # ----------------------------------------------------------------------------
 # Tests for libsvn_ra
@@ -1268,7 +1268,7 @@ type = exe
 path = subversion/tests/libsvn_ra
 sources = ra-test.c
 install = test
-libs = libsvn_test libsvn_ra libsvn_ra_svn libsvn_fs libsvn_delta libsvn_subr
+libs = libsvn_test libsvn_wc libsvn_ra libsvn_ra_svn libsvn_fs libsvn_delta 
libsvn_subr
        apriconv apr
 
 # ----------------------------------------------------------------------------
@@ -1280,7 +1280,7 @@ type = exe
 path = subversion/tests/libsvn_ra_local
 sources = ra-local-test.c
 install = test
-libs = libsvn_test libsvn_ra_local libsvn_ra libsvn_fs libsvn_delta libsvn_subr
+libs = libsvn_test libsvn_wc libsvn_ra_local libsvn_ra libsvn_fs libsvn_delta 
libsvn_subr
        apriconv apr
 
 # ----------------------------------------------------------------------------
@@ -1337,7 +1337,7 @@ type = exe
 path = subversion/tests/libsvn_wc
 sources = wc-queries-test.c ../../libsvn_subr/sqlite3wrapper.c
 install = test
-libs = libsvn_test libsvn_subr apriconv apr sqlite
+libs = libsvn_test libsvn_wc libsvn_subr apriconv apr sqlite
 
 [wc-test]
 description = Test the main WC API functions

Modified: subversion/trunk/build/run_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/build/run_tests.py?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/build/run_tests.py (original)
+++ subversion/trunk/build/run_tests.py Fri Feb 18 15:27:02 2022
@@ -29,7 +29,8 @@
             [--url=<base-url>] [--http-library=<http-library>] [--enable-sasl]
             [--fs-type=<fs-type>] [--fsfs-packing] [--fsfs-sharding=<n>]
             [--list] [--milestone-filter=<regex>] [--mode-filter=<type>]
-            [--server-minor-version=<version>] [--http-proxy=<host>:<port>]
+            [--server-minor-version=<version>] [--wc-format-version=<version>]
+            [--http-proxy=<host>:<port>]
             [--httpd-version=<version>] [--httpd-whitelist=<version>]
             [--config-file=<file>] [--ssl-cert=<file>]
             [--exclusive-wc-locks] [--memcached-server=<url:port>]
@@ -257,6 +258,8 @@ class TestHarness:
     if self.opts.server_minor_version is not None:
       cmdline.append('--server-minor-version=%d' %
                      self.opts.server_minor_version)
+    if self.opts.wc_format_version is not None:
+      cmdline.append('--wc-format-version=%s' % self.opts.wc_format_version)
     if self.opts.mode_filter is not None:
       cmdline.append('--mode-filter=' + self.opts.mode_filter)
     if self.opts.parallel is not None:
@@ -292,6 +295,8 @@ class TestHarness:
       cmdline.append('--fsfs-version=%d' % self.opts.fsfs_version)
     if self.opts.server_minor_version is not None:
       cmdline.append('--server-minor-version=%d' % 
self.opts.server_minor_version)
+    if self.opts.wc_format_version is not None:
+      cmdline.append('--wc-format-version=%s' % self.opts.wc_format_version)
     if self.opts.dump_load_cross_check is not None:
       cmdline.append('--dump-load-cross-check')
     if self.opts.enable_sasl is not None:
@@ -1037,6 +1042,8 @@ def create_parser():
                     help="Run 'svnadmin pack' automatically")
   parser.add_option('--server-minor-version', type='int', action='store',
                     help="Set the minor version for the server")
+  parser.add_option('--wc-format-version', action='store',
+                    help="Set the WC format version")
   parser.add_option('--skip-c-tests', '--skip-C-tests', action='store_true',
                     help="Run only the Python tests")
   parser.add_option('--dump-load-cross-check', action='store_true',

Modified: subversion/trunk/subversion/include/private/svn_wc_private.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_wc_private.h?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_wc_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_wc_private.h Fri Feb 18 
15:27:02 2022
@@ -2179,6 +2179,141 @@ svn_error_t *
 svn_wc__working_file_writer_close(svn_wc__working_file_writer_t *writer);
 
 
+/**
+ * Convert @a version to that version's characteristic working copy
+ * format, returned in @a format.
+ *
+ * A NULL @a version translates to the library's default version.
+ *
+ * Use @a scratch_pool for temporary allocations.
+ *
+ * @since New in 1.15.
+ */
+svn_error_t *
+svn_wc__format_from_version(int *format,
+                            const svn_version_t* version,
+                            apr_pool_t *scratch_pool);
+
+/**
+ * Return true iff @a format is a supported format.
+ */
+svn_boolean_t
+svn_wc__is_supported_format(int format);
+
+/**
+ * Return the highest WC format supported by this client.
+ */
+int
+svn_wc__max_supported_format(void);
+
+/**
+ * Return the lowest WC format supported by this client.
+ */
+int
+svn_wc__min_supported_format(void);
+
+/**
+ * Return true iff @a version is a supported format version.
+ */
+svn_boolean_t
+svn_wc__is_supported_format_version(const svn_version_t *version);
+
+/**
+ * Return the highest WC format supported by this client.
+ */
+const svn_version_t *
+svn_wc__max_supported_format_version(void);
+
+/**
+ * Return the lowest WC format supported by this client.
+ */
+const svn_version_t *
+svn_wc__min_supported_format_version(void);
+
+/**
+ * Set @a format to the format of the nearest parent working copy root of
+ * @a local_abspath in @a wc_ctx, or to the oldest format of any root stored
+ * there. If @a wc_ctx is empty, return the library's default format.
+ *
+ * Use @a scratch_pool for temporary allocations.
+ *
+ * @since New in 1.15.
+ */
+svn_error_t *
+svn_wc__format_from_context(int *format,
+                            svn_wc_context_t *wc_ctx,
+                            const char *local_abspath,
+                            apr_pool_t *scratch_pool);
+
+/**
+ * Ensure that an administrative area exists for @a local_abspath, so that @a
+ * local_abspath is a working copy subdir with schema version @a target_format
+ * based on @a url at @a revision, with depth @a depth, and with repository 
UUID
+ * @a repos_uuid and repository root URL @a repos_root_url.
+ *
+ * @a depth must be a definite depth, it cannot be #svn_depth_unknown.
+ * @a repos_uuid and @a repos_root_url MUST NOT be @c NULL, and
+ * @a repos_root_url must be a prefix of @a url.
+ *
+ * If the administrative area does not exist, then create it and
+ * initialize it to an unlocked state.
+ *
+ * If the administrative area already exists then the given @a url
+ * must match the URL in the administrative area and the given
+ * @a revision must match the BASE of the working copy dir unless
+ * the admin directory is scheduled for deletion or the
+ * #SVN_ERR_WC_OBSTRUCTED_UPDATE error will be returned.
+ *
+ * Do not ensure existence of @a local_abspath itself; if @a local_abspath
+ * does not exist, return error.
+ *
+ * Use @a scratch_pool for temporary allocations.
+ *
+ * @since New in 1.15.
+ */
+svn_error_t *
+svn_wc__ensure_adm(svn_wc_context_t *wc_ctx,
+                   int target_format,
+                   const char *local_abspath,
+                   const char *url,
+                   const char *repos_root_url,
+                   const char *repos_uuid,
+                   svn_revnum_t revision,
+                   svn_depth_t depth,
+                   apr_pool_t *scratch_pool);
+
+/**
+ * Upgrade the working copy at @a local_abspath to the metadata
+ * storage format indicated by @a target_format.  @a local_abspath
+ * should be an absolute path to the root of the working copy.
+ *
+ * If @a cancel_func is non-NULL, invoke it with @a cancel_baton at
+ * various points during the operation.  If it returns an error
+ * (typically #SVN_ERR_CANCELLED), return that error immediately.
+ *
+ * For each directory converted, @a notify_func will be called with
+ * in @a notify_baton action #svn_wc_notify_upgraded_path and as path
+ * the path of the upgraded directory. @a notify_func may be @c NULL
+ * if this notification is not needed.
+ *
+ * If the old working copy doesn't contain a repository root and/or
+ * repository uuid, @a repos_info_func (if non-NULL) will be called
+ * with @a repos_info_baton to provide the missing information.
+ *
+ * @since New in 1.15.
+ */
+svn_error_t *
+svn_wc__upgrade(svn_wc_context_t *wc_ctx,
+                const char *local_abspath,
+                int target_format,
+                svn_wc_upgrade_get_repos_info_t repos_info_func,
+                void *repos_info_baton,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
+                svn_wc_notify_func2_t notify_func,
+                void *notify_baton,
+                apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/trunk/subversion/include/svn_client.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Fri Feb 18 15:27:02 2022
@@ -1240,6 +1240,11 @@ svn_client_args_to_target_array(apr_arra
  *              set equal to the base properties. <br>
  *              If @c FALSE, then abort if there are any unversioned
  *              obstructing items.
+ * @param[in] wc_format_version is the version number of the Subversion
+ *              client that supports the metadata format of the
+ *              created working copy; @c NULL means the library's default
+ *              format. The earliest supported version is returned by
+ *              svn_client_supported_wc_version().
  * @param[in] ctx   The standard client context, used for authentication and
  *              notification.
  * @param[in] pool  Used for any temporary allocation.
@@ -1254,13 +1259,13 @@ svn_client_args_to_target_array(apr_arra
  *         #svn_opt_revision_date. <br>
  *         If no error occurred, return #SVN_NO_ERROR.
  *
- * @since New in 1.5.
+ * @since New in 1.15.
  *
  * @see #svn_depth_t <br> #svn_client_ctx_t <br> @ref clnt_revisions for
  *      a discussion of operative and peg revisions.
  */
 svn_error_t *
-svn_client_checkout3(svn_revnum_t *result_rev,
+svn_client_checkout4(svn_revnum_t *result_rev,
                      const char *URL,
                      const char *path,
                      const svn_opt_revision_t *peg_revision,
@@ -1268,9 +1273,29 @@ svn_client_checkout3(svn_revnum_t *resul
                      svn_depth_t depth,
                      svn_boolean_t ignore_externals,
                      svn_boolean_t allow_unver_obstructions,
+                     const svn_version_t *wc_format_version,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *pool);
 
+/**
+ * Similar to svn_client_checkout4() but always creates the newest
+ * supported working copy format.
+ *
+ * @since New in 1.5.
+ * @deprecated Provided for backward compatibility with the 1.10 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
+svn_client_checkout3(svn_revnum_t *result_rev,
+                     const char *URL,
+                     const char *path,
+                     const svn_opt_revision_t *peg_revision,
+                     const svn_opt_revision_t *revision,
+                     svn_depth_t depth,
+                     svn_boolean_t ignore_externals,
+                     svn_boolean_t allow_unver_obstructions,
+                     svn_client_ctx_t *ctx,
+                     apr_pool_t *pool);
 
 /**
  * Similar to svn_client_checkout3() but with @a allow_unver_obstructions
@@ -4369,18 +4394,47 @@ svn_client_cleanup(const char *dir,
  * @{
  */
 
-/** Recursively upgrade a working copy from any older format to the current
- * WC metadata storage format.  @a wcroot_dir is the path to the WC root.
+/**
+ * Recursively upgrade a working copy and nested externals working
+ * copies from any older format to the given WC metadata storage
+ * format.  @a wcroot_dir is the path to the WC root.
+ *
+ * @a wc_format_version is the version number of the Subversion client
+ * that supports a given WC metadata format; @c NULL means the library's
+ * default format. The earliest supported version is returned by
+ * svn_client_supported_wc_version().
  *
  * Use @a scratch_pool for any temporary allocations.
  *
+ * @since New in 1.15.
+ */
+svn_error_t *
+svn_client_upgrade2(const char *wcroot_dir,
+                    const svn_version_t *wc_format_version,
+                    svn_client_ctx_t *ctx,
+                    apr_pool_t *scratch_pool);
+
+/**
+ * Like svn_client_upgrade2(), but always upgrades to the newest
+ * supported format.
+ *
  * @since New in 1.7.
+ * @deprecated Provided for backward compatibility with the 1.14 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_client_upgrade(const char *wcroot_dir,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *scratch_pool);
 
+/**
+ * Returns the version related to the earliest supported
+ * working copy metadata format.
+ *
+ * @since New in 1.15.
+ */
+const svn_version_t *
+svn_client_supported_wc_version(void);
 
 /** @} */
 

Modified: subversion/trunk/subversion/include/svn_wc.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_wc.h?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_wc.h (original)
+++ subversion/trunk/subversion/include/svn_wc.h Fri Feb 18 15:27:02 2022
@@ -3292,6 +3292,24 @@ typedef struct svn_wc_info_t
   /** The path the node was moved to, if it was moved away. Else NULL.
    * @since New in 1.8. */
   const char *moved_to_abspath;
+
+  /**
+   * The format of the working copy.
+   * @since New in 1.15.
+   */
+  int wc_format;
+
+  /**
+   * The oldest supporter working copy format.
+   * @since New in 1.15.
+   */
+  int wc_format_min;
+
+  /**
+   * The newest supporter working copy format.
+   * @since New in 1.15.
+   */
+  int wc_format_max;
 } svn_wc_info_t;
 
 /**
@@ -3526,7 +3544,8 @@ svn_wc_mark_missing_deleted(const char *
                             apr_pool_t *pool);
 
 
-/** Ensure that an administrative area exists for @a local_abspath, so
+/**
+ * Ensure that an administrative area exists for @a local_abspath, so
  * that @a local_abspath is a working copy subdir based on @a url at @a
  * revision, with depth @a depth, and with repository UUID @a repos_uuid
  * and repository root URL @a repos_root_url.
@@ -3536,7 +3555,8 @@ svn_wc_mark_missing_deleted(const char *
  * @a repos_root_url must be a prefix of @a url.
  *
  * If the administrative area does not exist, then create it and
- * initialize it to an unlocked state.
+ * initialize it to an unlocked state. The format of the new
+ * administrative area will always be the newset supported format.
  *
  * If the administrative area already exists then the given @a url
  * must match the URL in the administrative area and the given
@@ -3550,7 +3570,9 @@ svn_wc_mark_missing_deleted(const char *
  * Use @a scratch_pool for temporary allocations.
  *
  * @since New in 1.7.
+ * @deprecated Provided for backwards compatibility with the 1.14 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_wc_ensure_adm4(svn_wc_context_t *wc_ctx,
                    const char *local_abspath,
@@ -7451,8 +7473,10 @@ typedef svn_error_t * (*svn_wc_upgrade_g
  * repository uuid, @a repos_info_func (if non-NULL) will be called
  * with @a repos_info_baton to provide the missing information.
  *
- * @since New in 1.7.
+ * @since New in 1.7
+ * @deprecated Provided for backward compatibility with the 1.14 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_wc_upgrade(svn_wc_context_t *wc_ctx,
                const char *local_abspath,

Modified: subversion/trunk/subversion/libsvn_client/checkout.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/checkout.c?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/checkout.c (original)
+++ subversion/trunk/subversion/libsvn_client/checkout.c Fri Feb 18 15:27:02 
2022
@@ -48,7 +48,8 @@
 /*** Public Interfaces. ***/
 
 static svn_error_t *
-initialize_area(const char *local_abspath,
+initialize_area(int target_format,
+                const char *local_abspath,
                 const svn_client__pathrev_t *pathrev,
                 svn_depth_t depth,
                 svn_client_ctx_t *ctx,
@@ -58,7 +59,8 @@ initialize_area(const char *local_abspat
     depth = svn_depth_infinity;
 
   /* Make the unversioned directory into a versioned one.  */
-  SVN_ERR(svn_wc_ensure_adm4(ctx->wc_ctx, local_abspath, pathrev->url,
+  SVN_ERR(svn_wc__ensure_adm(ctx->wc_ctx,
+                             target_format, local_abspath, pathrev->url,
                              pathrev->repos_root_url, pathrev->repos_uuid,
                              pathrev->rev, depth, pool));
   return SVN_NO_ERROR;
@@ -75,10 +77,12 @@ svn_client__checkout_internal(svn_revnum
                               svn_depth_t depth,
                               svn_boolean_t ignore_externals,
                               svn_boolean_t allow_unver_obstructions,
+                              const svn_version_t *wc_format_version,
                               svn_ra_session_t *ra_session,
                               svn_client_ctx_t *ctx,
                               apr_pool_t *scratch_pool)
 {
+  int target_format;
   svn_node_kind_t kind;
   svn_client__pathrev_t *pathrev;
   svn_opt_revision_t resolved_rev = { svn_opt_revision_number };
@@ -94,6 +98,15 @@ svn_client__checkout_internal(svn_revnum
       && (revision->kind != svn_opt_revision_head))
     return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);
 
+  /* Here the default for wc_format_version is determined from WC context,
+   * rather than the library's default version. */
+  if (wc_format_version)
+    SVN_ERR(svn_wc__format_from_version(&target_format, wc_format_version,
+                                        scratch_pool));
+  else
+    SVN_ERR(svn_wc__format_from_context(&target_format, ctx->wc_ctx,
+                                        local_abspath, scratch_pool));
+
   /* Get the RA connection, if needed. */
   if (ra_session)
     {
@@ -144,21 +157,21 @@ svn_client__checkout_internal(svn_revnum
          entries file should only have an entry for THIS_DIR with a
          URL, revnum, and an 'incomplete' flag.  */
       SVN_ERR(svn_io_make_dir_recursively(local_abspath, scratch_pool));
-      SVN_ERR(initialize_area(local_abspath, pathrev, depth, ctx,
-                              scratch_pool));
+      SVN_ERR(initialize_area(target_format, local_abspath, pathrev, depth,
+                              ctx, scratch_pool));
     }
   else if (kind == svn_node_dir)
     {
-      int wc_format;
+      int present_format;
       const char *entry_url;
 
-      SVN_ERR(svn_wc_check_wc2(&wc_format, ctx->wc_ctx, local_abspath,
+      SVN_ERR(svn_wc_check_wc2(&present_format, ctx->wc_ctx, local_abspath,
                                scratch_pool));
 
-      if (! wc_format)
+      if (! present_format)
         {
-          SVN_ERR(initialize_area(local_abspath, pathrev, depth, ctx,
-                                  scratch_pool));
+          SVN_ERR(initialize_area(target_format, local_abspath, pathrev, depth,
+                                  ctx, scratch_pool));
         }
       else
         {
@@ -171,10 +184,18 @@ svn_client__checkout_internal(svn_revnum
              interrupted checkout.  Otherwise bail out. */
           if (strcmp(entry_url, pathrev->url) != 0)
             return svn_error_createf(
-                          SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
-                          _("'%s' is already a working copy for a"
-                            " different URL"),
-                          svn_dirent_local_style(local_abspath, scratch_pool));
+                SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
+                _("'%s' is already a working copy for a different URL"),
+                svn_dirent_local_style(local_abspath, scratch_pool));
+
+          /* Warn if the existing WC's format is different than requested. */
+          if (present_format != target_format)
+            return svn_error_createf(
+                SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
+                _("'%s' is already a working copy for the same URL"
+                  " but its format is %d instead of the expected %d"),
+                svn_dirent_local_style(local_abspath, scratch_pool),
+                present_format, target_format);
         }
     }
   else
@@ -198,7 +219,7 @@ svn_client__checkout_internal(svn_revnum
 }
 
 svn_error_t *
-svn_client_checkout3(svn_revnum_t *result_rev,
+svn_client_checkout4(svn_revnum_t *result_rev,
                      const char *URL,
                      const char *path,
                      const svn_opt_revision_t *peg_revision,
@@ -206,6 +227,7 @@ svn_client_checkout3(svn_revnum_t *resul
                      svn_depth_t depth,
                      svn_boolean_t ignore_externals,
                      svn_boolean_t allow_unver_obstructions,
+                     const svn_version_t *wc_format_version,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *pool)
 {
@@ -215,11 +237,16 @@ svn_client_checkout3(svn_revnum_t *resul
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
 
+  /* A NULL wc_format_version translates to the default version. */
+  if (!wc_format_version)
+    wc_format_version = svn_client_supported_wc_version();
+
   err = svn_client__checkout_internal(result_rev, &sleep_here,
                                       URL, local_abspath,
                                       peg_revision, revision, depth,
                                       ignore_externals,
                                       allow_unver_obstructions,
+                                      wc_format_version,
                                       NULL /* ra_session */,
                                       ctx, pool);
   if (sleep_here)

Modified: subversion/trunk/subversion/libsvn_client/client.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/client.h?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/client.h (original)
+++ subversion/trunk/subversion/libsvn_client/client.h Fri Feb 18 15:27:02 2022
@@ -539,6 +539,11 @@ svn_client__update_internal(svn_revnum_t
    the repos are tolerated; if FALSE, these obstructions cause the checkout
    to fail.
 
+   A new working copy, if needed, will be created in the format corresponding
+   to the WC_FORMAT_VERSION of the client. If this parameter is NULL, the
+   format will be determined from context (see svn_wc__format_from_context).
+   The format of any existing working copy will remain unchanged.
+
    If RA_SESSION is NOT NULL, it may be used to avoid creating a new
    session. The session may point to a different URL after returning.
    */
@@ -552,6 +557,7 @@ svn_client__checkout_internal(svn_revnum
                               svn_depth_t depth,
                               svn_boolean_t ignore_externals,
                               svn_boolean_t allow_unver_obstructions,
+                              const svn_version_t *wc_format_version,
                               svn_ra_session_t *ra_session,
                               svn_client_ctx_t *ctx,
                               apr_pool_t *pool);

Modified: subversion/trunk/subversion/libsvn_client/copy.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/copy.c?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/copy.c (original)
+++ subversion/trunk/subversion/libsvn_client/copy.c Fri Feb 18 15:27:02 2022
@@ -2487,6 +2487,7 @@ svn_client__repos_to_wc_copy_dir(svn_boo
                                         svn_depth_infinity,
                                         TRUE /*ignore_externals*/,
                                         FALSE, /* we don't allow obstructions 
*/
+                                        NULL, /* default WC format */
                                         ra_session, ctx, scratch_pool);
 
     ctx->notify_func2 = old_notify_func2;

Modified: subversion/trunk/subversion/libsvn_client/deprecated.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/deprecated.c?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_client/deprecated.c Fri Feb 18 15:27:02 
2022
@@ -2669,6 +2669,24 @@ svn_client_cat(svn_stream_t *out,
 
 /*** From checkout.c ***/
 svn_error_t *
+svn_client_checkout3(svn_revnum_t *result_rev,
+                     const char *URL,
+                     const char *path,
+                     const svn_opt_revision_t *peg_revision,
+                     const svn_opt_revision_t *revision,
+                     svn_depth_t depth,
+                     svn_boolean_t ignore_externals,
+                     svn_boolean_t allow_unver_obstructions,
+                     svn_client_ctx_t *ctx,
+                     apr_pool_t *pool)
+{
+  return svn_error_trace(svn_client_checkout4(
+                             result_rev, URL, path,
+                             peg_revision, revision, depth,
+                             ignore_externals, FALSE, NULL, ctx, pool));
+}
+
+svn_error_t *
 svn_client_checkout2(svn_revnum_t *result_rev,
                      const char *URL,
                      const char *path,
@@ -3261,3 +3279,12 @@ svn_client_cleanup(const char *path,
                                              FALSE /* include_externals */,
                                              ctx, scratch_pool));
 }
+
+/*** From upgrade.c ***/
+svn_error_t *
+svn_client_upgrade(const char *path,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(svn_client_upgrade2(path, NULL, ctx, scratch_pool));
+}

Modified: subversion/trunk/subversion/libsvn_client/externals.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/externals.c?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/externals.c (original)
+++ subversion/trunk/subversion/libsvn_client/externals.c Fri Feb 18 15:27:02 
2022
@@ -412,6 +412,7 @@ switch_dir_external(const char *local_ab
                                         url, local_abspath, peg_revision,
                                         revision, svn_depth_infinity,
                                         FALSE, FALSE,
+                                        NULL, /* default WC format */
                                         ra_session,
                                         ctx, pool));
 

Modified: subversion/trunk/subversion/libsvn_client/shelf.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/shelf.c?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/shelf.c (original)
+++ subversion/trunk/subversion/libsvn_client/shelf.c Fri Feb 18 15:27:02 2022
@@ -1033,6 +1033,7 @@ shelf_copy_base(svn_client__shelf_versio
                                         svn_depth_infinity,
                                         TRUE /*ignore_externals*/,
                                         FALSE /*allow_unver_obstructions*/,
+                                        NULL, /* default WC format */
                                         ra_session,
                                         ctx, scratch_pool));
   /* ### hopefully we won't eventually need to sleep_here... */

Modified: subversion/trunk/subversion/libsvn_client/upgrade.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/upgrade.c?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_client/upgrade.c Fri Feb 18 15:27:02 2022
@@ -34,8 +34,10 @@
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
 #include "svn_pools.h"
-#include "client.h"
 #include "svn_props.h"
+#include "svn_version.h"
+
+#include "client.h"
 
 #include "svn_private_config.h"
 #include "private/svn_wc_private.h"
@@ -89,13 +91,15 @@ fetch_repos_info(const char **repos_root
 static svn_error_t *
 upgrade_externals_from_properties(svn_client_ctx_t *ctx,
                                   const char *local_abspath,
+                                  int wc_format,
                                   struct repos_info_baton *info_baton,
                                   apr_pool_t *scratch_pool);
 
-svn_error_t *
-svn_client_upgrade(const char *path,
-                   svn_client_ctx_t *ctx,
-                   apr_pool_t *scratch_pool)
+static svn_error_t *
+upgrade_internal(const char *path,
+                 int wc_format,
+                 svn_client_ctx_t *ctx,
+                 apr_pool_t *scratch_pool)
 {
   const char *local_abspath;
   apr_hash_t *externals;
@@ -111,11 +115,11 @@ svn_client_upgrade(const char *path,
                              _("'%s' is not a local path"), path);
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
-  SVN_ERR(svn_wc_upgrade(ctx->wc_ctx, local_abspath,
-                         fetch_repos_info, &info_baton,
-                         ctx->cancel_func, ctx->cancel_baton,
-                         ctx->notify_func2, ctx->notify_baton2,
-                         scratch_pool));
+  SVN_ERR(svn_wc__upgrade(ctx->wc_ctx, local_abspath, wc_format,
+                          fetch_repos_info, &info_baton,
+                          ctx->cancel_func, ctx->cancel_baton,
+                          ctx->notify_func2, ctx->notify_baton2,
+                          scratch_pool));
 
   SVN_ERR(svn_wc__externals_defined_below(&externals,
                                           ctx->wc_ctx, local_abspath,
@@ -149,7 +153,8 @@ svn_client_upgrade(const char *path,
 
           if (kind == svn_node_dir)
             {
-              svn_error_t *err = svn_client_upgrade(ext_abspath, ctx, 
iterpool);
+              svn_error_t *err = upgrade_internal(ext_abspath, wc_format,
+                                                  ctx, iterpool);
 
               if (err)
                 {
@@ -173,16 +178,40 @@ svn_client_upgrade(const char *path,
       /* Upgrading from <= 1.6, or no svn:properties defined.
          (There is no way to detect the difference from libsvn_client :( ) */
 
-      SVN_ERR(upgrade_externals_from_properties(ctx, local_abspath,
+      SVN_ERR(upgrade_externals_from_properties(ctx, local_abspath, wc_format,
                                                 &info_baton, scratch_pool));
     }
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_client_upgrade2(const char *path,
+                    const svn_version_t *wc_format_version,
+                    svn_client_ctx_t *ctx,
+                    apr_pool_t *scratch_pool)
+{
+  int wc_format;
+
+  SVN_ERR(svn_wc__format_from_version(&wc_format,
+                                      wc_format_version,
+                                      scratch_pool));
+  SVN_ERR(upgrade_internal(path, wc_format, ctx, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+const svn_version_t *
+svn_client_supported_wc_version(void)
+{
+  /* NOTE: For consistency, always return the version of the client
+     that first introduced the earliest supported format. */
+  static const svn_version_t version = { 1, 8, 0, NULL };
+  return &version;
+}
+
 /* Helper for upgrade_externals_from_properties: upgrades one external ITEM
    in EXTERNALS_PARENT. Uses SCRATCH_POOL for temporary allocations. */
 static svn_error_t *
-upgrade_external_item(svn_client_ctx_t *ctx,
+upgrade_external_item(svn_client_ctx_t *ctx, int wc_format,
                       const char *externals_parent_abspath,
                       const char *externals_parent_url,
                       const char *externals_parent_repos_root_url,
@@ -211,7 +240,7 @@ upgrade_external_item(svn_client_ctx_t *
               externals_parent_url,
               scratch_pool, scratch_pool));
 
-  /* This is a hack. We only need to call svn_wc_upgrade() on external
+  /* This is a hack. We only need to call svn_wc__upgrade() on external
    * dirs, as file externals are upgraded along with their defining
    * WC.  Reading the kind will throw an exception on an external dir,
    * saying that the wc must be upgraded.  If it's a file, the lookup
@@ -225,7 +254,7 @@ upgrade_external_item(svn_client_ctx_t *
     {
       svn_error_clear(err);
 
-      SVN_ERR(svn_client_upgrade(external_abspath, ctx, scratch_pool));
+      SVN_ERR(upgrade_internal(external_abspath, wc_format, ctx, 
scratch_pool));
     }
   else if (err)
     return svn_error_trace(err);
@@ -298,6 +327,7 @@ upgrade_external_item(svn_client_ctx_t *
 static svn_error_t *
 upgrade_externals_from_properties(svn_client_ctx_t *ctx,
                                   const char *local_abspath,
+                                  int wc_format,
                                   struct repos_info_baton *info_baton,
                                   apr_pool_t *scratch_pool)
 {
@@ -386,7 +416,8 @@ upgrade_externals_from_properties(svn_cl
           item = APR_ARRAY_IDX(externals_p, i, svn_wc_external_item2_t*);
 
           svn_pool_clear(inner_iterpool);
-          err = upgrade_external_item(ctx, externals_parent_abspath,
+          err = upgrade_external_item(ctx, wc_format,
+                                      externals_parent_abspath,
                                       externals_parent_url,
                                       externals_parent_repos_root_url,
                                       item, info_baton, inner_iterpool);

Propchange: subversion/trunk/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
  Merged 
/subversion/branches/better-pristines/subversion/libsvn_fs_x:r1807118-1843075
  Merged 
/subversion/branches/multi-wc-format/subversion/libsvn_fs_x:r1843076-1898186

Propchange: subversion/trunk/subversion/libsvn_subr/utf8proc/
------------------------------------------------------------------------------
  Merged 
/subversion/branches/multi-wc-format/subversion/libsvn_subr/utf8proc:r1843076-1898186
  Merged 
/subversion/branches/better-pristines/subversion/libsvn_subr/utf8proc:r1807118-1843075

Modified: subversion/trunk/subversion/libsvn_wc/adm_files.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_files.c?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_files.c Fri Feb 18 15:27:02 2022
@@ -38,6 +38,7 @@
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
 #include "svn_hash.h"
+#include "svn_version.h"
 
 #include "wc.h"
 #include "adm_files.h"
@@ -315,6 +316,7 @@ init_adm_tmp_area(const char *path, apr_
    unlock it when done. */
 static svn_error_t *
 init_adm(svn_wc__db_t *db,
+         int target_format,
          const char *local_abspath,
          const char *repos_relpath,
          const char *repos_root_url,
@@ -340,10 +342,9 @@ init_adm(svn_wc__db_t *db,
   SVN_ERR(init_adm_tmp_area(local_abspath, pool));
 
   /* Create the SDB. */
-  SVN_ERR(svn_wc__db_init(db, local_abspath,
+  SVN_ERR(svn_wc__db_init(db, target_format, local_abspath,
                           repos_relpath, repos_root_url, repos_uuid,
-                          initial_rev, depth,
-                          pool));
+                          initial_rev, depth, pool));
 
   /* Stamp ENTRIES and FORMAT files for old clients.  */
   SVN_ERR(svn_io_file_create(svn_wc__adm_child(local_abspath,
@@ -362,6 +363,7 @@ init_adm(svn_wc__db_t *db,
 
 svn_error_t *
 svn_wc__internal_ensure_adm(svn_wc__db_t *db,
+                            int target_format,
                             const char *local_abspath,
                             const char *url,
                             const char *repos_root_url,
@@ -370,7 +372,7 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
                             svn_depth_t depth,
                             apr_pool_t *scratch_pool)
 {
-  int format;
+  int present_format;
   const char *original_repos_relpath;
   const char *original_root_url;
   svn_boolean_t is_op_root;
@@ -386,15 +388,30 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
   SVN_ERR_ASSERT(repos_uuid != NULL);
   SVN_ERR_ASSERT(repos_relpath != NULL);
 
-  SVN_ERR(svn_wc__internal_check_wc(&format, db, local_abspath, TRUE,
+  SVN_ERR(svn_wc__internal_check_wc(&present_format, db, local_abspath, TRUE,
                                     scratch_pool));
 
   /* Early out: we know we're not dealing with an existing wc, so
      just create one. */
-  if (format == 0)
-    return svn_error_trace(init_adm(db, local_abspath,
-                                    repos_relpath, repos_root_url, repos_uuid,
-                                    revision, depth, scratch_pool));
+  if (present_format == 0)
+    {
+
+      if (target_format < SVN_WC__SUPPORTED_VERSION)
+        return svn_error_createf(
+            SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
+            _("Working copy format %d is not supported by client version %s."),
+            target_format, SVN_VER_NUM);
+
+      if (target_format > SVN_WC__VERSION)
+        return svn_error_createf(
+            SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
+            _("Working copy format %d can't be created by client version %s."),
+            target_format, SVN_VER_NUM);
+
+      return svn_error_trace(init_adm(db, target_format, local_abspath,
+                                      repos_relpath, repos_root_url, 
repos_uuid,
+                                      revision, depth, scratch_pool));
+    }
 
   SVN_ERR(svn_wc__db_read_info(&status, NULL,
                                &db_revision, &db_repos_relpath,
@@ -413,6 +430,13 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
   if (status != svn_wc__db_status_deleted
       && status != svn_wc__db_status_not_present)
     {
+      /* Check that the existing format matches the requested format. */
+      if (present_format != target_format)
+        return svn_error_createf(
+            SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
+            _("Format %d doesn't match existing format %d in '%s'"),
+            target_format, present_format, local_abspath);
+
       /* ### Should we match copyfrom_revision? */
       if (db_revision != revision)
         return
@@ -473,7 +497,8 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
 }
 
 svn_error_t *
-svn_wc_ensure_adm4(svn_wc_context_t *wc_ctx,
+svn_wc__ensure_adm(svn_wc_context_t *wc_ctx,
+                   int target_format,
                    const char *local_abspath,
                    const char *url,
                    const char *repos_root_url,
@@ -483,8 +508,9 @@ svn_wc_ensure_adm4(svn_wc_context_t *wc_
                    apr_pool_t *scratch_pool)
 {
   return svn_error_trace(
-    svn_wc__internal_ensure_adm(wc_ctx->db, local_abspath, url, repos_root_url,
-                                repos_uuid, revision, depth, scratch_pool));
+    svn_wc__internal_ensure_adm(wc_ctx->db, target_format, local_abspath,
+                                url, repos_root_url, repos_uuid, revision,
+                                depth, scratch_pool));
 }
 
 svn_error_t *

Modified: subversion/trunk/subversion/libsvn_wc/deprecated.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/deprecated.c?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_wc/deprecated.c Fri Feb 18 15:27:02 2022
@@ -570,6 +570,22 @@ svn_wc_transmit_prop_deltas(const char *
 
 /*** From adm_files.c ***/
 svn_error_t *
+svn_wc_ensure_adm4(svn_wc_context_t *wc_ctx,
+                   const char *local_abspath,
+                   const char *url,
+                   const char *repos_root_url,
+                   const char *repos_uuid,
+                   svn_revnum_t revision,
+                   svn_depth_t depth,
+                   apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(
+      svn_wc__ensure_adm(wc_ctx, SVN_WC__DEFAULT_VERSION, local_abspath,
+                         url, repos_root_url, repos_uuid, revision, depth,
+                         scratch_pool));
+}
+
+svn_error_t *
 svn_wc_ensure_adm3(const char *path,
                    const char *uuid,
                    const char *url,
@@ -4872,3 +4888,21 @@ svn_wc__conflict_description2_dup(const
 {
   return svn_wc_conflict_description2_dup(conflict, pool);
 }
+
+svn_error_t *
+svn_wc_upgrade(svn_wc_context_t *wc_ctx,
+               const char *local_abspath,
+               svn_wc_upgrade_get_repos_info_t repos_info_func,
+               void *repos_info_baton,
+               svn_cancel_func_t cancel_func,
+               void *cancel_baton,
+               svn_wc_notify_func2_t notify_func,
+               void *notify_baton,
+               apr_pool_t *scratch_pool)
+{
+  return svn_wc__upgrade(wc_ctx, local_abspath, SVN_WC__DEFAULT_VERSION,
+                         repos_info_func, repos_info_baton,
+                         cancel_func, cancel_baton,
+                         notify_func, notify_baton,
+                         scratch_pool);
+}

Modified: subversion/trunk/subversion/libsvn_wc/info.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/info.c?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/info.c (original)
+++ subversion/trunk/subversion/libsvn_wc/info.c Fri Feb 18 15:27:02 2022
@@ -105,6 +105,11 @@ build_info_for_node(svn_wc__info2_t **in
   tmpinfo->wc_info = wc_info;
 
   wc_info->copyfrom_rev = SVN_INVALID_REVNUM;
+  wc_info->wc_format_min = SVN_WC__SUPPORTED_VERSION;
+  wc_info->wc_format_max = SVN_WC__VERSION;
+
+  SVN_ERR(svn_wc__db_get_format(&wc_info->wc_format,
+                                db, local_abspath, scratch_pool));
 
   SVN_ERR(svn_wc__db_read_info(&status, &db_kind, &tmpinfo->rev,
                                &repos_relpath,

Modified: subversion/trunk/subversion/libsvn_wc/lock.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/lock.c?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/lock.c (original)
+++ subversion/trunk/subversion/libsvn_wc/lock.c Fri Feb 18 15:27:02 2022
@@ -566,10 +566,12 @@ open_single(svn_wc_adm_access_t **adm_ac
     }
   SVN_ERR(err);
 
-  /* The format version must match exactly. Note that wc_db will perform
-     an auto-upgrade if allowed. If it does *not*, then it has decided a
-     manual upgrade is required and it should have raised an error.  */
-  SVN_ERR_ASSERT(wc_format == SVN_WC__VERSION);
+  /* The format version must be in the supported version range. Note
+     that wc_db will perform an auto-upgrade if allowed. If it does
+     *not*, then it has decided a manual upgrade is required and it
+     should have raised an error.  */
+  SVN_ERR_ASSERT(SVN_WC__SUPPORTED_VERSION <= wc_format
+                 && wc_format <= SVN_WC__VERSION);
 
   /* Need to create a new lock */
   SVN_ERR(adm_access_alloc(&lock, path, db, db_provided, write_lock,

Modified: subversion/trunk/subversion/libsvn_wc/upgrade.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/upgrade.c?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_wc/upgrade.c Fri Feb 18 15:27:02 2022
@@ -28,6 +28,7 @@
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
 #include "svn_hash.h"
+#include "svn_version.h"
 
 #include "wc.h"
 #include "adm_files.h"
@@ -1426,6 +1427,15 @@ bump_to_31(void *baton,
 }
 
 static svn_error_t *
+bump_to_32(void *baton,
+           svn_sqlite__db_t *sdb,
+           apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_32));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 upgrade_apply_dav_cache(svn_sqlite__db_t *sdb,
                         const char *dir_relpath,
                         apr_int64_t wc_id,
@@ -1624,21 +1634,107 @@ svn_wc__version_string_from_format(int w
       case 9: return "1.5";
       case 10: return "1.6";
       case SVN_WC__WC_NG_VERSION: return "1.7";
+      case 29: return "1.7";
+      case 31: return "1.8";
+      case 32: return "1.15";
     }
   return _("(unreleased development version)");
 }
 
 svn_error_t *
+svn_wc__format_from_version(int *format,
+                            const svn_version_t* version,
+                            apr_pool_t *scratch_pool)
+{
+  if (!version)
+    {
+      *format = SVN_WC__DEFAULT_VERSION;
+      return SVN_NO_ERROR;
+    }
+
+  if (version->major != SVN_VER_MAJOR || version->minor > SVN_VER_MINOR)
+    return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                             _("Can't determine working copy format "
+                               "for Subversion %d.%d.%d"),
+                             version->major,
+                             version->minor,
+                             version->patch);
+
+  switch (version->minor)
+    {
+      case 0:  /* Same as 1.3.x. */
+      case 1:  /* Same as 1.3.x. */
+      case 2:  /* Same as 1.3.x. */
+      case 3:  *format = 4; break;
+      case 4:  *format = 8; break;
+      case 5:  *format = 9; break;
+      case 6:  *format = 10; break;
+      case 7:  *format = 29; break;
+      case 8:  /* Same as 1.14.x. */
+      case 9:  /* Same as 1.14.x. */
+      case 10: /* Same as 1.14.x. */
+      case 11: /* Same as 1.14.x. */
+      case 12: /* Same as 1.14.x. */
+      case 13: /* Same as 1.14.x. */
+      case 14: *format = 31; break;
+      case 15: /* Same as the current version. */
+      default: *format = SVN_WC__VERSION; break;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_boolean_t
+svn_wc__is_supported_format(int format)
+{
+  return format >= SVN_WC__SUPPORTED_VERSION && format <= SVN_WC__VERSION;
+}
+
+int
+svn_wc__max_supported_format(void)
+{
+  return SVN_WC__VERSION;
+}
+
+int
+svn_wc__min_supported_format(void)
+{
+  return SVN_WC__SUPPORTED_VERSION;
+}
+
+svn_boolean_t
+svn_wc__is_supported_format_version(const svn_version_t *version)
+{
+  return (version->major == 1
+          && (version->minor >= 8 && version->minor <= 15));
+}
+
+const svn_version_t *
+svn_wc__max_supported_format_version(void)
+{
+  /* NOTE: For consistency, always return the version
+     that first introduced the latest supported format. */
+  static const svn_version_t version = { 1, 15, 0, NULL };
+  return &version;
+}
+
+const svn_version_t *
+svn_wc__min_supported_format_version(void)
+{
+  /* NOTE: For consistency, always return the version
+     that first introduced the earliest supported format. */
+  static const svn_version_t version = { 1, 8, 0, NULL };
+  return &version;
+}
+
+svn_error_t *
 svn_wc__upgrade_sdb(int *result_format,
                     const char *wcroot_abspath,
                     svn_sqlite__db_t *sdb,
                     int start_format,
+                    int target_format,
                     apr_pool_t *scratch_pool)
 {
-  struct bump_baton bb;
-
-  bb.wcroot_abspath = wcroot_abspath;
-
   if (start_format < SVN_WC__WC_NG_VERSION /* 12 */)
     return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL,
                              _("Working copy '%s' is too old (format %d, "
@@ -1669,40 +1765,42 @@ svn_wc__upgrade_sdb(int *result_format,
                                                     scratch_pool),
                              start_format);
 
-  /* ### need lock-out. only one upgrade at a time. note that other code
-     ### cannot use this un-upgraded database until we finish the upgrade.  */
+  if (start_format > target_format)
+    return svn_error_createf(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
+                             _("Working copy '%s' is already at version %s "
+                               "(format %d) and cannot be downgraded to "
+                               "version %s (format %d)"),
+                             svn_dirent_local_style(wcroot_abspath,
+                                                    scratch_pool),
+                             svn_wc__version_string_from_format(start_format),
+                             start_format,
+                             svn_wc__version_string_from_format(target_format),
+                             target_format);
 
-  /* Note: none of these have "break" statements; the fall-through is
-     intentional. */
-  switch (start_format)
-    {
-      case 29:
-        SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_30, &bb,
-                                             scratch_pool));
-        *result_format = 30;
-
-      case 30:
-        SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_31, &bb,
-                                             scratch_pool));
-        *result_format = 31;
-        /* FALLTHROUGH  */
-      /* ### future bumps go here.  */
-#if 0
-      case XXX-1:
-        /* Revamp the recording of tree conflicts.  */
-        SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_XXX, &bb,
-                                             scratch_pool));
-        *result_format = XXX;
-        /* FALLTHROUGH  */
-#endif
-      case SVN_WC__VERSION:
-        /* already upgraded */
-        *result_format = SVN_WC__VERSION;
-
-        SVN_SQLITE__WITH_LOCK(
-            svn_wc__db_install_schema_statistics(sdb, scratch_pool),
-            sdb);
-    }
+  if (target_format < SVN_WC__SUPPORTED_VERSION)
+    return svn_error_createf(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
+                             _("Working copy version %s (format %d) "
+                               "is not supported by client version %s."),
+                             svn_wc__version_string_from_format(target_format),
+                             target_format, SVN_VER_NUM);
+
+  if (target_format > SVN_WC__VERSION)
+    return svn_error_createf(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
+                             _("Working copy with format %d "
+                               "can't be created by client version %s."),
+                             target_format, SVN_VER_NUM);
+
+  /* FIXME:
+     ### need lock-out. only one upgrade at a time. note that other code
+     ### _can_ use this un-upgraded database before we finish the upgrade. */
+  /* Update the schema */
+  SVN_ERR(svn_wc__update_schema(result_format, wcroot_abspath, sdb,
+                                start_format, target_format, scratch_pool));
+
+  /* Make sure that the stats1 table is populated. */
+  SVN_SQLITE__WITH_LOCK(
+      svn_wc__db_install_schema_statistics(sdb, scratch_pool),
+      sdb);
 
 #ifdef SVN_DEBUG
   if (*result_format != start_format)
@@ -1722,6 +1820,46 @@ svn_wc__upgrade_sdb(int *result_format,
 }
 
 
+svn_error_t *
+svn_wc__update_schema(int *result_format,
+                      const char *wcroot_abspath,
+                      svn_sqlite__db_t *sdb,
+                      int start_format,
+                      int target_format,
+                      apr_pool_t *scratch_pool)
+{
+  struct bump_baton bb;
+  bb.wcroot_abspath = wcroot_abspath;
+
+  /* Repeatedly upgrade until the target format version is reached. */
+  for (*result_format = start_format;
+       *result_format < target_format;)
+    {
+#define UPDATE_TO_FORMAT(X) \
+          case ((X) - 1):   \
+            SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_##X, &bb, 
scratch_pool)); \
+            *result_format = (X); \
+            break;
+
+      switch (*result_format)
+        {
+          UPDATE_TO_FORMAT(30);
+          UPDATE_TO_FORMAT(31);
+          UPDATE_TO_FORMAT(32);
+
+          /* ### future bumps go here.  */
+#if 0
+          UPDATE_TO_FORMAT(XXX);
+#endif
+        }
+#undef UPDATE_TO_FORMAT
+    }
+
+  SVN_ERR_ASSERT(*result_format == target_format);
+  return SVN_NO_ERROR;
+}
+
+
 /* */
 static svn_error_t *
 upgrade_working_copy(void *parent_baton,
@@ -1885,15 +2023,16 @@ is_old_wcroot(const char *local_abspath,
 }
 
 svn_error_t *
-svn_wc_upgrade(svn_wc_context_t *wc_ctx,
-               const char *local_abspath,
-               svn_wc_upgrade_get_repos_info_t repos_info_func,
-               void *repos_info_baton,
-               svn_cancel_func_t cancel_func,
-               void *cancel_baton,
-               svn_wc_notify_func2_t notify_func,
-               void *notify_baton,
-               apr_pool_t *scratch_pool)
+svn_wc__upgrade(svn_wc_context_t *wc_ctx,
+                const char *local_abspath,
+                int target_format,
+                svn_wc_upgrade_get_repos_info_t repos_info_func,
+                void *repos_info_baton,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
+                svn_wc_notify_func2_t notify_func,
+                void *notify_baton,
+                apr_pool_t *scratch_pool)
 {
   svn_wc__db_t *db;
   struct upgrade_data_t data = { NULL };
@@ -1913,7 +2052,7 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
 
 
   err = svn_wc__db_bump_format(&result_format, &bumped_format,
-                               db, local_abspath,
+                               db, local_abspath, target_format,
                                scratch_pool);
   if (err)
     {
@@ -1933,7 +2072,7 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
       /* Auto-upgrade worked! */
       SVN_ERR(svn_wc__db_close(db));
 
-      SVN_ERR_ASSERT(result_format == SVN_WC__VERSION);
+      SVN_ERR_ASSERT(result_format == target_format);
 
       if (bumped_format && notify_func)
         {
@@ -1987,7 +2126,7 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
   /* Create an empty sqlite database for this directory and store it in DB. */
   SVN_ERR(svn_wc__db_upgrade_begin(&data.sdb,
                                    &data.repos_id, &data.wc_id,
-                                   db, data.root_abspath,
+                                   db, target_format, data.root_abspath,
                                    this_dir->repos, this_dir->uuid,
                                    scratch_pool));
 

Modified: subversion/trunk/subversion/libsvn_wc/wc-metadata.sql
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-metadata.sql?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-metadata.sql Fri Feb 18 15:27:02 
2022
@@ -39,7 +39,16 @@
  *   "base-deleted" -- node represents a delete of a BASE node
  */
 
-/* One big list of statements to create our (current) schema.  */
+/* One big list of statements to create our initial schema.
+
+   STMT_CREATE_SCHEMA creates the schema for the minimum WC format
+   supported by the client (SVN_WC__SUPPORTED_VERSION).
+
+   When we're creating a new working copy, we first execute
+   STMT_CREATE_SCHEMA, and then use the normal WC upgrade code (using
+   STMT_UPGRADE_TO_xx) to bring the schema up to any higher requested
+   format.
+ */
 -- STMT_CREATE_SCHEMA
 
 /* ------------------------------------------------------------------------- */
@@ -228,7 +237,6 @@ CREATE TABLE WC_LOCK (
   PRIMARY KEY (wc_id, local_dir_relpath)
  );
 
-
 /* ------------------------------------------------------------------------- */
 
 /* The NODES table describes the way WORKING nodes are layered on top of
@@ -563,8 +571,9 @@ CREATE UNIQUE INDEX I_EXTERNALS_DEFINED
                                                       local_relpath);
 
 
+/* Identify the WC format corresponding to the schema we have created. */
 PRAGMA user_version =
--- define: SVN_WC__VERSION
+-- define: SVN_WC__SUPPORTED_VERSION
 ;
 
 
@@ -700,8 +709,8 @@ WHERE l.op_depth = 0
 
 /* ------------------------------------------------------------------------- */
 /* Format 32 ....  */
-/* -- STMT_UPGRADE_TO_32
-PRAGMA user_version = 32; */
+-- STMT_UPGRADE_TO_32
+PRAGMA user_version = 32;
 
 
 /* ------------------------------------------------------------------------- */

Modified: subversion/trunk/subversion/libsvn_wc/wc.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc.h?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc.h Fri Feb 18 15:27:02 2022
@@ -160,12 +160,22 @@ extern "C" {
  * == 1.8.x shipped with format 31
  * == 1.9.x shipped with format 31
  * == 1.10.x shipped with format 31
+ * == 1.11.x shipped with format 31
  *
  * Please document any further format changes here.
  */
 
-#define SVN_WC__VERSION 31
+/* The default WC version created by the client. */
+#define SVN_WC__VERSION 32
 
+/* The minimum WC version supported by the client.
+   IMPORTANT: Update the implementation of svn_client_supported_wc_version()
+              whenever you change this value! */
+#define SVN_WC__SUPPORTED_VERSION 31
+
+/* The default WC version that the Subversion library should create
+ * (or upgrade to) when not otherwise specified. */
+#define SVN_WC__DEFAULT_VERSION SVN_WC__SUPPORTED_VERSION
 
 /* Formats <= this have no concept of "revert text-base/props".  */
 #define SVN_WC__NO_REVERT_FILES 4
@@ -504,6 +514,7 @@ svn_wc__internal_transmit_prop_deltas(sv
 /* Library-internal version of svn_wc_ensure_adm4(). */
 svn_error_t *
 svn_wc__internal_ensure_adm(svn_wc__db_t *db,
+                            int target_format,
                             const char *local_abspath,
                             const char *url,
                             const char *repos_root_url,
@@ -585,7 +596,8 @@ svn_wc__internal_get_origin(svn_boolean_
                             apr_pool_t *scratch_pool);
 
 /* Upgrade the wc sqlite database given in SDB for the wc located at
-   WCROOT_ABSPATH. It's current/starting format is given by START_FORMAT.
+   WCROOT_ABSPATH. It's current/starting format is given by START_FORMAT,
+   and the intended format is given by TARGET_FORMAT.
    After the upgrade is complete (to as far as the automatic upgrade will
    perform), the resulting format is RESULT_FORMAT. All allocations are
    performed in SCRATCH_POOL.  */
@@ -594,8 +606,18 @@ svn_wc__upgrade_sdb(int *result_format,
                     const char *wcroot_abspath,
                     svn_sqlite__db_t *sdb,
                     int start_format,
+                    int target_format,
                     apr_pool_t *scratch_pool);
 
+/* The schema-update part of svn_wc__upgrade_sdb. */
+svn_error_t *
+svn_wc__update_schema(int *result_format,
+                      const char *wcroot_abspath,
+                      svn_sqlite__db_t *sdb,
+                      int start_format,
+                      int target_format,
+                      apr_pool_t *scratch_pool);
+
 /* Create a conflict skel from the old separated data */
 svn_error_t *
 svn_wc__upgrade_conflict_skel_from_raw(svn_skel_t **conflicts,

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1898187&r1=1898186&r2=1898187&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Fri Feb 18 15:27:02 2022
@@ -1360,17 +1360,23 @@ init_db(/* output values */
         apr_int64_t *wc_id,
         /* input values */
         svn_sqlite__db_t *db,
+        int target_format,
         const char *repos_root_url,
         const char *repos_uuid,
         const char *root_node_repos_relpath,
         svn_revnum_t root_node_revision,
         svn_depth_t root_node_depth,
+        const char *wcroot_abspath,
         apr_pool_t *scratch_pool)
 {
   svn_sqlite__stmt_t *stmt;
+  int result_format;
 
   /* Create the database's schema.  */
   SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_SCHEMA));
+  SVN_ERR(svn_wc__update_schema(&result_format, wcroot_abspath, db,
+                                SVN_WC__SUPPORTED_VERSION, target_format,
+                                scratch_pool));
 
   SVN_ERR(svn_wc__db_install_schema_statistics(db, scratch_pool));
 
@@ -1410,10 +1416,9 @@ init_db(/* output values */
   return SVN_NO_ERROR;
 }
 
-/* Create an sqlite database at DIR_ABSPATH/SDB_FNAME and insert
-   records for REPOS_ID (using REPOS_ROOT_URL and REPOS_UUID) into
-   REPOSITORY and for WC_ID into WCROOT.  Return the DB connection
-   in *SDB.
+/* Create an sqlite database with schema TARGET_FORMAT at DIR_ABSPATH/SDB_FNAME
+   and insert records for REPOS_ID (using REPOS_ROOT_URL and REPOS_UUID) into
+   REPOSITORY and for WC_ID into WCROOT. Return the DB connection in *SDB.
 
    If ROOT_NODE_REPOS_RELPATH is not NULL, insert a BASE node at
    the working copy root with repository relpath ROOT_NODE_REPOS_RELPATH,
@@ -1423,6 +1428,7 @@ static svn_error_t *
 create_db(svn_sqlite__db_t **sdb,
           apr_int64_t *repos_id,
           apr_int64_t *wc_id,
+          int target_format,
           const char *dir_abspath,
           const char *repos_root_url,
           const char *repos_uuid,
@@ -1442,9 +1448,9 @@ create_db(svn_sqlite__db_t **sdb,
                                   result_pool, scratch_pool));
 
   SVN_SQLITE__WITH_LOCK(init_db(repos_id, wc_id,
-                                *sdb, repos_root_url, repos_uuid,
+                                *sdb, target_format, repos_root_url, 
repos_uuid,
                                 root_node_repos_relpath, root_node_revision,
-                                root_node_depth, scratch_pool),
+                                root_node_depth, dir_abspath, scratch_pool),
                         *sdb);
 
   return SVN_NO_ERROR;
@@ -1453,6 +1459,7 @@ create_db(svn_sqlite__db_t **sdb,
 
 svn_error_t *
 svn_wc__db_init(svn_wc__db_t *db,
+                int target_format,
                 const char *local_abspath,
                 const char *repos_relpath,
                 const char *repos_root_url,
@@ -1469,6 +1476,8 @@ svn_wc__db_init(svn_wc__db_t *db,
   apr_int32_t sqlite_timeout = 0; /* default timeout */
   apr_hash_index_t *hi;
 
+  SVN_ERR_ASSERT(SVN_WC__SUPPORTED_VERSION <= target_format
+                 && target_format <= SVN_WC__VERSION);
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(repos_relpath != NULL);
   SVN_ERR_ASSERT(depth == svn_depth_empty
@@ -1484,10 +1493,10 @@ svn_wc__db_init(svn_wc__db_t *db,
                               FALSE));
 
   /* Create the SDB and insert the basic rows.  */
-  SVN_ERR(create_db(&sdb, &repos_id, &wc_id, local_abspath, repos_root_url,
-                    repos_uuid, SDB_FILE,
-                    repos_relpath, initial_rev, depth, sqlite_exclusive,
-                    sqlite_timeout,
+  SVN_ERR(create_db(&sdb, &repos_id, &wc_id, target_format, local_abspath,
+                    repos_root_url, repos_uuid, SDB_FILE,
+                    repos_relpath, initial_rev, depth,
+                    sqlite_exclusive, sqlite_timeout,
                     db->state_pool, scratch_pool));
 
   /* Create the WCROOT for this directory.  */
@@ -1528,6 +1537,27 @@ svn_wc__db_init(svn_wc__db_t *db,
 
 
 svn_error_t *
+svn_wc__db_get_format(int *format,
+                      svn_wc__db_t *db,
+                      const char *local_abspath,
+                      apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(
+              &wcroot, &local_relpath, db,
+              local_abspath, scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  *format = wcroot->format;
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
 svn_wc__db_to_relpath(const char **local_relpath,
                       svn_wc__db_t *db,
                       const char *wri_abspath,
@@ -13408,6 +13438,7 @@ svn_wc__db_upgrade_begin(svn_sqlite__db_
                          apr_int64_t *repos_id,
                          apr_int64_t *wc_id,
                          svn_wc__db_t *wc_db,
+                         int target_format,
                          const char *dir_abspath,
                          const char *repos_root_url,
                          const char *repos_uuid,
@@ -13416,8 +13447,8 @@ svn_wc__db_upgrade_begin(svn_sqlite__db_
   svn_wc__db_wcroot_t *wcroot;
 
   /* Upgrade is inherently exclusive so specify exclusive locking. */
-  SVN_ERR(create_db(sdb, repos_id, wc_id, dir_abspath,
-                    repos_root_url, repos_uuid,
+  SVN_ERR(create_db(sdb, repos_id, wc_id, target_format,
+                    dir_abspath, repos_root_url, repos_uuid,
                     SDB_FILE,
                     NULL, SVN_INVALID_REVNUM, svn_depth_unknown,
                     TRUE /* exclusive */,
@@ -16088,6 +16119,7 @@ svn_wc__db_bump_format(int *result_forma
                        svn_boolean_t *bumped_format,
                        svn_wc__db_t *db,
                        const char *wcroot_abspath,
+                       int target_format,
                        apr_pool_t *scratch_pool)
 {
   svn_sqlite__db_t *sdb;
@@ -16132,7 +16164,7 @@ svn_wc__db_bump_format(int *result_forma
 
   SVN_ERR(svn_sqlite__read_schema_version(&format, sdb, scratch_pool));
   err = svn_wc__upgrade_sdb(result_format, wcroot_abspath,
-                            sdb, format, scratch_pool);
+                            sdb, format, target_format, scratch_pool);
 
   if (err == SVN_NO_ERROR && bumped_format)
     *bumped_format = (*result_format > format);


Reply via email to