You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2012/11/27 23:13:38 UTC

svn commit: r1414433 [1/4] - in /subversion/branches/issue-4194-dev: ./ build/ac-macros/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_delta/ subversion/libsvn_diff/ subversion/libsvn_fs_fs/ subversion/libs...

Author: cmpilato
Date: Tue Nov 27 22:13:24 2012
New Revision: 1414433

URL: http://svn.apache.org/viewvc?rev=1414433&view=rev
Log:
Sync the 'issue-4194-dev' branch with recent trunk changes.
(Merged /subversion/trunk:r1411977-1414431.)

Added:
    subversion/branches/issue-4194-dev/subversion/include/private/svn_diff_private.h
      - copied unchanged from r1414431, subversion/trunk/subversion/include/private/svn_diff_private.h
Modified:
    subversion/branches/issue-4194-dev/   (props changed)
    subversion/branches/issue-4194-dev/build.conf
    subversion/branches/issue-4194-dev/build/ac-macros/apr.m4
    subversion/branches/issue-4194-dev/build/ac-macros/aprutil.m4
    subversion/branches/issue-4194-dev/build/ac-macros/macosx.m4
    subversion/branches/issue-4194-dev/build/ac-macros/sqlite.m4
    subversion/branches/issue-4194-dev/configure.ac
    subversion/branches/issue-4194-dev/subversion/include/private/svn_named_atomic.h
    subversion/branches/issue-4194-dev/subversion/include/private/svn_string_private.h
    subversion/branches/issue-4194-dev/subversion/include/private/svn_wc_private.h
    subversion/branches/issue-4194-dev/subversion/include/svn_client.h
    subversion/branches/issue-4194-dev/subversion/include/svn_delta.h
    subversion/branches/issue-4194-dev/subversion/include/svn_diff.h
    subversion/branches/issue-4194-dev/subversion/include/svn_dirent_uri.h
    subversion/branches/issue-4194-dev/subversion/include/svn_fs.h
    subversion/branches/issue-4194-dev/subversion/include/svn_props.h
    subversion/branches/issue-4194-dev/subversion/include/svn_wc.h
    subversion/branches/issue-4194-dev/subversion/libsvn_client/client.h
    subversion/branches/issue-4194-dev/subversion/libsvn_client/deprecated.c
    subversion/branches/issue-4194-dev/subversion/libsvn_client/diff.c
    subversion/branches/issue-4194-dev/subversion/libsvn_client/export.c
    subversion/branches/issue-4194-dev/subversion/libsvn_client/externals.c
    subversion/branches/issue-4194-dev/subversion/libsvn_client/iprops.c
    subversion/branches/issue-4194-dev/subversion/libsvn_client/list.c
    subversion/branches/issue-4194-dev/subversion/libsvn_client/mergeinfo.c
    subversion/branches/issue-4194-dev/subversion/libsvn_delta/compat.c
    subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff.h
    subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff_file.c
    subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff_memory.c
    subversion/branches/issue-4194-dev/subversion/libsvn_diff/util.c
    subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/temp_serializer.c
    subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/temp_serializer.h
    subversion/branches/issue-4194-dev/subversion/libsvn_ra_serf/inherited_props.c
    subversion/branches/issue-4194-dev/subversion/libsvn_ra_serf/util.c
    subversion/branches/issue-4194-dev/subversion/libsvn_ra_svn/cyrus_auth.c
    subversion/branches/issue-4194-dev/subversion/libsvn_repos/reporter.c
    subversion/branches/issue-4194-dev/subversion/libsvn_subr/named_atomic.c
    subversion/branches/issue-4194-dev/subversion/libsvn_subr/sqlite.c
    subversion/branches/issue-4194-dev/subversion/libsvn_subr/string.c
    subversion/branches/issue-4194-dev/subversion/libsvn_subr/temp_serializer.c
    subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_crashrpt.c
    subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_crypto.c
    subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_xlate.c
    subversion/branches/issue-4194-dev/subversion/libsvn_wc/deprecated.c
    subversion/branches/issue-4194-dev/subversion/libsvn_wc/lock.c
    subversion/branches/issue-4194-dev/subversion/libsvn_wc/props.c
    subversion/branches/issue-4194-dev/subversion/libsvn_wc/status.c
    subversion/branches/issue-4194-dev/subversion/libsvn_wc/update_editor.c
    subversion/branches/issue-4194-dev/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/issue-4194-dev/subversion/libsvn_wc/wc.h
    subversion/branches/issue-4194-dev/subversion/libsvn_wc/wc_db.c
    subversion/branches/issue-4194-dev/subversion/libsvn_wc/wc_db.h
    subversion/branches/issue-4194-dev/subversion/mod_dav_svn/reports/update.c
    subversion/branches/issue-4194-dev/subversion/svn/cl.h
    subversion/branches/issue-4194-dev/subversion/svn/list-cmd.c
    subversion/branches/issue-4194-dev/subversion/svn/main.c
    subversion/branches/issue-4194-dev/subversion/svn/propedit-cmd.c
    subversion/branches/issue-4194-dev/subversion/svn/props.c
    subversion/branches/issue-4194-dev/subversion/svn/propset-cmd.c
    subversion/branches/issue-4194-dev/subversion/svnlook/main.c
    subversion/branches/issue-4194-dev/subversion/svnmucc/svnmucc.c
    subversion/branches/issue-4194-dev/subversion/svnrdump/svnrdump.c
    subversion/branches/issue-4194-dev/subversion/svnrdump/svnrdump.h
    subversion/branches/issue-4194-dev/subversion/svnserve/cyrus_auth.c
    subversion/branches/issue-4194-dev/subversion/tests/cmdline/diff_tests.py
    subversion/branches/issue-4194-dev/subversion/tests/cmdline/externals_tests.py
    subversion/branches/issue-4194-dev/subversion/tests/cmdline/getopt_tests.py
    subversion/branches/issue-4194-dev/subversion/tests/cmdline/iprop_tests.py
    subversion/branches/issue-4194-dev/subversion/tests/cmdline/prop_tests.py
    subversion/branches/issue-4194-dev/subversion/tests/cmdline/stat_tests.py
    subversion/branches/issue-4194-dev/subversion/tests/cmdline/svntest/actions.py
    subversion/branches/issue-4194-dev/subversion/tests/cmdline/update_tests.py
    subversion/branches/issue-4194-dev/subversion/tests/libsvn_fs/fs-test.c
    subversion/branches/issue-4194-dev/subversion/tests/libsvn_repos/repos-test.c
    subversion/branches/issue-4194-dev/subversion/tests/libsvn_subr/spillbuf-test.c
    subversion/branches/issue-4194-dev/subversion/tests/libsvn_subr/string-test.c
    subversion/branches/issue-4194-dev/subversion/tests/libsvn_wc/   (props changed)
    subversion/branches/issue-4194-dev/subversion/tests/libsvn_wc/db-test.c
    subversion/branches/issue-4194-dev/subversion/tests/libsvn_wc/utils.c
    subversion/branches/issue-4194-dev/subversion/tests/svn_test_fs.c
    subversion/branches/issue-4194-dev/tools/client-side/svn-bench/main.c
    subversion/branches/issue-4194-dev/tools/client-side/svn-bench/null-log-cmd.c
    subversion/branches/issue-4194-dev/tools/server-side/   (props changed)
    subversion/branches/issue-4194-dev/tools/server-side/fsfs-reorg.c
    subversion/branches/issue-4194-dev/tools/server-side/fsfs-stats.c

Propchange: subversion/branches/issue-4194-dev/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1411977-1414431
  Merged /subversion/branches/ev2-export:r1413107

Modified: subversion/branches/issue-4194-dev/build.conf
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/build.conf?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/build.conf (original)
+++ subversion/branches/issue-4194-dev/build.conf Tue Nov 27 22:13:24 2012
@@ -226,7 +226,7 @@ type = lib
 path = subversion/libsvn_diff
 libs = libsvn_subr apriconv apr zlib
 install = lib
-msvc-export = svn_diff.h
+msvc-export = svn_diff.h private\svn_diff_private.h
 
 # The repository filesystem library
 [libsvn_fs]

Modified: subversion/branches/issue-4194-dev/build/ac-macros/apr.m4
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/build/ac-macros/apr.m4?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/build/ac-macros/apr.m4 (original)
+++ subversion/branches/issue-4194-dev/build/ac-macros/apr.m4 Tue Nov 27 22:13:24 2012
@@ -125,11 +125,11 @@ AC_DEFUN(SVN_DOWNLOAD_APR,
   echo "get it with SVN and put it in a subdirectory of this source:"
   echo ""
   echo "   svn co \\"
-  echo "    http://svn.apache.org/repos/asf/apr/apr/branches/1.3.x \\"
+  echo "    http://svn.apache.org/repos/asf/apr/apr/branches/1.4.x \\"
   echo "    apr"
   echo ""
   echo "Run that right here in the top level of the Subversion tree."
-  echo "Afterwards, run apr/buildconf in that subdirectory and"
+  echo "Afterwards, run ./buildconf in that subdirectory and"
   echo "then run configure again here."
   echo ""
   echo "Whichever of the above you do, you probably need to do"
@@ -138,7 +138,7 @@ AC_DEFUN(SVN_DOWNLOAD_APR,
   echo "getting both from SVN with:"
   echo ""
   echo "   svn co \\"
-  echo "    http://svn.apache.org/repos/asf/apr/apr-util/branches/1.3.x \\"
+  echo "    http://svn.apache.org/repos/asf/apr/apr-util/branches/1.5.x \\"
   echo "    apr-util"
   echo ""
   AC_MSG_ERROR([no suitable apr found])

Modified: subversion/branches/issue-4194-dev/build/ac-macros/aprutil.m4
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/build/ac-macros/aprutil.m4?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/build/ac-macros/aprutil.m4 (original)
+++ subversion/branches/issue-4194-dev/build/ac-macros/aprutil.m4 Tue Nov 27 22:13:24 2012
@@ -129,11 +129,11 @@ AC_DEFUN(SVN_DOWNLOAD_APRUTIL,
   echo "get it with SVN and put it in a subdirectory of this source:"
   echo ""
   echo "   svn co \\"
-  echo "    http://svn.apache.org/repos/asf/apr/apr-util/branches/1.3.x \\"
+  echo "    http://svn.apache.org/repos/asf/apr/apr-util/branches/1.5.x \\"
   echo "    apr-util"
   echo ""
   echo "Run that right here in the top level of the Subversion tree."
-  echo "Afterwards, run apr-util/buildconf in that subdirectory and"
+  echo "Afterwards, run ./buildconf in that subdirectory and"
   echo "then run configure again here."
   echo ""
   AC_MSG_ERROR([no suitable APRUTIL found])

Modified: subversion/branches/issue-4194-dev/build/ac-macros/macosx.m4
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/build/ac-macros/macosx.m4?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/build/ac-macros/macosx.m4 (original)
+++ subversion/branches/issue-4194-dev/build/ac-macros/macosx.m4 Tue Nov 27 22:13:24 2012
@@ -24,25 +24,21 @@ dnl Check for _dyld_image_name and _dyld
 AC_DEFUN(SVN_LIB_MACHO_ITERATE,
 [
   AC_MSG_CHECKING([for Mach-O dynamic module iteration functions])
-
-  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+  AC_RUN_IFELSE([AC_LANG_PROGRAM([[
     #include <mach-o/dyld.h>
     #include <mach-o/loader.h>
-    int check(void) {
-      const struct mach_header *header = _dyld_get_image_header(0);
-      const char *name = _dyld_get_image_name(0);
-      if (name && header) return 1;
-      return 0;
-    }
-  ]],[[]])],[have_macho_iterate=yes],[have_macho_iterate=no])
-
-  if test "$have_macho_iterate" = "yes"; then
+  ]],[[
+    const struct mach_header *header = _dyld_get_image_header(0);
+    const char *name = _dyld_get_image_name(0);
+    if (name && header) return 0;
+    return 1;
+  ]])],[
     AC_DEFINE([SVN_HAVE_MACHO_ITERATE], [1],
               [Is Mach-O low-level _dyld API available?])
     AC_MSG_RESULT([yes])
-  else
+  ],[
     AC_MSG_RESULT([no])
-  fi
+  ])
 ])
 
 dnl SVN_LIB_MACOS_PLIST
