You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2010/11/11 23:58:50 UTC
svn commit: r1034191 [1/3] - in /subversion/branches/issue-3668-3669: ./
build/ subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/include/ subversion/include/private/ subversion/libsvn_client/
su...
Author: pburba
Date: Thu Nov 11 22:58:49 2010
New Revision: 1034191
URL: http://svn.apache.org/viewvc?rev=1034191&view=rev
Log:
On the issue-3668-3669 branch: Sync with subversion/trunk.
Added:
subversion/branches/issue-3668-3669/subversion/tests/cmdline/upgrade_tests_data/upgrade_tc.tar.bz2
- copied unchanged from r1034170, subversion/trunk/subversion/tests/cmdline/upgrade_tests_data/upgrade_tc.tar.bz2
Removed:
subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/err.c
subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/err.h
Modified:
subversion/branches/issue-3668-3669/ (props changed)
subversion/branches/issue-3668-3669/CHANGES
subversion/branches/issue-3668-3669/Makefile.in
subversion/branches/issue-3668-3669/build/run_tests.py
subversion/branches/issue-3668-3669/get-deps.sh
subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/EnumMapper.cpp
subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
subversion/branches/issue-3668-3669/subversion/include/private/svn_wc_private.h
subversion/branches/issue-3668-3669/subversion/include/svn_error_codes.h
subversion/branches/issue-3668-3669/subversion/libsvn_client/cleanup.c
subversion/branches/issue-3668-3669/subversion/libsvn_client/patch.c
subversion/branches/issue-3668-3669/subversion/libsvn_diff/diff_file.c
subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/dag.c
subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs.c
subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs_fs.c
subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs_fs.h
subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/lock.c
subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/tree.c
subversion/branches/issue-3668-3669/subversion/libsvn_repos/load-fs-vtable.c
subversion/branches/issue-3668-3669/subversion/libsvn_subr/constructors.c
subversion/branches/issue-3668-3669/subversion/libsvn_subr/io.c
subversion/branches/issue-3668-3669/subversion/libsvn_wc/update_editor.c
subversion/branches/issue-3668-3669/subversion/libsvn_wc/upgrade.c
subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-metadata.sql
subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-queries.sql
subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.c
subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.h
subversion/branches/issue-3668-3669/subversion/libsvn_wc/workqueue.c
subversion/branches/issue-3668-3669/subversion/mod_dav_svn/activity.c
subversion/branches/issue-3668-3669/subversion/mod_dav_svn/dav_svn.h
subversion/branches/issue-3668-3669/subversion/mod_dav_svn/deadprops.c
subversion/branches/issue-3668-3669/subversion/mod_dav_svn/lock.c
subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/dated-rev.c
subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/deleted-rev.c
subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/get-locks.c
subversion/branches/issue-3668-3669/subversion/mod_dav_svn/repos.c
subversion/branches/issue-3668-3669/subversion/mod_dav_svn/util.c
subversion/branches/issue-3668-3669/subversion/mod_dav_svn/version.c
subversion/branches/issue-3668-3669/subversion/svn/cat-cmd.c
subversion/branches/issue-3668-3669/subversion/svn/cl.h
subversion/branches/issue-3668-3669/subversion/svn/conflict-callbacks.c
subversion/branches/issue-3668-3669/subversion/svn/export-cmd.c
subversion/branches/issue-3668-3669/subversion/svn/list-cmd.c
subversion/branches/issue-3668-3669/subversion/svn/notify.c
subversion/branches/issue-3668-3669/subversion/svn/switch-cmd.c
subversion/branches/issue-3668-3669/subversion/svn/update-cmd.c
subversion/branches/issue-3668-3669/subversion/svn/util.c
subversion/branches/issue-3668-3669/subversion/svnrdump/load_editor.c
subversion/branches/issue-3668-3669/subversion/svnsync/main.c
subversion/branches/issue-3668-3669/subversion/tests/cmdline/authz_tests.py
subversion/branches/issue-3668-3669/subversion/tests/cmdline/externals_tests.py
subversion/branches/issue-3668-3669/subversion/tests/cmdline/merge_authz_tests.py
subversion/branches/issue-3668-3669/subversion/tests/cmdline/patch_tests.py
subversion/branches/issue-3668-3669/subversion/tests/cmdline/svnrdump_tests.py
subversion/branches/issue-3668-3669/subversion/tests/cmdline/svnsync_tests.py
subversion/branches/issue-3668-3669/subversion/tests/cmdline/svntest/main.py
subversion/branches/issue-3668-3669/subversion/tests/cmdline/upgrade_tests.py
subversion/branches/issue-3668-3669/subversion/tests/libsvn_fs_fs/fs-pack-test.c
subversion/branches/issue-3668-3669/subversion/tests/libsvn_wc/op-depth-test.c
subversion/branches/issue-3668-3669/tools/dev/unix-build/Makefile.svn
subversion/branches/issue-3668-3669/tools/dist/construct-rolling-environment.sh
Propchange: subversion/branches/issue-3668-3669/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Nov 11 22:58:49 2010
@@ -39,4 +39,4 @@
/subversion/branches/tc_url_rev:874351-874483
/subversion/branches/tree-conflicts:868291-873154
/subversion/branches/tree-conflicts-notify:873926-874008
-/subversion/trunk:1031000-1033087
+/subversion/trunk:1031000-1034190
Modified: subversion/branches/issue-3668-3669/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/CHANGES?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/CHANGES (original)
+++ subversion/branches/issue-3668-3669/CHANGES Thu Nov 11 22:58:49 2010
@@ -1,3 +1,20 @@
+Version 1.6.14
+(?? Nov 2010, from /branches/1.6.x)
+http://svn.apache.org/repos/asf/subversion/tags/1.6.14
+
+ User-visible changes:
+ * improve svnsync handling of dir copies (r962377, -8)
+ * hide unreadable dirs in mod_dav_svn's GET response (r996884)
+ * make 'svnmucc propsetf' actually work (r1005446)
+ * limit memory fragmentation in svnserve (r1022675)
+ * fix 'svn export' regression from 1.6.13 (r1032970)
+ * fix 'svn export' mistakenly uri-encodes paths (issue #3745)
+ * fix server-side memory leaks triggered by 'blame -g' (r1032808)
+
+ Developer-visible changes:
+ * improve test accuracy over dav (r991534, r877814)
+
+
Version 1.6.13
(01 Oct 2010, from /branches/1.6.x)
http://svn.apache.org/repos/asf/subversion/tags/1.6.13
Modified: subversion/branches/issue-3668-3669/Makefile.in
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/Makefile.in?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/Makefile.in (original)
+++ subversion/branches/issue-3668-3669/Makefile.in Thu Nov 11 22:58:49 2010
@@ -340,8 +340,6 @@ ECHO_N = @ECHO_N@
TESTS = $(TEST_PROGRAMS) @BDB_TEST_PROGRAMS@
-TRUNK_TRAIL_URL = /repos/asf/subversion/trunk
-
all: mkdir-init external-all local-all
clean: external-clean local-clean
distclean: external-distclean local-distclean
@@ -410,18 +408,13 @@ local-distclean: fast-distclean check-cl
local-install: @INSTALL_RULES@
-### HACK!! Find a better way to do this
revision-install:
- subversion/svnversion/svnversion $(top_srcdir) $(TRUNK_TRAIL_URL) > \
- $(DESTDIR)$(includedir)/subversion-1/svn-revision.txt; \
- if test "$$?" != "0"; then \
- svnversion $(top_srcdir) $(TRUNK_TRAIL_URL) > \
- $(DESTDIR)$(includedir)/subversion-1/svn-revision.txt; \
- if test "$$?" != "0"; then \
- echo "unknown" > \
- $(DESTDIR)$(includedir)/subversion-1/svn-revision.txt; \
- fi; \
- fi;
+ test -d $(DESTDIR)$(includedir)/subversion-1 || \
+ $(MKDIR) $(DESTDIR)$(includedir)/subversion-1
+ (subversion/svnversion/svnversion $(top_srcdir) || \
+ svnversion $(top_srcdir) || \
+ echo "unknown"; \
+ ) > $(DESTDIR)$(includedir)/subversion-1/svn-revision.txt
install-static: @INSTALL_STATIC_RULES@
Modified: subversion/branches/issue-3668-3669/build/run_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/build/run_tests.py?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/build/run_tests.py (original)
+++ subversion/branches/issue-3668-3669/build/run_tests.py Thu Nov 11 22:58:49 2010
@@ -303,7 +303,7 @@ class TestHarness:
if self.enable_sasl is not None:
svntest.main.options.enable_sasl = True
if self.parallel is not None:
- svntest.main.options.parallel = True
+ svntest.main.options.parallel = svntest.main.default_num_threads
if self.config_file is not None:
svntest.main.options.config_file = self.config_file
if self.verbose is not None:
@@ -351,9 +351,12 @@ class TestHarness:
self.dots_written = dots
+ serial_only = hasattr(prog_mod, 'serial_only') and prog_mod.serial_only
+
# run the tests
svntest.testcase.TextColors.disable()
failed = svntest.main.execute_tests(prog_mod.test_list,
+ serial_only=serial_only,
test_name=progbase,
progress_func=progress_func)
Modified: subversion/branches/issue-3668-3669/get-deps.sh
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/get-deps.sh?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/get-deps.sh (original)
+++ subversion/branches/issue-3668-3669/get-deps.sh Thu Nov 11 22:58:49 2010
@@ -23,15 +23,15 @@
# get-deps.sh -- download the dependencies useful for building Subversion
#
-APR=apr-1.3.8
-APR_UTIL=apr-util-1.3.9
-NEON=neon-0.29.0
-SERF=serf-0.6.1
+APR=apr-1.3.9
+APR_UTIL=apr-util-1.3.10
+NEON=neon-0.29.5
+SERF=serf-0.7.0
ZLIB=zlib-1.2.5
-SQLITE_VERSION=3.7.2
+SQLITE_VERSION=3.7.3
SQLITE=sqlite-amalgamation-$SQLITE_VERSION
-HTTPD=httpd-2.2.14
+HTTPD=httpd-2.2.17
HTTPD_OOPS=
APR_ICONV=apr-iconv-1.2.1
APR_ICONV_OOPS=
Modified: subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/EnumMapper.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/EnumMapper.cpp?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/EnumMapper.cpp (original)
+++ subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/EnumMapper.cpp Thu Nov 11 22:58:49 2010
@@ -195,7 +195,7 @@ jobject EnumMapper::mapOperation(svn_wc_
jobject EnumMapper::mapTristate(svn_tristate_t tristate)
{
// We're assuming a valid value for the C enum above
- return mapEnum(JAVA_PACKAGE"/Tristate", (int) tristate);
+ return mapEnum(JAVA_PACKAGE"/Tristate", (int) (tristate - svn_tristate_false));
}
svn_wc_conflict_choice_t EnumMapper::toConflictChoice(jobject jchoice)
Modified: subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java (original)
+++ subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java Thu Nov 11 22:58:49 2010
@@ -200,12 +200,12 @@ public interface ISVNClient
/**
* Sets a file for deletion.
* @param path path or url to be deleted
- * @param message if path is a url, this will be the commit message.
* @param force delete even when there are local modifications.
* @param keepLocal only remove the paths from the repository.
* @param revpropTable A string-to-string mapping of revision properties
* to values which will be set if this operation
* results in a commit.
+ * @param handler the commit message callback
* @throws ClientException
* @since 1.5
*/
@@ -262,17 +262,14 @@ public interface ISVNClient
/**
* Commits changes to the repository.
* @param path files to commit.
- * @param message log message.
* @param depth how deep to recurse in subdirectories
* @param noUnlock do remove any locks
* @param keepChangelist keep changelist associations after the commit.
* @param changelists if non-null, filter paths using changelists
+ * @param handler the commit message callback
* @param revpropTable A string-to-string mapping of revision properties
* to values which will be set if this operation
* results in a commit.
- * @return The new revision number created by the commit, or
- * {@link Revision#SVN_INVALID_REVNUM} if the revision number is
- * invalid.
* @throws ClientException
* @since 1.5
*/
@@ -287,8 +284,6 @@ public interface ISVNClient
*
* @param sources A list of <code>CopySource</code> objects.
* @param destPath Destination path or URL.
- * @param message Commit message. May be <code>null</code> if
- * <code>destPath</code> is not a URL.
* @param copyAsChild Whether to copy <code>srcPaths</code> as
* children of <code>destPath</code>.
* @param makeParents Whether to create intermediate parents
@@ -297,6 +292,8 @@ public interface ISVNClient
* @param revpropTable A string-to-string mapping of revision properties
* to values which will be set if this operation
* results in a commit.
+ * @param handler the commit message callback, may be <code>null</code>
+ * if <code>destPath</code> is not a URL
* @throws ClientException If the copy operation fails.
* @since 1.7
*/
@@ -311,8 +308,6 @@ public interface ISVNClient
*
* @param srcPaths Source paths or URLs.
* @param destPath Destination path or URL.
- * @param message Commit message. May be <code>null</code> if
- * <code>destPath</code> is not a URL.
* @param force Whether to perform the move even if local
* modifications exist.
* @param moveAsChild Whether to move <code>srcPaths</code> as
@@ -321,6 +316,8 @@ public interface ISVNClient
* @param revpropTable A string-to-string mapping of revision properties
* to values which will be set if this operation
* results in a commit.
+ * @param handler the commit message callback, may be <code>null</code>
+ * if <code>destPath</code> is not a URL
* @throws ClientException If the move operation fails.
* @since 1.5
*/
@@ -334,11 +331,11 @@ public interface ISVNClient
* Creates a directory directly in a repository or creates a
* directory on disk and schedules it for addition.
* @param path directories to be created
- * @param message commit message to used if path contains urls
* @param makeParents Whether to create intermediate parents
* @param revpropTable A string-to-string mapping of revision properties
* to values which will be set if this operation
* results in a commit.
+ * @param handler the handler to use if paths contains URLs
* @throws ClientException
* @since 1.5
*/
@@ -412,7 +409,6 @@ public interface ISVNClient
* head.
* @param path the local path
* @param url the target url
- * @param message the log message.
* @param depth depth to traverse into subdirectories
* @param noIgnore whether to add files matched by ignore patterns
* @param ignoreUnknownNodeTypes whether to ignore files which
@@ -420,6 +416,7 @@ public interface ISVNClient
* @param revpropTable A string-to-string mapping of revision properties
* to values which will be set if this operation
* results in a commit.
+ * @param handler the commit message callback
* @throws ClientException
*
* @since 1.5
Modified: subversion/branches/issue-3668-3669/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/include/private/svn_wc_private.h?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/issue-3668-3669/subversion/include/private/svn_wc_private.h Thu Nov 11 22:58:49 2010
@@ -612,14 +612,14 @@ svn_wc__node_get_info_bits(apr_time_t *t
/**
- * Acquire a recursive write lock for @a local_abspath or if @a lock_anchor
+ * Acquire a recursive write lock for @a local_abspath. If @a lock_anchor
* is true, determine if @a local_abspath has an anchor that should be locked
- * instead. Store the obtained lock in @a wc_ctx.
+ * instead; otherwise, @a local_abspath must be a versioned directory.
+ * Store the obtained lock in @a wc_ctx.
*
* If @a lock_root_abspath is not NULL, store the root of the lock in
* @a *lock_root_abspath. If @a lock_root_abspath is NULL, then @a
- * local_abspath must be a versioned directory and @a lock_anchor must be
- * FALSE.
+ * lock_anchor must be FALSE.
*
* Returns @c SVN_ERR_WC_LOCKED if an existing lock is encountered, in
* which case any locks acquired will have been released.
Modified: subversion/branches/issue-3668-3669/subversion/include/svn_error_codes.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/include/svn_error_codes.h?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/include/svn_error_codes.h (original)
+++ subversion/branches/issue-3668-3669/subversion/include/svn_error_codes.h Thu Nov 11 22:58:49 2010
@@ -1391,6 +1391,10 @@ SVN_ERROR_START
SVN_ERR_CL_CATEGORY_START + 10,
"No external merge tool available")
+ SVN_ERRDEF(SVN_ERR_CL_ERROR_PROCESSING_EXTERNALS,
+ SVN_ERR_CL_CATEGORY_START + 11,
+ "Failed processing one or more externals definitions")
+
/* malfunctions such as assertion failures */
SVN_ERRDEF(SVN_ERR_ASSERTION_FAIL,
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_client/cleanup.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_client/cleanup.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_client/cleanup.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_client/cleanup.c Thu Nov 11 22:58:49 2010
@@ -163,11 +163,9 @@ svn_client_upgrade(const char *path,
externals_p = apr_array_make(iterpool, 1,
sizeof(svn_wc_external_item2_t*));
- SVN_ERR(svn_wc_parse_externals_description3(&externals_p,
- svn_dirent_dirname(path,
- iterpool),
- external_desc->data, TRUE,
- iterpool));
+ SVN_ERR(svn_wc_parse_externals_description3(
+ &externals_p, svn_dirent_dirname(path, iterpool),
+ external_desc->data, TRUE, iterpool));
for (i = 0; i < externals_p->nelts; i++)
{
svn_wc_external_item2_t *item;
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_client/patch.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_client/patch.c Thu Nov 11 22:58:49 2010
@@ -203,6 +203,9 @@ typedef struct patch_target_t {
/* True if the patch changed any of the properties of the target. */
svn_boolean_t has_prop_changes;
+ /* True if the patch contained a svn:special property. */
+ svn_boolean_t is_special;
+
/* All the information that is specific to the content of the target. */
target_content_info_t *content_info;
@@ -235,7 +238,7 @@ strip_path(const char **result, const ch
apr_array_header_t *stripped;
components = svn_path_decompose(path, scratch_pool);
- if (strip_count >= components->nelts)
+ if (strip_count > components->nelts)
return svn_error_createf(SVN_ERR_CLIENT_PATCH_BAD_STRIP_COUNT, NULL,
_("Cannot strip %u components from '%s'"),
strip_count,
@@ -1609,44 +1612,6 @@ send_patch_notification(const patch_targ
return SVN_NO_ERROR;
}
-/* Close the streams of the TARGET so that their content is flushed
- * to disk. This will also close underlying streams and files. Use POOL for
- * temporary allocations. */
-static svn_error_t *
-close_target_streams(const patch_target_t *target,
- apr_pool_t *pool)
-{
- apr_hash_index_t *hi;
- target_content_info_t *prop_content_info;
-
- /* First the streams belonging to properties .. */
- for (hi = apr_hash_first(pool, target->prop_targets);
- hi;
- hi = apr_hash_next(hi))
- {
- prop_patch_target_t *prop_target;
- prop_target = svn__apr_hash_index_val(hi);
- prop_content_info = prop_target->content_info;
-
- /* ### If the prop did not exist pre-patching we'll not have a
- * ### stream to read from. Find a better way to store info on
- * ### the existence of the target prop. */
- if (prop_content_info->stream)
- SVN_ERR(svn_stream_close(prop_content_info->stream));
-
- SVN_ERR(svn_stream_close(prop_content_info->patched));
- }
-
- /* .. and then streams associated with the file.
- * ### We're not closing the reject stream -- it still needed and
- * ### will be closed later in write_out_rejected_hunks(). */
- if (target->kind_on_disk == svn_node_file)
- SVN_ERR(svn_stream_close(target->content_info->stream));
- SVN_ERR(svn_stream_close(target->content_info->patched));
-
- return SVN_NO_ERROR;
-}
-
/* Apply a PATCH to a working copy at ABS_WC_PATH and put the result
* into temporary files, to be installed in the working copy later.
* Return information about the patch target in *PATCH_TARGET, allocated
@@ -1675,6 +1640,7 @@ apply_one_patch(patch_target_t **patch_t
int i;
static const int MAX_FUZZ = 2;
apr_hash_index_t *hash_index;
+ target_content_info_t *prop_content_info;
SVN_ERR(init_patch_target(&target, patch, abs_wc_path, wc_ctx, strip_count,
remove_tempfiles, result_pool, scratch_pool));
@@ -1773,6 +1739,9 @@ apply_one_patch(patch_target_t **patch_t
prop_name = svn__apr_hash_index_key(hash_index);
prop_patch = svn__apr_hash_index_val(hash_index);
+ if (! strcmp(prop_name, SVN_PROP_SPECIAL))
+ target->is_special = TRUE;
+
/* We'll store matched hunks in prop_content_info. */
prop_target = apr_hash_get(target->prop_targets, prop_name,
APR_HASH_KEY_STRING);
@@ -1855,7 +1824,31 @@ apply_one_patch(patch_target_t **patch_t
svn_pool_destroy(iterpool);
- SVN_ERR(close_target_streams(target, scratch_pool));
+ /* Now close some streams that we don't need any longer to get
+ * file buffers flushed to disk. First, close the props streams... */
+ for (hash_index = apr_hash_first(scratch_pool, target->prop_targets);
+ hash_index;
+ hash_index = apr_hash_next(hash_index))
+ {
+ prop_patch_target_t *prop_target;
+ prop_target = svn__apr_hash_index_val(hash_index);
+ prop_content_info = prop_target->content_info;
+
+ /* ### If the prop did not exist pre-patching we'll not have a
+ * ### stream to read from. Find a better way to store info on
+ * ### the existence of the target prop. */
+ if (prop_content_info->stream)
+ SVN_ERR(svn_stream_close(prop_content_info->stream));
+
+ SVN_ERR(svn_stream_close(prop_content_info->patched));
+ }
+
+ /* .. and then streams associated with the file.
+ * But we're not closing the reject stream -- it still needed and
+ * will be closed later in write_out_rejected_hunks(). */
+ if (target->kind_on_disk == svn_node_file)
+ SVN_ERR(svn_stream_close(target->content_info->stream));
+ SVN_ERR(svn_stream_close(target->content_info->patched));
if (! target->skipped)
{
@@ -2118,9 +2111,33 @@ install_patched_target(patch_target_t *t
if (! dry_run && ! target->skipped)
{
- /* Copy the patched file on top of the target file. */
- SVN_ERR(svn_io_copy_file(target->patched_path,
- target->local_abspath, FALSE, pool));
+ if (target->is_special)
+ {
+ svn_stream_t *stream;
+ svn_stream_t *patched_stream;
+ apr_file_t *file;
+
+ SVN_ERR(svn_io_file_open(&file, target->patched_path,
+ APR_READ | APR_BINARY, APR_OS_DEFAULT,
+ pool));
+
+ patched_stream = svn_stream_from_aprfile2(file, FALSE /* disown */,
+ pool);
+ SVN_ERR(svn_subst_create_specialfile(&stream,
+ target->local_abspath,
+ pool, pool));
+ SVN_ERR(svn_stream_copy3(patched_stream, stream,
+ NULL, /* cancel_func */
+ NULL, /* cancel_baton */
+ pool));
+ }
+ else
+ {
+ /* Copy the patched file on top of the target file. */
+ SVN_ERR(svn_io_copy_file(target->patched_path,
+ target->local_abspath, FALSE, pool));
+ }
+
if (target->added || target->replaced)
{
/* The target file didn't exist previously,
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_diff/diff_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_diff/diff_file.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_diff/diff_file.c Thu Nov 11 22:58:49 2010
@@ -562,12 +562,42 @@ svn_diff_file_options_create(apr_pool_t
return apr_pcalloc(pool, sizeof(svn_diff_file_options_t));
}
+/* A baton for use with opt_parsing_error_func(). */
+struct opt_parsing_error_baton_t
+{
+ svn_error_t *err;
+ apr_pool_t *pool;
+};
+
+/* Store an error message from apr_getopt_long(). Set BATON->err to a new
+ * error with a message generated from FMT and the remaining arguments.
+ * Implements apr_getopt_err_fn_t. */
+static void
+opt_parsing_error_func(void *baton,
+ const char *fmt, ...)
+{
+ struct opt_parsing_error_baton_t *b = baton;
+ const char *message;
+ va_list ap;
+
+ va_start(ap, fmt);
+ message = apr_pvsprintf(b->pool, fmt, ap);
+ va_end(ap);
+
+ /* Skip leading ": " (if present, which it always is in known cases). */
+ if (strncmp(message, ": ", 2) == 0)
+ message += 2;
+
+ b->err = svn_error_create(SVN_ERR_INVALID_DIFF_OPTION, NULL, message);
+}
+
svn_error_t *
svn_diff_file_options_parse(svn_diff_file_options_t *options,
const apr_array_header_t *args,
apr_pool_t *pool)
{
apr_getopt_t *os;
+ struct opt_parsing_error_baton_t opt_parsing_error_baton = { NULL, pool };
/* Make room for each option (starting at index 1) plus trailing NULL. */
const char **argv = apr_palloc(pool, sizeof(char*) * (args->nelts + 2));
@@ -576,8 +606,12 @@ svn_diff_file_options_parse(svn_diff_fil
argv[args->nelts + 1] = NULL;
apr_getopt_init(&os, pool, args->nelts + 1, argv);
- /* No printing of error messages, please! */
- os->errfn = NULL;
+
+ /* Capture any error message from apr_getopt_long(). This will typically
+ * say which option is wrong, which we would not otherwise know. */
+ os->errfn = opt_parsing_error_func;
+ os->errarg = &opt_parsing_error_baton;
+
while (1)
{
const char *opt_arg;
@@ -587,7 +621,13 @@ svn_diff_file_options_parse(svn_diff_fil
if (APR_STATUS_IS_EOF(err))
break;
if (err)
- return svn_error_wrap_apr(err, _("Error parsing diff options"));
+ /* Wrap apr_getopt_long()'s error message. Its doc string implies
+ * it always will produce one, but never mind if it doesn't. Avoid
+ * using the message associated with the return code ERR, because
+ * it refers to the "command line" which may be misleading here. */
+ return svn_error_create(SVN_ERR_INVALID_DIFF_OPTION,
+ opt_parsing_error_baton.err,
+ _("Error in options to internal diff"));
switch (opt_id)
{
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/dag.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/dag.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/dag.c Thu Nov 11 22:58:49 2010
@@ -29,7 +29,6 @@
#include "svn_pools.h"
#include "dag.h"
-#include "err.h"
#include "fs.h"
#include "key-gen.h"
#include "fs_fs.h"
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs.c Thu Nov 11 22:58:49 2010
@@ -34,7 +34,6 @@
#include "svn_version.h"
#include "svn_pools.h"
#include "fs.h"
-#include "err.h"
#include "fs_fs.h"
#include "tree.h"
#include "lock.h"
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs_fs.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs_fs.c Thu Nov 11 22:58:49 2010
@@ -51,7 +51,6 @@
#include "svn_ctype.h"
#include "fs.h"
-#include "err.h"
#include "tree.h"
#include "lock.h"
#include "key-gen.h"
@@ -2152,6 +2151,16 @@ read_rep_offsets(representation_t **rep_
return SVN_NO_ERROR;
}
+static svn_error_t *
+err_dangling_id(svn_fs_t *fs, const svn_fs_id_t *id)
+{
+ svn_string_t *id_str = svn_fs_fs__id_unparse(id, fs->pool);
+ return svn_error_createf
+ (SVN_ERR_FS_ID_NOT_FOUND, 0,
+ _("Reference to non-existent node '%s' in filesystem '%s'"),
+ id_str->data, fs->path);
+}
+
/* Get the node-revision for the node ID in FS.
Set *NODEREV_P to the new node-revision structure, allocated in POOL.
See svn_fs_fs__get_node_revision, which wraps this and adds another
@@ -2185,7 +2194,7 @@ get_node_revision_body(node_revision_t *
if (APR_STATUS_IS_ENOENT(err->apr_err))
{
svn_error_clear(err);
- return svn_fs_fs__err_dangling_id(fs, id);
+ return svn_error_return(err_dangling_id(fs, id));
}
return svn_error_return(err);
@@ -6924,15 +6933,41 @@ recover_body(void *baton, apr_pool_t *po
SVN_ERR(svn_io_check_path(path_revprops(fs, max_rev, pool),
&youngest_revprops_kind, pool));
if (youngest_revprops_kind == svn_node_none)
- return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
- _("Revision %ld has a revs file but no "
- "revprops file"),
- max_rev);
+ {
+ svn_boolean_t uhohs = TRUE;
+
+ /* No file? Hrm... maybe that's because this repository is
+ packed and the youngest revision is in the revprops.db
+ file? We can at least see if that's a possibility.
+
+ ### TODO: Could we check for revprops in the revprops.db?
+ ### What if rNNN legitimately has no revprops? */
+ if (ffd->format >= SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
+ {
+ svn_revnum_t min_unpacked_revprop;
+ const char *min_unpacked_revprop_path =
+ svn_dirent_join(fs->path, PATH_MIN_UNPACKED_REVPROP, pool);
+
+ SVN_ERR(read_min_unpacked_rev(&min_unpacked_revprop,
+ min_unpacked_revprop_path, pool));
+ if (min_unpacked_revprop == (max_rev + 1))
+ uhohs = FALSE;
+ }
+ if (uhohs)
+ {
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ _("Revision %ld has a revs file but no "
+ "revprops file"),
+ max_rev);
+ }
+ }
else if (youngest_revprops_kind != svn_node_file)
- return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
- _("Revision %ld has a non-file where its "
- "revprops file should be"),
- max_rev);
+ {
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ _("Revision %ld has a non-file where its "
+ "revprops file should be"),
+ max_rev);
+ }
/* Now store the discovered youngest revision, and the next IDs if
relevant, in a new 'current' file. */
@@ -7009,7 +7044,7 @@ svn_fs_fs__set_uuid(svn_fs_t *fs,
permissions as FS->path.*/
svn_error_t *
svn_fs_fs__ensure_dir_exists(const char *path,
- svn_fs_t *fs,
+ const char *fs_path,
apr_pool_t *pool)
{
svn_error_t *err = svn_io_dir_make(path, APR_OS_DEFAULT, pool);
@@ -7022,7 +7057,7 @@ svn_fs_fs__ensure_dir_exists(const char
/* We successfully created a new directory. Dup the permissions
from FS->path. */
- return svn_io_copy_perms(path, fs->path, pool);
+ return svn_io_copy_perms(path, fs_path, pool);
}
/* Set *NODE_ORIGINS to a hash mapping 'const char *' node IDs to
@@ -7094,7 +7129,7 @@ set_node_origins_for_file(svn_fs_t *fs,
SVN_ERR(svn_fs_fs__ensure_dir_exists(svn_dirent_join(fs->path,
PATH_NODE_ORIGINS_DIR,
pool),
- fs, pool));
+ fs->path, pool));
/* Read the previously existing origins (if any), and merge our
update with it. */
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs_fs.h?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/fs_fs.h Thu Nov 11 22:58:49 2010
@@ -492,9 +492,9 @@ svn_error_t *svn_fs_fs__txn_prop(svn_str
const char *propname, apr_pool_t *pool);
/* If directory PATH does not exist, create it and give it the same
- permissions as FS->path.*/
+ permissions as FS_PATH.*/
svn_error_t *svn_fs_fs__ensure_dir_exists(const char *path,
- svn_fs_t *fs,
+ const char *fs_path,
apr_pool_t *pool);
/* Update the node origin index for FS, recording the mapping from
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/lock.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/lock.c Thu Nov 11 22:58:49 2010
@@ -36,7 +36,6 @@
#include "lock.h"
#include "tree.h"
-#include "err.h"
#include "fs_fs.h"
#include "../libsvn_fs/fs-loader.h"
@@ -108,17 +107,28 @@ hash_fetch(apr_hash_t *hash,
}
+/* SVN_ERR_FS_CORRUPT: the lockfile for PATH in FS is corrupt. */
+static svn_error_t *
+err_corrupt_lockfile(const char *fs_path, const char *path)
+{
+ return
+ svn_error_createf(
+ SVN_ERR_FS_CORRUPT, 0,
+ _("Corrupt lockfile for path '%s' in filesystem '%s'"),
+ path, fs_path);
+}
+
/*** Digest file handling functions. ***/
/* Return the path of the lock/entries file for which DIGEST is the
hashed repository relative path. */
static const char *
-digest_path_from_digest(svn_fs_t *fs,
+digest_path_from_digest(const char *fs_path,
const char *digest,
apr_pool_t *pool)
{
- return svn_dirent_join_many(pool, fs->path, PATH_LOCKS_DIR,
+ return svn_dirent_join_many(pool, fs_path, PATH_LOCKS_DIR,
apr_pstrmemdup(pool, digest, DIGEST_SUBDIR_LEN),
digest, NULL);
}
@@ -158,9 +168,9 @@ write_digest_file(apr_hash_t *children,
const char *rev_0_path;
SVN_ERR(svn_fs_fs__ensure_dir_exists(svn_dirent_join(fs->path, PATH_LOCKS_DIR,
- pool), fs, pool));
+ pool), fs->path, pool));
SVN_ERR(svn_fs_fs__ensure_dir_exists(svn_dirent_dirname(digest_path, pool),
- fs, pool));
+ fs->path, pool));
if (lock)
{
@@ -224,7 +234,7 @@ write_digest_file(apr_hash_t *children,
static svn_error_t *
read_digest_file(apr_hash_t **children_p,
svn_lock_t **lock_p,
- svn_fs_t *fs,
+ const char *fs_path,
const char *digest_path,
apr_pool_t *pool)
{
@@ -275,17 +285,17 @@ read_digest_file(apr_hash_t **children_p
lock->path = path;
if (! ((lock->token = hash_fetch(hash, TOKEN_KEY, pool))))
- return svn_fs_fs__err_corrupt_lockfile(fs, path);
+ return svn_error_return(err_corrupt_lockfile(fs_path, path));
if (! ((lock->owner = hash_fetch(hash, OWNER_KEY, pool))))
- return svn_fs_fs__err_corrupt_lockfile(fs, path);
+ return svn_error_return(err_corrupt_lockfile(fs_path, path));
if (! ((val = hash_fetch(hash, IS_DAV_COMMENT_KEY, pool))))
- return svn_fs_fs__err_corrupt_lockfile(fs, path);
+ return svn_error_return(err_corrupt_lockfile(fs_path, path));
lock->is_dav_comment = (val[0] == '1');
if (! ((val = hash_fetch(hash, CREATION_DATE_KEY, pool))))
- return svn_fs_fs__err_corrupt_lockfile(fs, path);
+ return svn_error_return(err_corrupt_lockfile(fs_path, path));
SVN_ERR(svn_time_from_cstring(&(lock->creation_date), val, pool));
if ((val = hash_fetch(hash, EXPIRATION_DATE_KEY, pool)))
@@ -347,7 +357,7 @@ set_lock(svn_fs_t *fs,
digest_path = digest_path_from_path(fs, this_path->data, subpool);
digest_file = svn_dirent_basename(digest_path, subpool);
- SVN_ERR(read_digest_file(&this_children, &this_lock, fs,
+ SVN_ERR(read_digest_file(&this_children, &this_lock, fs->path,
digest_path, subpool));
/* We're either writing a new lock (first time through only) or
@@ -409,7 +419,7 @@ delete_lock(svn_fs_t *fs,
digest_path = digest_path_from_path(fs, this_path->data, subpool);
digest_file = svn_dirent_basename(digest_path, subpool);
- SVN_ERR(read_digest_file(&this_children, &this_lock, fs,
+ SVN_ERR(read_digest_file(&this_children, &this_lock, fs->path,
digest_path, subpool));
/* Delete the lock (first time through only). */
@@ -460,7 +470,7 @@ get_lock(svn_lock_t **lock_p,
svn_lock_t *lock;
const char *digest_path = digest_path_from_path(fs, path, pool);
- SVN_ERR(read_digest_file(NULL, &lock, fs, digest_path, pool));
+ SVN_ERR(read_digest_file(NULL, &lock, fs->path, digest_path, pool));
if (! lock)
return SVN_FS__ERR_NO_SUCH_LOCK(fs, path, pool);
@@ -513,43 +523,82 @@ get_lock_helper(svn_fs_t *fs,
}
-/* A recursive function that calls GET_LOCKS_FUNC/GET_LOCKS_BATON for
- all locks in and under PATH in FS.
- HAVE_WRITE_LOCK should be true if the caller (directly or indirectly)
- has the FS write lock. */
+/* Baton for locks_walker(). */
+struct walk_locks_baton {
+ svn_fs_get_locks_callback_t get_locks_func;
+ void *get_locks_baton;
+ svn_fs_t *fs;
+};
+
+/* Implements walk_digests_callback_t. */
static svn_error_t *
-walk_digest_files(svn_fs_t *fs,
- const char *digest_path,
- svn_fs_get_locks_callback_t get_locks_func,
- void *get_locks_baton,
- svn_boolean_t have_write_lock,
- apr_pool_t *pool)
+locks_walker(void *baton,
+ const char *fs_path,
+ const char *digest_path,
+ apr_hash_t *children,
+ svn_lock_t *lock,
+ svn_boolean_t have_write_lock,
+ apr_pool_t *pool)
{
- apr_hash_t *children;
- svn_lock_t *lock;
- apr_hash_index_t *hi;
- apr_pool_t *subpool;
+ struct walk_locks_baton *wlb = baton;
- /* First, send up any locks in the current digest file. */
- SVN_ERR(read_digest_file(&children, &lock, fs, digest_path, pool));
if (lock)
{
/* Don't report an expired lock. */
if (lock->expiration_date == 0
|| (apr_time_now() <= lock->expiration_date))
{
- if (get_locks_func)
- SVN_ERR(get_locks_func(get_locks_baton, lock, pool));
+ if (wlb->get_locks_func)
+ SVN_ERR(wlb->get_locks_func(wlb->get_locks_baton, lock, pool));
}
else
{
/* Only remove the lock if we have the write lock.
Read operations shouldn't change the filesystem. */
if (have_write_lock)
- SVN_ERR(delete_lock(fs, lock, pool));
+ SVN_ERR(delete_lock(wlb->fs, lock, pool));
}
}
+ return SVN_NO_ERROR;
+}
+
+/* Callback type for walk_digest_files().
+ *
+ * CHILDREN and LOCK come from a read_digest_file(digest_path) call.
+ */
+typedef svn_error_t *(*walk_digests_callback_t)(void *baton,
+ const char *fs_path,
+ const char *digest_path,
+ apr_hash_t *children,
+ svn_lock_t *lock,
+ svn_boolean_t have_write_lock,
+ apr_pool_t *pool);
+
+/* A recursive function that calls WALK_DIGESTS_FUNC/WALK_DIGESTS_BATON for
+ all lock digest files in and under PATH in FS.
+ HAVE_WRITE_LOCK should be true if the caller (directly or indirectly)
+ has the FS write lock. */
+static svn_error_t *
+walk_digest_files(const char *fs_path,
+ const char *digest_path,
+ walk_digests_callback_t walk_digests_func,
+ void *walk_digests_baton,
+ svn_boolean_t have_write_lock,
+ apr_pool_t *pool)
+{
+ apr_hash_index_t *hi;
+ apr_hash_t *children;
+ apr_pool_t *subpool;
+ svn_lock_t *lock;
+
+ /* First, send up any locks in the current digest file. */
+ SVN_ERR(read_digest_file(&children, &lock, fs_path, digest_path, pool));
+
+ SVN_ERR(walk_digests_func(walk_digests_baton, fs_path, digest_path,
+ children, lock,
+ have_write_lock, pool));
+
/* Now, recurse on this thing's child entries (if any; bail otherwise). */
if (! apr_hash_count(children))
return SVN_NO_ERROR;
@@ -559,13 +608,31 @@ walk_digest_files(svn_fs_t *fs,
const char *digest = svn__apr_hash_index_key(hi);
svn_pool_clear(subpool);
SVN_ERR(walk_digest_files
- (fs, digest_path_from_digest(fs, digest, subpool),
- get_locks_func, get_locks_baton, have_write_lock, subpool));
+ (fs_path, digest_path_from_digest(fs_path, digest, subpool),
+ walk_digests_func, walk_digests_baton, have_write_lock, subpool));
}
svn_pool_destroy(subpool);
return SVN_NO_ERROR;
}
+/* A recursive function that calls GET_LOCKS_FUNC/GET_LOCKS_BATON for
+ all locks in and under PATH in FS.
+ HAVE_WRITE_LOCK should be true if the caller (directly or indirectly)
+ has the FS write lock. */
+static svn_error_t *
+walk_locks(svn_fs_t *fs,
+ const char *digest_path,
+ svn_fs_get_locks_callback_t get_locks_func,
+ void *get_locks_baton,
+ svn_boolean_t have_write_lock,
+ apr_pool_t *pool)
+{
+ struct walk_locks_baton wlb = { get_locks_func, get_locks_baton, fs };
+ SVN_ERR(walk_digest_files(fs->path, digest_path, locks_walker, &wlb,
+ have_write_lock, pool));
+ return SVN_NO_ERROR;
+}
+
/* Utility function: verify that a lock can be used. Interesting
errors returned from this function:
@@ -626,8 +693,8 @@ svn_fs_fs__allow_locked_operation(const
{
/* Discover all locks at or below the path. */
const char *digest_path = digest_path_from_path(fs, path, pool);
- SVN_ERR(walk_digest_files(fs, digest_path, get_locks_callback,
- fs, have_write_lock, pool));
+ SVN_ERR(walk_locks(fs, digest_path, get_locks_callback,
+ fs, have_write_lock, pool));
}
else
{
@@ -974,6 +1041,6 @@ svn_fs_fs__get_locks(svn_fs_t *fs,
/* Get the top digest path in our tree of interest, and then walk it. */
digest_path = digest_path_from_path(fs, path, pool);
- return walk_digest_files(fs, digest_path, get_locks_filter_func, &glfb,
+ return walk_locks(fs, digest_path, get_locks_filter_func, &glfb,
FALSE, pool);
}
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/tree.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_fs_fs/tree.c Thu Nov 11 22:58:49 2010
@@ -51,7 +51,6 @@
#include "svn_props.h"
#include "fs.h"
-#include "err.h"
#include "key-gen.h"
#include "dag.h"
#include "lock.h"
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_repos/load-fs-vtable.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_repos/load-fs-vtable.c Thu Nov 11 22:58:49 2010
@@ -626,7 +626,10 @@ set_node_property(void *baton,
if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
{
- svn_string_t *renumbered_mergeinfo, *prop_val = (svn_string_t *)value;
+ svn_string_t *renumbered_mergeinfo;
+ /* ### Need to cast away const. We cannot change the declaration of
+ * ### this function since it is part of svn_repos_parse_fns2_t. */
+ svn_string_t *prop_val = (svn_string_t *)value;
/* Tolerate mergeinfo with "\r\n" line endings because some
dumpstream sources might contain as much. If so normalize
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_subr/constructors.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_subr/constructors.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_subr/constructors.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_subr/constructors.c Thu Nov 11 22:58:49 2010
@@ -45,7 +45,8 @@ svn_commit_info_t *
svn_commit_info_dup(const svn_commit_info_t *src_commit_info,
apr_pool_t *pool)
{
- svn_commit_info_t *dst_commit_info = svn_create_commit_info(pool);
+ svn_commit_info_t *dst_commit_info
+ = apr_palloc(pool, sizeof(*dst_commit_info));
dst_commit_info->date = src_commit_info->date
? apr_pstrdup(pool, src_commit_info->date) : NULL;
@@ -74,7 +75,7 @@ svn_log_changed_path2_dup(const svn_log_
apr_pool_t *pool)
{
svn_log_changed_path2_t *new_changed_path
- = svn_log_changed_path2_create(pool);
+ = apr_palloc(pool, sizeof(*new_changed_path));
*new_changed_path = *changed_path;
@@ -190,7 +191,7 @@ svn_log_entry_t *
svn_log_entry_dup(const svn_log_entry_t *log_entry, apr_pool_t *pool)
{
apr_hash_index_t *hi;
- svn_log_entry_t *new_entry = svn_log_entry_create(pool);
+ svn_log_entry_t *new_entry = apr_palloc(pool, sizeof(*new_entry));
*new_entry = *log_entry;
@@ -228,7 +229,8 @@ svn_location_segment_dup(const svn_locat
apr_pool_t *pool)
{
svn_location_segment_t *new_segment =
- apr_pcalloc(pool, sizeof(*new_segment));
+ apr_palloc(pool, sizeof(*new_segment));
+
*new_segment = *segment;
if (segment->path)
new_segment->path = apr_pstrdup(pool, segment->path);
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_subr/io.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_subr/io.c Thu Nov 11 22:58:49 2010
@@ -392,7 +392,7 @@ svn_io_open_uniquely_named(apr_file_t **
if (i == 1)
unique_name = apr_psprintf(scratch_pool, "%s%s", path, suffix);
else
- unique_name = apr_psprintf(scratch_pool, "%s.%u_%s", path, i, suffix);
+ unique_name = apr_psprintf(scratch_pool, "%s.%u%s", path, i, suffix);
/* Hmmm. Ideally, we would append to a native-encoding buf
before starting iteration, then convert back to UTF-8 for
@@ -3314,6 +3314,10 @@ svn_io_dir_walk2(const char *dirname,
SVN_ERR(cstring_from_utf8(&dirname_apr, dirname, pool));
+ /* APR doesn't like "" directories */
+ if (dirname_apr[0] == '\0')
+ dirname_apr = ".";
+
apr_err = apr_dir_open(&handle, dirname_apr, pool);
if (apr_err)
return svn_error_wrap_apr(apr_err, _("Can't open directory '%s'"),
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_wc/update_editor.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_wc/update_editor.c Thu Nov 11 22:58:49 2010
@@ -1965,7 +1965,10 @@ do_entry_deletion(struct edit_baton *eb,
}
/* Receive the remote removal of excluded/absent/not present node.
- Do not notify. */
+ Do not notify.
+
+ ### This is wrong if svn_wc__db_status_excluded refers to a
+ working node replacing the base node. */
if (status == svn_wc__db_status_not_present
|| status == svn_wc__db_status_excluded
|| status == svn_wc__db_status_absent)
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_wc/upgrade.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_wc/upgrade.c Thu Nov 11 22:58:49 2010
@@ -372,14 +372,15 @@ get_versioned_files(const apr_array_head
}
-/* */
+/* Return the path of the old-school administrative lock file
+ associated with LOCAL_DIR_ABSPATH, allocated from RESULT_POOL. */
static const char *
build_lockfile_path(const char *local_dir_abspath,
apr_pool_t *result_pool)
{
return svn_dirent_join_many(result_pool,
local_dir_abspath,
- ".svn", /* ### switch to dynamic? */
+ svn_wc_get_adm_dir(result_pool),
ADM_LOCK,
NULL);
}
@@ -631,91 +632,6 @@ bump_to_13(void *baton, svn_sqlite__db_t
}
-#if 0 /* ### no tree conflict migration yet */
-
-/* ### duplicated from wc_db.c */
-static const char *
-kind_to_word(svn_wc__db_kind_t kind)
-{
- switch (kind)
- {
- case svn_wc__db_kind_dir:
- return "dir";
- case svn_wc__db_kind_file:
- return "file";
- case svn_wc__db_kind_symlink:
- return "symlink";
- case svn_wc__db_kind_unknown:
- return "unknown";
- case svn_wc__db_kind_subdir:
- return "subdir";
- default:
- SVN_ERR_MALFUNCTION_NO_RETURN();
- }
-}
-
-
-/* */
-static const char *
-conflict_kind_to_word(svn_wc_conflict_kind_t conflict_kind)
-{
- switch (conflict_kind)
- {
- case svn_wc_conflict_kind_text:
- return "text";
- case svn_wc_conflict_kind_property:
- return "property";
- case svn_wc_conflict_kind_tree:
- return "tree";
- default:
- SVN_ERR_MALFUNCTION_NO_RETURN();
- }
-}
-
-
-/* */
-static const char *
-conflict_action_to_word(svn_wc_conflict_action_t action)
-{
- return svn_token__to_word(svn_wc__conflict_action_map, action);
-}
-
-
-/* */
-static const char *
-conflict_reason_to_word(svn_wc_conflict_reason_t reason)
-{
- return svn_token__to_word(svn_wc__conflict_reason_map, reason);
-}
-
-
-/* */
-static const char *
-wc_operation_to_word(svn_wc_operation_t operation)
-{
- return svn_token__to_word(svn_wc__operation_map, operation);
-}
-
-
-/* */
-static svn_wc__db_kind_t
-db_kind_from_node_kind(svn_node_kind_t node_kind)
-{
- switch (node_kind)
- {
- case svn_node_file:
- return svn_wc__db_kind_file;
- case svn_node_dir:
- return svn_wc__db_kind_dir;
- case svn_node_unknown:
- case svn_node_none:
- return svn_wc__db_kind_unknown;
- default:
- SVN_ERR_MALFUNCTION_NO_RETURN();
- }
-}
-
-
/* */
static svn_error_t *
migrate_single_tree_conflict_data(svn_sqlite__db_t *sdb,
@@ -724,14 +640,10 @@ migrate_single_tree_conflict_data(svn_sq
const char *local_relpath,
apr_pool_t *scratch_pool)
{
- svn_sqlite__stmt_t *insert_stmt;
apr_hash_t *conflicts;
apr_hash_index_t *hi;
apr_pool_t *iterpool;
- SVN_ERR(svn_sqlite__get_statement(&insert_stmt, sdb,
- STMT_INSERT_NEW_CONFLICT));
-
SVN_ERR(svn_wc__read_tree_conflicts(&conflicts, tree_conflict_data,
local_relpath, scratch_pool));
@@ -743,8 +655,10 @@ migrate_single_tree_conflict_data(svn_sq
const svn_wc_conflict_description2_t *conflict =
svn__apr_hash_index_val(hi);
const char *conflict_relpath;
- apr_int64_t left_repos_id;
- apr_int64_t right_repos_id;
+ const char *conflict_data;
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ svn_skel_t *skel;
svn_pool_clear(iterpool);
@@ -753,72 +667,34 @@ migrate_single_tree_conflict_data(svn_sq
conflict->local_abspath, iterpool),
iterpool);
- /* Optionally get the right repos ids. */
- if (conflict->src_left_version)
- {
- SVN_ERR(svn_wc__db_upgrade_get_repos_id(
- &left_repos_id,
- sdb,
- conflict->src_left_version->repos_url,
- iterpool));
- }
-
- if (conflict->src_right_version)
- {
- SVN_ERR(svn_wc__db_upgrade_get_repos_id(
- &right_repos_id,
- sdb,
- conflict->src_right_version->repos_url,
- iterpool));
- }
-
- SVN_ERR(svn_sqlite__bindf(insert_stmt, "is", wc_id, conflict_relpath));
+ SVN_ERR(svn_wc__serialize_conflict(&skel, conflict, iterpool, iterpool));
+ conflict_data = svn_skel__unparse(skel, iterpool)->data;
- SVN_ERR(svn_sqlite__bind_text(insert_stmt, 3,
- svn_dirent_dirname(conflict_relpath,
- iterpool)));
- SVN_ERR(svn_sqlite__bind_text(insert_stmt, 4,
- kind_to_word(db_kind_from_node_kind(
- conflict->node_kind))));
- SVN_ERR(svn_sqlite__bind_text(insert_stmt, 5,
- conflict_kind_to_word(conflict->kind)));
-
- if (conflict->property_name)
- SVN_ERR(svn_sqlite__bind_text(insert_stmt, 6,
- conflict->property_name));
-
- SVN_ERR(svn_sqlite__bind_text(insert_stmt, 7,
- conflict_action_to_word(conflict->action)));
- SVN_ERR(svn_sqlite__bind_text(insert_stmt, 8,
- conflict_reason_to_word(conflict->reason)));
- SVN_ERR(svn_sqlite__bind_text(insert_stmt, 9,
- wc_operation_to_word(conflict->operation)));
+ /* See if we need to update or insert an ACTUAL node. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_ACTUAL_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, conflict_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ SVN_ERR(svn_sqlite__reset(stmt));
- if (conflict->src_left_version)
+ if (have_row)
{
- SVN_ERR(svn_sqlite__bind_int64(insert_stmt, 10, left_repos_id));
- SVN_ERR(svn_sqlite__bind_text(insert_stmt, 11,
- conflict->src_left_version->path_in_repos));
- SVN_ERR(svn_sqlite__bind_int64(insert_stmt, 12,
- conflict->src_left_version->peg_rev));
- SVN_ERR(svn_sqlite__bind_text(insert_stmt, 13,
- kind_to_word(db_kind_from_node_kind(
- conflict->src_left_version->node_kind))));
+ /* There is an existing ACTUAL row, so just update it. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_UPDATE_ACTUAL_CONFLICT_DATA));
}
-
- if (conflict->src_right_version)
+ else
{
- SVN_ERR(svn_sqlite__bind_int64(insert_stmt, 14, right_repos_id));
- SVN_ERR(svn_sqlite__bind_text(insert_stmt, 15,
- conflict->src_right_version->path_in_repos));
- SVN_ERR(svn_sqlite__bind_int64(insert_stmt, 16,
- conflict->src_right_version->peg_rev));
- SVN_ERR(svn_sqlite__bind_text(insert_stmt, 17,
- kind_to_word(db_kind_from_node_kind(
- conflict->src_right_version->node_kind))));
+ /* We need to insert an ACTUAL row with the tree conflict data. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_INSERT_ACTUAL_CONFLICT_DATA));
}
- SVN_ERR(svn_sqlite__insert(NULL, insert_stmt));
+ SVN_ERR(svn_sqlite__bindf(stmt, "iss", wc_id, conflict_relpath,
+ conflict_data));
+ if (!have_row)
+ SVN_ERR(svn_sqlite__bind_text(stmt, 4, local_relpath));
+
+ SVN_ERR(svn_sqlite__step_done(stmt));
}
svn_pool_destroy(iterpool);
@@ -829,22 +705,20 @@ migrate_single_tree_conflict_data(svn_sq
/* */
static svn_error_t *
-migrate_tree_conflicts(svn_sqlite__db_t *sdb,
- apr_pool_t *scratch_pool)
+migrate_tree_conflict_data(svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
{
- svn_sqlite__stmt_t *select_stmt;
- svn_sqlite__stmt_t *erase_stmt;
+ svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
/* Iterate over each node which has a set of tree conflicts, then insert
all of them into the new schema. */
- SVN_ERR(svn_sqlite__get_statement(&select_stmt, sdb,
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
STMT_SELECT_OLD_TREE_CONFLICT));
/* Get all the existing tree conflict data. */
- SVN_ERR(svn_sqlite__step(&have_row, select_stmt));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
while (have_row)
{
apr_int64_t wc_id;
@@ -853,33 +727,28 @@ migrate_tree_conflicts(svn_sqlite__db_t
svn_pool_clear(iterpool);
- wc_id = svn_sqlite__column_int64(select_stmt, 0);
- local_relpath = svn_sqlite__column_text(select_stmt, 1, iterpool);
- tree_conflict_data = svn_sqlite__column_text(select_stmt, 2,
- iterpool);
+ wc_id = svn_sqlite__column_int64(stmt, 0);
+ local_relpath = svn_sqlite__column_text(stmt, 1, iterpool);
+ tree_conflict_data = svn_sqlite__column_text(stmt, 2, iterpool);
- SVN_ERR(migrate_single_tree_conflict_data(sdb,
- tree_conflict_data,
+ SVN_ERR(migrate_single_tree_conflict_data(sdb, tree_conflict_data,
wc_id, local_relpath,
iterpool));
/* We don't need to do anything but step over the previously
prepared statement. */
- SVN_ERR(svn_sqlite__step(&have_row, select_stmt));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
}
- SVN_ERR(svn_sqlite__reset(select_stmt));
+ SVN_ERR(svn_sqlite__reset(stmt));
/* Erase all the old tree conflict data. */
- SVN_ERR(svn_sqlite__get_statement(&erase_stmt, sdb,
- STMT_ERASE_OLD_CONFLICTS));
- SVN_ERR(svn_sqlite__step_done(erase_stmt));
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_ERASE_OLD_CONFLICTS));
+ SVN_ERR(svn_sqlite__step_done(stmt));
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
-#endif /* ### no tree conflict migration yet */
-
/* */
static svn_error_t *
@@ -1195,7 +1064,6 @@ bump_to_17(void *baton, svn_sqlite__db_t
return SVN_NO_ERROR;
}
-#if (SVN_WC__VERSION > 19)
static svn_error_t *
bump_to_20(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
{
@@ -1203,25 +1071,15 @@ bump_to_20(void *baton, svn_sqlite__db_t
SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_20));
return SVN_NO_ERROR;
}
-#endif
-
-
-#if 0 /* ### no tree conflict migration yet */
-/* */
static svn_error_t *
-bump_to_XXX(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
+bump_to_21(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
{
- const char *wcroot_abspath = ((struct bump_baton *)baton)->wcroot_abspath;
-
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_XXX));
-
- SVN_ERR(migrate_tree_conflicts(sdb, scratch_pool));
-
+ SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_21));
+ SVN_ERR(migrate_tree_conflict_data(sdb, scratch_pool));
return SVN_NO_ERROR;
}
-#endif /* ### no tree conflict migration yet */
struct upgrade_data_t {
svn_sqlite__db_t *sdb;
@@ -1498,12 +1356,18 @@ svn_wc__upgrade_sdb(int *result_format,
"use 'tools/dev/wc-ng/bump-to-19.py' to "
"upgrade it"), wcroot_abspath);
-#if (SVN_WC__VERSION > 19)
case 19:
SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_20, &bb,
scratch_pool));
*result_format = 20;
/* FALLTHROUGH */
+
+#if SVN_WC__VERSION >= 21
+ case 20:
+ SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_21, &bb,
+ scratch_pool));
+ *result_format = 21;
+ /* FALLTHROUGH */
#endif
/* ### future bumps go here. */
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-metadata.sql?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-metadata.sql Thu Nov 11 22:58:49 2010
@@ -626,6 +626,16 @@ DROP TABLE WORKING_NODE;
PRAGMA user_version = 20;
+
+/* ------------------------------------------------------------------------- */
+
+/* Format 21 involves no schema changes, it moves the tree conflict victim
+ information to victime nodes, rather than parents. */
+
+-- STMT_UPGRADE_TO_21
+PRAGMA user_version = 21;
+
+
/* ------------------------------------------------------------------------- */
/* Format YYY introduces new handling for conflict information. */
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-queries.sql?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-queries.sql Thu Nov 11 22:58:49 2010
@@ -304,6 +304,13 @@ WHERE wc_id = ?1 AND local_relpath = ?2
AND op_depth = (SELECT MAX(op_depth) FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0);
+-- STMT_DELETE_LOWEST_WORKING_NODE
+DELETE FROM nodes
+WHERE wc_id = ?1 AND local_relpath = ?2
+ AND op_depth = (SELECT MIN(op_depth) FROM nodes
+ WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0)
+ AND presence = 'base-deleted';
+
-- STMT_DELETE_ALL_WORKING_NODES
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0;
@@ -321,6 +328,11 @@ DELETE FROM actual_node
WHERE wc_id = ?1 AND local_relpath = ?2
AND changelist IS NULL;
+-- STMT_DELETE_ACTUAL_NODE_WITHOUT_CONFLICT
+DELETE FROM actual_node
+WHERE wc_id = ?1 AND local_relpath = ?2
+ AND conflict_data IS NULL;
+
-- STMT_DELETE_NOT_PRESENT_NODES_RECURSIVE
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath LIKE ?2 ESCAPE '#' AND op_depth = ?3
@@ -341,6 +353,21 @@ SET properties = NULL,
right_checksum = NULL
WHERE wc_id = ?1 and local_relpath = ?2;
+-- STMT_CLEAR_ACTUAL_NODE_LEAVING_CONFLICT
+UPDATE actual_node
+SET properties = NULL,
+ text_mod = NULL,
+ changelist = NULL,
+ tree_conflict_data = NULL,
+ conflict_old = NULL,
+ conflict_new = NULL,
+ conflict_working = NULL,
+ prop_reject = NULL,
+ older_checksum = NULL,
+ left_checksum = NULL,
+ right_checksum = NULL
+WHERE wc_id = ?1 and local_relpath = ?2;
+
-- STMT_UPDATE_NODE_BASE_DEPTH
UPDATE nodes SET depth = ?3
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
@@ -679,7 +706,8 @@ WHERE wc_id = ?1 AND (local_relpath = ?2
-- STMT_SELECT_ACTUAL_NODE_RECURSIVE
SELECT 1
FROM actual_node
-WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#');
+WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#')
+ AND conflict_data IS NULL;
/* ------------------------------------------------------------------------- */
@@ -725,15 +753,6 @@ SELECT wc_id, local_relpath, tree_confli
FROM actual_node
WHERE tree_conflict_data IS NOT NULL;
--- STMT_INSERT_NEW_CONFLICT
-INSERT INTO conflict_victim (
- wc_id, local_relpath, parent_relpath, node_kind, conflict_kind,
- property_name, conflict_action, conflict_reason, operation,
- left_repos_id, left_repos_relpath, left_peg_rev, left_kind,
- right_repos_id, right_repos_relpath, right_peg_rev, right_kind)
-VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15,
- ?16, ?17);
-
-- STMT_ERASE_OLD_CONFLICTS
UPDATE actual_node SET tree_conflict_data = NULL;
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.c Thu Nov 11 22:58:49 2010
@@ -55,7 +55,9 @@
#define NOT_IMPLEMENTED() SVN__NOT_IMPLEMENTED()
-/* #define TREE_CONFLICTS_ON_CHILDREN */
+#if SVN_WC__VERSION >= 21
+ #define TREE_CONFLICTS_ON_CHILDREN
+#endif
/*
@@ -786,6 +788,28 @@ extend_parent_delete(svn_sqlite__db_t *s
return SVN_NO_ERROR;
}
+/* This is the reverse of extend_parent_delete.
+
+ When removing a base node if the parent has a working node then the
+ parent base and this node are both deleted and so the delete of
+ this node must be removed.
+ */
+static svn_error_t *
+retract_parent_delete(svn_sqlite__db_t *sdb,
+ apr_int64_t wc_id,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool)
+{
+ svn_sqlite__stmt_t *stmt;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_DELETE_LOWEST_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ return SVN_NO_ERROR;
+}
+
/* */
@@ -1824,6 +1848,45 @@ svn_wc__db_base_add_not_present_node(svn
kind, svn_wc__db_status_not_present, conflict, work_items, scratch_pool);
}
+struct base_remove_baton {
+ const char *local_relpath;
+ apr_int64_t wc_id;
+};
+
+static svn_error_t *
+db_base_remove(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
+{
+ struct base_remove_baton *brb = baton;
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_BASE_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", brb->wc_id, brb->local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ SVN_ERR(retract_parent_delete(sdb, brb->wc_id, brb->local_relpath,
+ scratch_pool));
+
+ /* If there is no working node then any actual node must be deleted,
+ unless it marks a conflict */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", brb->wc_id, brb->local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ SVN_ERR(svn_sqlite__reset(stmt));
+ if (!have_row)
+ {
+#ifndef TREE_CONFLICTS_ON_CHILDREN
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_ACTUAL_NODE));
+#else
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_DELETE_ACTUAL_NODE_WITHOUT_CONFLICT));
+#endif
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", brb->wc_id, brb->local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+
+ return SVN_NO_ERROR;
+}
svn_error_t *
svn_wc__db_base_remove(svn_wc__db_t *db,
@@ -1832,7 +1895,7 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
{
svn_wc__db_pdh_t *pdh;
const char *local_relpath;
- svn_sqlite__stmt_t *stmt;
+ struct base_remove_baton brb;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -1841,18 +1904,18 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
scratch_pool, scratch_pool));
VERIFY_USABLE_PDH(pdh);
- SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
- STMT_DELETE_BASE_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
+ brb.local_relpath = local_relpath;
+ brb.wc_id = pdh->wcroot->wc_id;
- SVN_ERR(svn_sqlite__step_done(stmt));
+ SVN_ERR(svn_sqlite__with_transaction(pdh->wcroot->sdb,
+ db_base_remove, &brb,
+ scratch_pool));
SVN_ERR(flush_entries(db, pdh, local_abspath, scratch_pool));
return SVN_NO_ERROR;
}
-
static svn_error_t *
base_get_info(svn_wc__db_status_t *status,
svn_wc__db_kind_t *kind,
@@ -3061,7 +3124,10 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
apr_pool_t *scratch_pool)
{
svn_wc__db_pdh_t *src_pdh, *dst_pdh;
- const char *src_relpath, *dst_relpath, *dst_op_root_relpath;
+ const char *src_relpath, *dst_relpath;
+#ifdef SVN_WC__OP_DEPTH
+ const char *dst_op_root_relpath;
+#endif
apr_int64_t dst_op_depth;
SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
@@ -4136,10 +4202,11 @@ set_tc_txn2(void *baton, svn_sqlite__db_
if (stb->tree_conflict)
{
- apr_hash_t *conflicts = apr_hash_make(scratch_pool);
- apr_hash_set(conflicts, "", APR_HASH_KEY_STRING, stb->tree_conflict);
- SVN_ERR(svn_wc__write_tree_conflicts(&tree_conflict_data, conflicts,
- scratch_pool));
+ svn_skel_t *skel;
+
+ SVN_ERR(svn_wc__serialize_conflict(&skel, stb->tree_conflict,
+ scratch_pool, scratch_pool));
+ tree_conflict_data = svn_skel__unparse(skel, scratch_pool)->data;
}
else
tree_conflict_data = NULL;
@@ -4347,23 +4414,23 @@ read_all_tree_conflicts(apr_hash_t **tre
{
const char *child_basename;
const char *child_relpath;
- const char *child_abspath;
const char *conflict_data;
- apr_hash_t *conflict_hash;
+ const svn_skel_t *skel;
+ const svn_wc_conflict_description2_t *conflict;
svn_pool_clear(iterpool);
child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
- child_basename = svn_relpath_basename(child_relpath, iterpool);
- child_abspath = svn_dirent_join(pdh->wcroot->abspath, child_relpath,
- iterpool);
+ child_basename = svn_relpath_basename(child_relpath, result_pool);
conflict_data = svn_sqlite__column_text(stmt, 1, NULL);
- SVN_ERR(svn_wc__read_tree_conflicts(&conflict_hash, conflict_data,
- pdh->wcroot->abspath, result_pool));
+ skel = svn_skel__parse(conflict_data, strlen(conflict_data), iterpool);
+ SVN_ERR(svn_wc__deserialize_conflict(&conflict, skel,
+ pdh->wcroot->abspath,
+ result_pool, iterpool));
- *tree_conflicts = apr_hash_overlay(result_pool, conflict_hash,
- *tree_conflicts);
+ apr_hash_set(*tree_conflicts, child_basename, APR_HASH_KEY_STRING,
+ conflict);
SVN_ERR(svn_sqlite__step(&have_row, stmt));
}
@@ -4478,7 +4545,12 @@ svn_wc__db_temp_op_remove_entry(svn_wc__
SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
+#ifndef TREE_CONFLICTS_ON_CHILDREN
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_ACTUAL_NODE));
+#else
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_DELETE_ACTUAL_NODE_WITHOUT_CONFLICT));
+#endif
SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
@@ -4671,8 +4743,18 @@ db_working_actual_remove(svn_wc__db_pdh_
SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
+#ifndef TREE_CONFLICTS_ON_CHILDREN
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
STMT_DELETE_ACTUAL_NODE));
+#else
+ SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+ STMT_CLEAR_ACTUAL_NODE_LEAVING_CONFLICT));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+ STMT_DELETE_ACTUAL_NODE_WITHOUT_CONFLICT));
+#endif
SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
@@ -4692,7 +4774,8 @@ db_working_actual_remove(svn_wc__db_pdh_
SVN_ERR_ASSERT(! have_row);
SVN_ERR(svn_sqlite__reset(stmt));
}
- /* Postcondition: There are no ACTUAL_NODE rows in this subtree. */
+ /* Postcondition: There are no ACTUAL_NODE rows in this subtree, save
+ those with conflict information. */
{
svn_boolean_t have_row;
@@ -5300,13 +5383,72 @@ read_info(svn_wc__db_status_t *status,
}
else if (have_act)
{
+#ifdef TREE_CONFLICTS_ON_CHILDREN
/* A row in ACTUAL_NODE should never exist without a corresponding
- node in BASE_NODE and/or WORKING_NODE. */
- err = svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
- _("Corrupt data for '%s'"),
- path_for_error_message(pdh->wcroot,
- local_relpath,
- scratch_pool));
+ node in BASE_NODE and/or WORKING_NODE unless it flags a conflict. */
+ if (svn_sqlite__column_is_null(stmt_act, 7)) /* conflict_data */
+#endif
+ err = svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
+ _("Corrupt data for '%s'"),
+ path_for_error_message(pdh->wcroot,
+ local_relpath,
+ scratch_pool));
+#ifdef TREE_CONFLICTS_ON_CHILDREN
+ /* ### What should we return? Should we have a separate
+ function for reading actual-only nodes? */
+
+ /* As a safety measure, until we decide if we want to use
+ read_info for actual-only nodes, make sure the caller asked
+ for the conflict status. */
+ SVN_ERR_ASSERT(conflicted);
+
+ if (status)
+ *status = svn_wc__db_status_normal; /* What! No it's not! */
+ if (kind)
+ *kind = svn_wc__db_kind_unknown;
+ if (revision)
+ *revision = SVN_INVALID_REVNUM;
+ if (repos_relpath)
+ *repos_relpath = NULL;
+ if (repos_root_url)
+ *repos_root_url = NULL;
+ if (repos_uuid)
+ *repos_uuid = NULL;
+ if (changed_rev)
+ *changed_rev = SVN_INVALID_REVNUM;
+ if (changed_date)
+ *changed_date = 0;
+ if (last_mod_time)
+ *last_mod_time = 0;
+ if (depth)
+ *depth = svn_depth_unknown;
+ if (checksum)
+ *checksum = NULL;
+ if (translated_size)
+ *translated_size = 0;
+ if (target)
+ *target = NULL;
+ if (changelist)
+ *changelist = svn_sqlite__column_text(stmt_act, 1, result_pool);
+ if (original_repos_relpath)
+ *original_repos_relpath = NULL;
+ if (original_root_url)
+ *original_root_url = NULL;
+ if (original_uuid)
+ *original_uuid = NULL;
+ if (original_revision)
+ *original_revision = SVN_INVALID_REVNUM;
+ if (props_mod)
+ *props_mod = !svn_sqlite__column_is_null(stmt_act, 6);
+ if (have_base)
+ *have_base = FALSE;
+ if (have_work)
+ *have_work = FALSE;
+ if (conflicted)
+ *conflicted = TRUE;
+ if (lock)
+ *lock = NULL;
+#endif
}
else
{
@@ -5410,6 +5552,7 @@ svn_wc__db_read_children_info(apr_hash_t
#endif
SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
+ *conflicts = apr_hash_make(result_pool);
SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &dir_relpath, db,
dir_abspath,
@@ -5596,6 +5739,10 @@ svn_wc__db_read_children_info(apr_hash_t
#ifdef TREE_CONFLICTS_ON_CHILDREN
child->conflicted = child->conflicted ||
!svn_sqlite__column_is_null(stmt, 8); /* tree */
+
+ if (child->conflicted)
+ apr_hash_set(*conflicts, apr_pstrdup(result_pool, name),
+ APR_HASH_KEY_STRING, "");
#endif
err = svn_sqlite__step(&have_row, stmt);
@@ -5605,7 +5752,6 @@ svn_wc__db_read_children_info(apr_hash_t
SVN_ERR(svn_sqlite__reset(stmt));
- *conflicts = apr_hash_make(result_pool);
#ifndef TREE_CONFLICTS_ON_CHILDREN
SVN_ERR(read_all_tree_conflicts(&tree_conflicts, pdh, dir_relpath,
scratch_pool, scratch_pool));
@@ -6848,6 +6994,7 @@ scan_addition(svn_wc__db_status_t *statu
if (original_repos_relpath
|| original_repos_id
+ || (original_revision && *original_revision == SVN_INVALID_REVNUM)
|| status)
{
if (local_relpath != current_relpath)
@@ -6871,6 +7018,9 @@ scan_addition(svn_wc__db_status_t *statu
current_relpath,
scratch_pool));
}
+
+ if (original_revision && *original_revision == SVN_INVALID_REVNUM)
+ *original_revision = svn_sqlite__column_revnum(stmt, 12);
}
/* current_relpath / current_abspath
@@ -8050,20 +8200,16 @@ svn_wc__db_read_conflicts(const apr_arra
conflict_data = svn_sqlite__column_text(stmt, 4, scratch_pool);
if (conflict_data)
{
- apr_hash_t *conflict_hash;
- svn_wc_conflict_description2_t *desc;
+ const svn_wc_conflict_description2_t *desc;
+ const svn_skel_t *skel;
- SVN_ERR(svn_wc__read_tree_conflicts(&conflict_hash, conflict_data,
+ skel = svn_skel__parse(conflict_data, strlen(conflict_data),
+ scratch_pool);
+ SVN_ERR(svn_wc__deserialize_conflict(&desc, skel,
svn_dirent_dirname(local_abspath, scratch_pool),
- result_pool));
-
- desc = apr_hash_get(conflict_hash,
- svn_dirent_basename(local_abspath,
- scratch_pool),
- APR_HASH_KEY_STRING);
+ result_pool, scratch_pool));
- SVN_ERR_ASSERT(desc != NULL);
- APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t *) = desc;
+ APR_ARRAY_PUSH(cflcts, const svn_wc_conflict_description2_t *) = desc;
}
}
#endif
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.h?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.h Thu Nov 11 22:58:49 2010
@@ -681,10 +681,14 @@ svn_wc__db_base_add_not_present_node(svn
Note that no changes are made to the local filesystem; LOCAL_ABSPATH
is merely the key to figure out which BASE node to remove.
- If the node is a directory, then ALL child nodes will be removed
- from the BASE tree, too.
+ To maintain a consistent database this function will also remove
+ any working node that marks LOCAL_ABSPATH as base-deleted. If this
+ results in there being no working node for LOCAL_ABSPATH then any
+ actual node will be removed if the actual node does not mark a
+ conflict.
- All temporary allocations will be made in SCRATCH_POOL.
+ Note the caller is responsible for removing base node
+ children before calling this function (this may change).
*/
svn_error_t *
svn_wc__db_base_remove(svn_wc__db_t *db,
Modified: subversion/branches/issue-3668-3669/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_wc/workqueue.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_wc/workqueue.c Thu Nov 11 22:58:49 2010
@@ -569,21 +569,9 @@ remove_base_node(svn_wc__db_t *db,
else
SVN_ERR(err);
}
-
- /* This should remove just BASE and ACTUAL, but for now also remove
- not existing WORKING_NODE data. */
- SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath, scratch_pool));
- }
- else if (wrk_status == svn_wc__db_status_added
- || (have_work && wrk_status == svn_wc__db_status_excluded))
- /* ### deletes of working additions should fall in this case, but
- ### we can't express these without the 4th tree */
- {
- /* Just remove the BASE_NODE data */
- SVN_ERR(svn_wc__db_base_remove(db, local_abspath, scratch_pool));
}
- else
- SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath, scratch_pool));
+
+ SVN_ERR(svn_wc__db_base_remove(db, local_abspath, scratch_pool));
return SVN_NO_ERROR;
}
Modified: subversion/branches/issue-3668-3669/subversion/mod_dav_svn/activity.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/mod_dav_svn/activity.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/mod_dav_svn/activity.c (original)
+++ subversion/branches/issue-3668-3669/subversion/mod_dav_svn/activity.c Thu Nov 11 22:58:49 2010
@@ -164,8 +164,8 @@ dav_svn__delete_activity(const dav_svn_r
txn_name = read_txn(pathname, repos->pool);
if (txn_name == NULL)
{
- return dav_new_error(repos->pool, HTTP_NOT_FOUND, 0,
- "could not find activity.");
+ return dav_svn__new_error(repos->pool, HTTP_NOT_FOUND, 0,
+ "could not find activity.");
}
/* After this point, we have to cleanup the value and database. */