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. */