@@ -53,12 +49,12 @@ AC_DEFUN(SVN_LIB_MACOS_PLIST,
 
   AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
     #include <AvailabilityMacros.h>
-    #if !DARWIN || (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_0)
+    #if !defined(MAC_OS_X_VERSION_MAX_ALLOWED) \
+     || !defined(MAC_OS_X_VERSION_10_0) \
+     || (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_0)
     #error ProperyList API unavailable.
     #endif
-  ]],[[]])],[have_macos_plist=yes],[have_macos_plist=no])
-
-  if test "$have_macos_plist" = "yes"; then
+  ]],[[]])],[
     dnl ### Hack.  We should only need to pass the -framework options when
     dnl linking libsvn_subr, since it is the only library that uses Keychain.
     dnl
@@ -75,9 +71,9 @@ AC_DEFUN(SVN_LIB_MACOS_PLIST,
     AC_DEFINE([SVN_HAVE_MACOS_PLIST], [1],
               [Is Mac OS property list API available?])
     AC_MSG_RESULT([yes])
-  else
+  ],[
     AC_MSG_RESULT([no])
-  fi
+  ])
 ])
 
 dnl SVN_LIB_MACOS_KEYCHAIN
@@ -92,28 +88,23 @@ AC_DEFUN(SVN_LIB_MACOS_KEYCHAIN,
 
   AC_MSG_CHECKING([for Mac OS KeyChain Services])
 
-  if test "$have_macos_plist" != "yes"; then
-    dnl There's no sense in checking for KeyChain if plists are not available
-    enable_keychain=no
-    AC_MSG_RESULT([no])
-  else
-    if test "$enable_keychain" = "yes"; then
-      AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-        #include <AvailabilityMacros.h>
-        #if !DARWIN || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_2)
-        #error KeyChain API unavailable.
-        #endif
-      ]],[[]])],[],[enable_keychain=no])
-    fi
-
-    if test "$enable_keychain" = "yes"; then
+  if test "$enable_keychain" = "yes"; then
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+      #include <AvailabilityMacros.h>
+      #if !defined(MAC_OS_X_VERSION_MAX_ALLOWED) \
+       || !defined(MAC_OS_X_VERSION_10_2) \
+       || (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_2)
+      #error KeyChain API unavailable.
+      #endif
+    ]],[[]])],[
       dnl ### Hack, see SVN_LIB_MACOS_PLIST
       LIBS="$LIBS -framework Security"
       LIBS="$LIBS -framework CoreServices"
       AC_DEFINE([SVN_HAVE_KEYCHAIN_SERVICES], [1], [Is Mac OS KeyChain support enabled?])
       AC_MSG_RESULT([yes])
-    else
+    ],[
+      enable_keychain=no
       AC_MSG_RESULT([no])
-    fi
+    ])
   fi
 ])

Modified: subversion/branches/issue-4194-dev/build/ac-macros/sqlite.m4
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/build/ac-macros/sqlite.m4?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/build/ac-macros/sqlite.m4 (original)
+++ subversion/branches/issue-4194-dev/build/ac-macros/sqlite.m4 Tue Nov 27 22:13:24 2012
@@ -243,9 +243,9 @@ AC_DEFUN(SVN_DOWNLOAD_SQLITE,
   echo ""
   echo "get the sqlite ${SQLITE_RECOMMENDED_VER} amalgamation from:"
   echo "    ${SQLITE_URL}"
-  echo "unpack the archive using tar/gunzip and copy sqlite3.c from the"
+  echo "unpack the archive using tar/gunzip and rename the"
   echo "resulting directory to:"
-  echo "$abs_srcdir/sqlite-amalgamation/sqlite3.c"
+  echo "$abs_srcdir/sqlite-amalgamation"
   echo ""
   AC_MSG_ERROR([Subversion requires SQLite])
 ])

Modified: subversion/branches/issue-4194-dev/configure.ac
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/configure.ac?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/configure.ac (original)
+++ subversion/branches/issue-4194-dev/configure.ac Tue Nov 27 22:13:24 2012
@@ -626,16 +626,18 @@ AC_SUBST(SVN_GNOME_KEYRING_INCLUDES)
 AC_SUBST(SVN_GNOME_KEYRING_LIBS)
 
 
-dnl Ev2 experimental feature ----------------------
-dnl Note: The Ev2 compat code will be built unconditionally, but by providing
-dnl this flag, users can enforce Ev2 compliance for testing purposes
-AC_ARG_ENABLE(ev2-shims,
-  AS_HELP_STRING([--enable-ev2-shims],
-                 [Compile with Ev2 translation [EXPERIMENTAL]]),
-  [enable_ev2_shims=$enableval],[enable_ev2_shims=no])
-if test "$enable_ev2_shims" = "yes"; then
-  AC_DEFINE(ENABLE_EV2_SHIMS, 1,
-            [Define to 1 if Ev2 should be interjected into editor stacks.])
+dnl Ev2 experimental features ----------------------
+dnl Note: The Ev2 implementations will be built unconditionally, but by
+dnl providing this flag, users can choose to use the currently-shimmed Ev2
+dnl editor implementations for various operations.  This will probably
+dnl negatively impact performance, but is useful for testing.
+AC_ARG_ENABLE(ev2-impl,
+  AS_HELP_STRING([--enable-ev2-impl],
+                 [Use Ev2 implementations, where available [EXPERIMENTAL]]),
+  [enable_ev2_impl=$enableval],[enable_ev2_impl=no])
+if test "$enable_ev2_impl" = "yes"; then
+  AC_DEFINE(ENABLE_EV2_IMPL, 1,
+            [Define to 1 if Ev2 implementations should be used.])
 fi
 
 

