Vendor import svn-1.8.9

This commit is contained in:
Peter Wemm 2014-05-27 04:55:31 +00:00
parent 219f5ebf8f
commit 41a48a0a18
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/subversion/dist/; revision=266729
svn path=/vendor/subversion/subversion-1.8.9/; revision=266730; tag=vendor/subversion/subversion-1.8.9
44 changed files with 2232 additions and 1489 deletions

111
CHANGES
View File

@ -1,3 +1,70 @@
Version 1.8.9
(07 May 2014, from /branches/1.8.x)
http://svn.apache.org/repos/asf/subversion/tags/1.8.9
User-visible changes:
- Client-side bugfixes:
* log: use proper peg revision over DAV (r1568872)
* upgrade: allow upgrading from 1.7 with exclusive locks (r1572102 et al)
* proplist: resolve inconsitent inherited property results (r1575270 et al)
* increase minimal timestamp sleep from 1ms to 10ms (r1581305 et al)
* merge: automatic merge confused by subtree merge (issue #4481)
* propget: report proper error on invalid revision for url (r1586255)
* commit: fix an assertion when committing a deleted descendant
(r1571747, r1571787, r1571795)
* merge: resolve segfault when '--force' merges a directory delete
(r1577812, r1577813, r1579429)
* resolve: prevent interactive conflict resolution when nothing has been
done to resolve the conflict (r1577294)
* update: fix locks lost from wc with pre-1.6.17 servers (issue #4412)
* merge: honor the 'preserved-conflict-file-exts' setting (r1577151)
* list: fix '--verbose' against older servers (r1591111)
* unlock: fix ability to remove locks with timeouts (r1579588)
* copy: fix 'svn copy URL WC' on relocated working copies
(r1580626, r1580650)
* export: allow file externals to be exported (issue #4427)
* move: fix working copy db inconsistency in cert scenarios (issue #4437)
* commit: fix an issue where mixed revision copy with non copy descendants
that shadow a not present node couldn't be committed (r1518942 et al)
* delete: properly remove move_to info when the node in its original
location is removed (r1538812 et al)
* status; fix an issue where output would vary based on if the target
was the node itself or its parent (r1544597 et al)
- Server-side bugfixes:
* ensure proper access synchronization in fsfs on Windows (r1568953 et al)
* svnadmin dump: don't let invalid mergeinfo stop dump (r1574868 et al)
* svnserve: resolve performance regression caused by iprops (r1578853 et al)
* reduce size of memory buffer when reading config files (r1581296)
* remove dead transaction if commit was blocked by hook (r1583977)
* svnrdump load: fix crash when svn:* normalization (issue #4490)
* fix memcached support (issue #4470)
* svndumpfilter: fix order of node record headers (r1578670 et al)
* mod_dav_svn: blacklist building with broken versions of httpd; 2.2.25,
2.4.5 and 2.4.6 (r1545835)
* mod_dav_svn: allow generic DAV clients to refresh locks (issue #3515)
* mod_dav_svn: detect out of dateness correctly during commit (issue #4480)
Developer-visible changes:
- General:
* improve consistency checks of DAV inherited property requests (r1498000)
* fix ocassional failure in autoprop_tests.py (r1567752)
* avoid duplicate sqlite analyze information rows (r1571214)
* add Mavericks to our sysinfo output (r1573088)
* bump copyright years to 2014 (r1555403)
* unbreak test suite when running as root (r1583580)
* resolve buffer overflow in testcode (r1481782)
* fix libmagic detection with custom LDFLAGS (r1577200)
* fix an out of scope variable use in merge (r1587946)
* javahl: fix crash from resolve callback throwing an exception (r1586439)
* ruby: fix two memory lifetime bugs (r1586052, r1586467)
* fix a missing null byte when handling old pre-1.4 deltas (r1587968)
* fix building with APR 0.9.x (r1585499)
* make svn_ra_get_locks() and svn_ra_get_lock() report not locked nodes
with a NULL svn_lock_t *, as documented (r1578273, r1578311, r1578326)
* fix tests for compiler flags (r1573106)
Version 1.8.8
(19 Feb 2014, from /branches/1.8.x)
http://svn.apache.org/repos/asf/subversion/tags/1.8.8
@ -620,9 +687,36 @@ http://svn.apache.org/repos/asf/subversion/tags/1.8.0
* fix some reference counting bugs in swig-py bindings (r1464899, r1466524)
Version 1.7.15
(12 Feb 2014, from /branches/1.7.x)
http://svn.apache.org/repos/asf/subversion/tags/1.7.15
Version 1.7.17
(07 May 2014, from /branches/1.7.x)
http://svn.apache.org/repos/asf/subversion/tags/1.7.17
User-visible changes:
- Client-side bugfixes:
* log: use proper peg revision over DAV (r1568872)
* move: fix errors when moving files between an external and the parent
working copy (r1551579)
* copy: fix 'svn copy URL WC' on relocated working copies
(r1580626, r1580650)
- Server-side bugfixes:
* mod_dav_svn: blacklist building with broken versions of httpd; 2.2.25,
2.4.5 and 2.4.6 (r1545835)
* mod_dav_svn: detect out of dateness correctly during commit (issue #4480)
Developer-visible changes:
- General:
* fix libmagic detection with custom LDFLAGS (r1577200)
* fix a missing null byte when handling old pre-1.4 deltas (r1587968)
* support building with Serf 1.3.x (r1517123, r1535139)
- Bindings:
* javahl: fix crash from resolve callback throwing an exception (r1586439)
Version 1.7.16
(26 Feb 2014, from /branches/1.7.x)
http://svn.apache.org/repos/asf/subversion/tags/1.7.16
User-visible changes:
- Client-side bugfixes:
@ -637,6 +731,11 @@ http://svn.apache.org/repos/asf/subversion/tags/1.7.15
- General:
* fix failure in checkout_tests.py
* support compiling against Cyrus sasl 2.1.25 (r1404912, r1413402)
* support compiling against neon 0.30.x (r1566320)
Version 1.7.15
(Not released, see changes for 1.7.16.)
Version 1.7.14
@ -883,7 +982,7 @@ http://svn.apache.org/repos/asf/subversion/tags/1.7.6
* fix ra_serf against Subversion 1.2 servers (r1349367)
* fix 'svn upgrade' on working copies with certain tree conflicts (r1345482)
* avoid workqueue references to system temp dir (r1367854)
* allow non-existant canonical paths (r1367853)
* allow non-existent canonical paths (r1367853)
* fix 'svn revert --depth files' to operate on files (r1365554)
* fix ra_serf XML namespace handling against malicious server (r1337441)
* fix relocate with server-relative externals (issue 4216)
@ -1235,7 +1334,7 @@ the 1.6 release: http://subversion.apache.org/docs/release-notes/1.7.html
* fixed: rm -> ci -> cp = missing directory (issue #2763)
* fixed: 'svn info' returns parent info on missing dirs (issue #3178)
* fixed: spurious prop conflict with 'merge --reintegrate' (issue #3919)
* fixed: 'svn --version' fails with non-existant $HOME (issue #3947)
* fixed: 'svn --version' fails with non-existent $HOME (issue #3947)
* fixed: unforced export silently overwites existing file (issue #3799)
* fixed: reverse merge which adds subtree mergeinfo fails (issue #3978)
* fixed: 'svn up -r{R>HEAD}' hangs client over ra_svn (issue #3963)
@ -1410,7 +1509,7 @@ http://svn.apache.org/repos/asf/subversion/tags/1.6.17
* fix crash in mod_dav_svn with GETs of baselined resources (r1104126)
See CVE-2011-1752, and descriptive advisory at
http://subversion.apache.org/security/CVE-2011-1752-advisory.txt
* fixed: write-through proxy could direcly commit to slave (r917523)
* fixed: write-through proxy could directly commit to slave (r917523)
* detect a particular corruption condition in FSFS (r1100213)
* improve error message when clients refer to unknown revisions (r939000)
* bugfixes and optimizations to the DAV mirroring code (r878607)

2
NOTICE
View File

@ -1,5 +1,5 @@
Apache Subversion
Copyright 2013 The Apache Software Foundation
Copyright 2014 The Apache Software Foundation
This product includes software developed by many people, and distributed
under Contributor License Agreements to The Apache Software Foundation

View File

@ -2829,17 +2829,17 @@ subversion/tests/libsvn_wc/op-depth-test.lo: subversion/tests/libsvn_wc/op-depth
subversion/tests/libsvn_wc/pristine-store-test.lo: subversion/tests/libsvn_wc/pristine-store-test.c subversion/include/private/svn_debug.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/workqueue.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h
subversion/tests/libsvn_wc/utils.lo: subversion/tests/libsvn_wc/utils.c subversion/include/private/svn_debug.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/wc_db_private.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h subversion/tests/svn_test_fs.h
subversion/tests/libsvn_wc/utils.lo: subversion/tests/libsvn_wc/utils.c subversion/include/private/svn_debug.h subversion/include/private/svn_dep_compat.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/wc_db_private.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h subversion/tests/svn_test_fs.h
subversion/tests/libsvn_wc/utils.lo: subversion/tests/libsvn_wc/utils.c subversion/include/private/svn_debug.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/wc_db_private.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h subversion/tests/svn_test_fs.h
subversion/tests/libsvn_wc/utils.lo: subversion/tests/libsvn_wc/utils.c subversion/include/private/svn_debug.h subversion/include/private/svn_dep_compat.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/wc_db_private.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h subversion/tests/svn_test_fs.h
subversion/tests/libsvn_wc/utils.lo: subversion/tests/libsvn_wc/utils.c subversion/include/private/svn_debug.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/wc_db_private.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h subversion/tests/svn_test_fs.h
subversion/tests/libsvn_wc/utils.lo: subversion/tests/libsvn_wc/utils.c subversion/include/private/svn_debug.h subversion/include/private/svn_dep_compat.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/wc_db_private.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h subversion/tests/svn_test_fs.h
subversion/tests/libsvn_wc/utils.lo: subversion/tests/libsvn_wc/utils.c subversion/include/private/svn_debug.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/wc_db_private.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h subversion/tests/svn_test_fs.h
subversion/tests/libsvn_wc/utils.lo: subversion/tests/libsvn_wc/utils.c subversion/include/private/svn_debug.h subversion/include/private/svn_dep_compat.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/wc_db_private.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h subversion/tests/svn_test_fs.h
subversion/tests/libsvn_wc/utils.lo: subversion/tests/libsvn_wc/utils.c subversion/include/private/svn_debug.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/wc_db_private.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h subversion/tests/svn_test_fs.h
subversion/tests/libsvn_wc/utils.lo: subversion/tests/libsvn_wc/utils.c subversion/include/private/svn_debug.h subversion/include/private/svn_dep_compat.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/wc_db_private.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h subversion/tests/svn_test_fs.h
subversion/tests/libsvn_wc/utils.lo: subversion/tests/libsvn_wc/utils.c subversion/include/private/svn_debug.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/wc_db_private.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h subversion/tests/svn_test_fs.h
subversion/tests/libsvn_wc/utils.lo: subversion/tests/libsvn_wc/utils.c subversion/include/private/svn_debug.h subversion/include/private/svn_dep_compat.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_client.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_diff.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_fs.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_repos.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc-queries.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/libsvn_wc/wc_db_private.h subversion/svn_private_config.h subversion/tests/libsvn_wc/utils.h subversion/tests/svn_test.h subversion/tests/svn_test_fs.h
subversion/tests/libsvn_wc/wc-incomplete-tester.lo: subversion/tests/libsvn_wc/wc-incomplete-tester.c subversion/include/private/svn_debug.h subversion/include/private/svn_diff_tree.h subversion/include/private/svn_skel.h subversion/include/private/svn_sqlite.h subversion/include/private/svn_token.h subversion/include/private/svn_wc_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_opt.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_wc.h subversion/libsvn_wc/wc.h subversion/libsvn_wc/wc_db.h subversion/svn_private_config.h

638
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -98,7 +98,7 @@ dnl now generating errors instead of silently ignoring
dnl them. Only .7 and later can guarantee repository
dnl integrity with FSFS.
APR_VER_REGEXES=["0\.9\.[7-9] 0\.9\.1[0-9] 1\. 2\."]
APR_VER_REGEXES=["0\.9\.[7-9] 0\.9\.[12][0-9] 1\. 2\."]
SVN_LIB_APR($APR_VER_REGEXES)
@ -755,7 +755,7 @@ AC_ARG_WITH(libmagic,AS_HELP_STRING([--with-libmagic=PREFIX],
CPPFLAGS="$CPPFLAGS -I$libmagic_prefix/include"
AC_CHECK_HEADERS(magic.h,[
save_ldflags="$LDFLAGS"
LDFLAGS="-L$libmagic_prefix/lib"
LDFLAGS="-L$libmagic_prefix/lib $LDFLAGS"
AC_CHECK_LIB(magic, magic_open, [libmagic_found="yes"])
LDFLAGS="$save_ldflags"
])

View File

@ -182,6 +182,10 @@ typedef struct svn_cache__info_t
* if they are strings. Cached values will be copied in and out of
* the cache using @a serialize_func and @a deserialize_func, respectively.
*
* If @a deserialize_func is NULL, then the data is returned as an
* svn_stringbuf_t; if @a serialize_func is NULL, then the data is
* assumed to be an svn_stringbuf_t.
*
* The cache stores up to @a pages * @a items_per_page items at a
* time. The exact cache invalidation strategy is not defined here,
* but in general, a lower value for @a items_per_page means more
@ -224,7 +228,7 @@ svn_cache__create_inprocess(svn_cache__t **cache_p,
* other caches. @a *cache_p will be allocated in @a result_pool.
*
* If @a deserialize_func is NULL, then the data is returned as an
* svn_string_t; if @a serialize_func is NULL, then the data is
* svn_stringbuf_t; if @a serialize_func is NULL, then the data is
* assumed to be an svn_stringbuf_t.
*
* These caches are always thread safe.
@ -309,7 +313,7 @@ svn_cache__membuffer_cache_create(svn_membuffer_t **cache,
* this cache from other caches. @a *cache_p will be allocated in @a result_pool.
*
* If @a deserialize_func is NULL, then the data is returned as an
* svn_string_t; if @a serialize_func is NULL, then the data is
* svn_stringbuf_t; if @a serialize_func is NULL, then the data is
* assumed to be an svn_stringbuf_t.
*
* If @a thread_safe is true, and APR is compiled with threads, all

View File

@ -78,6 +78,7 @@ void svn_hash__clear(struct apr_hash_t *ht);
#if !APR_VERSION_AT_LEAST(1,0,0)
#define APR_UINT64_C(val) UINT64_C(val)
#define APR_FPROT_OS_DEFAULT APR_OS_DEFAULT
#define apr_hash_make_custom(pool,hash_func) apr_hash_make(pool)
#endif
#if !APR_VERSION_AT_LEAST(1,3,0)
@ -114,6 +115,12 @@ typedef apr_uint32_t apr_uintptr_t;
#define SVN_LOCK_IS_BUSY(x) APR_STATUS_IS_EBUSY(x)
#endif
#if !APR_VERSION_AT_LEAST(1,4,0)
#ifndef apr_time_from_msec
#define apr_time_from_msec(msec) ((apr_time_t)(msec) * 1000)
#endif
#endif
/**
* Check at compile time if the Serf version is at least a certain
* level.

View File

@ -72,7 +72,7 @@ extern "C" {
*
* @since New in 1.1.
*/
#define SVN_VER_PATCH 8
#define SVN_VER_PATCH 9
/** @deprecated Provided for backward compatibility with the 1.0 API. */
@ -95,7 +95,7 @@ extern "C" {
*
* Always change this at the same time as SVN_VER_NUMTAG.
*/
#define SVN_VER_TAG " (r1568071)"
#define SVN_VER_TAG " (r1591380)"
/** Number tag: a string describing the version.
@ -121,7 +121,7 @@ extern "C" {
* When rolling a tarball, we automatically replace it with what we
* guess to be the correct revision number.
*/
#define SVN_VER_REVISION 1568071
#define SVN_VER_REVISION 1591380
/* Version strings composed from the above definitions. */

View File

@ -892,7 +892,7 @@ harvest_status_callback(void *status_baton,
if (matches_changelists
&& (is_harvest_root || baton->changelists)
&& state_flags
&& is_added
&& (is_added || (is_deleted && is_op_root && status->copied))
&& baton->danglers)
{
/* If a node is added, its parent must exist in the repository at the
@ -966,17 +966,19 @@ struct handle_descendants_baton
void *cancel_baton;
svn_client__check_url_kind_t check_url_func;
void *check_url_baton;
svn_client__committables_t *committables;
};
/* Helper for the commit harvesters */
static svn_error_t *
handle_descendants(void *baton,
const void *key, apr_ssize_t klen, void *val,
apr_pool_t *pool)
const void *key, apr_ssize_t klen, void *val,
apr_pool_t *pool)
{
struct handle_descendants_baton *hdb = baton;
apr_array_header_t *commit_items = val;
apr_pool_t *iterpool = svn_pool_create(pool);
const char *repos_root_url = key;
int i;
for (i = 0; i < commit_items->nelts; i++)
@ -1002,33 +1004,65 @@ handle_descendants(void *baton,
for (j = 0; j < absent_descendants->nelts; j++)
{
int k;
svn_boolean_t found_item = FALSE;
svn_node_kind_t kind;
svn_client_commit_item3_t *desc_item;
const char *relpath = APR_ARRAY_IDX(absent_descendants, j,
const char *);
const char *local_abspath = svn_dirent_join(item->path, relpath,
iterpool);
/* If the path has a commit operation, we do nothing.
(It will be deleted by the operation) */
for (k = 0; k < commit_items->nelts; k++)
{
svn_client_commit_item3_t *cmt_item =
APR_ARRAY_IDX(commit_items, k, svn_client_commit_item3_t *);
if (! strcmp(cmt_item->path, local_abspath))
{
found_item = TRUE;
break;
}
}
if (found_item)
continue; /* We have an explicit delete or replace for this path */
/* ### Need a sub-iterpool? */
/* We found a 'not present' descendant during a copy (at op_depth>0),
this is most commonly caused by copying some mixed revision tree.
In this case not present can imply that the node does not exist
in the parent revision, or that the node does. But we want to copy
the working copy state in which it does not exist, but might be
replaced. */
desc_item = svn_hash_gets(hdb->committables->by_path, local_abspath);
/* If the path has a commit operation (possibly at an higher
op_depth, we might want to turn an add in a replace. */
if (desc_item)
{
const char *dir;
svn_boolean_t found_intermediate = FALSE;
if (desc_item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
continue; /* We already have a delete or replace */
else if (!(desc_item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
continue; /* Not a copy/add, just a modification */
dir = svn_dirent_dirname(local_abspath, iterpool);
while (strcmp(dir, item->path))
{
svn_client_commit_item3_t *i_item;
i_item = svn_hash_gets(hdb->committables->by_path, dir);
if (i_item)
{
if ((i_item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
|| (i_item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
{
found_intermediate = TRUE;
break;
}
}
dir = svn_dirent_dirname(dir, iterpool);
}
if (found_intermediate)
continue; /* Some intermediate ancestor is an add or delete */
/* Fall through to detect if we need to turn the add in a
replace. */
}
if (hdb->check_url_func)
{
const char *from_url = svn_path_url_add_component2(
@ -1045,25 +1079,35 @@ handle_descendants(void *baton,
else
kind = svn_node_unknown; /* 'Ok' for a delete of something */
{
/* Add a new commit item that describes the delete */
apr_pool_t *result_pool = commit_items->pool;
svn_client_commit_item3_t *new_item
= svn_client_commit_item3_create(result_pool);
if (desc_item)
{
/* Extend the existing add/copy item to create a replace */
desc_item->state_flags |= SVN_CLIENT_COMMIT_ITEM_DELETE;
continue;
}
new_item->path = svn_dirent_join(item->path, relpath,
result_pool);
new_item->kind = kind;
new_item->url = svn_path_url_add_component2(item->url, relpath,
result_pool);
new_item->revision = SVN_INVALID_REVNUM;
new_item->state_flags = SVN_CLIENT_COMMIT_ITEM_DELETE;
new_item->incoming_prop_changes = apr_array_make(result_pool, 1,
sizeof(svn_prop_t *));
/* Add a new commit item that describes the delete */
APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *)
= new_item;
}
SVN_ERR(add_committable(hdb->committables,
svn_dirent_join(item->path, relpath,
iterpool),
kind,
repos_root_url,
svn_uri_skip_ancestor(
repos_root_url,
svn_path_url_add_component2(item->url,
relpath,
iterpool),
iterpool),
SVN_INVALID_REVNUM,
NULL /* copyfrom_relpath */,
SVN_INVALID_REVNUM,
NULL /* moved_from_abspath */,
SVN_CLIENT_COMMIT_ITEM_DELETE,
NULL /* lock tokens */,
NULL /* lock */,
commit_items->pool,
iterpool));
}
}
@ -1181,6 +1225,7 @@ svn_client__harvest_committables(svn_client__committables_t **committables,
hdb.cancel_baton = ctx->cancel_baton;
hdb.check_url_func = check_url_func;
hdb.check_url_baton = check_url_baton;
hdb.committables = *committables;
SVN_ERR(svn_iter_apr_hash(NULL, (*committables)->by_repository,
handle_descendants, &hdb, iterpool));
@ -1274,6 +1319,7 @@ harvest_copy_committables(void *baton, void *item, apr_pool_t *pool)
hdb.cancel_baton = btn->ctx->cancel_baton;
hdb.check_url_func = btn->check_url_func;
hdb.check_url_baton = btn->check_url_baton;
hdb.committables = btn->committables;
SVN_ERR(svn_iter_apr_hash(NULL, btn->committables->by_repository,
handle_descendants, &hdb, pool));

View File

@ -267,7 +267,9 @@ export_node(void *baton,
scratch_pool));
}
if (status->file_external)
/* Skip file externals if they are a descendant of the export,
BUT NOT if we are explictly exporting the file external. */
if (status->file_external && strcmp(eib->origin_abspath, local_abspath) != 0)
return SVN_NO_ERROR;
/* Produce overwrite errors for the export root */
@ -1587,3 +1589,4 @@ svn_client_export5(svn_revnum_t *result_rev,
return SVN_NO_ERROR;
}

View File

@ -322,6 +322,10 @@ typedef struct merge_cmd_baton_t {
const char *diff3_cmd;
const apr_array_header_t *merge_options;
/* Array of file extension patterns to preserve as extensions in
generated conflict files. */
const apr_array_header_t *ext_patterns;
/* RA sessions used throughout a merge operation. Opened/re-parented
as needed.
@ -2023,17 +2027,36 @@ merge_file_changed(const char *relpath,
{
svn_boolean_t has_local_mods;
enum svn_wc_merge_outcome_t content_outcome;
const char *target_label;
const char *left_label;
const char *right_label;
const char *path_ext = "";
if (merge_b->ext_patterns && merge_b->ext_patterns->nelts)
{
svn_path_splitext(NULL, &path_ext, local_abspath, scratch_pool);
if (! (*path_ext
&& svn_cstring_match_glob_list(path_ext,
merge_b->ext_patterns)))
{
path_ext = "";
}
}
/* xgettext: the '.working', '.merge-left.r%ld' and
'.merge-right.r%ld' strings are used to tag onto a file
name in case of a merge conflict */
const char *target_label = _(".working");
const char *left_label = apr_psprintf(scratch_pool,
_(".merge-left.r%ld"),
left_source->revision);
const char *right_label = apr_psprintf(scratch_pool,
_(".merge-right.r%ld"),
right_source->revision);
target_label = apr_psprintf(scratch_pool, _(".working%s%s"),
*path_ext ? "." : "", path_ext);
left_label = apr_psprintf(scratch_pool,
_(".merge-left.r%ld%s%s"),
left_source->revision,
*path_ext ? "." : "", path_ext);
right_label = apr_psprintf(scratch_pool,
_(".merge-right.r%ld%s%s"),
right_source->revision,
*path_ext ? "." : "", path_ext);
SVN_ERR(svn_wc_text_modified_p2(&has_local_mods, ctx->wc_ctx,
local_abspath, FALSE, scratch_pool));
@ -3062,7 +3085,6 @@ merge_dir_deleted(const char *relpath,
struct merge_dir_baton_t *db = dir_baton;
const char *local_abspath = svn_dirent_join(merge_b->target->abspath,
relpath, scratch_pool);
struct dir_delete_baton_t *delb;
svn_boolean_t same;
apr_hash_t *working_props;
@ -3093,66 +3115,69 @@ merge_dir_deleted(const char *relpath,
scratch_pool, scratch_pool));
if (merge_b->force_delete)
same = TRUE;
{
/* In this legacy mode we just assume that a directory delete
matches any directory. db->delete_state is NULL */
same = TRUE;
}
else
{
struct dir_delete_baton_t *delb;
/* Compare the properties */
SVN_ERR(properties_same_p(&same, left_props, working_props,
scratch_pool));
}
delb = db->delete_state;
assert(delb != NULL);
delb = db->delete_state;
assert(delb != NULL);
if (! same)
{
delb->found_edit = TRUE;
}
else
{
store_path(delb->compared_abspaths, local_abspath);
}
if (delb->del_root != db)
return SVN_NO_ERROR;
if (delb->found_edit)
same = FALSE;
else if (merge_b->force_delete)
same = TRUE;
else
{
apr_array_header_t *ignores;
svn_error_t *err;
same = TRUE;
SVN_ERR(svn_wc_get_default_ignores(&ignores, merge_b->ctx->config,
scratch_pool));
/* None of the descendants was modified, but maybe there are
descendants we haven't walked?
Note that we aren't interested in changes, as we already verified
changes in the paths touched by the merge. And the existance of
other paths is enough to mark the directory edited */
err = svn_wc_walk_status(merge_b->ctx->wc_ctx, local_abspath,
svn_depth_infinity, TRUE /* get-all */,
FALSE /* no-ignore */,
TRUE /* ignore-text-mods */, ignores,
verify_touched_by_del_check, delb,
merge_b->ctx->cancel_func,
merge_b->ctx->cancel_baton,
scratch_pool);
if (err)
if (! same)
{
if (err->apr_err != SVN_ERR_CEASE_INVOCATION)
return svn_error_trace(err);
svn_error_clear(err);
delb->found_edit = TRUE;
}
else
{
store_path(delb->compared_abspaths, local_abspath);
}
same = ! delb->found_edit;
if (delb->del_root != db)
return SVN_NO_ERROR;
if (delb->found_edit)
same = FALSE;
else
{
apr_array_header_t *ignores;
svn_error_t *err;
same = TRUE;
SVN_ERR(svn_wc_get_default_ignores(&ignores, merge_b->ctx->config,
scratch_pool));
/* None of the descendants was modified, but maybe there are
descendants we haven't walked?
Note that we aren't interested in changes, as we already verified
changes in the paths touched by the merge. And the existence of
other paths is enough to mark the directory edited */
err = svn_wc_walk_status(merge_b->ctx->wc_ctx, local_abspath,
svn_depth_infinity, TRUE /* get-all */,
FALSE /* no-ignore */,
TRUE /* ignore-text-mods */, ignores,
verify_touched_by_del_check, delb,
merge_b->ctx->cancel_func,
merge_b->ctx->cancel_baton,
scratch_pool);
if (err)
{
if (err->apr_err != SVN_ERR_CEASE_INVOCATION)
return svn_error_trace(err);
svn_error_clear(err);
}
same = ! delb->found_edit;
}
}
if (same && !merge_b->dry_run)
@ -9668,6 +9693,7 @@ do_merge(apr_hash_t **modified_subtrees,
merge_cmd_baton_t merge_cmd_baton = { 0 };
svn_config_t *cfg;
const char *diff3_cmd;
const char *preserved_exts_str;
int i;
svn_boolean_t checked_mergeinfo_capability = FALSE;
svn_ra_session_t *ra_session1 = NULL, *ra_session2 = NULL;
@ -9728,6 +9754,11 @@ do_merge(apr_hash_t **modified_subtrees,
if (diff3_cmd != NULL)
SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, scratch_pool));
/* See which files the user wants to preserve the extension of when
conflict files are made. */
svn_config_get(cfg, &preserved_exts_str, SVN_CONFIG_SECTION_MISCELLANY,
SVN_CONFIG_OPTION_PRESERVED_CF_EXTS, "");
/* Build the merge context baton (or at least the parts of it that
don't need to be reset for each merge source). */
merge_cmd_baton.force_delete = force_delete;
@ -9743,6 +9774,11 @@ do_merge(apr_hash_t **modified_subtrees,
merge_cmd_baton.pool = iterpool;
merge_cmd_baton.merge_options = merge_options;
merge_cmd_baton.diff3_cmd = diff3_cmd;
merge_cmd_baton.ext_patterns = *preserved_exts_str
? svn_cstring_split(preserved_exts_str, "\n\r\t\v ",
FALSE, scratch_pool)
: NULL;
merge_cmd_baton.use_sleep = use_sleep;
/* Do we already know the specific subtrees with mergeinfo we want
@ -10447,15 +10483,10 @@ merge_locked(conflict_report_t **conflict_report,
}
else
{
merge_source_t source;
source.loc1 = source1_loc;
source.loc2 = source2_loc;
source.ancestral = FALSE;
/* Build a single-item merge_source_t array. */
merge_sources = apr_array_make(scratch_pool, 1, sizeof(merge_source_t *));
APR_ARRAY_PUSH(merge_sources, merge_source_t *) = &source;
APR_ARRAY_PUSH(merge_sources, merge_source_t *)
= merge_source_create(source1_loc, source2_loc, FALSE, scratch_pool);
}
err = do_merge(NULL, NULL, conflict_report, &use_sleep,
@ -10761,7 +10792,7 @@ log_find_operative_revs(void *baton,
UNMERGED_CATALOG represents the history (as mergeinfo) from
TARGET_LOC that is not represented in SOURCE_LOC's
explicit/inherited mergeinfo as represented by MERGED_CATALOG.
MERGEINFO_CATALOG may be empty if the source has no explicit or inherited
MERGED_CATALOG may be empty if the source has no explicit or inherited
mergeinfo.
Check that all of the unmerged revisions in UNMERGED_CATALOG's
@ -11464,7 +11495,7 @@ find_reintegrate_merge(merge_source_t **source_p,
prefix. */
svn_mergeinfo_catalog_t final_unmerged_catalog = apr_hash_make(scratch_pool);
SVN_ERR(find_unsynced_ranges(source_loc, yc_ancestor,
SVN_ERR(find_unsynced_ranges(source_loc, &target->loc,
unmerged_to_source_mergeinfo_catalog,
merged_to_source_mergeinfo_catalog,
final_unmerged_catalog,

View File

@ -890,8 +890,14 @@ svn_client_propget5(apr_hash_t **props,
const char *copy_root_abspath;
svn_boolean_t is_copy;
SVN_ERR(svn_dirent_get_absolute(&local_abspath, target,
scratch_pool));
/* Avoid assertion on the next line when somebody accidentally asks for
a working copy revision on a URL */
if (svn_path_is_url(target))
return svn_error_create(SVN_ERR_CLIENT_VERSIONED_PATH_REQUIRED,
NULL, NULL);
SVN_ERR_ASSERT(svn_dirent_is_absolute(target));
local_abspath = target;
if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_revision->kind))
{
@ -1232,7 +1238,7 @@ recursive_proplist_receiver(void *baton,
Report iprops anyway */
SVN_ERR(b->wrapped_receiver(b->wrapped_receiver_baton,
b->anchor ? b->anchor : local_abspath,
b->anchor ? b->anchor : b->anchor_abspath,
NULL /* prop_hash */,
b->iprops,
scratch_pool));
@ -1293,6 +1299,12 @@ get_remote_props(const char *path_or_url,
const char *copy_root_abspath;
svn_boolean_t is_copy;
/* Avoid assertion on the next line when somebody accidentally asks for
a working copy revision on a URL */
if (svn_path_is_url(path_or_url))
return svn_error_create(SVN_ERR_CLIENT_VERSIONED_PATH_REQUIRED,
NULL, NULL);
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url,
scratch_pool));

View File

@ -723,8 +723,6 @@ decode_window(svn_txdelta_window_t *window, svn_filesize_t sview_offset,
svn_stringbuf_t *instout = svn_stringbuf_create_empty(pool);
svn_stringbuf_t *ndout = svn_stringbuf_create_empty(pool);
/* these may in fact simply return references to insend */
SVN_ERR(zlib_decode(insend, newlen, ndout,
SVN_DELTA_WINDOW_SIZE));
SVN_ERR(zlib_decode(data, insend - data, instout,
@ -739,7 +737,13 @@ decode_window(svn_txdelta_window_t *window, svn_filesize_t sview_offset,
}
else
{
new_data->data = (const char *) insend;
/* Copy the data because an svn_string_t must have the invariant
data[len]=='\0'. */
char *buf = apr_palloc(pool, newlen + 1);
memcpy(buf, insend, newlen);
buf[newlen] = '\0';
new_data->data = buf;
new_data->len = newlen;
}

View File

@ -98,8 +98,11 @@ fs_serialized_init(svn_fs_t *fs, apr_pool_t *common_pool, apr_pool_t *pool)
SVN_ERR(svn_mutex__init(&ffsd->txn_current_lock,
SVN_FS_FS__USE_LOCK_MUTEX, common_pool));
/* We also need a mutex for synchronizing access to the active
transaction list and free transaction pointer. This one is
enabled unconditionally. */
SVN_ERR(svn_mutex__init(&ffsd->txn_list_lock,
SVN_FS_FS__USE_LOCK_MUTEX, common_pool));
TRUE, common_pool));
key = apr_pstrdup(common_pool, key);
status = apr_pool_userdata_set(ffsd, key, NULL, common_pool);

View File

@ -266,7 +266,7 @@ typedef struct fs_fs_data_t
svn_cache__t *dir_cache;
/* Fulltext cache; currently only used with memcached. Maps from
rep key (revision/offset) to svn_string_t. */
rep key (revision/offset) to svn_stringbuf_t. */
svn_cache__t *fulltext_cache;
/* Access object to the atomics namespace used by revprop caching.

View File

@ -1,4 +1,4 @@
/* This file is automatically generated from rep-cache-db.sql and .dist_sandbox/subversion-1.8.8/subversion/libsvn_fs_fs/token-map.h.
/* This file is automatically generated from rep-cache-db.sql and .dist_sandbox/subversion-1.8.9/subversion/libsvn_fs_fs/token-map.h.
* Do not edit this file -- edit the source and rerun gen-make.py */
#define STMT_CREATE_SCHEMA 0

View File

@ -116,6 +116,7 @@ getlocks_closed(svn_ra_serf__xml_estate_t *xes,
if (leaving_state == LOCK)
{
const char *path = svn_hash_gets(attrs, "path");
const char *token = svn_hash_gets(attrs, "token");
svn_boolean_t save_lock = FALSE;
/* Filter out unwanted paths. Since Subversion only allows
@ -128,6 +129,12 @@ getlocks_closed(svn_ra_serf__xml_estate_t *xes,
c) we've asked for depth=files or depth=immediates, and this
lock is on an immediate child of our query path.
*/
if (! token)
{
/* A lock without a token is not a lock; just an answer that there
is no lock on the node. */
save_lock = FALSE;
}
if (strcmp(lock_ctx->path, path) == 0
|| lock_ctx->requested_depth == svn_depth_infinity)
{
@ -154,7 +161,7 @@ getlocks_closed(svn_ra_serf__xml_estate_t *xes,
them may have not been sent, so the value will be NULL. */
lock.path = path;
lock.token = svn_hash_gets(attrs, "token");
lock.token = token;
lock.owner = svn_hash_gets(attrs, "owner");
lock.comment = svn_hash_gets(attrs, "comment");
@ -234,6 +241,7 @@ svn_ra_serf__get_locks(svn_ra_session_t *ra_session,
svn_ra_serf__handler_t *handler;
svn_ra_serf__xml_context_t *xmlctx;
const char *req_url, *rel_path;
svn_error_t *err;
req_url = svn_path_url_add_component2(session->session_url.path, path, pool);
SVN_ERR(svn_ra_serf__get_relative_path(&rel_path, req_url, session,
@ -260,7 +268,14 @@ svn_ra_serf__get_locks(svn_ra_session_t *ra_session,
handler->body_delegate = create_getlocks_body;
handler->body_delegate_baton = lock_ctx;
SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
err = svn_ra_serf__context_run_one(handler, pool);
/* Wrap the server generated error for an unsupported report with the
documented error for this ra function. */
if (svn_error_find_cause(err, SVN_ERR_UNSUPPORTED_FEATURE))
err = svn_error_create(SVN_ERR_RA_NOT_IMPLEMENTED, err, NULL);
SVN_ERR(err);
/* We get a 404 when a path doesn't exist in HEAD, but it might
have existed earlier (E.g. 'svn ls http://s/svn/trunk/file@1' */

View File

@ -41,7 +41,7 @@
/* The current state of our XML parsing. */
typedef enum iprops_state_e {
NONE = 0,
INITIAL = 0,
IPROPS_REPORT,
IPROPS_ITEM,
IPROPS_PATH,
@ -61,18 +61,12 @@ typedef struct iprops_context_t {
/* The repository's root URL. */
const char *repos_root_url;
/* Current CDATA values*/
svn_stringbuf_t *curr_path;
/* Current property name */
svn_stringbuf_t *curr_propname;
svn_stringbuf_t *curr_propval;
const char *curr_prop_val_encoding;
/* Current element in IPROPS. */
svn_prop_inherited_item_t *curr_iprop;
/* Serf context completion flag for svn_ra_serf__context_run_wait() */
svn_boolean_t done;
/* Path we are finding inherited properties for. This is relative to
the RA session passed to svn_ra_serf__get_inherited_props. */
const char *path;
@ -80,162 +74,121 @@ typedef struct iprops_context_t {
svn_revnum_t revision;
} iprops_context_t;
#define S_ SVN_XML_NAMESPACE
static const svn_ra_serf__xml_transition_t iprops_table[] = {
{ INITIAL, S_, SVN_DAV__INHERITED_PROPS_REPORT, IPROPS_REPORT,
FALSE, { NULL }, FALSE },
{ IPROPS_REPORT, S_, SVN_DAV__IPROP_ITEM, IPROPS_ITEM,
FALSE, { NULL }, TRUE },
{ IPROPS_ITEM, S_, SVN_DAV__IPROP_PATH, IPROPS_PATH,
TRUE, { NULL }, TRUE },
{ IPROPS_ITEM, S_, SVN_DAV__IPROP_PROPNAME, IPROPS_PROPNAME,
TRUE, { NULL }, TRUE },
{ IPROPS_ITEM, S_, SVN_DAV__IPROP_PROPVAL, IPROPS_PROPVAL,
TRUE, { "?V:encoding", NULL }, TRUE },
{ 0 }
};
/* Conforms to svn_ra_serf__xml_opened_t */
static svn_error_t *
start_element(svn_ra_serf__xml_parser_t *parser,
svn_ra_serf__dav_props_t name,
const char **attrs,
iprops_opened(svn_ra_serf__xml_estate_t *xes,
void *baton,
int entered_state,
const svn_ra_serf__dav_props_t *tag,
apr_pool_t *scratch_pool)
{
iprops_context_t *iprops_ctx = parser->user_data;
iprops_state_e state;
iprops_context_t *iprops_ctx = baton;
state = parser->state->current_state;
if (state == NONE
&& strcmp(name.name, SVN_DAV__INHERITED_PROPS_REPORT) == 0)
if (entered_state == IPROPS_ITEM)
{
svn_ra_serf__xml_push_state(parser, IPROPS_REPORT);
}
else if (state == IPROPS_REPORT &&
strcmp(name.name, SVN_DAV__IPROP_ITEM) == 0)
{
svn_stringbuf_setempty(iprops_ctx->curr_path);
svn_stringbuf_setempty(iprops_ctx->curr_propname);
svn_stringbuf_setempty(iprops_ctx->curr_propval);
iprops_ctx->curr_prop_val_encoding = NULL;
iprops_ctx->curr_iprop = NULL;
svn_ra_serf__xml_push_state(parser, IPROPS_ITEM);
}
else if (state == IPROPS_ITEM &&
strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0)
{
const char *prop_val_encoding = svn_xml_get_attr_value("encoding",
attrs);
iprops_ctx->curr_prop_val_encoding = apr_pstrdup(iprops_ctx->pool,
prop_val_encoding);
svn_ra_serf__xml_push_state(parser, IPROPS_PROPVAL);
}
else if (state == IPROPS_ITEM &&
strcmp(name.name, SVN_DAV__IPROP_PATH) == 0)
{
svn_ra_serf__xml_push_state(parser, IPROPS_PATH);
}
else if (state == IPROPS_ITEM &&
strcmp(name.name, SVN_DAV__IPROP_PROPNAME) == 0)
{
svn_ra_serf__xml_push_state(parser, IPROPS_PROPNAME);
}
else if (state == IPROPS_ITEM &&
strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0)
{
svn_ra_serf__xml_push_state(parser, IPROPS_PROPVAL);
}
iprops_ctx->curr_iprop = apr_pcalloc(iprops_ctx->pool,
sizeof(*iprops_ctx->curr_iprop));
iprops_ctx->curr_iprop->prop_hash = apr_hash_make(iprops_ctx->pool);
}
return SVN_NO_ERROR;
}
/* Conforms to svn_ra_serf__xml_closed_t */
static svn_error_t *
end_element(svn_ra_serf__xml_parser_t *parser,
svn_ra_serf__dav_props_t name,
apr_pool_t *scratch_pool)
iprops_closed(svn_ra_serf__xml_estate_t *xes,
void *baton,
int leaving_state,
const svn_string_t *cdata,
apr_hash_t *attrs,
apr_pool_t *scratch_pool)
{
iprops_context_t *iprops_ctx = parser->user_data;
iprops_state_e state;
iprops_context_t *iprops_ctx = baton;
state = parser->state->current_state;
if (state == IPROPS_REPORT &&
strcmp(name.name, SVN_DAV__INHERITED_PROPS_REPORT) == 0)
if (leaving_state == IPROPS_ITEM)
{
svn_ra_serf__xml_pop_state(parser);
APR_ARRAY_PUSH(iprops_ctx->iprops, svn_prop_inherited_item_t *) =
iprops_ctx->curr_iprop;
iprops_ctx->curr_iprop = NULL;
}
else if (state == IPROPS_PATH
&& strcmp(name.name, SVN_DAV__IPROP_PATH) == 0)
else if (leaving_state == IPROPS_PATH)
{
iprops_ctx->curr_iprop = apr_palloc(
iprops_ctx->pool, sizeof(svn_prop_inherited_item_t));
/* Every <iprop-item> has a single <iprop-path> */
if (iprops_ctx->curr_iprop->path_or_url)
return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
iprops_ctx->curr_iprop->path_or_url =
svn_path_url_add_component2(iprops_ctx->repos_root_url,
iprops_ctx->curr_path->data,
cdata->data,
iprops_ctx->pool);
iprops_ctx->curr_iprop->prop_hash = apr_hash_make(iprops_ctx->pool);
svn_ra_serf__xml_pop_state(parser);
}
else if (state == IPROPS_PROPVAL
&& strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0)
else if (leaving_state == IPROPS_PROPNAME)
{
const svn_string_t *prop_val;
if (iprops_ctx->curr_propname->len)
return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
if (iprops_ctx->curr_prop_val_encoding)
/* Store propname for value */
svn_stringbuf_set(iprops_ctx->curr_propname, cdata->data);
}
else if (leaving_state == IPROPS_PROPVAL)
{
const char *encoding;
const svn_string_t *val_str;
if (! iprops_ctx->curr_propname->len)
return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
encoding = svn_hash_gets(attrs, "V:encoding");
if (encoding)
{
svn_string_t encoded_prop_val;
if (strcmp(encoding, "base64") != 0)
return svn_error_createf(SVN_ERR_XML_MALFORMED,
NULL,
_("Got unrecognized encoding '%s'"),
encoding);
if (strcmp(iprops_ctx->curr_prop_val_encoding, "base64") != 0)
return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
encoded_prop_val.data = iprops_ctx->curr_propval->data;
encoded_prop_val.len = iprops_ctx->curr_propval->len;
prop_val = svn_base64_decode_string(&encoded_prop_val,
iprops_ctx->pool);
/* Decode into the right pool. */
val_str = svn_base64_decode_string(cdata, iprops_ctx->pool);
}
else
{
prop_val = svn_string_create_from_buf(iprops_ctx->curr_propval,
iprops_ctx->pool);
/* Copy into the right pool. */
val_str = svn_string_dup(cdata, iprops_ctx->pool);
}
svn_hash_sets(iprops_ctx->curr_iprop->prop_hash,
apr_pstrdup(iprops_ctx->pool,
iprops_ctx->curr_propname->data),
prop_val);
/* Clear current propname and propval in the event there are
multiple properties on the current path. */
val_str);
/* Clear current propname. */
svn_stringbuf_setempty(iprops_ctx->curr_propname);
svn_stringbuf_setempty(iprops_ctx->curr_propval);
svn_ra_serf__xml_pop_state(parser);
}
else if (state == IPROPS_PROPNAME
&& strcmp(name.name, SVN_DAV__IPROP_PROPNAME) == 0)
{
svn_ra_serf__xml_pop_state(parser);
}
else if (state == IPROPS_ITEM
&& strcmp(name.name, SVN_DAV__IPROP_ITEM) == 0)
{
APR_ARRAY_PUSH(iprops_ctx->iprops, svn_prop_inherited_item_t *) =
iprops_ctx->curr_iprop;
svn_ra_serf__xml_pop_state(parser);
}
return SVN_NO_ERROR;
}
static svn_error_t *
cdata_handler(svn_ra_serf__xml_parser_t *parser,
const char *data,
apr_size_t len,
apr_pool_t *scratch_pool)
{
iprops_context_t *iprops_ctx = parser->user_data;
iprops_state_e state = parser->state->current_state;
switch (state)
{
case IPROPS_PATH:
svn_stringbuf_appendbytes(iprops_ctx->curr_path, data, len);
break;
case IPROPS_PROPNAME:
svn_stringbuf_appendbytes(iprops_ctx->curr_propname, data, len);
break;
case IPROPS_PROPVAL:
svn_stringbuf_appendbytes(iprops_ctx->curr_propval, data, len);
break;
default:
break;
}
else
SVN_ERR_MALFUNCTION(); /* Invalid transition table */
return SVN_NO_ERROR;
}
@ -281,7 +234,7 @@ svn_ra_serf__get_inherited_props(svn_ra_session_t *ra_session,
iprops_context_t *iprops_ctx;
svn_ra_serf__session_t *session = ra_session->priv;
svn_ra_serf__handler_t *handler;
svn_ra_serf__xml_parser_t *parser_ctx;
svn_ra_serf__xml_context_t *xmlctx;
const char *req_url;
SVN_ERR(svn_ra_serf__get_stable_url(&req_url,
@ -295,19 +248,20 @@ svn_ra_serf__get_inherited_props(svn_ra_session_t *ra_session,
SVN_ERR_ASSERT(session->repos_root_str);
iprops_ctx = apr_pcalloc(scratch_pool, sizeof(*iprops_ctx));
iprops_ctx->done = FALSE;
iprops_ctx->repos_root_url = session->repos_root_str;
iprops_ctx->pool = result_pool;
iprops_ctx->curr_path = svn_stringbuf_create_empty(scratch_pool);
iprops_ctx->curr_propname = svn_stringbuf_create_empty(scratch_pool);
iprops_ctx->curr_propval = svn_stringbuf_create_empty(scratch_pool);
iprops_ctx->curr_iprop = NULL;
iprops_ctx->iprops = apr_array_make(result_pool, 1,
sizeof(svn_prop_inherited_item_t *));
iprops_ctx->path = path;
iprops_ctx->revision = revision;
handler = apr_pcalloc(scratch_pool, sizeof(*handler));
xmlctx = svn_ra_serf__xml_context_create(iprops_table,
iprops_opened, iprops_closed, NULL,
iprops_ctx,
scratch_pool);
handler = svn_ra_serf__create_expat_handler(xmlctx, scratch_pool);
handler->method = "REPORT";
handler->path = req_url;
@ -318,18 +272,6 @@ svn_ra_serf__get_inherited_props(svn_ra_session_t *ra_session,
handler->body_type = "text/xml";
handler->handler_pool = scratch_pool;
parser_ctx = apr_pcalloc(scratch_pool, sizeof(*parser_ctx));
parser_ctx->pool = scratch_pool;
parser_ctx->user_data = iprops_ctx;
parser_ctx->start = start_element;
parser_ctx->end = end_element;
parser_ctx->cdata = cdata_handler;
parser_ctx->done = &iprops_ctx->done;
handler->response_handler = svn_ra_serf__handle_xml_parser;
handler->response_baton = parser_ctx;
err = svn_ra_serf__context_run_one(handler, scratch_pool);
SVN_ERR(svn_error_compose_create(
svn_ra_serf__error_on_status(handler->sline,
@ -337,8 +279,7 @@ svn_ra_serf__get_inherited_props(svn_ra_session_t *ra_session,
handler->location),
err));
if (iprops_ctx->done)
*iprops = iprops_ctx->iprops;
*iprops = iprops_ctx->iprops;
return SVN_NO_ERROR;
}

View File

@ -156,11 +156,20 @@ locks_closed(svn_ra_serf__xml_estate_t *xes,
if (leaving_state == TIMEOUT)
{
if (strcmp(cdata->data, "Infinite") == 0)
if (strcasecmp(cdata->data, "Infinite") == 0)
lock_ctx->lock->expiration_date = 0;
else if (strncasecmp(cdata->data, "Second-", 7) == 0)
{
unsigned n;
SVN_ERR(svn_cstring_atoui(&n, cdata->data+7));
lock_ctx->lock->expiration_date = apr_time_now() +
apr_time_from_sec(n);
}
else
SVN_ERR(svn_time_from_cstring(&lock_ctx->lock->creation_date,
cdata->data, lock_ctx->pool));
return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
_("Invalid LOCK timeout value '%s'"),
cdata->data);
}
else if (leaving_state == HREF)
{
@ -362,29 +371,30 @@ svn_error_t *
svn_ra_serf__get_lock(svn_ra_session_t *ra_session,
svn_lock_t **lock,
const char *path,
apr_pool_t *pool)
apr_pool_t *result_pool)
{
svn_ra_serf__session_t *session = ra_session->priv;
svn_ra_serf__handler_t *handler;
svn_ra_serf__xml_context_t *xmlctx;
apr_pool_t *scratch_pool = svn_pool_create(result_pool);
lock_info_t *lock_ctx;
const char *req_url;
svn_error_t *err;
req_url = svn_path_url_add_component2(session->session_url.path, path, pool);
req_url = svn_path_url_add_component2(session->session_url.path, path,
scratch_pool);
lock_ctx = apr_pcalloc(pool, sizeof(*lock_ctx));
lock_ctx->pool = pool;
lock_ctx = apr_pcalloc(scratch_pool, sizeof(*lock_ctx));
lock_ctx->pool = result_pool;
lock_ctx->path = req_url;
lock_ctx->lock = svn_lock_create(pool);
lock_ctx->lock->path = apr_pstrdup(pool, path); /* be sure */
lock_ctx->lock = svn_lock_create(result_pool);
lock_ctx->lock->path = apr_pstrdup(result_pool, path);
xmlctx = svn_ra_serf__xml_context_create(locks_ttable,
NULL, locks_closed, NULL,
lock_ctx,
pool);
handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
scratch_pool);
handler = svn_ra_serf__create_expat_handler(xmlctx, scratch_pool);
handler->method = "PROPFIND";
handler->path = req_url;
@ -405,7 +415,7 @@ svn_ra_serf__get_lock(svn_ra_session_t *ra_session,
lock_ctx->handler = handler;
err = svn_ra_serf__context_run_one(handler, pool);
err = svn_ra_serf__context_run_one(handler, scratch_pool);
err = determine_error(handler, err);
if (handler->sline.code == 404)
@ -420,7 +430,12 @@ svn_ra_serf__get_lock(svn_ra_session_t *ra_session,
_("Server does not support locking features"));
}
*lock = lock_ctx->lock;
if (lock_ctx->lock && lock_ctx->lock->token)
*lock = lock_ctx->lock;
else
*lock = NULL;
svn_pool_destroy(scratch_pool);
return SVN_NO_ERROR;
}
@ -574,7 +589,7 @@ svn_ra_serf__unlock(svn_ra_session_t *ra_session,
{
SVN_ERR(svn_ra_serf__get_lock(ra_session, &existing_lock, path,
iterpool));
token = existing_lock->token;
token = existing_lock ? existing_lock->token : NULL;
if (!token)
{
err = svn_error_createf(SVN_ERR_RA_NOT_LOCKED, NULL,

View File

@ -571,7 +571,7 @@ svn_ra_serf__get_log(svn_ra_session_t *ra_session,
/* At this point, we may have a deleted file. So, we'll match ra_neon's
* behavior and use the larger of start or end as our 'peg' rev.
*/
peg_rev = (start > end) ? start : end;
peg_rev = (start == SVN_INVALID_REVNUM || start > end) ? start : end;
SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
session, NULL /* conn */,

View File

@ -329,9 +329,6 @@ struct report_context_t {
files/dirs? */
svn_boolean_t add_props_included;
/* Path -> lock token mapping. */
apr_hash_t *lock_path_tokens;
/* Path -> const char *repos_relpath mapping */
apr_hash_t *switched_paths;
@ -2248,8 +2245,6 @@ end_report(svn_ra_serf__xml_parser_t *parser,
info->pool);
}
info->lock_token = svn_hash_gets(ctx->lock_path_tokens, info->name);
if (info->lock_token && !info->fetch_props)
info->fetch_props = TRUE;
@ -2578,13 +2573,6 @@ set_path(void *report_baton,
SVN_ERR(svn_io_file_write_full(report->body_file, buf->data, buf->len,
NULL, pool));
if (lock_token)
{
svn_hash_sets(report->lock_path_tokens,
apr_pstrdup(report->pool, path),
apr_pstrdup(report->pool, lock_token));
}
return SVN_NO_ERROR;
}
@ -2660,12 +2648,6 @@ link_path(void *report_baton,
if (!*path)
report->root_is_switched = TRUE;
if (lock_token)
{
svn_hash_sets(report->lock_path_tokens,
path, apr_pstrdup(report->pool, lock_token));
}
return APR_SUCCESS;
}
@ -3193,7 +3175,6 @@ make_update_reporter(svn_ra_session_t *ra_session,
report->ignore_ancestry = ignore_ancestry;
report->send_copyfrom_args = send_copyfrom_args;
report->text_deltas = text_deltas;
report->lock_path_tokens = apr_hash_make(report->pool);
report->switched_paths = apr_hash_make(report->pool);
report->source = src_path;

View File

@ -310,6 +310,7 @@ second place for auth-request point as noted below.
sends file contents as a series of strings, terminated by the empty
string, followed by a second empty command response to indicate
whether an error occurred during the sending of the file.
NOTE: the standard client never sends want-iprops, it uses get-iprops.
get-dir
params: ( path:string [ rev:number ] want-props:bool want-contents:bool
@ -321,6 +322,7 @@ second place for auth-request point as noted below.
[ last-author:string ] )
dirent-field: kind | size | has-props | created-rev | time | last-author
| word
NOTE: the standard client never sends want-iprops, it uses get-iprops.
check-path
params: ( path:string [ rev:number ] )

View File

@ -217,6 +217,49 @@ make_dir_baton(const char *path,
}
/* If the mergeinfo in MERGEINFO_STR refers to any revisions older than
* OLDEST_DUMPED_REV, issue a warning and set *FOUND_OLD_MERGEINFO to TRUE,
* otherwise leave *FOUND_OLD_MERGEINFO unchanged.
*/
static svn_error_t *
verify_mergeinfo_revisions(svn_boolean_t *found_old_mergeinfo,
const char *mergeinfo_str,
svn_revnum_t oldest_dumped_rev,
svn_repos_notify_func_t notify_func,
void *notify_baton,
apr_pool_t *pool)
{
svn_mergeinfo_t mergeinfo, old_mergeinfo;
SVN_ERR(svn_mergeinfo_parse(&mergeinfo, mergeinfo_str, pool));
SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
&old_mergeinfo, mergeinfo,
oldest_dumped_rev - 1, 0,
TRUE, pool, pool));
if (apr_hash_count(old_mergeinfo))
{
svn_repos_notify_t *notify =
svn_repos_notify_create(svn_repos_notify_warning, pool);
notify->warning = svn_repos_notify_warning_found_old_mergeinfo;
notify->warning_str = apr_psprintf(
pool,
_("Mergeinfo referencing revision(s) prior "
"to the oldest dumped revision (r%ld). "
"Loading this dump may result in invalid "
"mergeinfo."),
oldest_dumped_rev);
if (found_old_mergeinfo)
*found_old_mergeinfo = TRUE;
notify_func(notify_baton, notify, pool);
}
return SVN_NO_ERROR;
}
/* This helper is the main "meat" of the editor -- it does all the
work of writing a node record.
@ -475,32 +518,13 @@ dump_node(struct edit_baton *eb,
SVN_PROP_MERGEINFO);
if (mergeinfo_str)
{
svn_mergeinfo_t mergeinfo, old_mergeinfo;
SVN_ERR(svn_mergeinfo_parse(&mergeinfo, mergeinfo_str->data,
pool));
SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
&old_mergeinfo, mergeinfo,
eb->oldest_dumped_rev - 1, 0,
TRUE, pool, pool));
if (apr_hash_count(old_mergeinfo))
{
svn_repos_notify_t *notify =
svn_repos_notify_create(svn_repos_notify_warning, pool);
notify->warning = svn_repos_notify_warning_found_old_mergeinfo;
notify->warning_str = apr_psprintf(
pool,
_("Mergeinfo referencing revision(s) prior "
"to the oldest dumped revision (r%ld). "
"Loading this dump may result in invalid "
"mergeinfo."),
eb->oldest_dumped_rev);
if (eb->found_old_mergeinfo)
*eb->found_old_mergeinfo = TRUE;
eb->notify_func(eb->notify_baton, notify, pool);
}
/* An error in verifying the mergeinfo must not prevent dumping
the data. Ignore any such error. */
svn_error_clear(verify_mergeinfo_revisions(
eb->found_old_mergeinfo,
mergeinfo_str->data, eb->oldest_dumped_rev,
eb->notify_func, eb->notify_baton,
pool));
}
}

View File

@ -117,6 +117,8 @@ svn_repos_fs_begin_txn_for_commit2(svn_fs_txn_t **txn_p,
const char *txn_name;
svn_string_t *author = svn_hash_gets(revprop_table, SVN_PROP_REVISION_AUTHOR);
apr_hash_t *hooks_env;
svn_error_t *err;
svn_fs_txn_t *txn;
/* Parse the hooks-env file (if any). */
SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
@ -124,21 +126,30 @@ svn_repos_fs_begin_txn_for_commit2(svn_fs_txn_t **txn_p,
/* Begin the transaction, ask for the fs to do on-the-fly lock checks.
We fetch its name, too, so the start-commit hook can use it. */
SVN_ERR(svn_fs_begin_txn2(txn_p, repos->fs, rev,
SVN_ERR(svn_fs_begin_txn2(&txn, repos->fs, rev,
SVN_FS_TXN_CHECK_LOCKS, pool));
SVN_ERR(svn_fs_txn_name(&txn_name, *txn_p, pool));
err = svn_fs_txn_name(&txn_name, txn, pool);
if (err)
return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));
/* We pass the revision properties to the filesystem by adding them
as properties on the txn. Later, when we commit the txn, these
properties will be copied into the newly created revision. */
revprops = svn_prop_hash_to_array(revprop_table, pool);
SVN_ERR(svn_repos_fs_change_txn_props(*txn_p, revprops, pool));
err = svn_repos_fs_change_txn_props(txn, revprops, pool);
if (err)
return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));
/* Run start-commit hooks. */
SVN_ERR(svn_repos__hooks_start_commit(repos, hooks_env,
author ? author->data : NULL,
repos->client_capabilities, txn_name,
pool));
err = svn_repos__hooks_start_commit(repos, hooks_env,
author ? author->data : NULL,
repos->client_capabilities, txn_name,
pool);
if (err)
return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));
/* We have API promise that *TXN_P is unaffected on faulure. */
*txn_p = txn;
return SVN_NO_ERROR;
}

View File

@ -203,9 +203,10 @@ memcache_get(void **value_p,
}
else
{
svn_string_t *value = apr_pcalloc(result_pool, sizeof(*value));
svn_stringbuf_t *value = svn_stringbuf_create_empty(result_pool);
value->data = data;
value->len = data_len;
value->blocksize = data_len;
value->len = data_len - 1; /* account for trailing NUL */
*value_p = value;
}
}
@ -263,7 +264,7 @@ memcache_set(void *cache_void,
{
svn_stringbuf_t *value_str = value;
data = value_str->data;
data_len = value_str->len;
data_len = value_str->len + 1; /* copy trailing NUL */
}
err = memcache_internal_set(cache_void, key, data, data_len, subpool);

View File

@ -69,7 +69,7 @@ typedef struct parse_context_t
/* Parser buffer for getc() to avoid call overhead into several libraries
for every character */
char parser_buffer[SVN_STREAM_CHUNK_SIZE]; /* Larger than most config files */
char parser_buffer[SVN__STREAM_CHUNK_SIZE]; /* Larger than most config files */
size_t buffer_pos; /* Current position within parser_buffer */
size_t buffer_size; /* parser_buffer contains this many bytes */
} parse_context_t;

View File

@ -1,4 +1,4 @@
/* This file is automatically generated from internal_statements.sql and .dist_sandbox/subversion-1.8.8/subversion/libsvn_subr/token-map.h.
/* This file is automatically generated from internal_statements.sql and .dist_sandbox/subversion-1.8.9/subversion/libsvn_subr/token-map.h.
* Do not edit this file -- edit the source and rerun gen-make.py */
#define STMT_INTERNAL_SAVEPOINT_SVN 0

View File

@ -1243,32 +1243,44 @@ svn_io_sleep_for_timestamps(const char *path, apr_pool_t *pool)
{
/* Very simplistic but safe approach:
If the filesystem has < sec mtime we can be reasonably sure
that the filesystem has <= millisecond precision.
that the filesystem has some sub-second resolution. On Windows
it is likely to be sub-millisecond; on Linux systems it depends
on the filesystem, ext4 is typically 1ms, 4ms or 10ms resolution.
## Perhaps find a better algorithm here. This will fail once
in every 1000 cases on a millisecond precision filesystem.
in every 1000 cases on a millisecond precision filesystem
if the mtime happens to be an exact second.
But better to fail once in every thousand cases than every
time, like we did before.
(All tested filesystems I know have at least microsecond precision.)
Note for further research on algorithm:
FAT32 has < 1 sec precision on ctime, but 2 sec on mtime */
FAT32 has < 1 sec precision on ctime, but 2 sec on mtime.
/* Sleep for at least 1 millisecond.
(t < 1000 will be round to 0 in apr) */
apr_sleep(1000);
Linux/ext4 with CONFIG_HZ=250 has high resolution
apr_time_now and although the filesystem timestamps
have similar high precision they are only updated with
a coarser 4ms resolution. */
return;
/* 10 milliseconds after now. */
#ifndef SVN_HI_RES_SLEEP_MS
#define SVN_HI_RES_SLEEP_MS 10
#endif
then = now + apr_time_from_msec(SVN_HI_RES_SLEEP_MS);
}
now = apr_time_now(); /* Extract the time used for the path stat */
if (now >= then)
return; /* Passing negative values may suspend indefinitely (Windows) */
/* Remove time taken to do stat() from sleep. */
now = apr_time_now();
}
apr_sleep(then - now);
if (now >= then)
return; /* Passing negative values may suspend indefinitely (Windows) */
/* (t < 1000 will be round to 0 in apr) */
if (then - now < 1000)
apr_sleep(1000);
else
apr_sleep(then - now);
}

View File

@ -177,7 +177,7 @@ terminal_open(terminal_handle_t **terminal, svn_boolean_t noecho,
and stderr for prompting. */
apr_file_t *tmpfd;
status = apr_file_open(&tmpfd, "/dev/tty",
APR_FOPEN_READ | APR_FOPEN_WRITE,
APR_READ | APR_WRITE,
APR_OS_DEFAULT, pool);
*terminal = apr_palloc(pool, sizeof(terminal_handle_t));
if (!status)

View File

@ -1022,6 +1022,7 @@ release_name_from_version(const char *osver)
case 6: return "Snow Leopard";
case 7: return "Lion";
case 8: return "Mountain Lion";
case 9: return "Mavericks";
}
return NULL;

View File

@ -136,7 +136,7 @@ svn_version_extended(svn_boolean_t verbose,
info->build_time = __TIME__;
info->build_host = SVN_BUILD_HOST;
info->copyright = apr_pstrdup
(pool, _("Copyright (C) 2013 The Apache Software Foundation.\n"
(pool, _("Copyright (C) 2014 The Apache Software Foundation.\n"
"This software consists of contributions made by many people;\n"
"see the NOTICE file for more information.\n"
"Subversion is open source software, see "

View File

@ -242,144 +242,7 @@ struct file_baton
/** Code **/
/* Fill in *INFO with the information it would contain if it were
obtained from svn_wc__db_read_children_info. */
static svn_error_t *
read_info(const struct svn_wc__db_info_t **info,
const char *local_abspath,
svn_wc__db_t *db,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
struct svn_wc__db_info_t *mtb = apr_pcalloc(result_pool, sizeof(*mtb));
const svn_checksum_t *checksum;
const char *original_repos_relpath;
SVN_ERR(svn_wc__db_read_info(&mtb->status, &mtb->kind,
&mtb->revnum, &mtb->repos_relpath,
&mtb->repos_root_url, &mtb->repos_uuid,
&mtb->changed_rev, &mtb->changed_date,
&mtb->changed_author, &mtb->depth,
&checksum, NULL, &original_repos_relpath, NULL,
NULL, NULL, &mtb->lock, &mtb->recorded_size,
&mtb->recorded_time, &mtb->changelist,
&mtb->conflicted, &mtb->op_root,
&mtb->had_props, &mtb->props_mod,
&mtb->have_base, &mtb->have_more_work, NULL,
db, local_abspath,
result_pool, scratch_pool));
SVN_ERR(svn_wc__db_wclocked(&mtb->locked, db, local_abspath, scratch_pool));
/* Maybe we have to get some shadowed lock from BASE to make our test suite
happy... (It might be completely unrelated, but...) */
if (mtb->have_base
&& (mtb->status == svn_wc__db_status_added
|| mtb->status == svn_wc__db_status_deleted
|| mtb->kind == svn_node_file))
{
svn_boolean_t update_root;
svn_wc__db_lock_t **lock_arg = NULL;
if (mtb->status == svn_wc__db_status_added
|| mtb->status == svn_wc__db_status_deleted)
lock_arg = &mtb->lock;
SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
lock_arg, NULL, NULL, &update_root,
db, local_abspath,
result_pool, scratch_pool));
mtb->file_external = (update_root && mtb->kind == svn_node_file);
if (mtb->status == svn_wc__db_status_deleted)
{
const char *moved_to_abspath;
const char *moved_to_op_root_abspath;
/* NOTE: we can't use op-root-ness as a condition here since a base
* node can be the root of a move and still not be an explicit
* op-root (having a working node with op_depth == pathelements).
*
* Both these (almost identical) situations showcase this:
* svn mv a/b bb
* svn del a
* and
* svn mv a aa
* svn mv aa/b bb
* In both, 'bb' is moved from 'a/b', but 'a/b' has no op_depth>0
* node at all, as its parent 'a' is locally deleted. */
SVN_ERR(svn_wc__db_scan_deletion(NULL,
&moved_to_abspath,
NULL,
&moved_to_op_root_abspath,
db, local_abspath,
scratch_pool, scratch_pool));
if (moved_to_abspath != NULL
&& moved_to_op_root_abspath != NULL
&& strcmp(moved_to_abspath, moved_to_op_root_abspath) == 0)
{
mtb->moved_to_abspath = apr_pstrdup(result_pool,
moved_to_abspath);
}
/* ### ^^^ THIS SUCKS. For at least two reasons:
* 1) We scan the node deletion and that's technically not necessary.
* We'd be fine to know if this is an actual root of a move.
* 2) From the elaborately calculated results, we backwards-guess
* whether this is a root.
* It works ok, and this code only gets called when a node is an
* explicit target of a 'status'. But it would be better to do this
* differently.
* We could return moved-to via svn_wc__db_base_get_info() (called
* just above), but as moved-to is only intended to be returned for
* roots of a move, that doesn't fit too well. */
}
}
/* ### svn_wc__db_read_info() could easily return the moved-here flag. But
* for now... (The per-dir query for recursive status is far more optimal.)
* Note that this actually scans around to get the full path, for a bool.
* This bool then gets returned, later is evaluated, and if true leads to
* the same paths being scanned again. We'd want to obtain this bool here as
* cheaply as svn_wc__db_read_children_info() does. */
if (mtb->status == svn_wc__db_status_added)
{
svn_wc__db_status_t status;
SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
db, local_abspath,
result_pool, scratch_pool));
mtb->moved_here = (status == svn_wc__db_status_moved_here);
mtb->incomplete = (status == svn_wc__db_status_incomplete);
}
mtb->has_checksum = (checksum != NULL);
mtb->copied = (original_repos_relpath != NULL);
#ifdef HAVE_SYMLINK
if (mtb->kind == svn_node_file
&& (mtb->had_props || mtb->props_mod))
{
apr_hash_t *properties;
if (mtb->props_mod)
SVN_ERR(svn_wc__db_read_props(&properties, db, local_abspath,
scratch_pool, scratch_pool));
else
SVN_ERR(svn_wc__db_read_pristine_props(&properties, db, local_abspath,
scratch_pool, scratch_pool));
mtb->special = (NULL != svn_hash_gets(properties, SVN_PROP_SPECIAL));
}
#endif
*info = mtb;
return SVN_NO_ERROR;
}
/* Return *REPOS_RELPATH and *REPOS_ROOT_URL for LOCAL_ABSPATH using
information in INFO if available, falling back on
@ -421,13 +284,42 @@ get_repos_root_url_relpath(const char **repos_relpath,
db, local_abspath,
result_pool, scratch_pool));
}
else if (info->have_base)
else if (info->status == svn_wc__db_status_deleted
&& !info->have_more_work
&& info->have_base)
{
SVN_ERR(svn_wc__db_scan_base_repos(repos_relpath, repos_root_url,
repos_uuid,
db, local_abspath,
result_pool, scratch_pool));
}
else if (info->status == svn_wc__db_status_deleted)
{
const char *work_del_abspath;
const char *add_abspath;
/* Handles working DELETE and the special case where there is just
svn_wc__db_status_not_present in WORKING */
SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, &work_del_abspath, NULL,
db, local_abspath,
scratch_pool, scratch_pool));
/* The parent of what has been deleted must be added */
add_abspath = svn_dirent_dirname(work_del_abspath, scratch_pool);
SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, repos_relpath,
repos_root_url, repos_uuid, NULL,
NULL, NULL, NULL,
db, add_abspath,
result_pool, scratch_pool));
*repos_relpath = svn_relpath_join(*repos_relpath,
svn_dirent_skip_ancestor(
add_abspath,
local_abspath),
result_pool);
}
else
{
*repos_relpath = NULL;
@ -493,7 +385,8 @@ assemble_status(svn_wc_status3_t **status,
if (!info)
SVN_ERR(read_info(&info, local_abspath, db, result_pool, scratch_pool));
SVN_ERR(svn_wc__db_read_single_info(&info, db, local_abspath,
result_pool, scratch_pool));
if (!info->repos_relpath || !parent_repos_relpath)
switched_p = FALSE;
@ -799,8 +692,11 @@ assemble_status(svn_wc_status3_t **status,
stat->changelist = apr_pstrdup(result_pool, info->changelist);
stat->moved_from_abspath = moved_from_abspath;
if (info->moved_to_abspath)
stat->moved_to_abspath = apr_pstrdup(result_pool, info->moved_to_abspath);
/* ### TODO: Handle multiple moved_to values properly */
if (info->moved_to)
stat->moved_to_abspath = apr_pstrdup(result_pool,
info->moved_to->moved_to_abspath);
stat->file_external = info->file_external;
@ -1345,8 +1241,8 @@ get_dir_status(const struct walk_status_baton *wb,
SVN_ERR(err);
if (!dir_info)
SVN_ERR(read_info(&dir_info, local_abspath, wb->db,
scratch_pool, iterpool));
SVN_ERR(svn_wc__db_read_single_info(&dir_info, wb->db, local_abspath,
scratch_pool, iterpool));
SVN_ERR(get_repos_root_url_relpath(&dir_repos_relpath, &dir_repos_root_url,
&dir_repos_uuid, dir_info,
@ -1506,8 +1402,9 @@ get_child_status(const struct walk_status_baton *wb,
if (dirent->kind == svn_node_none)
dirent = NULL;
SVN_ERR(read_info(&dir_info, parent_abspath, wb->db,
scratch_pool, scratch_pool));
SVN_ERR(svn_wc__db_read_single_info(&dir_info,
wb->db, parent_abspath,
scratch_pool, scratch_pool));
SVN_ERR(get_repos_root_url_relpath(&dir_repos_relpath, &dir_repos_root_url,
&dir_repos_uuid, dir_info,
@ -2710,7 +2607,8 @@ svn_wc__internal_walk_status(svn_wc__db_t *db,
ignore_patterns = ignores;
}
err = read_info(&info, local_abspath, db, scratch_pool, scratch_pool);
err = svn_wc__db_read_single_info(&info, db, local_abspath,
scratch_pool, scratch_pool);
if (err)
{

View File

@ -1,4 +1,4 @@
/* This file is automatically generated from wc-checks.sql and .dist_sandbox/subversion-1.8.8/subversion/libsvn_wc/token-map.h.
/* This file is automatically generated from wc-checks.sql and .dist_sandbox/subversion-1.8.9/subversion/libsvn_wc/token-map.h.
* Do not edit this file -- edit the source and rerun gen-make.py */
#define STMT_VERIFICATION_TRIGGERS 0

View File

@ -1,4 +1,4 @@
/* This file is automatically generated from wc-metadata.sql and .dist_sandbox/subversion-1.8.8/subversion/libsvn_wc/token-map.h.
/* This file is automatically generated from wc-metadata.sql and .dist_sandbox/subversion-1.8.9/subversion/libsvn_wc/token-map.h.
* Do not edit this file -- edit the source and rerun gen-make.py */
#define STMT_CREATE_SCHEMA 0
@ -163,6 +163,8 @@
#define STMT_4_INFO {"STMT_INSTALL_SCHEMA_STATISTICS", NULL}
#define STMT_4 \
"ANALYZE sqlite_master; " \
"DELETE FROM sqlite_stat1 " \
"WHERE tbl in ('NODES', 'ACTUAL_NODE', 'LOCK', 'WC_LOCK'); " \
"INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES " \
" ('NODES', 'sqlite_autoindex_NODES_1', '8000 8000 2 1'); " \
"INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES " \

View File

@ -597,6 +597,9 @@ CREATE UNIQUE INDEX I_EXTERNALS_DEFINED ON EXTERNALS (wc_id,
-- STMT_INSTALL_SCHEMA_STATISTICS
ANALYZE sqlite_master; /* Creates empty sqlite_stat1 if necessary */
DELETE FROM sqlite_stat1
WHERE tbl in ('NODES', 'ACTUAL_NODE', 'LOCK', 'WC_LOCK');
INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
('NODES', 'sqlite_autoindex_NODES_1', '8000 8000 2 1');
INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES

File diff suppressed because it is too large Load Diff

View File

@ -191,7 +191,7 @@ WHERE wc_id = ?1
-- STMT_DELETE_NODE
DELETE
FROM NODES
WHERE wc_id = ?1 AND local_relpath = ?2
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
-- STMT_DELETE_ACTUAL_FOR_BASE_RECURSIVE
/* The ACTUAL_NODE applies to BASE, unless there is in at least one op_depth
@ -417,6 +417,12 @@ LEFT OUTER JOIN nodes AS moved
WHERE work.wc_id = ?1 AND work.local_relpath = ?2 AND work.op_depth > 0
LIMIT 1
-- STMT_SELECT_MOVED_TO_NODE
SELECT op_depth, moved_to
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND moved_to IS NOT NULL
ORDER BY op_depth DESC
-- STMT_SELECT_OP_DEPTH_MOVED_TO
SELECT op_depth, moved_to, repos_path, revision
FROM nodes
@ -711,7 +717,7 @@ WHERE wc_id = ?1 AND local_relpath = ?2
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3)
AND presence = MAP_BASE_DELETED
-- STMT_DELETE_ALL_LAYERS
-- STMT_DELETE_NODE_ALL_LAYERS
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2
@ -1503,7 +1509,6 @@ WHERE wc_id = ?1
AND presence=MAP_NORMAL
AND file_external IS NULL
/* ### FIXME: op-depth? What about multiple moves? */
-- STMT_SELECT_MOVED_FROM_RELPATH
SELECT local_relpath, op_depth FROM nodes
WHERE wc_id = ?1 AND moved_to = ?2 AND op_depth > 0
@ -1530,14 +1535,31 @@ SELECT moved_to, local_relpath FROM nodes
WHERE wc_id = ?1 AND op_depth > 0
AND IS_STRICT_DESCENDANT_OF(moved_to, ?2)
/* If the node is moved here (r.moved_here = 1) we are really interested in
where the node was moved from. To obtain that we need the op_depth, but
this form of select only allows a single return value */
-- STMT_SELECT_MOVED_FOR_DELETE
SELECT local_relpath, moved_to, op_depth FROM nodes
SELECT local_relpath, moved_to, op_depth,
(SELECT CASE WHEN r.moved_here THEN r.op_depth END FROM nodes r
WHERE r.wc_id = ?1
AND r.local_relpath = n.local_relpath
AND r.op_depth < n.op_depth
ORDER BY r.op_depth DESC LIMIT 1) AS moved_here_op_depth
FROM nodes n
WHERE wc_id = ?1
AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
AND moved_to IS NOT NULL
AND op_depth >= (SELECT MAX(op_depth) FROM nodes o
WHERE o.wc_id = ?1
AND o.local_relpath = ?2)
AND op_depth >= ?3
-- STMT_SELECT_MOVED_FROM_FOR_DELETE
SELECT local_relpath, op_depth,
(SELECT CASE WHEN r.moved_here THEN r.op_depth END FROM nodes r
WHERE r.wc_id = ?1
AND r.local_relpath = n.local_relpath
AND r.op_depth < n.op_depth
ORDER BY r.op_depth DESC LIMIT 1) AS moved_here_op_depth
FROM nodes n
WHERE wc_id = ?1 AND moved_to = ?2 AND op_depth > 0
-- STMT_UPDATE_MOVED_TO_DESCENDANTS
UPDATE nodes SET moved_to = RELPATH_SKIP_JOIN(?2, ?3, moved_to)

View File

@ -627,6 +627,10 @@ svn_wc__db_extend_parent_delete(svn_wc__db_wcroot_t *wcroot,
When removing a node if the parent has a higher working node then
the parent node and this node are both deleted or replaced and any
delete over this node must be removed.
This function (like most wcroot functions) assumes that its caller
only uses this function within an sqlite transaction if atomic
behavior is needed.
*/
svn_error_t *
svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
@ -635,14 +639,60 @@ svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
int working_depth;
svn_wc__db_status_t presence;
const char *moved_to;
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_DELETE_LOWEST_WORKING_NODE));
STMT_SELECT_LOWEST_WORKING_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
op_depth));
SVN_ERR(svn_sqlite__step_done(stmt));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
return SVN_NO_ERROR;
if (!have_row)
return svn_error_trace(svn_sqlite__reset(stmt));
working_depth = svn_sqlite__column_int(stmt, 0);
presence = svn_sqlite__column_token(stmt, 1, presence_map);
moved_to = svn_sqlite__column_text(stmt, 3, scratch_pool);
SVN_ERR(svn_sqlite__reset(stmt));
if (moved_to)
{
/* Turn the move into a copy to keep the NODES table valid */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_CLEAR_MOVED_HERE_RECURSIVE));
SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
moved_to, relpath_depth(moved_to)));
SVN_ERR(svn_sqlite__step_done(stmt));
/* This leaves just the moved_to information on the origin,
which we will remove in the next step */
}
if (presence == svn_wc__db_status_base_deleted)
{
/* Nothing left to shadow; remove the base-deleted node */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_DELETE_NODE));
}
else if (moved_to)
{
/* Clear moved to information, as this node is no longer base-deleted */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_CLEAR_MOVED_TO_RELPATH));
}
else
{
/* Nothing to update */
return SVN_NO_ERROR;
}
SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
working_depth));
return svn_error_trace(svn_sqlite__update(NULL, stmt));
}
@ -4076,8 +4126,9 @@ get_info_for_copy(apr_int64_t *copyfrom_id,
svn_wc__db_status_t *status,
svn_node_kind_t *kind,
svn_boolean_t *op_root,
svn_wc__db_wcroot_t *wcroot,
svn_wc__db_wcroot_t *src_wcroot,
const char *local_relpath,
svn_wc__db_wcroot_t *dst_wcroot,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@ -4094,7 +4145,7 @@ get_info_for_copy(apr_int64_t *copyfrom_id,
NULL /* have_base */,
NULL /* have_more_work */,
NULL /* have_work */,
wcroot, local_relpath, result_pool, scratch_pool));
src_wcroot, local_relpath, result_pool, scratch_pool));
if (op_root)
*op_root = is_op_root;
@ -4109,7 +4160,7 @@ get_info_for_copy(apr_int64_t *copyfrom_id,
scratch_pool);
SVN_ERR(get_info_for_copy(copyfrom_id, copyfrom_relpath, copyfrom_rev,
NULL, NULL, NULL,
wcroot, parent_relpath,
src_wcroot, parent_relpath, dst_wcroot,
scratch_pool, scratch_pool));
if (*copyfrom_relpath)
*copyfrom_relpath = svn_relpath_join(*copyfrom_relpath, base_name,
@ -4118,7 +4169,7 @@ get_info_for_copy(apr_int64_t *copyfrom_id,
else if (node_status == svn_wc__db_status_added)
{
SVN_ERR(scan_addition(&node_status, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, wcroot, local_relpath,
NULL, NULL, NULL, src_wcroot, local_relpath,
scratch_pool, scratch_pool));
}
else if (node_status == svn_wc__db_status_deleted && is_op_root)
@ -4127,7 +4178,7 @@ get_info_for_copy(apr_int64_t *copyfrom_id,
SVN_ERR(scan_deletion_txn(&base_del_relpath, NULL,
&work_del_relpath,
NULL, wcroot, local_relpath,
NULL, src_wcroot, local_relpath,
scratch_pool, scratch_pool));
if (work_del_relpath)
{
@ -4140,7 +4191,8 @@ get_info_for_copy(apr_int64_t *copyfrom_id,
SVN_ERR(scan_addition(NULL, &op_root_relpath,
NULL, NULL, /* repos_* */
copyfrom_relpath, copyfrom_id, copyfrom_rev,
NULL, NULL, NULL, wcroot, parent_del_relpath,
NULL, NULL, NULL,
src_wcroot, parent_del_relpath,
scratch_pool, scratch_pool));
*copyfrom_relpath
= svn_relpath_join(*copyfrom_relpath,
@ -4155,7 +4207,7 @@ get_info_for_copy(apr_int64_t *copyfrom_id,
copyfrom_id, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
wcroot, local_relpath,
src_wcroot, local_relpath,
result_pool,
scratch_pool));
}
@ -4177,6 +4229,24 @@ get_info_for_copy(apr_int64_t *copyfrom_id,
if (status)
*status = node_status;
if (src_wcroot != dst_wcroot && *copyfrom_relpath)
{
const char *repos_root_url;
const char *repos_uuid;
/* Pass the right repos-id for the destination db. We can't just use
the id of the source database, as this value can change after
relocation (and perhaps also when we start storing multiple
working copies in a single db)! */
SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, &repos_uuid,
src_wcroot->sdb, *copyfrom_id,
scratch_pool));
SVN_ERR(create_repos_id(copyfrom_id, repos_root_url, repos_uuid,
dst_wcroot->sdb, scratch_pool));
}
return SVN_NO_ERROR;
}
@ -4336,8 +4406,9 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcroot,
const apr_array_header_t *children;
SVN_ERR(get_info_for_copy(&copyfrom_id, &copyfrom_relpath, &copyfrom_rev,
&status, &kind, &op_root, src_wcroot,
src_relpath, scratch_pool, scratch_pool));
&status, &kind, &op_root,
src_wcroot, src_relpath, dst_wcroot,
scratch_pool, scratch_pool));
SVN_ERR(op_depth_for_copy(&dst_op_depth, &dst_np_op_depth,
&dst_parent_op_depth,
@ -4562,21 +4633,6 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcroot,
}
else
{
if (copyfrom_relpath)
{
const char *repos_root_url;
const char *repos_uuid;
/* Pass the right repos-id for the destination db! */
SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, &repos_uuid,
src_wcroot->sdb, copyfrom_id,
scratch_pool));
SVN_ERR(create_repos_id(&copyfrom_id, repos_root_url, repos_uuid,
dst_wcroot->sdb, scratch_pool));
}
SVN_ERR(cross_db_copy(src_wcroot, src_relpath, dst_wcroot,
dst_relpath, dst_presence, dst_op_depth,
dst_np_op_depth, kind,
@ -7176,7 +7232,7 @@ remove_node_txn(svn_boolean_t *left_changes,
if (local_relpath[0] != '\0')
{
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_DELETE_NODE));
STMT_DELETE_NODE_ALL_LAYERS));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
}
@ -7487,8 +7543,86 @@ struct moved_node_t {
/* The op-depth of the deleted node at the source of the move. */
int op_depth;
/* When >= 1 the op_depth at which local_relpath was moved to its
location. Used to find its original location outside the delete */
int moved_from_depth;
};
/* Helper function to resolve the original location of local_relpath at OP_DEPTH
before it was moved into the tree rooted at ROOT_RELPATH. */
static svn_error_t *
resolve_moved_from(const char **moved_from_relpath,
int *moved_from_op_depth,
svn_wc__db_wcroot_t *wcroot,
const char *root_relpath,
const char *local_relpath,
int op_depth,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
const char *suffix = "";
svn_sqlite__stmt_t *stmt;
const char *m_from_relpath;
int m_from_op_depth;
int m_move_from_depth;
svn_boolean_t have_row;
while (relpath_depth(local_relpath) > op_depth)
{
const char *name;
svn_relpath_split(&local_relpath, &name, local_relpath, scratch_pool);
suffix = svn_relpath_join(suffix, name, scratch_pool);
}
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_MOVED_FROM_FOR_DELETE));
SVN_ERR(svn_sqlite__bindf(stmt, "is",
wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
if (!have_row)
{
/* assert(have_row); */
*moved_from_relpath = NULL;
*moved_from_op_depth = -1;
SVN_ERR(svn_sqlite__reset(stmt));
return SVN_NO_ERROR;
}
m_from_relpath = svn_sqlite__column_text(stmt, 0, scratch_pool);
m_from_op_depth = svn_sqlite__column_int(stmt, 1);
m_move_from_depth = svn_sqlite__column_int(stmt, 2);
SVN_ERR(svn_sqlite__reset(stmt));
if (! svn_relpath_skip_ancestor(root_relpath, m_from_relpath))
{
*moved_from_relpath = svn_relpath_join(m_from_relpath, suffix,
result_pool);
*moved_from_op_depth = m_from_op_depth; /* ### Ok? */
return SVN_NO_ERROR;
}
else if (!m_move_from_depth)
{
*moved_from_relpath = NULL;
*moved_from_op_depth = -1;
return SVN_NO_ERROR;
}
return svn_error_trace(
resolve_moved_from(moved_from_relpath,
moved_from_op_depth,
wcroot,
root_relpath,
svn_relpath_join(m_from_relpath, suffix,
scratch_pool),
m_move_from_depth,
result_pool, scratch_pool));
}
static svn_error_t *
delete_node(void *baton,
svn_wc__db_wcroot_t *wcroot,
@ -7500,19 +7634,70 @@ delete_node(void *baton,
svn_boolean_t have_row, op_root;
svn_boolean_t add_work = FALSE;
svn_sqlite__stmt_t *stmt;
int select_depth; /* Depth of what is to be deleted */
svn_boolean_t refetch_depth = FALSE;
int working_op_depth; /* Depth of what is to be deleted */
int keep_op_depth = 0; /* Depth of what is below what is deleted */
svn_node_kind_t kind;
apr_array_header_t *moved_nodes = NULL;
int delete_depth = relpath_depth(local_relpath);
int delete_op_depth = relpath_depth(local_relpath);
SVN_ERR(read_info(&status,
&kind, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
&op_root, NULL, NULL,
NULL, NULL, NULL,
wcroot, local_relpath,
scratch_pool, scratch_pool));
assert(*local_relpath); /* Can't delete wcroot */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_NODE_INFO));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
if (!have_row)
{
return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND,
svn_sqlite__reset(stmt),
_("The node '%s' was not found."),
path_for_error_message(wcroot,
local_relpath,
scratch_pool));
}
working_op_depth = svn_sqlite__column_int(stmt, 0);
status = svn_sqlite__column_token(stmt, 3, presence_map);
kind = svn_sqlite__column_token(stmt, 4, kind_map);
if (working_op_depth < delete_op_depth)
{
op_root = FALSE;
add_work = TRUE;
keep_op_depth = working_op_depth;
}
else
{
op_root = TRUE;
SVN_ERR(svn_sqlite__step(&have_row, stmt));
if (have_row)
{
svn_wc__db_status_t below_status;
int below_op_depth;
below_op_depth = svn_sqlite__column_int(stmt, 0);
below_status = svn_sqlite__column_token(stmt, 3, presence_map);
if (below_status != svn_wc__db_status_not_present
&& below_status != svn_wc__db_status_base_deleted)
{
add_work = TRUE;
keep_op_depth = below_op_depth;
}
else
keep_op_depth = 0;
}
else
keep_op_depth = -1;
}
SVN_ERR(svn_sqlite__reset(stmt));
if (working_op_depth != 0) /* WORKING */
SVN_ERR(convert_to_working_status(&status, status));
if (status == svn_wc__db_status_deleted
|| status == svn_wc__db_status_not_present)
@ -7591,6 +7776,7 @@ delete_node(void *baton,
part, scratch_pool);
moved_node->op_depth = move_op_depth;
moved_node->moved_to_relpath = b->moved_to_relpath;
moved_node->moved_from_depth = -1;
APR_ARRAY_PUSH(moved_nodes, const struct moved_node_t *) = moved_node;
}
@ -7602,8 +7788,9 @@ delete_node(void *baton,
* possibly because of a nested move operation. */
moved_node = apr_palloc(scratch_pool, sizeof(struct moved_node_t));
moved_node->local_relpath = local_relpath;
moved_node->op_depth = delete_depth;
moved_node->op_depth = delete_op_depth;
moved_node->moved_to_relpath = b->moved_to_relpath;
moved_node->moved_from_depth = -1;
APR_ARRAY_PUSH(moved_nodes, const struct moved_node_t *) = moved_node;
}
@ -7618,24 +7805,18 @@ delete_node(void *baton,
b->moved_to_relpath));
SVN_ERR(svn_sqlite__update(NULL, stmt));
}
else
{
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_CLEAR_MOVED_TO_DESCENDANTS));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
local_relpath));
SVN_ERR(svn_sqlite__update(NULL, stmt));
}
/* Find children that were moved out of the subtree rooted at this node.
* We'll need to update their op-depth columns because their deletion
* is now implied by the deletion of their parent (i.e. this node). */
{
apr_pool_t *iterpool;
int i;
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_MOVED_FOR_DELETE));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
delete_op_depth));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
iterpool = svn_pool_create(scratch_pool);
@ -7645,52 +7826,85 @@ delete_node(void *baton,
const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
const char *mv_to_relpath = svn_sqlite__column_text(stmt, 1, NULL);
int child_op_depth = svn_sqlite__column_int(stmt, 2);
int moved_from_depth = -1;
svn_boolean_t fixup = FALSE;
if (!b->moved_to_relpath
if (! b->moved_to_relpath
&& ! svn_relpath_skip_ancestor(local_relpath, mv_to_relpath))
{
/* Update the op-depth of an moved node below this tree */
fixup = TRUE;
child_op_depth = delete_depth;
}
else if (b->moved_to_relpath
&& delete_depth == child_op_depth)
{
/* Update the op-depth of a tree shadowed by this tree */
fixup = TRUE;
child_op_depth = delete_depth;
}
else if (b->moved_to_relpath
&& child_op_depth >= delete_depth
&& !svn_relpath_skip_ancestor(local_relpath, mv_to_relpath))
{
/* Update the move destination of something that is now moved
away further */
/* a NULL moved_here_depth will be reported as 0 */
int moved_here_depth = svn_sqlite__column_int(stmt, 3);
child_relpath = svn_relpath_skip_ancestor(local_relpath, child_relpath);
/* Plain delete. Fixup move information of descendants that were
moved here, or that were moved out */
if (child_relpath)
if (moved_here_depth >= delete_op_depth)
{
child_relpath = svn_relpath_join(b->moved_to_relpath, child_relpath, scratch_pool);
/* The move we recorded here must be moved to the location
this node had before it was moved here.
if (child_op_depth > delete_depth
&& svn_relpath_skip_ancestor(local_relpath, child_relpath))
child_op_depth = delete_depth;
else
child_op_depth = relpath_depth(child_relpath);
This might contain multiple steps when the node was moved
in several places within the to be deleted tree */
/* ### TODO: Add logic */
fixup = TRUE;
moved_from_depth = moved_here_depth;
}
else
{
/* Update the op-depth of an moved away node that was
registered as moved by the records that we are about
to delete */
fixup = TRUE;
child_op_depth = delete_op_depth;
}
}
else if (b->moved_to_relpath)
{
/* The node is moved to a new location */
if (delete_op_depth == child_op_depth)
{
/* Update the op-depth of a tree shadowed by this tree */
fixup = TRUE;
/*child_op_depth = delete_depth;*/
}
else if (child_op_depth >= delete_op_depth
&& !svn_relpath_skip_ancestor(local_relpath,
mv_to_relpath))
{
/* Update the move destination of something that is now moved
away further */
child_relpath = svn_relpath_skip_ancestor(local_relpath,
child_relpath);
if (child_relpath)
{
child_relpath = svn_relpath_join(b->moved_to_relpath,
child_relpath,
scratch_pool);
if (child_op_depth > delete_op_depth
&& svn_relpath_skip_ancestor(local_relpath,
child_relpath))
child_op_depth = delete_op_depth;
else
child_op_depth = relpath_depth(child_relpath);
fixup = TRUE;
}
}
}
if (fixup)
{
mn = apr_pcalloc(scratch_pool, sizeof(struct moved_node_t));
mn = apr_palloc(scratch_pool, sizeof(struct moved_node_t));
mn->local_relpath = apr_pstrdup(scratch_pool, child_relpath);
mn->moved_to_relpath = apr_pstrdup(scratch_pool, mv_to_relpath);
mn->op_depth = child_op_depth;
mn->moved_from_depth = moved_from_depth;
if (!moved_nodes)
moved_nodes = apr_array_make(scratch_pool, 1,
@ -7700,58 +7914,67 @@ delete_node(void *baton,
SVN_ERR(svn_sqlite__step(&have_row, stmt));
}
svn_pool_destroy(iterpool);
SVN_ERR(svn_sqlite__reset(stmt));
}
if (op_root)
{
svn_boolean_t below_base;
svn_boolean_t below_work;
svn_wc__db_status_t below_status;
/* Use STMT_SELECT_NODE_INFO directly instead of read_info plus
info_below_working */
SVN_ERR(info_below_working(&below_base, &below_work, &below_status,
wcroot, local_relpath, -1, scratch_pool));
if ((below_base || below_work)
&& below_status != svn_wc__db_status_not_present
&& below_status != svn_wc__db_status_deleted)
for (i = 0; moved_nodes && (i < moved_nodes->nelts); i++)
{
add_work = TRUE;
refetch_depth = TRUE;
struct moved_node_t *mn = APR_ARRAY_IDX(moved_nodes, i,
struct moved_node_t *);
if (mn->moved_from_depth > 0)
{
svn_pool_clear(iterpool);
SVN_ERR(resolve_moved_from(&mn->local_relpath, &mn->op_depth,
wcroot, local_relpath,
mn->local_relpath,
mn->moved_from_depth,
scratch_pool, iterpool));
if (!mn->local_relpath)
svn_sort__array_delete(moved_nodes, i--, 1);
}
}
select_depth = relpath_depth(local_relpath);
svn_pool_destroy(iterpool);
}
else
if (!b->moved_to_relpath)
{
add_work = TRUE;
if (status != svn_wc__db_status_normal)
SVN_ERR(op_depth_of(&select_depth, wcroot, local_relpath));
else
select_depth = 0; /* Deleting BASE node */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_CLEAR_MOVED_TO_DESCENDANTS));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
local_relpath));
SVN_ERR(svn_sqlite__update(NULL, stmt));
if (op_root)
{
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_CLEAR_MOVED_TO_FROM_DEST));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
local_relpath));
SVN_ERR(svn_sqlite__update(NULL, stmt));
}
}
/* ### Put actual-only nodes into the list? */
if (b->notify)
{
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_INSERT_DELETE_LIST));
SVN_ERR(svn_sqlite__bindf(stmt, "isd",
wcroot->wc_id, local_relpath, select_depth));
wcroot->wc_id, local_relpath, working_op_depth));
SVN_ERR(svn_sqlite__step_done(stmt));
}
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_DELETE_NODES_ABOVE_DEPTH_RECURSIVE));
SVN_ERR(svn_sqlite__bindf(stmt, "isd",
wcroot->wc_id, local_relpath, delete_depth));
wcroot->wc_id, local_relpath, delete_op_depth));
SVN_ERR(svn_sqlite__step_done(stmt));
if (refetch_depth)
SVN_ERR(op_depth_of(&select_depth, wcroot, local_relpath));
/* Delete ACTUAL_NODE rows, but leave those that have changelist
and a NODES row. */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
@ -7781,7 +8004,7 @@ delete_node(void *baton,
STMT_INSERT_DELETE_FROM_NODE_RECURSIVE));
SVN_ERR(svn_sqlite__bindf(stmt, "isdd",
wcroot->wc_id, local_relpath,
select_depth, delete_depth));
keep_op_depth, delete_op_depth));
SVN_ERR(svn_sqlite__step_done(stmt));
}
@ -8680,7 +8903,11 @@ read_children_info(svn_wc__db_wcroot_t *wcroot,
else
child->op_root = (op_depth == relpath_depth(child_relpath));
svn_hash_sets(nodes, apr_pstrdup(result_pool, name), child);
if (op_depth && child->op_root)
child_item->info.moved_here = svn_sqlite__column_boolean(stmt, 20);
if (new_child)
svn_hash_sets(nodes, apr_pstrdup(result_pool, name), child);
}
if (op_depth == 0)
@ -8702,18 +8929,48 @@ read_children_info(svn_wc__db_wcroot_t *wcroot,
child_item->nr_layers++;
child_item->info.have_more_work = (child_item->nr_layers > 1);
/* Moved-to can only exist at op_depth > 0. */
/* ### Should we really do this for every layer where op_depth > 0
in undefined order? */
/* A local_relpath can be moved multiple times at different op
depths and it really depends on the caller what is interesting.
We provide a simple linked list with the moved_from information */
moved_to_relpath = svn_sqlite__column_text(stmt, 21, NULL);
if (moved_to_relpath)
child_item->info.moved_to_abspath =
svn_dirent_join(wcroot->abspath, moved_to_relpath, result_pool);
{
struct svn_wc__db_moved_to_info_t *moved_to;
struct svn_wc__db_moved_to_info_t **next;
const char *shadow_op_relpath;
int cur_op_depth;
/* Moved-here can only exist at op_depth > 0. */
/* ### Should we really do this for every layer where op_depth > 0
in undefined order? */
child_item->info.moved_here = svn_sqlite__column_boolean(stmt, 20);
moved_to = apr_pcalloc(result_pool, sizeof(*moved_to));
moved_to->moved_to_abspath = svn_dirent_join(wcroot->abspath,
moved_to_relpath,
result_pool);
cur_op_depth = relpath_depth(child_relpath);
shadow_op_relpath = child_relpath;
while (cur_op_depth > op_depth)
{
shadow_op_relpath = svn_relpath_dirname(shadow_op_relpath,
scratch_pool);
cur_op_depth--;
}
moved_to->shadow_op_root_abspath =
svn_dirent_join(wcroot->abspath, shadow_op_relpath,
result_pool);
next = &child_item->info.moved_to;
while (*next &&
0 < strcmp((*next)->shadow_op_root_abspath,
moved_to->shadow_op_root_abspath))
next = &((*next)->next);
moved_to->next = *next;
*next = moved_to;
}
}
SVN_ERR(svn_sqlite__step(&have_row, stmt));
@ -8801,6 +9058,178 @@ svn_wc__db_read_children_info(apr_hash_t **nodes,
return SVN_NO_ERROR;
}
static svn_error_t *
db_read_props(apr_hash_t **props,
svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
static svn_error_t *
read_single_info(const struct svn_wc__db_info_t **info,
svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
struct svn_wc__db_info_t *mtb;
apr_int64_t repos_id;
const svn_checksum_t *checksum;
const char *original_repos_relpath;
svn_boolean_t have_work;
mtb = apr_pcalloc(result_pool, sizeof(*mtb));
SVN_ERR(read_info(&mtb->status, &mtb->kind, &mtb->revnum,
&mtb->repos_relpath, &repos_id, &mtb->changed_rev,
&mtb->changed_date, &mtb->changed_author, &mtb->depth,
&checksum, NULL, &original_repos_relpath, NULL, NULL,
&mtb->lock, &mtb->recorded_size, &mtb->recorded_time,
&mtb->changelist, &mtb->conflicted, &mtb->op_root,
&mtb->had_props, &mtb->props_mod, &mtb->have_base,
&mtb->have_more_work, &have_work,
wcroot, local_relpath,
result_pool, scratch_pool));
/* Query the same rows in the database again for move information */
if (have_work && (mtb->have_base || mtb->have_more_work))
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
const char *cur_relpath = NULL;
int cur_op_depth;
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_MOVED_TO_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
while (have_row)
{
struct svn_wc__db_moved_to_info_t *move;
int op_depth = svn_sqlite__column_int(stmt, 0);
const char *moved_to_relpath = svn_sqlite__column_text(stmt, 1, NULL);
move = apr_pcalloc(result_pool, sizeof(*move));
move->moved_to_abspath = svn_dirent_join(wcroot->abspath,
moved_to_relpath,
result_pool);
if (!cur_relpath)
{
cur_relpath = local_relpath;
cur_op_depth = relpath_depth(cur_relpath);
}
while (cur_op_depth > op_depth)
{
cur_relpath = svn_relpath_dirname(cur_relpath, scratch_pool);
cur_op_depth--;
}
move->shadow_op_root_abspath = svn_dirent_join(wcroot->abspath,
cur_relpath,
result_pool);
move->next = mtb->moved_to;
mtb->moved_to = move;
SVN_ERR(svn_sqlite__step(&have_row, stmt));
}
SVN_ERR(svn_sqlite__reset(stmt));
}
/* Maybe we have to get some shadowed lock from BASE to make our test suite
happy... (It might be completely unrelated, but...)
This queries the same BASE row again, joined to the lock table */
if (mtb->have_base && (have_work || mtb->kind == svn_node_file))
{
svn_boolean_t update_root;
svn_wc__db_lock_t **lock_arg = NULL;
if (have_work)
lock_arg = &mtb->lock;
SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
NULL, lock_arg, NULL, NULL,
&update_root,
wcroot, local_relpath,
result_pool, scratch_pool));
mtb->file_external = (update_root && mtb->kind == svn_node_file);
}
if (mtb->status == svn_wc__db_status_added)
{
svn_wc__db_status_t status;
SVN_ERR(scan_addition(&status, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL,
wcroot, local_relpath,
result_pool, scratch_pool));
mtb->moved_here = (status == svn_wc__db_status_moved_here);
mtb->incomplete = (status == svn_wc__db_status_incomplete);
}
#ifdef HAVE_SYMLINK
if (mtb->kind == svn_node_file
&& (mtb->had_props || mtb->props_mod))
{
apr_hash_t *properties;
if (mtb->props_mod)
SVN_ERR(db_read_props(&properties,
wcroot, local_relpath,
scratch_pool, scratch_pool));
else
SVN_ERR(db_read_pristine_props(&properties, wcroot, local_relpath,
TRUE /* deleted_ok */,
scratch_pool, scratch_pool));
mtb->special = (NULL != svn_hash_gets(properties, SVN_PROP_SPECIAL));
}
#endif
mtb->has_checksum = (checksum != NULL);
mtb->copied = (original_repos_relpath != NULL);
SVN_ERR(svn_wc__db_fetch_repos_info(&mtb->repos_root_url, &mtb->repos_uuid,
wcroot->sdb, repos_id, result_pool));
if (mtb->kind == svn_node_dir)
SVN_ERR(is_wclocked(&mtb->locked, wcroot, local_relpath, scratch_pool));
*info = mtb;
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__db_read_single_info(const struct svn_wc__db_info_t **info,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *result_pool,
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);
SVN_WC__DB_WITH_TXN(read_single_info(info, wcroot, local_relpath,
result_pool, scratch_pool),
wcroot);
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__db_read_pristine_info(svn_wc__db_status_t *status,
svn_node_kind_t *kind,
@ -10730,7 +11159,7 @@ commit_node(svn_wc__db_wcroot_t *wcroot,
if we need to remove shadowed layers below our descendants. */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_DELETE_ALL_LAYERS));
STMT_DELETE_NODE_ALL_LAYERS));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__update(&affected_rows, stmt));

View File

@ -1909,6 +1909,16 @@ svn_wc__db_read_info(svn_wc__db_status_t *status, /* ### derived */
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
/* Structure used as linked list in svn_wc__db_info_t to describe all nodes
in this location that were moved to another location */
struct svn_wc__db_moved_to_info_t
{
const char *moved_to_abspath;
const char *shadow_op_root_abspath;
struct svn_wc__db_moved_to_info_t *next;
};
/* Structure returned by svn_wc__db_read_children_info. Only has the
fields needed by status. */
struct svn_wc__db_info_t {
@ -1945,7 +1955,10 @@ struct svn_wc__db_info_t {
svn_wc__db_lock_t *lock; /* Repository file lock */
svn_boolean_t incomplete; /* TRUE if a working node is incomplete */
const char *moved_to_abspath; /* Only on op-roots. See svn_wc_status3_t. */
struct svn_wc__db_moved_to_info_t *moved_to; /* A linked list of locations
where nodes at this path
are moved to. Highest layers
first */
svn_boolean_t moved_here; /* Only on op-roots. */
svn_boolean_t file_external;
@ -1967,6 +1980,14 @@ svn_wc__db_read_children_info(apr_hash_t **nodes,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
/* Like svn_wc__db_read_children_info, but only gets an info node for the root
element. */
svn_error_t *
svn_wc__db_read_single_info(const struct svn_wc__db_info_t **info,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
/* Structure returned by svn_wc__db_read_walker_info. Only has the
fields needed by svn_wc__internal_walk_children(). */

View File

@ -690,8 +690,12 @@ svn_wc__db_wcroot_parse_local_abspath(svn_wc__db_wcroot_t **wcroot,
svn_error_clear(err);
*wcroot = NULL;
}
else
SVN_ERR(err);
else if (err)
{
/* Close handle if we are not going to use it to support
upgrading with exclusive wc locking. */
return svn_error_compose_create(err, svn_sqlite__close(sdb));
}
}
else
{

View File

@ -935,7 +935,7 @@ handle_text_conflict(svn_wc_conflict_result_t *result,
/* We only allow the user accept the merged version of
the file if they've edited it, or at least looked at
the diff. */
if (result->choice == svn_wc_conflict_choose_merged
if (opt->choice == svn_wc_conflict_choose_merged
&& ! knows_something)
{
SVN_ERR(svn_cmdline_fprintf(

View File

@ -570,6 +570,9 @@ new_node_record(void **node_baton,
}
else
{
const char *kind;
const char *action;
tcl = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH);
/* Test if this node was copied from dropped source. */
@ -584,7 +587,6 @@ new_node_record(void **node_baton,
dumpfile should contain the new contents of the file. In this
scenario, we'll just do an add without history using the new
contents. */
const char *kind;
kind = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_NODE_KIND);
/* If there is a Text-content-length header, and the kind is
@ -623,6 +625,30 @@ new_node_record(void **node_baton,
if (! nb->rb->writing_begun)
SVN_ERR(output_revision(nb->rb));
/* A node record is required to begin with 'Node-path', skip the
leading '/' to match the form used by 'svnadmin dump'. */
SVN_ERR(svn_stream_printf(nb->rb->pb->out_stream,
pool, "%s: %s\n",
SVN_REPOS_DUMPFILE_NODE_PATH, node_path + 1));
/* Node-kind is next and is optional. */
kind = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_NODE_KIND);
if (kind)
SVN_ERR(svn_stream_printf(nb->rb->pb->out_stream,
pool, "%s: %s\n",
SVN_REPOS_DUMPFILE_NODE_KIND, kind));
/* Node-action is next and required. */
action = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_NODE_ACTION);
if (action)
SVN_ERR(svn_stream_printf(nb->rb->pb->out_stream,
pool, "%s: %s\n",
SVN_REPOS_DUMPFILE_NODE_ACTION, action));
else
return svn_error_createf(SVN_ERR_INCOMPLETE_DATA, 0,
_("Missing Node-action for path '%s'"),
node_path);
for (hi = apr_hash_first(pool, headers); hi; hi = apr_hash_next(hi))
{
const char *key = svn__apr_hash_index_key(hi);
@ -638,7 +664,10 @@ new_node_record(void **node_baton,
if ((!strcmp(key, SVN_REPOS_DUMPFILE_CONTENT_LENGTH))
|| (!strcmp(key, SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH))
|| (!strcmp(key, SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH)))
|| (!strcmp(key, SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH))
|| (!strcmp(key, SVN_REPOS_DUMPFILE_NODE_PATH))
|| (!strcmp(key, SVN_REPOS_DUMPFILE_NODE_KIND))
|| (!strcmp(key, SVN_REPOS_DUMPFILE_NODE_ACTION)))
continue;
/* Rewrite Node-Copyfrom-Rev if we are renumbering revisions.

View File

@ -35,7 +35,7 @@ svn_rdump__normalize_prop(const char *name,
const svn_string_t **value,
apr_pool_t *result_pool)
{
if (svn_prop_needs_translation(name))
if (svn_prop_needs_translation(name) && *value)
{
const char *cstring;

View File

@ -1526,6 +1526,9 @@ static svn_error_t *get_file(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
&want_props, &want_contents,
&wants_inherited_props));
if (wants_inherited_props == SVN_RA_SVN_UNSPECIFIED_NUMBER)
wants_inherited_props = FALSE;
full_path = svn_fspath__join(b->fs_path->data,
svn_relpath_canonicalize(path, pool), pool);
@ -1545,8 +1548,14 @@ static svn_error_t *get_file(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
SVN_CMD_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5, root,
full_path, TRUE, pool));
hex_digest = svn_checksum_to_cstring_display(checksum, pool);
/* Fetch the file's explicit and/or inherited properties if
requested. Although the wants-iprops boolean was added to the
protocol in 1.8 a standard 1.8 client never requests iprops. */
if (want_props || wants_inherited_props)
SVN_CMD_ERR(get_props(&props, &inherited_props, &ab, root, full_path,
SVN_CMD_ERR(get_props(want_props ? &props : NULL,
wants_inherited_props ? &inherited_props : NULL,
&ab, root, full_path,
pool));
if (want_contents)
SVN_CMD_ERR(svn_fs_file_contents(&contents, root, full_path, pool));
@ -1640,6 +1649,9 @@ static svn_error_t *get_dir(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
&dirent_fields_list,
&wants_inherited_props));
if (wants_inherited_props == SVN_RA_SVN_UNSPECIFIED_NUMBER)
wants_inherited_props = FALSE;
if (! dirent_fields_list)
{
dirent_fields = SVN_DIRENT_ALL;
@ -1689,10 +1701,13 @@ static svn_error_t *get_dir(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
/* Fetch the root of the appropriate revision. */
SVN_CMD_ERR(svn_fs_revision_root(&root, b->fs, rev, pool));
/* Fetch the directory's explicit and/or inherited properties
if requested. */
/* Fetch the directory's explicit and/or inherited properties if
requested. Although the wants-iprops boolean was added to the
protocol in 1.8 a standard 1.8 client never requests iprops. */
if (want_props || wants_inherited_props)
SVN_CMD_ERR(get_props(&props, &inherited_props, &ab, root, full_path,
SVN_CMD_ERR(get_props(want_props ? &props : NULL,
wants_inherited_props ? &inherited_props : NULL,
&ab, root, full_path,
pool));
/* Begin response ... */