Modified: subversion/branches/issue-4194-dev/subversion/include/private/svn_named_atomic.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/include/private/svn_named_atomic.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/include/private/svn_named_atomic.h (original)
+++ subversion/branches/issue-4194-dev/subversion/include/private/svn_named_atomic.h Tue Nov 27 22:13:24 2012
@@ -104,8 +104,10 @@ svn_atomic_namespace__cleanup(const char
  * characters and an error will be returned if the specified name is longer
  * than supported.
  *
- * @note The lifetime of the atomic is bound to the lifetime
+ * @note The lifetime of the atomic object is bound to the lifetime
  * of the @a ns object, i.e. the pool the latter was created in.
+ * The data in the namespace persists as long as at least one process
+ * holds an #svn_atomic_namespace__t object corresponding to it.
  */
 svn_error_t *
 svn_named_atomic__get(svn_named_atomic__t **atomic,

Modified: subversion/branches/issue-4194-dev/subversion/include/private/svn_string_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/include/private/svn_string_private.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/include/private/svn_string_private.h (original)
+++ subversion/branches/issue-4194-dev/subversion/include/private/svn_string_private.h Tue Nov 27 22:13:24 2012
@@ -46,6 +46,83 @@ extern "C" {
  * @{
  */
 
+
+/** A self-contained memory buffer of known size.
+ *
+ * Intended to be used where a single variable-sized buffer is needed
+ * within an iteration, a scratch pool is available and we want to
+ * avoid the cost of creating another pool just for the iteration.
+ */
+typedef struct svn_membuf_t
+{
+  /** The a pool from which this buffer was originally allocated, and is not
+   * necessarily specific to this buffer.  This is used only for allocating
+   * more memory from when the buffer needs to grow.
+   */
+  apr_pool_t *pool;
+
+  /** pointer to the memory */
+  void *data;
+
+  /** total size of buffer allocated */
+  apr_size_t size;
+} svn_membuf_t;
+
+
+/* Initialize a memory buffer of the given size */
+void
+svn_membuf__create(svn_membuf_t *membuf, apr_size_t size, apr_pool_t *pool);
+
+/* Ensure that the given memory buffer has at least the given size */
+void
+svn_membuf__ensure(svn_membuf_t *membuf, apr_size_t size);
+
+/* Resize the given memory buffer, preserving its contents. */
+void
+svn_membuf__resize(svn_membuf_t *membuf, apr_size_t size);
+
+/* Zero-fill the given memory */
+void
+svn_membuf__zero(svn_membuf_t *membuf);
+
+/* Zero-fill the given memory buffer up to the smaller of SIZE and the
+   current buffer size. */
+void
+svn_membuf__nzero(svn_membuf_t *membuf, apr_size_t size);
+
+/* Inline implementation of svn_membuf__zero.
+ * Note that PMEMBUF is evaluated only once.
+ */
+#define SVN_MEMBUF__ZERO(pmembuf)                \
+  do                                             \
+    {                                            \
+      svn_membuf_t *const _m_b_f_ = (pmembuf);   \
+      memset(_m_b_f_->data, 0, _m_b_f_->size);   \
+    }                                            \
+  while(0)
+
+/* Inline implementation of svn_membuf__nzero
+ * Note that PMEMBUF and PSIZE are evaluated only once.
+ */
+#define SVN_MEMBUF__NZERO(pmembuf, psize)        \
+  do                                             \
+    {                                            \
+      svn_membuf_t *const _m_b_f_ = (pmembuf);   \
+      const apr_size_t _s_z_ = (psize);          \
+      if (_s_z_ > _m_b_f_->size)                 \
+        memset(_m_b_f_->data, 0, _m_b_f_->size); \
+      else                                       \
+        memset(_m_b_f_->data, 0, _s_z_);         \
+    }                                            \
+  while(0)
+
+#ifndef SVN_DEBUG
+/* In non-debug mode, just use these inlie replacements */
+#define svn_membuf__zero(B) SVN_MEMBUF__ZERO((B))
+#define svn_membuf__nzero(B, S) SVN_MEMBUF__NZERO((B), (S))
+#endif
+
+
 /** Returns the #svn_string_t information contained in the data and
  * len members of @a strbuf. This is effectively a typecast, converting
  * @a strbuf into an #svn_string_t. This first will become invalid and must
@@ -90,6 +167,49 @@ svn__ui64toa_sep(apr_uint64_t number, ch
 char *
 svn__i64toa_sep(apr_int64_t number, char seperator, apr_pool_t *pool);
 
+/**
+ * Computes the similarity score of STRA and STRB. Returns the ratio
+ * of the length of their longest common subsequence and the average
+ * length of the strings, normalized to the range [0..1000].
+ * The result is equivalent to Python's
+ *
+ *   difflib.SequenceMatcher.ratio
+ *
+ * Optionally sets *RLCS to the length of the longest common
+ * subsequence of STRA and STRB. Using BUFFER for temporary storage,
+ * requires memory proportional to the length of the shorter string.
+ *
+ * The LCS algorithm used is described in, e.g.,
+ *
+ *   http://en.wikipedia.org/wiki/Longest_common_subsequence_problem
+ *
+ * Q: Why another LCS when we already have one in libsvn_diff?
+ * A: svn_diff__lcs is too heavyweight and too generic for the
+ *    purposes of similarity testing. Whilst it would be possible
+ *    to use a character-based tokenizer with it, we really only need
+ *    the *length* of the LCS for the similarity score, not all the
+ *    other information that svn_diff__lcs produces in order to
+ *    make printing diffs possible.
+ *
+ * Q: Is there a limit on the length of the string parameters?
+ * A: Only available memory. But note that the LCS algorithm used
+ *    has O(strlen(STRA) * strlen(STRB)) worst-case performance,
+ *    so do keep a rein on your enthusiasm.
+ */
+unsigned int
+svn_cstring__similarity(const char *stra, const char *strb,
+                        svn_membuf_t *buffer, apr_size_t *rlcs);
+
+/**
+ * Like svn_cstring__similarity, but accepts svn_string_t's instead
+ * of NUL-terminated character strings.
+ */
+unsigned int
+svn_string__similarity(const svn_string_t *stringa,
+                       const svn_string_t *stringb,
+                       svn_membuf_t *buffer, apr_size_t *rlcs);
+
+
 /** @} */
 
 /** @} */

Modified: subversion/branches/issue-4194-dev/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/include/private/svn_wc_private.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/issue-4194-dev/subversion/include/private/svn_wc_private.h Tue Nov 27 22:13:24 2012
@@ -887,9 +887,11 @@ svn_wc__prop_retrieve_recursive(apr_hash
 
 /**
  * Set @a *iprops_paths to a hash mapping const char * absolute working
- * copy paths to the same for each path in the working copy at or below
- * @a local_abspath, limited by @a depth, that has cached inherited
- * properties for the base node of the path.  Allocate @a *iprop_paths
+ * copy paths to the nodes repository root relative path for each path
+ * in the working copy at or below @a local_abspath, limited by @a depth,
+ * that has cached inherited properties for the base node of the path.
+ *
+ * Allocate @a *iprop_paths
  * in @a result_pool.  Use @a scratch_pool for temporary allocations.
  */
 svn_error_t *
@@ -1202,7 +1204,12 @@ svn_wc__get_info(svn_wc_context_t *wc_ct
 
 /* Internal version of svn_wc_delete4(). It has one additional parameter,
  * MOVED_TO_ABSPATH. If not NULL, this parameter indicates that the
- * delete operation is the delete-half of a move. */
+ * delete operation is the delete-half of a move.
+ *
+ * ### Inconsistency: if DELETE_UNVERSIONED_TARGET is FALSE and a target is
+ *     unversioned, svn_wc__delete_many() will continue whereas
+ *     svn_wc__delete_internal() will throw an error.
+ */
 svn_error_t *
 svn_wc__delete_internal(svn_wc_context_t *wc_ctx,
                         const char *local_abspath,
@@ -1218,7 +1225,12 @@ svn_wc__delete_internal(svn_wc_context_t
 
 /* Alternative version of svn_wc_delete4().
  * It can delete multiple TARGETS more efficiently (within a single sqlite
- * transaction per working copy), but lacks support for moves. */
+ * transaction per working copy), but lacks support for moves.
+ *
+ * ### Inconsistency: if DELETE_UNVERSIONED_TARGET is FALSE and a target is
+ *     unversioned, svn_wc__delete_many() will continue whereas
+ *     svn_wc__delete_internal() will throw an error.
+ */
 svn_error_t *
 svn_wc__delete_many(svn_wc_context_t *wc_ctx,
                     const apr_array_header_t *targets,

Modified: subversion/branches/issue-4194-dev/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/include/svn_client.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/include/svn_client.h (original)
+++ subversion/branches/issue-4194-dev/subversion/include/svn_client.h Tue Nov 27 22:13:24 2012
@@ -1011,7 +1011,7 @@ svn_client_create_context2(svn_client_ct
                            apr_pool_t *pool);
 
 
-/** Similar to svn_client_create_context but passes a NULL @a cfg_hash.
+/** Similar to svn_client_create_context2 but passes a NULL @a cfg_hash.
  *
  * @deprecated Provided for backward compatibility with the 1.7 API.
  */
@@ -5368,7 +5368,7 @@ svn_client_export(svn_revnum_t *result_r
  * @{
  */
 
-/** The type of function invoked by svn_client_list2() to report the details
+/** The type of function invoked by svn_client_list3() to report the details
  * of each directory entry being listed.
  *
  * @a baton is the baton that was passed to the caller.  @a path is the
@@ -5378,11 +5378,45 @@ svn_client_export(svn_revnum_t *result_r
  * the entry's lock, if it is locked and if lock information is being
  * reported by the caller; otherwise @a lock is NULL.  @a abs_path is the
  * repository path of the top node of the list operation; it is relative to
- * the repository root and begins with "/".  @a pool may be used for
- * temporary allocations.
+ * the repository root and begins with "/".
  *
- * @since New in 1.4.
+ * If svn_client_list3() was called with @a include_externals set to TRUE,
+ * @a external_parent_url and @a external_target will be set.
+ * @a external_parent_url is url of the directory which has the
+ * externals definitions. @a external_target is the target subdirectory of 
+ * externals definitions which is relative to the parent directory that holds 
+ * the external item.
+ *
+ * If external_parent_url and external_target are defined, the item being
+ * listed is part of the external described by external_parent_url and
+ * external_target. Else, the item is not part of any external.
+ * Moreover, we will never mix items which are part of separate
+ * externals, and will always finish listing an external before listing
+ * the next one.
+
+ * @a pool may be used for temporary allocations.
+ *
+ * @since New in 1.8.
  */
+typedef svn_error_t *(*svn_client_list_func2_t)(
+  void *baton,
+  const char *path,
+  const svn_dirent_t *dirent,
+  const svn_lock_t *lock,
+  const char *abs_path,
+  const char *external_parent_url,
+  const char *external_target,
+  apr_pool_t *pool);
+
+/**
+ * Similar to #svn_client_list_func2_t, but without any information about
+ * externals definitions.
+ *
+ * @deprecated Provided for backward compatibility with the 1.7 API.
+ *
+ * @since New in 1.4
+ *
+ * */
 typedef svn_error_t *(*svn_client_list_func_t)(void *baton,
                                                const char *path,
                                                const svn_dirent_t *dirent,
@@ -5406,6 +5440,10 @@ typedef svn_error_t *(*svn_client_list_f
  *
  * If @a fetch_locks is TRUE, include locks when reporting directory entries.
  *
+ * If @a include_externals is TRUE, also list all external items 
+ * reached by recursion. @a depth value passed to the original list target
+ * applies for the externals also. 
+ *
  * Use @a pool for temporary allocations.
  *
  * Use authentication baton cached in @a ctx to authenticate against the
@@ -5422,8 +5460,30 @@ typedef svn_error_t *(*svn_client_list_f
  * otherwise simply bitwise OR together the combination of @c SVN_DIRENT_
  * fields you care about.
  *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_client_list3(const char *path_or_url,
+                 const svn_opt_revision_t *peg_revision,
+                 const svn_opt_revision_t *revision,
+                 svn_depth_t depth,
+                 apr_uint32_t dirent_fields,
+                 svn_boolean_t fetch_locks,
+                 svn_boolean_t include_externals,
+                 svn_client_list_func2_t list_func,
+                 void *baton,
+                 svn_client_ctx_t *ctx,
+                 apr_pool_t *pool);
+
+
+/** Similar to svn_client_list3(), but with @a include_externals set to FALSE, 
+ * and using a #svn_client_list_func2_t as callback.
+ *
+ * @deprecated Provided for backwards compatibility with the 1.7 API.
+ *
  * @since New in 1.5.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_client_list2(const char *path_or_url,
                  const svn_opt_revision_t *peg_revision,

Modified: subversion/branches/issue-4194-dev/subversion/include/svn_delta.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/include/svn_delta.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/include/svn_delta.h (original)
+++ subversion/branches/issue-4194-dev/subversion/include/svn_delta.h Tue Nov 27 22:13:24 2012
@@ -1290,7 +1290,8 @@ svn_delta_depth_filter_editor(const svn_
 /** Callback function type for svn_delta_path_driver().
  *
  * The handler of this callback is given the callback baton @a
- * callback_baton, @a path, and the @a parent_baton which represents
+ * callback_baton, @a path which is a relpath relative to the
+ * root of the edit, and the @a parent_baton which represents
  * path's parent directory as created by the editor passed to
  * svn_delta_path_driver().
  *
@@ -1321,7 +1322,8 @@ typedef svn_error_t *(*svn_delta_path_dr
  * @a callback_func and @a callback_baton to allow the caller to handle
  * the portion of the editor drive related to that path.
  *
- * Each path in @a paths is a const char *. The editor drive will be
+ * Each path in @a paths is a (const char *) relpath, relative
+ * to the root path of the @a edit. The editor drive will be
  * performed in the same order as @a paths. The paths should be sorted
  * using something like svn_sort_compare_paths to ensure that a depth-first
  * pattern is observed for directory/file baton creation. If @a sort_paths

Modified: subversion/branches/issue-4194-dev/subversion/include/svn_diff.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/include/svn_diff.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/include/svn_diff.h (original)
+++ subversion/branches/issue-4194-dev/subversion/include/svn_diff.h Tue Nov 27 22:13:24 2012
@@ -748,17 +748,21 @@ svn_diff_mem_string_diff4(svn_diff_t **d
 /** Outputs the @a diff object generated by svn_diff_mem_string_diff()
  * in unified diff format on @a output_stream, using @a original
  * and @a modified for the text in the output.
- * A diff header is only written to the output if @a with_diff_header
- * is TRUE.
+ *
+ * If @a with_diff_header is TRUE, write a diff header ("---" and "+++"
+ * lines), using @a original_header and @a modified_header to fill the field
+ * after the "---" and "+++" markers; otherwise @a original_header and
+ * @a modified_header are ignored and may be NULL.
  *
  * Outputs the header and hunk delimiters in @a header_encoding.
  * A @a hunk_delimiter can optionally be specified.
  * If @a hunk_delimiter is NULL, use the default hunk delimiter "@@".
  *
- * @a original_header and @a modified header are
- * used to fill the field after the "---" and "+++" header markers.
+ * As a special case, if the hunk delimiter is "##", then for an incomplete
+ * final line use the text "\ No newline at end of property" instead of
+ * "\ No newline at end of file".
  *
- * @since New in 1.7.
+ * @since New in 1.7. Hunk delimiter "##" has the special meaning since 1.8.
  */
 svn_error_t *
 svn_diff_mem_string_output_unified2(svn_stream_t *output_stream,
@@ -843,7 +847,6 @@ svn_diff_mem_string_output_merge(svn_str
                                  apr_pool_t *pool);
 
 
-
 
 /* Diff parsing. If you want to apply a patch to a working copy
  * rather than parse it, see svn_client_patch(). */

Modified: subversion/branches/issue-4194-dev/subversion/include/svn_dirent_uri.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/include/svn_dirent_uri.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/include/svn_dirent_uri.h (original)
+++ subversion/branches/issue-4194-dev/subversion/include/svn_dirent_uri.h Tue Nov 27 22:13:24 2012
@@ -32,7 +32,7 @@
  *    But not:
  *       "http://server"
  *
- * - a uri, for our purposes, is a percent-encoded, absolute path
+ *  - a uri, for our purposes, is a percent-encoded, absolute path
  *    (URI) that starts with a schema definition.  In practice, these
  *    tend to look like URLs, but never carry query strings.
  *    Examples:

Modified: subversion/branches/issue-4194-dev/subversion/include/svn_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/include/svn_fs.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/include/svn_fs.h (original)
+++ subversion/branches/issue-4194-dev/subversion/include/svn_fs.h Tue Nov 27 22:13:24 2012
@@ -320,6 +320,10 @@ svn_fs_path(svn_fs_t *fs,
 /**
  * Delete the filesystem at @a path.
  *
+ * @note: Deleting a filesystem that has an open svn_fs_t is not
+ * supported.  Clear/destroy all pools used to create/open @a path.
+ * See issue 4264.
+ *
  * @since New in 1.1.
  */
 svn_error_t *

Modified: subversion/branches/issue-4194-dev/subversion/include/svn_props.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/include/svn_props.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/include/svn_props.h (original)
+++ subversion/branches/issue-4194-dev/subversion/include/svn_props.h Tue Nov 27 22:13:24 2012
@@ -429,6 +429,27 @@ svn_prop_name_is_valid(const char *prop_
 
 /** @} */ /* Meta-data properties */
 
+/**
+ * This is a list of all user-vixible and -settable versioned node properties.
+ *
+ * @since New in 1.8
+ */
+#define SVN_PROP_NODE_ALL_PROPS SVN_PROP_MIME_TYPE, \
+                                SVN_PROP_IGNORE, \
+                                SVN_PROP_EOL_STYLE, \
+                                SVN_PROP_KEYWORDS, \
+                                SVN_PROP_EXECUTABLE, \
+                                SVN_PROP_NEEDS_LOCK, \
+                                SVN_PROP_SPECIAL, \
+                                SVN_PROP_EXTERNALS, \
+                                SVN_PROP_MERGEINFO, \
+                                SVN_PROP_INHERITABLE_AUTO_PROPS, \
+                                SVN_PROP_INHERITABLE_IGNORES, \
+                                \
+                                SVN_PROP_TEXT_TIME, \
+                                SVN_PROP_OWNER, \
+                                SVN_PROP_GROUP, \
+                                SVN_PROP_UNIX_MODE
 
 /** @} */
 

Modified: subversion/branches/issue-4194-dev/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/include/svn_wc.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/include/svn_wc.h (original)
+++ subversion/branches/issue-4194-dev/subversion/include/svn_wc.h Tue Nov 27 22:13:24 2012
@@ -5403,25 +5403,53 @@ svn_wc_crawl_revisions(const char *path,
  * @{
  */
 
+/** If @a is_wcroot is not @c NULL, set @a *is_wcroot to @c TRUE if @a
+ * local_abspath is the root of the working, otherwise to @c FALSE.
+ *
+ * If @a is_switched is not @c NULL, set @a *is_switched to @c TRUE if @a
+ * local_abspath is not the root of the working, and switched against its
+ * parent.
+ *
+ * If @a kind is not @c NULL, set @a *kind to the node kind of @a
+ * local_abspath.
+ *
+ * Use @a scratch_pool for any temporary allocations.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_wc_check_root(svn_boolean_t *is_wcroot,
+                  svn_boolean_t *is_switched,
+                  svn_kind_t *kind,
+                  svn_wc_context_t *wc_ctx,
+                  const char *local_abspath,
+                  apr_pool_t *scratch_pool);
+
 /** Set @a *wc_root to @c TRUE if @a local_abspath represents a "working copy
  * root", @c FALSE otherwise. Here, @a local_abspath is a "working copy root"
- * if its parent directory is not a WC or if its parent directory's repository
- * URL is not the parent of its own repository URL. Thus, a switched subtree is
- * considered to be a working copy root. Also, a deleted tree-conflict
- * victim is considered a "working copy root" because it has no URL.
+ * if its parent directory is not a WC or if it is switched. Also, a deleted
+ * tree-conflict victim is considered a "working copy root" because it has no
+ * URL.
  *
  * If @a local_abspath is not found, return the error #SVN_ERR_ENTRY_NOT_FOUND.
  *
  * Use @a scratch_pool for any temporary allocations.
  *
+ * @note For legacy reasons only a directory can be a wc-root. However, this
+ * function will also set wc_root to @c TRUE for a switched file.
+ *
  * @since New in 1.7.
+ * @deprecated Provided for backward compatibility with the 1.7 API. Consider
+ * using svn_wc_check_root() instead.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_wc_is_wc_root2(svn_boolean_t *wc_root,
                    svn_wc_context_t *wc_ctx,
                    const char *local_abspath,
                    apr_pool_t *scratch_pool);
 
+
 /**
  * Similar to svn_wc_is_wc_root2(), but with an access baton and relative
  * path.

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_client/client.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_client/client.h (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_client/client.h Tue Nov 27 22:13:24 2012
@@ -596,6 +596,58 @@ svn_client__switch_internal(svn_revnum_t
 
 /* ---------------------------------------------------------------- */
 
+/*** List ***/
+
+/* List the file/directory entries for PATH_OR_URL at REVISION.
+   The actual node revision selected is determined by the path as 
+   it exists in PEG_REVISION.  
+   
+   If DEPTH is svn_depth_infinity, then list all file and directory entries 
+   recursively.  Else if DEPTH is svn_depth_files, list all files under 
+   PATH_OR_URL (if any), but not subdirectories.  Else if DEPTH is
+   svn_depth_immediates, list all files and include immediate
+   subdirectories (at svn_depth_empty).  Else if DEPTH is
+   svn_depth_empty, just list PATH_OR_URL with none of its entries.
+ 
+   DIRENT_FIELDS controls which fields in the svn_dirent_t's are
+   filled in.  To have them totally filled in use SVN_DIRENT_ALL,
+   otherwise simply bitwise OR together the combination of SVN_DIRENT_*
+   fields you care about.
+ 
+   If FETCH_LOCKS is TRUE, include locks when reporting directory entries.
+ 
+   If INCLUDE_EXTERNALS is TRUE, also list all external items 
+   reached by recursion.  DEPTH value passed to the original list target
+   applies for the externals also.  EXTERNAL_PARENT_URL is url of the 
+   directory which has the externals definitions.  EXTERNAL_TARGET is the
+   target subdirectory of externals definitions.
+
+   Report directory entries by invoking LIST_FUNC/BATON. 
+   Pass EXTERNAL_PARENT_URL and EXTERNAL_TARGET to LIST_FUNC when external
+   items are listed, otherwise both are set to NULL.
+ 
+   Use authentication baton cached in CTX to authenticate against the
+   repository.
+ 
+   Use POOL for all allocations.
+*/
+svn_error_t *
+svn_client__list_internal(const char *path_or_url,
+                          const svn_opt_revision_t *peg_revision,
+                          const svn_opt_revision_t *revision,
+                          svn_depth_t depth,
+                          apr_uint32_t dirent_fields,
+                          svn_boolean_t fetch_locks,
+                          svn_boolean_t include_externals,
+                          const char *external_parent_url,
+                          const char *external_target,
+                          svn_client_list_func2_t list_func,
+                          void *baton,
+                          svn_client_ctx_t *ctx,
+                          apr_pool_t *pool);
+
+/* ---------------------------------------------------------------- */
+
 /*** Inheritable Properties ***/
 
 /* Fetch the inherited properties for the base of LOCAL_ABSPATH as well
@@ -1035,6 +1087,22 @@ svn_client__do_external_status(svn_clien
                                void *status_baton,
                                apr_pool_t *pool);
 
+
+/* List external items defined on each external in EXTERNALS, a const char *
+   externals_parent_url(url of the directory which has the externals
+   definitions) of all externals mapping to the svn_string_t * externals_desc
+   (externals description text). All other options are the same as those 
+   passed to svn_client_list(). */
+svn_error_t * 
+svn_client__list_externals(apr_hash_t *externals, 
+                           svn_depth_t depth,
+                           apr_uint32_t dirent_fields,
+                           svn_boolean_t fetch_locks,
+                           svn_client_list_func2_t list_func,
+                           void *baton,
+                           svn_client_ctx_t *ctx,
+                           apr_pool_t *scratch_pool);
+
 /* Baton for svn_client__dirent_fetcher */
 struct svn_client__dirent_fetcher_baton_t
 {

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_client/deprecated.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_client/deprecated.c Tue Nov 27 22:13:24 2012
@@ -1282,6 +1282,77 @@ svn_client_export(svn_revnum_t *result_r
 }
 
 /*** From list.c ***/
+
+/* Baton for use with wrap_list_func */
+struct list_func_wrapper_baton {
+    void *list_func1_baton;
+    svn_client_list_func_t list_func1;
+};
+
+/* This implements svn_client_list_func2_t */
+static svn_error_t *
+list_func_wrapper(void *baton,
+                  const char *path,
+                  const svn_dirent_t *dirent,
+                  const svn_lock_t *lock,
+                  const char *abs_path,
+                  const char *external_parent_url,
+                  const char *external_target,
+                  apr_pool_t *scratch_pool)
+{
+  struct list_func_wrapper_baton *lfwb = baton;
+
+  if (lfwb->list_func1)
+    return lfwb->list_func1(lfwb->list_func1_baton, path, dirent, 
+                           lock, abs_path, scratch_pool);
+
+  return SVN_NO_ERROR;
+}
+
+/* Helper function for svn_client_list2().  It wraps old format baton
+   and callback function in list_func_wrapper_baton and
+   returns new baton and callback to use with svn_client_list3(). */
+static void
+wrap_list_func(svn_client_list_func2_t *list_func2,
+               void **list_func2_baton,
+               svn_client_list_func_t list_func,
+               void *baton,
+               apr_pool_t *result_pool)
+{
+  struct list_func_wrapper_baton *lfwb = apr_palloc(result_pool, 
+                                                    sizeof(*lfwb));
+
+  /* Set the user provided old format callback in the baton. */
+  lfwb->list_func1_baton = baton;
+  lfwb->list_func1 = list_func;
+
+  *list_func2_baton = lfwb;
+  *list_func2 = list_func_wrapper;
+}
+
+svn_error_t *
+svn_client_list2(const char *path_or_url,
+                 const svn_opt_revision_t *peg_revision,
+                 const svn_opt_revision_t *revision,
+                 svn_depth_t depth,
+                 apr_uint32_t dirent_fields,
+                 svn_boolean_t fetch_locks,
+                 svn_client_list_func_t list_func,
+                 void *baton,
+                 svn_client_ctx_t *ctx,
+                 apr_pool_t *pool)
+{
+  svn_client_list_func2_t list_func2;
+  void *list_func2_baton;
+
+  wrap_list_func(&list_func2, &list_func2_baton, list_func, baton, pool);
+
+  return svn_client_list3(path_or_url, peg_revision, revision, depth, 
+                          dirent_fields, fetch_locks, 
+                          FALSE /* include externals */,
+                          list_func2, list_func2_baton, ctx, pool);
+}
+
 svn_error_t *
 svn_client_list(const char *path_or_url,
                 const svn_opt_revision_t *peg_revision,

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_client/diff.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_client/diff.c Tue Nov 27 22:13:24 2012
@@ -52,134 +52,19 @@
 #include "client.h"
 
 #include "private/svn_wc_private.h"
+#include "private/svn_diff_private.h"
 
 #include "svn_private_config.h"
 
 
-/*
- * Constant separator strings
- */
-static const char equal_string[] =
-  "===================================================================";
-static const char under_string[] =
-  "___________________________________________________________________";
-
-
-/*-----------------------------------------------------------------*/
-
 /* Utilities */
 
 
-/* A helper function for display_prop_diffs.  Output the differences between
-   the mergeinfo stored in ORIG_MERGEINFO_VAL and NEW_MERGEINFO_VAL in a
-   human-readable form to OUTSTREAM, using ENCODING.  Use POOL for temporary
-   allocations. */
-static svn_error_t *
-display_mergeinfo_diff(const char *old_mergeinfo_val,
-                       const char *new_mergeinfo_val,
-                       const char *encoding,
-                       svn_stream_t *outstream,
-                       apr_pool_t *pool)
-{
-  apr_hash_t *old_mergeinfo_hash, *new_mergeinfo_hash, *added, *deleted;
-  apr_pool_t *iterpool = svn_pool_create(pool);
-  apr_hash_index_t *hi;
-
-  if (old_mergeinfo_val)
-    SVN_ERR(svn_mergeinfo_parse(&old_mergeinfo_hash, old_mergeinfo_val, pool));
-  else
-    old_mergeinfo_hash = NULL;
-
-  if (new_mergeinfo_val)
-    SVN_ERR(svn_mergeinfo_parse(&new_mergeinfo_hash, new_mergeinfo_val, pool));
-  else
-    new_mergeinfo_hash = NULL;
-
-  SVN_ERR(svn_mergeinfo_diff2(&deleted, &added, old_mergeinfo_hash,
-                              new_mergeinfo_hash,
-                              TRUE, pool, pool));
-
-  for (hi = apr_hash_first(pool, deleted);
-       hi; hi = apr_hash_next(hi))
-    {
-      const char *from_path = svn__apr_hash_index_key(hi);
-      svn_rangelist_t *merge_revarray = svn__apr_hash_index_val(hi);
-      svn_string_t *merge_revstr;
-
-      svn_pool_clear(iterpool);
-      SVN_ERR(svn_rangelist_to_string(&merge_revstr, merge_revarray,
-                                      iterpool));
-
-      SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, iterpool,
-                                          _("   Reverse-merged %s:r%s%s"),
-                                          from_path, merge_revstr->data,
-                                          APR_EOL_STR));
-    }
-
-  for (hi = apr_hash_first(pool, added);
-       hi; hi = apr_hash_next(hi))
-    {
-      const char *from_path = svn__apr_hash_index_key(hi);
-      svn_rangelist_t *merge_revarray = svn__apr_hash_index_val(hi);
-      svn_string_t *merge_revstr;
-
-      svn_pool_clear(iterpool);
-      SVN_ERR(svn_rangelist_to_string(&merge_revstr, merge_revarray,
-                                      iterpool));
-
-      SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, iterpool,
-                                          _("   Merged %s:r%s%s"),
-                                          from_path, merge_revstr->data,
-                                          APR_EOL_STR));
-    }
-
-  svn_pool_destroy(iterpool);
-  return SVN_NO_ERROR;
-}
-
 #define MAKE_ERR_BAD_RELATIVE_PATH(path, relative_to_dir) \
         svn_error_createf(SVN_ERR_BAD_RELATIVE_PATH, NULL, \
                           _("Path '%s' must be an immediate child of " \
                             "the directory '%s'"), path, relative_to_dir)
 
-/* A helper function used by display_prop_diffs.
-   TOKEN is a string holding a property value.
-   If TOKEN is empty, or is already terminated by an EOL marker,
-   return TOKEN unmodified. Else, return a new string consisting
-   of the concatenation of TOKEN and the system's default EOL marker.
-   The new string is allocated from POOL.
-   If HAD_EOL is not NULL, indicate in *HAD_EOL if the token had a EOL. */
-static const svn_string_t *
-maybe_append_eol(const svn_string_t *token, svn_boolean_t *had_eol,
-                 apr_pool_t *pool)
-{
-  const char *curp;
-
-  if (had_eol)
-    *had_eol = FALSE;
-
-  if (token->len == 0)
-    return token;
-
-  curp = token->data + token->len - 1;
-  if (*curp == '\r')
-    {
-      if (had_eol)
-        *had_eol = TRUE;
-      return token;
-    }
-  else if (*curp != '\n')
-    {
-      return svn_string_createf(pool, "%s%s", token->data, APR_EOL_STR);
-    }
-  else
-    {
-      if (had_eol)
-        *had_eol = TRUE;
-      return token;
-    }
-}
-
 /* Adjust PATH to be relative to the repository root beneath ORIG_TARGET,
  * using RA_SESSION and WC_CTX, and return the result in *ADJUSTED_PATH.
  * ORIG_TARGET is one of the original targets passed to the diff command,
@@ -548,10 +433,8 @@ display_prop_diffs(const apr_array_heade
                    const char *wc_root_abspath,
                    apr_pool_t *pool)
 {
-  int i;
   const char *path1 = orig_path1;
   const char *path2 = orig_path2;
-  apr_pool_t *iterpool;
 
   if (use_git_diff_format)
     {
@@ -588,8 +471,8 @@ display_prop_diffs(const apr_array_heade
 
       SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, pool,
                                           "Index: %s" APR_EOL_STR
-                                          "%s" APR_EOL_STR,
-                                          path, equal_string));
+                                          SVN_DIFF__EQUAL_STRING APR_EOL_STR,
+                                          path));
 
       if (use_git_diff_format)
         SVN_ERR(print_git_diff_header(outstream, &label1, &label2,
@@ -598,11 +481,10 @@ display_prop_diffs(const apr_array_heade
                                       SVN_INVALID_REVNUM,
                                       encoding, pool));
 
-      SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, pool,
-                                          "--- %s" APR_EOL_STR
-                                          "+++ %s" APR_EOL_STR,
-                                          label1,
-                                          label2));
+      /* --- label1
+       * +++ label2 */
+      SVN_ERR(svn_diff__unidiff_write_header(
+        outstream, encoding, label1, label2, pool));
     }
 
   SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, pool,
@@ -612,107 +494,11 @@ display_prop_diffs(const apr_array_heade
                                       APR_EOL_STR));
 
   SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, pool,
-                                      "%s" APR_EOL_STR, under_string));
+                                      SVN_DIFF__UNDER_STRING APR_EOL_STR));
 
-  iterpool = svn_pool_create(pool);
-  for (i = 0; i < propchanges->nelts; i++)
-    {
-      const char *action;
-      const svn_string_t *original_value;
-      const svn_prop_t *propchange
-        = &APR_ARRAY_IDX(propchanges, i, svn_prop_t);
-
-      if (original_props)
-        original_value = apr_hash_get(original_props,
-                                      propchange->name, APR_HASH_KEY_STRING);
-      else
-        original_value = NULL;
-
-      /* If the property doesn't exist on either side, or if it exists
-         with the same value, skip it.  This can happen if the client is
-         hitting an old mod_dav_svn server that doesn't understand the
-         "send-all" REPORT style. */
-      if ((! (original_value || propchange->value))
-          || (original_value && propchange->value
-              && svn_string_compare(original_value, propchange->value)))
-        continue;
-
-      svn_pool_clear(iterpool);
-
-      if (! original_value)
-        action = "Added";
-      else if (! propchange->value)
-        action = "Deleted";
-      else
-        action = "Modified";
-      SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, iterpool,
-                                          "%s: %s%s", action,
-                                          propchange->name, APR_EOL_STR));
-
-      if (strcmp(propchange->name, SVN_PROP_MERGEINFO) == 0)
-        {
-          const char *orig = original_value ? original_value->data : NULL;
-          const char *val = propchange->value ? propchange->value->data : NULL;
-          svn_error_t *err = display_mergeinfo_diff(orig, val, encoding,
-                                                    outstream, iterpool);
-
-          /* Issue #3896: If we can't pretty-print mergeinfo differences
-             because invalid mergeinfo is present, then don't let the diff
-             fail, just print the diff as any other property. */
-          if (err && err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
-            {
-              svn_error_clear(err);
-            }
-          else
-            {
-              SVN_ERR(err);
-              continue;
-            }
-        }
-
-      {
-        svn_diff_t *diff;
-        svn_diff_file_options_t options = { 0 };
-        const svn_string_t *tmp;
-        const svn_string_t *orig;
-        const svn_string_t *val;
-        svn_boolean_t val_has_eol;
-
-        /* The last character in a property is often not a newline.
-           An eol character is appended to prevent the diff API to add a
-           '\ No newline at end of file' line. We add
-           '\ No newline at end of property' manually if needed. */
-        tmp = original_value ? original_value
-                             : svn_string_create_empty(iterpool);
-        orig = maybe_append_eol(tmp, NULL, iterpool);
-
-        tmp = propchange->value ? propchange->value :
-                                  svn_string_create_empty(iterpool);
-        val = maybe_append_eol(tmp, &val_has_eol, iterpool);
-
-        SVN_ERR(svn_diff_mem_string_diff(&diff, orig, val, &options,
-                                         iterpool));
-
-        /* UNIX patch will try to apply a diff even if the diff header
-         * is missing. It tries to be helpful by asking the user for a
-         * target filename when it can't determine the target filename
-         * from the diff header. But there usually are no files which
-         * UNIX patch could apply the property diff to, so we use "##"
-         * instead of "@@" as the default hunk delimiter for property diffs.
-         * We also supress the diff header. */
-        SVN_ERR(svn_diff_mem_string_output_unified2(
-                  outstream, diff, FALSE, "##",
-                  svn_dirent_local_style(path, iterpool),
-                  svn_dirent_local_style(path, iterpool),
-                  encoding, orig, val, iterpool));
-        if (!val_has_eol)
-          {
-            const char *s = "\\ No newline at end of property" APR_EOL_STR;
-            SVN_ERR(svn_stream_puts(outstream, s));
-          }
-      }
-    }
-  svn_pool_destroy(iterpool);
+  SVN_ERR(svn_diff__display_prop_diffs(
+            outstream, encoding, propchanges, original_props,
+            TRUE /* pretty_print_mergeinfo */, pool));
 
   return SVN_NO_ERROR;
 }
@@ -959,7 +745,9 @@ diff_content_changed(const char *path,
       /* Print out the diff header. */
       SVN_ERR(svn_stream_printf_from_utf8(outstream,
                diff_cmd_baton->header_encoding, subpool,
-               "Index: %s" APR_EOL_STR "%s" APR_EOL_STR, path, equal_string));
+               "Index: %s" APR_EOL_STR
+               SVN_DIFF__EQUAL_STRING APR_EOL_STR,
+               path));
 
       /* ### Print git diff headers. */
 
@@ -1007,7 +795,9 @@ diff_content_changed(const char *path,
       /* Print out the diff header. */
       SVN_ERR(svn_stream_printf_from_utf8(outstream,
                diff_cmd_baton->header_encoding, subpool,
-               "Index: %s" APR_EOL_STR "%s" APR_EOL_STR, path, equal_string));
+               "Index: %s" APR_EOL_STR
+               SVN_DIFF__EQUAL_STRING APR_EOL_STR,
+               path));
 
       /* ### Do we want to add git diff headers here too? I'd say no. The
        * ### 'Index' and '===' line is something subversion has added. The rest
@@ -1062,8 +852,9 @@ diff_content_changed(const char *path,
           /* Print out the diff header. */
           SVN_ERR(svn_stream_printf_from_utf8(outstream,
                    diff_cmd_baton->header_encoding, subpool,
-                   "Index: %s" APR_EOL_STR "%s" APR_EOL_STR,
-                   path, equal_string));
+                   "Index: %s" APR_EOL_STR
+                   SVN_DIFF__EQUAL_STRING APR_EOL_STR,
+                   path));
 
           if (diff_cmd_baton->use_git_diff_format)
             {
@@ -1270,8 +1061,9 @@ diff_file_deleted(svn_wc_notify_state_t 
     {
       SVN_ERR(svn_stream_printf_from_utf8(diff_cmd_baton->outstream,
                 diff_cmd_baton->header_encoding, scratch_pool,
-                "Index: %s (deleted)" APR_EOL_STR "%s" APR_EOL_STR,
-                path, equal_string));
+                "Index: %s (deleted)" APR_EOL_STR
+                SVN_DIFF__EQUAL_STRING APR_EOL_STR,
+                path));
     }
   else
     {

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_client/export.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_client/export.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_client/export.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_client/export.c Tue Nov 27 22:13:24 2012
@@ -907,6 +907,47 @@ fetch_base_func(const char **filename,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+get_editor(const svn_delta_editor_t **export_editor,
+           void **edit_baton,
+           struct edit_baton *eb,
+           svn_client_ctx_t *ctx,
+           apr_pool_t *result_pool,
+           apr_pool_t *scratch_pool)
+{
+  svn_delta_editor_t *editor = svn_delta_default_editor(result_pool);
+  svn_delta_shim_callbacks_t *shim_callbacks =
+                            svn_delta_shim_callbacks_default(result_pool);
+  
+  editor->set_target_revision = set_target_revision;
+  editor->open_root = open_root;
+  editor->add_directory = add_directory;
+  editor->add_file = add_file;
+  editor->apply_textdelta = apply_textdelta;
+  editor->close_file = close_file;
+  editor->change_file_prop = change_file_prop;
+  editor->change_dir_prop = change_dir_prop;
+
+  SVN_ERR(svn_delta_get_cancellation_editor(ctx->cancel_func,
+                                            ctx->cancel_baton,
+                                            editor,
+                                            eb,
+                                            export_editor,
+                                            edit_baton,
+                                            result_pool));
+
+  shim_callbacks->fetch_kind_func = fetch_kind_func;
+  shim_callbacks->fetch_props_func = fetch_props_func;
+  shim_callbacks->fetch_base_func = fetch_base_func;
+  shim_callbacks->fetch_baton = eb;
+
+  SVN_ERR(svn_editor__insert_shims(export_editor, edit_baton,
+                                   *export_editor, *edit_baton,
+                                   NULL, NULL, shim_callbacks,
+                                   result_pool, scratch_pool));
+
+   return SVN_NO_ERROR;
+}
 
 
 /*** Public Interfaces ***/
@@ -1044,37 +1085,10 @@ svn_client_export5(svn_revnum_t *result_
           const svn_delta_editor_t *export_editor;
           const svn_ra_reporter3_t *reporter;
           void *report_baton;
-          svn_delta_editor_t *editor = svn_delta_default_editor(pool);
           svn_boolean_t use_sleep = FALSE;
-          svn_delta_shim_callbacks_t *shim_callbacks =
-                                    svn_delta_shim_callbacks_default(pool);
 
-          editor->set_target_revision = set_target_revision;
-          editor->open_root = open_root;
-          editor->add_directory = add_directory;
-          editor->add_file = add_file;
-          editor->apply_textdelta = apply_textdelta;
-          editor->close_file = close_file;
-          editor->change_file_prop = change_file_prop;
-          editor->change_dir_prop = change_dir_prop;
-
-          SVN_ERR(svn_delta_get_cancellation_editor(ctx->cancel_func,
-                                                    ctx->cancel_baton,
-                                                    editor,
-                                                    eb,
-                                                    &export_editor,
-                                                    &edit_baton,
-                                                    pool));
-
-          shim_callbacks->fetch_kind_func = fetch_kind_func;
-          shim_callbacks->fetch_props_func = fetch_props_func;
-          shim_callbacks->fetch_base_func = fetch_base_func;
-          shim_callbacks->fetch_baton = eb;
-
-          SVN_ERR(svn_editor__insert_shims(&export_editor, &edit_baton,
-                                           export_editor, edit_baton,
-                                           NULL, NULL, shim_callbacks,
-                                           pool, pool));
+          SVN_ERR(get_editor(&export_editor, &edit_baton, eb, ctx,
+                             pool, pool));
 
           /* Manufacture a basic 'report' to the update reporter. */
           SVN_ERR(svn_ra_do_update2(ra_session,

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_client/externals.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_client/externals.c Tue Nov 27 22:13:24 2012
@@ -1180,3 +1180,105 @@ svn_client__do_external_status(svn_clien
   return SVN_NO_ERROR;
 }
 
+/* Walk through all the external items and list them. */
+static svn_error_t *
+list_external_items(apr_array_header_t *external_items,
+                    const char *externals_parent_url,
+                    svn_depth_t depth,
+                    apr_uint32_t dirent_fields,
+                    svn_boolean_t fetch_locks,
+                    svn_client_list_func2_t list_func,
+                    void *baton,
+                    svn_client_ctx_t *ctx,
+                    apr_pool_t *scratch_pool)
+{
+  const char *externals_parent_repos_root_url;
+  apr_pool_t *iterpool;
+  int i;
+
+  SVN_ERR(svn_client_get_repos_root(&externals_parent_repos_root_url, 
+                                    NULL /* uuid */,
+                                    externals_parent_url, ctx, 
+                                    scratch_pool, scratch_pool));
+
+  iterpool = svn_pool_create(scratch_pool);
+
+  for (i = 0; i < external_items->nelts; i++)
+    {
+      const char *resolved_url;
+
+      svn_wc_external_item2_t *item = 
+          APR_ARRAY_IDX(external_items, i, svn_wc_external_item2_t *);
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_wc__resolve_relative_external_url(
+                  &resolved_url, 
+                  item,
+                  externals_parent_repos_root_url,
+                  externals_parent_url,
+                  iterpool, iterpool));
+
+      /* List the external */
+      SVN_ERR(wrap_external_error(ctx, item->target_dir,
+                                  svn_client__list_internal(
+                                                resolved_url,
+                                                &item->peg_revision,
+                                                &item->revision,
+                                                depth, dirent_fields, 
+                                                fetch_locks,
+                                                TRUE,
+                                                externals_parent_url,
+                                                item->target_dir,
+                                                list_func, baton, ctx,
+                                                iterpool),
+                                  iterpool));
+    
+    }
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+      
+    
+svn_error_t * 
+svn_client__list_externals(apr_hash_t *externals, 
+                           svn_depth_t depth,
+                           apr_uint32_t dirent_fields,
+                           svn_boolean_t fetch_locks,
+                           svn_client_list_func2_t list_func,
+                           void *baton,
+                           svn_client_ctx_t *ctx,
+                           apr_pool_t *scratch_pool)
+{
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  apr_hash_index_t *hi;
+
+  for (hi = apr_hash_first(scratch_pool, externals);
+       hi;
+       hi = apr_hash_next(hi))
+    {
+      const char *externals_parent_url = svn__apr_hash_index_key(hi);
+      svn_string_t *externals_desc = svn__apr_hash_index_val(hi);
+      apr_array_header_t *external_items;
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_wc_parse_externals_description3(&external_items, 
+                                                  externals_parent_url,
+                                                  externals_desc->data, 
+                                                  FALSE, iterpool));
+
+      if (! external_items->nelts)
+        continue;
+
+      SVN_ERR(list_external_items(external_items, externals_parent_url, depth,
+                                  dirent_fields, fetch_locks, list_func,
+                                  baton, ctx, iterpool));
+
+    }
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_client/iprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_client/iprops.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_client/iprops.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_client/iprops.c Tue Nov 27 22:13:24 2012
@@ -40,31 +40,30 @@
 
 /*** Code. ***/
 
-/* Determine if ABSPATH needs an inherited property cache (i.e. it is a WC
-   root that is not also the repository root or it is switched).  If it does,
-   then set *NEEDS_CACHE to true, set it to false otherwise. */
+/* Determine if LOCAL_ABSPATH needs an inherited property cache.  If it does,
+   then set *NEEDS_CACHE to TRUE, set it to FALSE otherwise. */
 static svn_error_t *
 need_to_cache_iprops(svn_boolean_t *needs_cache,
-                     const char *abspath,
+                     const char *local_abspath,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *scratch_pool)
 {
   svn_boolean_t is_wc_root;
+  svn_boolean_t is_switched;
   svn_error_t *err;
 
-  /* Our starting assumption. */
-  *needs_cache = FALSE;
-
-  err = svn_wc_is_wc_root2(&is_wc_root, ctx->wc_ctx, abspath,
+  err = svn_wc_check_root(&is_wc_root, &is_switched, NULL,
+                          ctx->wc_ctx, local_abspath,
                            scratch_pool);
 
-  /* ABSPATH can't need a cache if it doesn't exist. */
+  /* LOCAL_ABSPATH doesn't need a cache if it doesn't exist. */
   if (err)
     {
-      if (err->apr_err == SVN_ERR_ENTRY_NOT_FOUND)
+      if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
         {
           svn_error_clear(err);
           is_wc_root = FALSE;
+          is_switched = FALSE;
         }
       else
         {
@@ -72,19 +71,7 @@ need_to_cache_iprops(svn_boolean_t *need
         }
     }
 
-  if (is_wc_root)
-    {
-      const char *child_repos_relpath;
-
-      /* We want to cache the inherited properties for WC roots, unless that
-         root points to the root of the repository, then there in nowhere to
-         inherit properties from. */
-      SVN_ERR(svn_wc__node_get_repos_relpath(&child_repos_relpath,
-                                             ctx->wc_ctx, abspath,
-                                             scratch_pool, scratch_pool));
-      if (child_repos_relpath[0] != '\0')
-        *needs_cache = TRUE;
-    }
+  *needs_cache = (is_wc_root || is_switched);
 
   return SVN_NO_ERROR;
 }
@@ -129,7 +116,10 @@ svn_client__get_inheritable_props(apr_ha
             {
               const char *target_abspath = apr_pstrdup(scratch_pool,
                                                        local_abspath);
-              apr_hash_set(iprop_paths, target_abspath, 
+
+              /* As value we set TARGET_ABSPATH, but any string besides ""
+                 would do */
+              apr_hash_set(iprop_paths, target_abspath,
                            APR_HASH_KEY_STRING, target_abspath);
             }
         }
@@ -139,10 +129,18 @@ svn_client__get_inheritable_props(apr_ha
            hi = apr_hash_next(hi))
         {
           const char *child_abspath = svn__apr_hash_index_key(hi);
+          const char *child_repos_relpath = svn__apr_hash_index_val(hi);
           const char *url;
           apr_array_header_t *inherited_props;
 
           svn_pool_clear(iterpool);
+
+          if (*child_repos_relpath == '\0')
+            {
+              /* A repository root doesn't have inherited properties */
+              continue;
+            }
+
           SVN_ERR(svn_wc__node_get_url(&url, ctx->wc_ctx, child_abspath,
                                        iterpool, iterpool));
           if (ra_session)
@@ -166,7 +164,7 @@ svn_client__get_inheritable_props(apr_ha
 
           SVN_ERR(svn_ra_get_inherited_props(ra_session, &inherited_props,
                                              "", revision, result_pool,
-                                             scratch_pool));
+                                             iterpool));
           apr_hash_set(*wcroot_iprops,
                        apr_pstrdup(result_pool, child_abspath),
                        APR_HASH_KEY_STRING,

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_client/list.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_client/list.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_client/list.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_client/list.c Tue Nov 27 22:13:24 2012
@@ -47,7 +47,15 @@
 
    LOCKS, if non-NULL, is a hash mapping const char * paths to svn_lock_t
    objects and FS_PATH is the absolute filesystem path of the RA session.
-   Use POOL for temporary allocations.
+   Use SCRATCH_POOL for temporary allocations.
+
+   If the caller passes EXTERNALS as non-NULL, populate the EXTERNALS 
+   hash table whose keys are URLs of the directory which has externals
+   definitions, and whose values are the externals description text. 
+   Allocate the hash's keys and values in RESULT_POOL.
+
+   EXTERNAL_PARENT_URL and EXTERNAL_TARGET are set when external items
+   are listed, otherwise both are set to NULL by the caller.
 */
 static svn_error_t *
 get_dir_contents(apr_uint32_t dirent_fields,
@@ -58,23 +66,31 @@ get_dir_contents(apr_uint32_t dirent_fie
                  const char *fs_path,
                  svn_depth_t depth,
                  svn_client_ctx_t *ctx,
-                 svn_client_list_func_t list_func,
+                 apr_hash_t *externals,
+                 const char *external_parent_url,
+                 const char *external_target,
+                 svn_client_list_func2_t list_func,
                  void *baton,
-                 apr_pool_t *pool)
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
 {
   apr_hash_t *tmpdirents;
-  apr_pool_t *iterpool = svn_pool_create(pool);
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   apr_array_header_t *array;
   svn_error_t *err;
+  apr_hash_t *prop_hash = NULL;
+  const svn_string_t *prop_val = NULL;
   int i;
 
   if (depth == svn_depth_empty)
     return SVN_NO_ERROR;
-
-  /* Get the directory's entries, but not its props.  Ignore any
-     not-authorized errors.  */
-  err = svn_ra_get_dir2(ra_session, &tmpdirents, NULL, NULL,
-                        dir, rev, dirent_fields, pool);
+  
+  /* Get the directory's entries. If externals hash is non-NULL, get its
+     properties also. Ignore any not-authorized errors.  */
+  err = svn_ra_get_dir2(ra_session, &tmpdirents, NULL, 
+                        externals ? &prop_hash : NULL,
+                        dir, rev, dirent_fields, scratch_pool);
+      
   if (err && ((err->apr_err == SVN_ERR_RA_NOT_AUTHORIZED) ||
               (err->apr_err == SVN_ERR_RA_DAV_FORBIDDEN)))
     {
@@ -82,12 +98,29 @@ get_dir_contents(apr_uint32_t dirent_fie
       return SVN_NO_ERROR;
     }
   SVN_ERR(err);
+ 
+ /* Filter out svn:externals from all properties hash. */ 
+  if (prop_hash) 
+    prop_val = apr_hash_get(prop_hash, SVN_PROP_EXTERNALS, 
+                            APR_HASH_KEY_STRING);
+  if (prop_val)
+    {
+      const char *url;
+
+      SVN_ERR(svn_ra_get_session_url(ra_session, &url, scratch_pool));
+      
+      apr_hash_set(externals, svn_path_url_add_component2(url, dir, 
+                                                          result_pool),
+                   APR_HASH_KEY_STRING, svn_string_dup(prop_val, 
+                                                       result_pool));
+    }
 
   if (ctx->cancel_func)
     SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
   /* Sort the hash, so we can call the callback in a "deterministic" order. */
-  array = svn_sort__hash(tmpdirents, svn_sort_compare_items_lexically, pool);
+  array = svn_sort__hash(tmpdirents, svn_sort_compare_items_lexically, 
+                         scratch_pool);
   for (i = 0; i < array->nelts; ++i)
     {
       svn_sort__item_t *item = &APR_ARRAY_IDX(array, i, svn_sort__item_t);
@@ -110,12 +143,17 @@ get_dir_contents(apr_uint32_t dirent_fie
       if (the_ent->kind == svn_node_file
           || depth == svn_depth_immediates
           || depth == svn_depth_infinity)
-        SVN_ERR(list_func(baton, path, the_ent, lock, fs_path, iterpool));
-
+        SVN_ERR(list_func(baton, path, the_ent, lock, fs_path,
+                          external_parent_url, external_target, iterpool));
+      
+      /* If externals is non-NULL, populate the externals hash table 
+         recursively for all directory entries. */
       if (depth == svn_depth_infinity && the_ent->kind == svn_node_dir)
         SVN_ERR(get_dir_contents(dirent_fields, path, rev,
-                                 ra_session, locks, fs_path, depth, ctx,
-                                 list_func, baton, iterpool));
+                                 ra_session, locks, fs_path, depth, ctx, 
+                                 externals, external_parent_url,
+                                 external_target, list_func, baton,
+                                 result_pool, iterpool));
     }
 
   svn_pool_destroy(iterpool);
@@ -236,16 +274,19 @@ svn_client__ra_stat_compatible(svn_ra_se
 }
 
 svn_error_t *
-svn_client_list2(const char *path_or_url,
-                 const svn_opt_revision_t *peg_revision,
-                 const svn_opt_revision_t *revision,
-                 svn_depth_t depth,
-                 apr_uint32_t dirent_fields,
-                 svn_boolean_t fetch_locks,
-                 svn_client_list_func_t list_func,
-                 void *baton,
-                 svn_client_ctx_t *ctx,
-                 apr_pool_t *pool)
+svn_client__list_internal(const char *path_or_url,
+                          const svn_opt_revision_t *peg_revision,
+                          const svn_opt_revision_t *revision,
+                          svn_depth_t depth,
+                          apr_uint32_t dirent_fields,
+                          svn_boolean_t fetch_locks,
+                          svn_boolean_t include_externals,
+                          const char *external_parent_url,
+                          const char *external_target,
+                          svn_client_list_func2_t list_func,
+                          void *baton,
+                          svn_client_ctx_t *ctx,
+                          apr_pool_t *pool)
 {
   svn_ra_session_t *ra_session;
   svn_client__pathrev_t *loc;
@@ -253,6 +294,12 @@ svn_client_list2(const char *path_or_url
   const char *fs_path;
   svn_error_t *err;
   apr_hash_t *locks;
+  apr_hash_t *externals;
+
+  if (include_externals)
+    externals = apr_hash_make(pool);
+  else
+    externals = NULL;
 
   /* We use the kind field to determine if we should recurse, so we
      always need it. */
@@ -295,14 +342,52 @@ svn_client_list2(const char *path_or_url
   SVN_ERR(list_func(baton, "", dirent, locks
                     ? (apr_hash_get(locks, fs_path,
                                     APR_HASH_KEY_STRING))
-                    : NULL, fs_path, pool));
+                    : NULL, fs_path, external_parent_url, 
+                    external_target, pool));
 
   if (dirent->kind == svn_node_dir
       && (depth == svn_depth_files
           || depth == svn_depth_immediates
           || depth == svn_depth_infinity))
     SVN_ERR(get_dir_contents(dirent_fields, "", loc->rev, ra_session, locks,
-                             fs_path, depth, ctx, list_func, baton, pool));
-
+                             fs_path, depth, ctx, externals, 
+                             external_parent_url, external_target, list_func,
+                             baton, pool, pool));
+  
+  /* We handle externals after listing entries under path_or_url, so that
+     handling external items (and any errors therefrom) doesn't delay
+     the primary operation. */
+  if (include_externals && apr_hash_count(externals))
+    {
+      /* The 'externals' hash populated by get_dir_contents() is processed 
+         here. */
+      SVN_ERR(svn_client__list_externals(externals, depth, dirent_fields, 
+                                         fetch_locks, list_func, baton,
+                                         ctx, pool));
+    } 
+  
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_client_list3(const char *path_or_url,
+                 const svn_opt_revision_t *peg_revision,
+                 const svn_opt_revision_t *revision,
+                 svn_depth_t depth,
+                 apr_uint32_t dirent_fields,
+                 svn_boolean_t fetch_locks,
+                 svn_boolean_t include_externals,
+                 svn_client_list_func2_t list_func,
+                 void *baton,
+                 svn_client_ctx_t *ctx,
+                 apr_pool_t *pool)
+{
+
+  return svn_error_trace(svn_client__list_internal(path_or_url, peg_revision,
+                                                   revision, 
+                                                   depth, dirent_fields, 
+                                                   fetch_locks, 
+                                                   include_externals, 
+                                                   NULL, NULL, list_func,
+                                                   baton, ctx, pool));
+}

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_client/mergeinfo.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_client/mergeinfo.c Tue Nov 27 22:13:24 2012
@@ -264,6 +264,7 @@ svn_client__get_wc_mergeinfo(svn_mergein
           !svn_dirent_is_root(local_abspath, strlen(local_abspath)))
         {
           svn_boolean_t is_wc_root;
+          svn_boolean_t is_switched;
           svn_revnum_t parent_base_rev;
           svn_revnum_t parent_changed_rev;
 
@@ -273,9 +274,9 @@ svn_client__get_wc_mergeinfo(svn_mergein
 
           /* If we've reached the root of the working copy don't look any
              higher. */
-          SVN_ERR(svn_wc_is_wc_root2(&is_wc_root, ctx->wc_ctx,
-                                     local_abspath, iterpool));
-          if (is_wc_root)
+          SVN_ERR(svn_wc_check_root(&is_wc_root, &is_switched, NULL,
+                                    ctx->wc_ctx, local_abspath, iterpool));
+          if (is_wc_root || is_switched)
             break;
 
           /* No explicit mergeinfo on this path.  Look higher up the

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_delta/compat.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_delta/compat.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_delta/compat.c Tue Nov 27 22:13:24 2012
@@ -163,7 +163,7 @@ enum restructure_action_t
   RESTRUCTURE_NONE = 0,
   RESTRUCTURE_ADD,         /* add the node, maybe replacing. maybe copy  */
   RESTRUCTURE_ADD_ABSENT,  /* add an absent node, possibly replacing  */
-  RESTRUCTURE_DELETE,      /* delete this node  */
+  RESTRUCTURE_DELETE       /* delete this node  */
 };
 
 /* Records everything about how this node is to be changed.  */

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff.h (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff.h Tue Nov 27 22:13:24 2012
@@ -213,19 +213,5 @@ svn_diff__unified_write_hunk_header(svn_
                                     const char *hunk_extra_context,
                                     apr_pool_t *scratch_pool);
 
-/* Write a unidiff "---" and "+++" header to OUTPUT_STREAM.
- *
- * Write "---" followed by a space and OLD_HEADER and a newline,
- * then "+++" followed by a space and NEW_HEADER and a newline.
- *
- * The text will be encoded into HEADER_ENCODING.
- */
-svn_error_t *
-svn_diff__unidiff_write_header(svn_stream_t *output_stream,
-                               const char *header_encoding,
-                               const char *old_header,
-                               const char *new_header,
-                               apr_pool_t *scratch_pool);
-
 
 #endif /* DIFF_H */

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff_file.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff_file.c Tue Nov 27 22:13:24 2012
@@ -48,6 +48,7 @@
 #include "private/svn_eol_private.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_adler32.h"
+#include "private/svn_diff_private.h"
 
 /* A token, i.e. a line read from a file. */
 typedef struct svn_diff__file_token_t

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff_memory.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff_memory.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff_memory.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_diff/diff_memory.c Tue Nov 27 22:13:24 2012
@@ -35,6 +35,7 @@
 #include "diff.h"
 #include "svn_private_config.h"
 #include "private/svn_adler32.h"
+#include "private/svn_diff_private.h"
 
 typedef struct source_tokens_t
 {
@@ -363,6 +364,9 @@ typedef struct unified_output_baton_t
   /* The delimiters of the hunk header, '@@' for text hunks and '##' for
    * property hunks. */
   const char *hunk_delimiter;
+  /* The string to print after a line that does not end with a newline.
+   * It must start with a '\'.  Typically "\ No newline at end of file". */
+  const char *no_newline_string;
 
   /* Pool for allocation of temporary memory in the callbacks
      Should be cleared on entry of each iteration of a callback */
@@ -417,8 +421,12 @@ output_unified_token_range(output_baton_
     }
   if (past_last == source->tokens->nelts && source->ends_without_eol)
     {
-      SVN_ERR(svn_diff__unified_append_no_newline_msg(
-                btn->hunk, btn->header_encoding, btn->pool));
+      const char *out_str;
+
+      SVN_ERR(svn_utf_cstring_from_utf8_ex2(
+                &out_str, btn->no_newline_string,
+                btn->header_encoding, btn->pool));
+      svn_stringbuf_appendcstr(btn->hunk, out_str);
     }
 
   if (tokens == 0)
@@ -553,6 +561,10 @@ svn_diff_mem_string_output_unified2(svn_
       baton.header_encoding = header_encoding;
       baton.hunk = svn_stringbuf_create_empty(pool);
       baton.hunk_delimiter = hunk_delimiter;
+      baton.no_newline_string
+        = (hunk_delimiter == NULL || strcmp(hunk_delimiter, "##") != 0)
+          ? APR_EOL_STR SVN_DIFF__NO_NEWLINE_AT_END_OF_FILE APR_EOL_STR
+          : APR_EOL_STR SVN_DIFF__NO_NEWLINE_AT_END_OF_PROPERTY APR_EOL_STR;
 
       SVN_ERR(svn_utf_cstring_from_utf8_ex2
               (&(baton.prefix_str[unified_output_context]), " ",