You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/08/11 18:43:31 UTC

svn commit: r984468 [10/25] - in /subversion/branches/ignore-mergeinfo: ./ build/ build/generator/ build/generator/templates/ notes/ notes/tree-conflicts/ notes/wc-ng/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subvers...

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/deprecated.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/deprecated.c Wed Aug 11 16:43:22 2010
@@ -729,6 +729,64 @@ svn_error_t *svn_io_file_lock(const char
   return svn_io_file_lock2(lock_file, exclusive, FALSE, pool);
 }
 
+svn_error_t *
+svn_io_get_dirents2(apr_hash_t **dirents,
+                    const char *path,
+                    apr_pool_t *pool)
+{
+  /* Note that the first part of svn_io_dirent2_t is identical
+     to svn_io_dirent_t to allow this construct */
+  return svn_error_return(
+            svn_io_get_dirents3(dirents, path, FALSE, pool, pool));
+}
+
+svn_error_t *
+svn_io_get_dirents(apr_hash_t **dirents,
+                   const char *path,
+                   apr_pool_t *pool)
+{
+  /* Note that in C, padding is not allowed at the beginning of structs,
+     so this is actually portable, since the kind field of svn_io_dirent_t
+     is first in that struct. */
+  return svn_io_get_dirents2(dirents, path, pool);
+}
+
+struct walk_func_filter_baton_t
+{
+  svn_io_walk_func_t walk_func;
+  void *walk_baton;
+};
+
+/* Implements svn_io_walk_func_t, but only allows APR_DIR and APR_REG
+   finfo types through to the wrapped function/baton.  */
+static svn_error_t *
+walk_func_filter_func(void *baton,
+                      const char *path,
+                      const apr_finfo_t *finfo,
+                      apr_pool_t *pool)
+{
+  struct walk_func_filter_baton_t *b = baton;
+
+  if (finfo->filetype == APR_DIR || finfo->filetype == APR_REG)
+    SVN_ERR(b->walk_func(b->walk_baton, path, finfo, pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_io_dir_walk(const char *dirname,
+                apr_int32_t wanted,
+                svn_io_walk_func_t walk_func,
+                void *walk_baton,
+                apr_pool_t *pool)
+{
+  struct walk_func_filter_baton_t baton;
+  baton.walk_func = walk_func;
+  baton.walk_baton = walk_baton;
+  return svn_error_return(svn_io_dir_walk2(dirname, wanted,
+                                           walk_func_filter_func,
+                                           &baton, pool));
+}
 
 /*** From constructors.c ***/
 svn_log_changed_path_t *

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/dirent_uri.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/dirent_uri.c Wed Aug 11 16:43:22 2010
@@ -1482,119 +1482,119 @@ svn_uri_get_longest_ancestor(const char 
 }
 
 const char *
-svn_dirent_is_child(const char *dirent1,
-                    const char *dirent2,
+svn_dirent_is_child(const char *parent_dirent,
+                    const char *child_dirent,
                     apr_pool_t *pool)
 {
-  return is_child(type_dirent, dirent1, dirent2, pool);
+  return is_child(type_dirent, parent_dirent, child_dirent, pool);
 }
 
 const char *
-svn_relpath_is_child(const char *relpath1,
-                     const char *relpath2,
+svn_relpath_is_child(const char *parent_relpath,
+                     const char *child_relpath,
                      apr_pool_t *pool)
 {
-  return is_child(type_relpath, relpath1, relpath2, pool);
+  return is_child(type_relpath, parent_relpath, child_relpath, pool);
 }
 
 const char *
-svn_uri_is_child(const char *uri1,
-                 const char *uri2,
+svn_uri_is_child(const char *parent_uri,
+                 const char *child_uri,
                  apr_pool_t *pool)
 {
-  return is_child(type_uri, uri1, uri2, pool);
+  return is_child(type_uri, parent_uri, child_uri, pool);
 }
 
 svn_boolean_t
-svn_dirent_is_ancestor(const char *dirent1, const char *dirent2)
+svn_dirent_is_ancestor(const char *parent_dirent, const char *child_dirent)
 {
-  return is_ancestor(type_dirent, dirent1, dirent2);
+  return is_ancestor(type_dirent, parent_dirent, child_dirent);
 }
 
 svn_boolean_t
-svn_relpath_is_ancestor(const char *relpath1, const char *relpath2)
+svn_relpath_is_ancestor(const char *parent_relpath, const char *child_relpath)
 {
-  return is_ancestor(type_relpath, relpath1, relpath2);
+  return is_ancestor(type_relpath, parent_relpath, child_relpath);
 }
 
 svn_boolean_t
-svn_uri_is_ancestor(const char *uri1, const char *uri2)
+svn_uri_is_ancestor(const char *parent_uri, const char *child_uri)
 {
-  return is_ancestor(type_uri, uri1, uri2);
+  return is_ancestor(type_uri, parent_uri, child_uri);
 }
 
 const char *
-svn_dirent_skip_ancestor(const char *dirent1,
-                         const char *dirent2)
+svn_dirent_skip_ancestor(const char *parent_dirent,
+                         const char *child_dirent)
 {
-  apr_size_t len = strlen(dirent1);
+  apr_size_t len = strlen(parent_dirent);
   apr_size_t root_len;
 
-  if (0 != memcmp(dirent1, dirent2, len))
-    return dirent2; /* dirent1 is no ancestor of dirent2 */
+  if (0 != memcmp(parent_dirent, child_dirent, len))
+    return child_dirent; /* parent_dirent is no ancestor of child_dirent */
 
-  if (dirent2[len] == 0)
-    return ""; /* dirent1 == dirent2 */
+  if (child_dirent[len] == 0)
+    return ""; /* parent_dirent == child_dirent */
 
-  root_len = dirent_root_length(dirent2, strlen(dirent2));
+  root_len = dirent_root_length(child_dirent, strlen(child_dirent));
   if (root_len > len)
-    return dirent2; /* Different root */
+    return child_dirent; /* Different root */
 
-  if (len == 1 && dirent2[0] == '/')
-    return dirent2 + 1;
+  if (len == 1 && child_dirent[0] == '/')
+    return child_dirent + 1;
 
-  if (dirent2[len] == '/')
-    return dirent2 + len + 1;
+  if (child_dirent[len] == '/')
+    return child_dirent + len + 1;
 
 #ifdef SVN_USE_DOS_PATHS
-  if (root_len == len && len > 0 && dirent2[len-1])
-    return dirent2 + len;
+  if (root_len == len && len > 0 && child_dirent[len-1])
+    return child_dirent + len;
 #endif
 
-  return dirent2;
+  return child_dirent;
 }
 
 const char *
-svn_relpath_skip_ancestor(const char *relpath1,
-                         const char *relpath2)
+svn_relpath_skip_ancestor(const char *parent_relpath,
+                          const char *child_relpath)
 {
-  apr_size_t len = strlen(relpath1);
+  apr_size_t len = strlen(parent_relpath);
 
-  if (0 != memcmp(relpath1, relpath2, len))
-    return relpath2; /* relpath1 is no ancestor of relpath2 */
+  if (0 != memcmp(parent_relpath, child_relpath, len))
+    return child_relpath; /* parent_relpath is no ancestor of child_relpath */
 
-  if (relpath2[len] == 0)
-    return ""; /* relpath1 == relpath2 */
+  if (child_relpath[len] == 0)
+    return ""; /* parent_relpath == child_relpath */
 
-  if (len == 1 && relpath2[0] == '/')
-    return relpath2 + 1;
+  if (len == 1 && child_relpath[0] == '/')
+    return child_relpath + 1;
 
-  if (relpath2[len] == '/')
-    return relpath2 + len + 1;
+  if (child_relpath[len] == '/')
+    return child_relpath + len + 1;
 
-  return relpath2;
+  return child_relpath;
 }
 
 
 const char *
-svn_uri_skip_ancestor(const char *uri1,
-                      const char *uri2)
+svn_uri_skip_ancestor(const char *parent_uri,
+                      const char *child_uri)
 {
-  apr_size_t len = strlen(uri1);
+  apr_size_t len = strlen(parent_uri);
 
-  if (0 != memcmp(uri1, uri2, len))
-    return uri2; /* dirent1 is no ancestor of dirent2 */
+  if (0 != memcmp(parent_uri, child_uri, len))
+    return child_uri; /* parent_uri is no ancestor of child_uri */
 
-  if (uri2[len] == 0)
-    return ""; /* dirent1 == dirent2 */
+  if (child_uri[len] == 0)
+    return ""; /* parent_uri == child_uri */
 
-  if (len == 1 && uri2[0] == '/')
-    return uri2 + 1;
+  if (len == 1 && child_uri[0] == '/')
+    return child_uri + 1;
 
-  if (len > 0 && uri2[len] == '/')
-    return uri2 + len + 1;
+  if (len > 0 && child_uri[len] == '/')
+    return child_uri + len + 1;
 
-  return uri2;
+  return child_uri;
 }
 
 svn_boolean_t
@@ -2254,21 +2254,42 @@ svn_uri_condense_targets(const char **pc
   return SVN_NO_ERROR;
 }
 
-svn_boolean_t
-svn_dirent_is_under_root(char **full_path,
+svn_error_t *
+svn_dirent_is_under_root(svn_boolean_t *under_root,
+                         const char **abspath,
                          const char *base_path,
                          const char *path,
                          apr_pool_t *pool)
 
 {
   apr_status_t status;
+  char *full_path;
 
-  status = apr_filepath_merge(
-     full_path, base_path, path,
-     APR_FILEPATH_NOTABOVEROOT | APR_FILEPATH_SECUREROOTTEST,
-     pool);
+  *under_root = FALSE;
+  if (abspath)
+    *abspath = NULL;
+
+  status = apr_filepath_merge(&full_path,
+                              base_path,
+                              path,
+                              APR_FILEPATH_NOTABOVEROOT
+                              | APR_FILEPATH_SECUREROOTTEST,
+                              pool);
+
+  if (status == APR_SUCCESS)
+    {
+      if (abspath)
+        *abspath = svn_dirent_canonicalize(full_path, pool);
+      *under_root = TRUE;
+      return SVN_NO_ERROR;
+    }
+  else if (status == APR_EABOVEROOT)
+    {
+      *under_root = FALSE;
+      return SVN_NO_ERROR;
+    }
 
-  return status == APR_SUCCESS ? TRUE : FALSE;
+  return svn_error_wrap_apr(status, NULL);
 }
 
 svn_error_t *

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/io.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/io.c Wed Aug 11 16:43:22 2010
@@ -222,14 +222,7 @@ io_check_path(const char *path,
 
   if (APR_STATUS_IS_ENOENT(apr_err))
     *kind = svn_node_none;
-  else if (APR_STATUS_IS_ENOTDIR(apr_err)
-#ifdef WIN32
-           /* On Windows, APR_STATUS_IS_ENOTDIR includes several kinds of
-            * invalid-pathname error but not this one, so we include it. */
-           /* ### This fix should go into APR. */
-           || (APR_TO_OS_ERROR(apr_err) == ERROR_INVALID_NAME)
-#endif
-           )
+  else if (SVN__APR_STATUS_IS_ENOTDIR(apr_err))
     *kind = svn_node_none;
   else if (apr_err)
     return svn_error_wrap_apr(apr_err, _("Can't check path '%s'"),
@@ -1918,7 +1911,7 @@ svn_io_remove_dir2(const char *path, svn
   svn_error_t *err;
   apr_pool_t *subpool;
   apr_hash_t *dirents;
-  apr_hash_index_t *ent;
+  apr_hash_index_t *hi;
 
   /* Check for pending cancellation request.
      If we need to bail out, do so early. */
@@ -1928,7 +1921,7 @@ svn_io_remove_dir2(const char *path, svn
 
   subpool = svn_pool_create(pool);
 
-  err = svn_io_get_dirents2(&dirents, path, subpool);
+  err = svn_io_get_dirents3(&dirents, path, TRUE, subpool, subpool);
   if (err)
     {
       /* if the directory doesn't exist, our mission is accomplished */
@@ -1940,15 +1933,14 @@ svn_io_remove_dir2(const char *path, svn
       return svn_error_return(err);
     }
 
-  for (ent = apr_hash_first(subpool, dirents); ent; ent = apr_hash_next(ent))
+  for (hi = apr_hash_first(subpool, dirents); hi; hi = apr_hash_next(hi))
     {
-      const void *key;
-      void *val;
-      char *fullpath;
-
-      apr_hash_this(ent, &key, NULL, &val);
-      fullpath = svn_dirent_join(path, key, subpool);
-      if (((svn_io_dirent_t *)val)->kind == svn_node_dir)
+      const char *name = svn__apr_hash_index_key(hi);
+      const svn_io_dirent2_t *dirent = svn__apr_hash_index_val(hi);
+      const char *fullpath;
+
+      fullpath = svn_dirent_join(path, name, subpool);
+      if (dirent->kind == svn_node_dir)
         {
           /* Don't check for cancellation, the callee will immediately do so */
           SVN_ERR(svn_io_remove_dir2(fullpath, FALSE, cancel_func,
@@ -1977,59 +1969,50 @@ svn_io_get_dir_filenames(apr_hash_t **di
                          const char *path,
                          apr_pool_t *pool)
 {
-  apr_status_t status;
-  apr_dir_t *this_dir;
-  apr_finfo_t this_entry;
-  apr_int32_t flags = APR_FINFO_NAME;
-
-  *dirents = apr_hash_make(pool);
-
-  SVN_ERR(svn_io_dir_open(&this_dir, path, pool));
+  return svn_error_return(svn_io_get_dirents3(dirents, path, TRUE,
+                                              pool, pool));
+}
 
-  for (status = apr_dir_read(&this_entry, flags, this_dir);
-       status == APR_SUCCESS;
-       status = apr_dir_read(&this_entry, flags, this_dir))
-    {
-      if ((this_entry.name[0] == '.')
-          && ((this_entry.name[1] == '\0')
-              || ((this_entry.name[1] == '.')
-                  && (this_entry.name[2] == '\0'))))
-        {
-          continue;
-        }
-      else
-        {
-          const char *name;
-          SVN_ERR(entry_name_to_utf8(&name, this_entry.name, path, pool));
-          apr_hash_set(*dirents, name, APR_HASH_KEY_STRING, name);
-        }
-    }
+svn_io_dirent2_t *
+svn_io_dirent2_create(apr_pool_t *result_pool)
+{
+  svn_io_dirent2_t *dirent = apr_pcalloc(result_pool, sizeof(*dirent));
 
-  if (! (APR_STATUS_IS_ENOENT(status)))
-    return svn_error_wrap_apr(status, _("Can't read directory '%s'"),
-                              svn_dirent_local_style(path, pool));
+  /*dirent->kind = svn_node_none;
+  dirent->special = FALSE;*/
+  dirent->filesize = SVN_INVALID_FILESIZE;
+  /*dirent->mtime = 0;*/
 
-  status = apr_dir_close(this_dir);
-  if (status)
-    return svn_error_wrap_apr(status, _("Error closing directory '%s'"),
-                              svn_dirent_local_style(path, pool));
+  return dirent;
+}
 
-  return SVN_NO_ERROR;
+svn_io_dirent2_t *
+svn_io_dirent2_dup(const svn_io_dirent2_t *item,
+                   apr_pool_t *result_pool)
+{
+  return apr_pmemdup(result_pool,
+                     item,
+                     sizeof(*item));
 }
 
 svn_error_t *
-svn_io_get_dirents2(apr_hash_t **dirents,
+svn_io_get_dirents3(apr_hash_t **dirents,
                     const char *path,
-                    apr_pool_t *pool)
+                    svn_boolean_t only_check_type,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool)
 {
   apr_status_t status;
   apr_dir_t *this_dir;
   apr_finfo_t this_entry;
   apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;
 
-  *dirents = apr_hash_make(pool);
+  if (!only_check_type)
+    flags |= APR_FINFO_SIZE | APR_FINFO_MTIME;
+
+  *dirents = apr_hash_make(result_pool);
 
-  SVN_ERR(svn_io_dir_open(&this_dir, path, pool));
+  SVN_ERR(svn_io_dir_open(&this_dir, path, scratch_pool));
 
   for (status = apr_dir_read(&this_entry, flags, this_dir);
        status == APR_SUCCESS;
@@ -2045,39 +2028,74 @@ svn_io_get_dirents2(apr_hash_t **dirents
       else
         {
           const char *name;
-          svn_io_dirent_t *dirent = apr_palloc(pool, sizeof(*dirent));
+          svn_io_dirent2_t *dirent = svn_io_dirent2_create(result_pool);
 
-          SVN_ERR(entry_name_to_utf8(&name, this_entry.name, path, pool));
+          SVN_ERR(entry_name_to_utf8(&name, this_entry.name, path, result_pool));
 
           map_apr_finfo_to_node_kind(&(dirent->kind),
                                      &(dirent->special),
                                      &this_entry);
 
+          if (!only_check_type)
+            {
+              dirent->filesize = this_entry.size;
+              dirent->mtime = this_entry.mtime;
+            }
+
           apr_hash_set(*dirents, name, APR_HASH_KEY_STRING, dirent);
         }
     }
 
   if (! (APR_STATUS_IS_ENOENT(status)))
     return svn_error_wrap_apr(status, _("Can't read directory '%s'"),
-                              svn_dirent_local_style(path, pool));
+                              svn_dirent_local_style(path, scratch_pool));
 
   status = apr_dir_close(this_dir);
   if (status)
     return svn_error_wrap_apr(status, _("Error closing directory '%s'"),
-                              svn_dirent_local_style(path, pool));
+                              svn_dirent_local_style(path, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
-svn_io_get_dirents(apr_hash_t **dirents,
+svn_io_stat_dirent(const svn_io_dirent2_t **dirent_p,
                    const char *path,
-                   apr_pool_t *pool)
+                   svn_boolean_t ignore_enoent,
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
 {
-  /* Note that in C, padding is not allowed at the beginning of structs,
-     so this is actually portable, since the kind field of svn_io_dirent_t
-     is first in that struct. */
-  return svn_io_get_dirents2(dirents, path, pool);
+  apr_finfo_t finfo;
+  svn_io_dirent2_t *dirent;
+  svn_error_t *err;
+
+  err = svn_io_stat(&finfo, path,
+                    APR_FINFO_TYPE | APR_FINFO_LINK
+                    | APR_FINFO_SIZE | APR_FINFO_MTIME,
+                    scratch_pool);
+
+  if (err && ignore_enoent && 
+      (APR_STATUS_IS_ENOENT(err->apr_err)
+       || SVN__APR_STATUS_IS_ENOTDIR(err->apr_err)))
+    {
+      svn_error_clear(err);
+      dirent = svn_io_dirent2_create(result_pool);
+      SVN_ERR_ASSERT(dirent->kind == svn_node_none);
+
+      *dirent_p = dirent;
+      return SVN_NO_ERROR;
+    }
+  SVN_ERR(err);
+
+  dirent = svn_io_dirent2_create(result_pool);
+  map_apr_finfo_to_node_kind(&(dirent->kind), &(dirent->special), &finfo);
+
+  dirent->filesize = finfo.size;
+  dirent->mtime = finfo.mtime;
+
+  *dirent_p = dirent;
+
+  return SVN_NO_ERROR;
 }
 
 /* Pool userdata key for the error file passed to svn_io_start_cmd(). */
@@ -2628,11 +2646,15 @@ svn_io_detect_mimetype2(const char **mim
 
 
   /* Right now, this function is going to be really stupid.  It's
-     going to examine the first block of data, and make sure that 85%
+     going to examine the first block of data, and make sure that 15%
      of the bytes are such that their value is in the ranges 0x07-0x0D
-     or 0x20-0x7F, and that 100% of those bytes is not 0x00.
+     or 0x20-0x7F, and that none of those bytes is 0x00.  If those
+     criteria are not met, we're calling it binary.
 
-     If those criteria are not met, we're calling it binary. */
+     NOTE:  Originally, I intended to target 85% of the bytes being in
+     the specified ranges, but I flubbed the condition.  At any rate,
+     folks aren't complaining, so I'm not sure that it's worth
+     adjusting this retroactively now.  --cmpilato  */
   if (amt_read > 0)
     {
       apr_size_t i;
@@ -3117,6 +3139,10 @@ svn_io_dir_open(apr_dir_t **new_dir, con
   return SVN_NO_ERROR;
 }
 
+/* Forward declaration */
+static apr_status_t
+dir_is_empty(const char *dir, apr_pool_t *pool);
+
 
 svn_error_t *
 svn_io_dir_remove_nonrecursive(const char *dirname, apr_pool_t *pool)
@@ -3129,10 +3155,22 @@ svn_io_dir_remove_nonrecursive(const cha
   status = apr_dir_remove(dirname_apr, pool);
 
 #ifdef WIN32
-  if (APR_TO_OS_ERROR(status) != ERROR_DIR_NOT_EMPTY)
-    {
-      WIN32_RETRY_LOOP(status, apr_dir_remove(dirname_apr, pool));
-    }
+  {
+    svn_boolean_t retry = TRUE;
+
+    if (APR_TO_OS_ERROR(status) == ERROR_DIR_NOT_EMPTY)
+      {
+        apr_status_t empty_status = dir_is_empty(dirname_apr, pool);
+
+        if (APR_STATUS_IS_ENOTEMPTY(empty_status))
+          retry = FALSE;
+      }
+    
+    if (retry)
+      {
+        WIN32_RETRY_LOOP(status, apr_dir_remove(dirname_apr, pool));
+      }
+  }
 #endif
   if (status)
     return svn_error_wrap_apr(status, _("Can't remove directory '%s'"),
@@ -3170,11 +3208,11 @@ svn_io_dir_read(apr_finfo_t *finfo,
 
 
 svn_error_t *
-svn_io_dir_walk(const char *dirname,
-                apr_int32_t wanted,
-                svn_io_walk_func_t walk_func,
-                void *walk_baton,
-                apr_pool_t *pool)
+svn_io_dir_walk2(const char *dirname,
+                 apr_int32_t wanted,
+                 svn_io_walk_func_t walk_func,
+                 void *walk_baton,
+                 apr_pool_t *pool)
 {
   apr_status_t apr_err;
   apr_dir_t *handle;
@@ -3243,11 +3281,11 @@ svn_io_dir_walk(const char *dirname,
           SVN_ERR(entry_name_to_utf8(&name_utf8, finfo.name, dirname,
                                      subpool));
           full_path = svn_dirent_join(dirname, name_utf8, subpool);
-          SVN_ERR(svn_io_dir_walk(full_path,
-                                  wanted,
-                                  walk_func,
-                                  walk_baton,
-                                  subpool));
+          SVN_ERR(svn_io_dir_walk2(full_path,
+                                   wanted,
+                                   walk_func,
+                                   walk_baton,
+                                   subpool));
         }
       else if (finfo.filetype == APR_REG || finfo.filetype == APR_LNK)
         {
@@ -3261,9 +3299,10 @@ svn_io_dir_walk(const char *dirname,
                                subpool));
         }
       /* else:
-         some other type of file; skip it.
+         Some other type of file; skip it for now.  We've reserved the
+         right to expand our coverage here in the future, though,
+         without revving this API.
       */
-
     }
 
   svn_pool_destroy(subpool);

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/mergeinfo.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/mergeinfo.c Wed Aug 11 16:43:22 2010
@@ -1344,6 +1344,69 @@ svn_mergeinfo_merge(svn_mergeinfo_t merg
 }
 
 svn_error_t *
+svn_mergeinfo_catalog_merge(svn_mergeinfo_catalog_t mergeinfo_cat,
+                            svn_mergeinfo_catalog_t changes_cat,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  int i = 0;
+  int j = 0;
+  apr_array_header_t *sorted_cat =
+    svn_sort__hash(mergeinfo_cat, svn_sort_compare_items_as_paths,
+                   scratch_pool);
+  apr_array_header_t *sorted_changes =
+    svn_sort__hash(changes_cat, svn_sort_compare_items_as_paths,
+                   scratch_pool);
+
+  while (i < sorted_cat->nelts && j < sorted_changes->nelts)
+    {
+      svn_sort__item_t cat_elt, change_elt;
+      int res;
+
+      cat_elt = APR_ARRAY_IDX(sorted_cat, i, svn_sort__item_t);
+      change_elt = APR_ARRAY_IDX(sorted_changes, j, svn_sort__item_t);
+      res = svn_sort_compare_items_as_paths(&cat_elt, &change_elt);
+
+      if (res == 0) /* Both catalogs have mergeinfo for a give path. */
+        {
+          svn_mergeinfo_t mergeinfo = cat_elt.value;
+          svn_mergeinfo_t changes_mergeinfo = change_elt.value;
+
+          SVN_ERR(svn_mergeinfo_merge(mergeinfo, changes_mergeinfo,
+                                      result_pool));
+          apr_hash_set(mergeinfo_cat, cat_elt.key, cat_elt.klen, mergeinfo);
+          i++;
+          j++;
+        }
+      else if (res < 0) /* Only MERGEINFO_CAT has mergeinfo for this path. */
+        {
+          i++;
+        }
+      else /* Only CHANGES_CAT has mergeinfo for this path. */
+        {
+          apr_hash_set(mergeinfo_cat,
+                       apr_pstrdup(result_pool, change_elt.key),
+                       change_elt.klen,
+                       svn_mergeinfo_dup(change_elt.value, result_pool));
+          j++;
+        }
+    }
+
+  /* Copy back any remaining elements from the CHANGES_CAT catalog. */
+  for (; j < sorted_changes->nelts; j++)
+    {
+      svn_sort__item_t elt = APR_ARRAY_IDX(sorted_changes, j,
+                                           svn_sort__item_t);
+      apr_hash_set(mergeinfo_cat,
+                   apr_pstrdup(result_pool, elt.key),
+                   elt.klen,
+                   svn_mergeinfo_dup(elt.value, result_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_mergeinfo_intersect(svn_mergeinfo_t *mergeinfo,
                         svn_mergeinfo_t mergeinfo1,
                         svn_mergeinfo_t mergeinfo2,
@@ -2027,6 +2090,58 @@ svn_mergeinfo__filter_mergeinfo_by_range
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_mergeinfo__adjust_mergeinfo_rangelists(svn_mergeinfo_t *adjusted_mergeinfo,
+                                           svn_mergeinfo_t mergeinfo,
+                                           svn_revnum_t offset,
+                                           apr_pool_t *result_pool,
+                                           apr_pool_t *scratch_pool)
+{
+  apr_hash_index_t *hi;
+  *adjusted_mergeinfo = apr_hash_make(result_pool);
+
+  if (mergeinfo)
+    {
+      for (hi = apr_hash_first(scratch_pool, mergeinfo);
+           hi;
+           hi = apr_hash_next(hi))
+        {
+          int i;
+          const char *path = svn__apr_hash_index_key(hi);
+          apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
+          apr_array_header_t *adjusted_rangelist =
+            apr_array_make(result_pool, rangelist->nelts,
+                           sizeof(svn_merge_range_t *));
+
+          for (i = 0; i < rangelist->nelts; i++)
+            {
+              svn_merge_range_t *range =
+                APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
+
+              if (range->start + offset > 0 && range->end + offset > 0)
+                {                  
+                  if (range->start + offset < 0)
+                    range->start = 0;
+                  else
+                    range->start = range->start + offset;
+
+                  if (range->end + offset < 0)
+                    range->end = 0;
+                  else
+                    range->end = range->end + offset;
+                  APR_ARRAY_PUSH(adjusted_rangelist, svn_merge_range_t *) =
+                    range;
+                }
+            }
+
+          if (adjusted_rangelist->nelts)
+            apr_hash_set(*adjusted_mergeinfo, apr_pstrdup(result_pool, path),
+                         APR_HASH_KEY_STRING, adjusted_rangelist);
+        }
+    }
+  return SVN_NO_ERROR;
+}
+
 svn_boolean_t
 svn_mergeinfo__is_noninheritable(svn_mergeinfo_t mergeinfo,
                                  apr_pool_t *scratch_pool)

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/opt.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/opt.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/opt.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/opt.c Wed Aug 11 16:43:22 2010
@@ -941,12 +941,6 @@ svn_opt__arg_canonicalize_url(const char
   /* Auto-escape some ASCII characters. */
   target = svn_path_uri_autoescape(target, pool);
 
-  /* The above doesn't guarantee a valid URI. */
-  if (! svn_path_is_uri_safe(target))
-    return svn_error_createf(SVN_ERR_BAD_URL, 0,
-                             _("URL '%s' is not properly URI-encoded"),
-                             target);
-
   /* Verify that no backpaths are present in the URL. */
   if (svn_path_is_backpath_present(target))
     return svn_error_createf(SVN_ERR_BAD_URL, 0,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/sqlite.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/sqlite.c Wed Aug 11 16:43:22 2010
@@ -81,10 +81,12 @@ struct svn_sqlite__stmt_t
 };
 
 
-/* Convert SQLite error codes to SVN */
-#define SQLITE_ERROR_CODE(x) ((x) == SQLITE_READONLY    \
-                              ? SVN_ERR_SQLITE_READONLY \
-                              : SVN_ERR_SQLITE_ERROR )
+/* Convert SQLite error codes to SVN. Evaluates X multiple times */
+#define SQLITE_ERROR_CODE(x) ((x) == SQLITE_READONLY       \
+                              ? SVN_ERR_SQLITE_READONLY    \
+                              : ((x) == SQLITE_BUSY        \
+                                 ? SVN_ERR_SQLITE_BUSY     \
+                                 : SVN_ERR_SQLITE_ERROR) )
 
 
 /* SQLITE->SVN quick error wrap, much like SVN_ERR. */
@@ -174,10 +176,11 @@ step_with_expectation(svn_sqlite__stmt_t
   if ((got_row && !expecting_row)
       ||
       (!got_row && expecting_row))
-    return svn_error_create(SVN_ERR_SQLITE_ERROR, NULL,
+    return svn_error_create(SVN_ERR_SQLITE_ERROR,
+                            svn_sqlite__reset(stmt),
                             expecting_row
-                            ? _("Expected database row missing")
-                            : _("Extra database row found"));
+                              ? _("Expected database row missing")
+                              : _("Extra database row found"));
 
   return SVN_NO_ERROR;
 }
@@ -965,8 +968,50 @@ svn_sqlite__with_transaction(svn_sqlite_
   /* Commit or rollback the sqlite transaction. */
   if (err)
     {
-      svn_error_clear(exec_sql(db, "ROLLBACK TRANSACTION;"));
-      return svn_error_return(err);
+      svn_error_t *err2 = exec_sql(db, "ROLLBACK TRANSACTION;");
+
+      if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY)
+        {
+          int i;
+          /* ### Houston, we have a problem!
+
+             We are trying to rollback but we can't because some
+             statements are still busy. This leaves the database
+             unusable for future transactions as the current transaction
+             is still open.
+
+             As we are returning the actual error as the most relevant
+             error in the chain, our caller might assume that it can
+             retry/compensate on this error (e.g. SVN_WC_LOCKED), while
+             in fact the SQLite database is unusable until the statements
+             started within this transaction are reset and the transaction
+             aborted.
+
+             We try to compensate by resetting al prepared but unreset
+             statements; but we leave the busy error in the chain anyway to
+             help diagnosing the original error and help in finding where
+             a reset statement is missing. */
+
+          /* ### Should we reorder the errors in this specific case
+             ### to avoid returning the normal error as top level error? */
+
+          err2 = svn_error_compose_create(err2,
+                   svn_error_create(SVN_ERR_SQLITE_RESETTING_FOR_ROLLBACK,
+                                    NULL, NULL));
+
+          for (i = 0; i < db->nbr_statements; i++)
+            if (db->prepared_stmts[i] && db->prepared_stmts[i]->needs_reset)
+              err2 = svn_error_compose_create(
+                         err2,
+                         svn_sqlite__reset(db->prepared_stmts[i]));
+
+          err2 = svn_error_compose_create(
+                      exec_sql(db, "ROLLBACK TRANSACTION;"),
+                      err2);
+        }
+
+      return svn_error_compose_create(err,
+                                      err2);
     }
 
   return svn_error_return(exec_sql(db, "COMMIT TRANSACTION;"));

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/stream.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/stream.c Wed Aug 11 16:43:22 2010
@@ -50,11 +50,8 @@ struct svn_stream_t {
   svn_read_fn_t read_fn;
   svn_write_fn_t write_fn;
   svn_close_fn_t close_fn;
-  svn_io_reset_fn_t reset_fn;
   svn_io_mark_fn_t mark_fn;
   svn_io_seek_fn_t seek_fn;
-  svn_io_line_filter_cb_t line_filter_cb;
-  svn_io_line_transformer_cb_t line_transformer_cb;
 };
 
 
@@ -70,11 +67,8 @@ svn_stream_create(void *baton, apr_pool_
   stream->read_fn = NULL;
   stream->write_fn = NULL;
   stream->close_fn = NULL;
-  stream->reset_fn = NULL;
   stream->mark_fn = NULL;
   stream->seek_fn = NULL;
-  stream->line_filter_cb = NULL;
-  stream->line_transformer_cb = NULL;
   return stream;
 }
 
@@ -106,12 +100,6 @@ svn_stream_set_close(svn_stream_t *strea
 }
 
 void
-svn_stream_set_reset(svn_stream_t *stream, svn_io_reset_fn_t reset_fn)
-{
-  stream->reset_fn = reset_fn;
-}
-
-void
 svn_stream_set_mark(svn_stream_t *stream, svn_io_mark_fn_t mark_fn)
 {
   stream->mark_fn = mark_fn;
@@ -123,21 +111,6 @@ svn_stream_set_seek(svn_stream_t *stream
   stream->seek_fn = seek_fn;
 }
 
-void
-svn_stream_set_line_filter_callback(svn_stream_t *stream,
-                                    svn_io_line_filter_cb_t line_filter_cb)
-{
-  stream->line_filter_cb = line_filter_cb;
-}
-
-void
-svn_stream_set_line_transformer_callback(
-  svn_stream_t *stream,
-  svn_io_line_transformer_cb_t line_transformer_cb)
-{
-  stream->line_transformer_cb = line_transformer_cb;
-}
-
 svn_error_t *
 svn_stream_read(svn_stream_t *stream, char *buffer, apr_size_t *len)
 {
@@ -157,10 +130,8 @@ svn_stream_write(svn_stream_t *stream, c
 svn_error_t *
 svn_stream_reset(svn_stream_t *stream)
 {
-  if (stream->reset_fn == NULL)
-    return svn_error_create(SVN_ERR_STREAM_RESET_NOT_SUPPORTED, NULL, NULL);
-
-  return stream->reset_fn(stream->baton);
+  return svn_error_return(
+            svn_stream_seek(stream, NULL));
 }
 
 svn_error_t *
@@ -233,45 +204,6 @@ svn_stream_printf_from_utf8(svn_stream_t
   return svn_stream_write(stream, translated, &len);
 }
 
-/* If a line filter callback was set on STREAM, invoke it on LINE,
- * and indicate in *FILTERED whether the line should be filtered.
- * If no line filter callback was set on STREAM, just set *FILTERED to FALSE.
- */
-static svn_error_t *
-line_filter(svn_stream_t *stream, svn_boolean_t *filtered, const char *line,
-            apr_pool_t *pool)
-{
-  apr_pool_t *scratch_pool;
-
-  if (! stream->line_filter_cb)
-    {
-      *filtered = FALSE;
-      return SVN_NO_ERROR;
-    }
-
-  scratch_pool = svn_pool_create(pool);
-  SVN_ERR(stream->line_filter_cb(filtered, line, stream->baton, scratch_pool));
-  svn_pool_destroy(scratch_pool);
-  return SVN_NO_ERROR;
-}
-
-/* Run the line transformer callback of STREAM with LINE as input,
- * and expect the transformation result to be returned in BUF,
- * allocated in POOL. */
-static svn_error_t *
-line_transformer(svn_stream_t *stream, svn_stringbuf_t **buf,
-                 const char *line, apr_pool_t *pool, apr_pool_t *scratch_pool)
-{
-  *buf = NULL;  /* so we can assert that the callback has set it non-null */
-  SVN_ERR(stream->line_transformer_cb(buf, line, stream->baton,
-                                      pool, scratch_pool));
-
-  /* Die if the line transformer didn't provide any output. */
-  SVN_ERR_ASSERT(*buf);
-
-  return SVN_NO_ERROR;
-}
-
 /* Scan STREAM for an end-of-line indicatior, and return it in *EOL.
  * Set *EOL to NULL if the stream runs out before an end-of-line indicator
  * is found. */
@@ -318,84 +250,58 @@ stream_readline(svn_stringbuf_t **string
                 apr_pool_t *pool)
 {
   svn_stringbuf_t *str;
-  apr_pool_t *iterpool;
-  svn_boolean_t filtered;
   const char *eol_str;
+  apr_size_t numbytes;
+  const char *match;
+  char c;
+
+  /* Since we're reading one character at a time, let's at least
+     optimize for the 90% case.  90% of the time, we can avoid the
+     stringbuf ever having to realloc() itself if we start it out at
+     80 chars.  */
+  str = svn_stringbuf_create_ensure(80, pool);
 
-  *eof = FALSE;
-
-  iterpool = svn_pool_create(pool);
-  do
+  if (detect_eol)
     {
-      apr_size_t numbytes;
-      const char *match;
-      char c;
-
-      svn_pool_clear(iterpool);
-
-      /* Since we're reading one character at a time, let's at least
-         optimize for the 90% case.  90% of the time, we can avoid the
-         stringbuf ever having to realloc() itself if we start it out at
-         80 chars.  */
-      str = svn_stringbuf_create_ensure(80, iterpool);
-
-      if (detect_eol)
+      SVN_ERR(scan_eol(&eol_str, stream, pool));
+      if (eol)
+        *eol = eol_str;
+      if (! eol_str)
         {
-          SVN_ERR(scan_eol(&eol_str, stream, iterpool));
-          if (eol)
-            *eol = eol_str;
-          if (! eol_str)
-            {
-              /* No newline until EOF, EOL_STR can be anything. */
-              eol_str = APR_EOL_STR;
-            }
+          /* No newline until EOF, EOL_STR can be anything. */
+          eol_str = APR_EOL_STR;
         }
-      else
-        eol_str = *eol;
+    }
+  else
+    eol_str = *eol;
 
-      /* Read into STR up to and including the next EOL sequence. */
-      match = eol_str;
+  /* Read into STR up to and including the next EOL sequence. */
+  match = eol_str;
+  while (*match)
+    {
       numbytes = 1;
-      while (*match)
+      SVN_ERR(svn_stream_read(stream, &c, &numbytes));
+      if (numbytes != 1)
         {
-          SVN_ERR(svn_stream_read(stream, &c, &numbytes));
-          if (numbytes != 1)
-            {
-              /* a 'short' read means the stream has run out. */
-              *eof = TRUE;
-              /* We know we don't have a whole EOL sequence, but ensure we
-               * don't chop off any partial EOL sequence that we may have. */
-              match = eol_str;
-              /* Process this short (or empty) line just like any other
-               * except with *EOF set. */
-              break;
-            }
-
-          if (c == *match)
-            match++;
-          else
-            match = eol_str;
-
-          svn_stringbuf_appendbytes(str, &c, 1);
+          /* a 'short' read means the stream has run out. */
+          *eof = TRUE;
+          if (detect_eol && eol)
+            *eol = NULL;
+          *stringbuf = str;
+          return SVN_NO_ERROR;
         }
 
-      svn_stringbuf_chop(str, match - eol_str);
+      if (c == *match)
+        match++;
+      else
+        match = eol_str;
 
-      SVN_ERR(line_filter(stream, &filtered, str->data, iterpool));
+      svn_stringbuf_appendbytes(str, &c, 1);
     }
-  while (filtered && ! *eof);
-  /* Not destroying the iterpool just yet since we still need STR
-   * which is allocated in it. */
-
-  if (filtered)
-    *stringbuf = svn_stringbuf_create_ensure(0, pool);
-  else if (stream->line_transformer_cb)
-    SVN_ERR(line_transformer(stream, stringbuf, str->data, pool, iterpool));
-  else
-    *stringbuf = svn_stringbuf_dup(str, pool);
 
-  /* Done. RIP iterpool. */
-  svn_pool_destroy(iterpool);
+  *eof = FALSE;
+  svn_stringbuf_chop(str, match - eol_str);
+  *stringbuf = str;
 
   return SVN_NO_ERROR;
 }
@@ -519,14 +425,9 @@ write_handler_empty(void *baton, const c
 }
 
 static svn_error_t *
-reset_handler_empty(void *baton)
-{
-  return SVN_NO_ERROR;
-}
-
-static svn_error_t *
 mark_handler_empty(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
 {
+  *mark = NULL; /* Seek to start of stream marker */
   return SVN_NO_ERROR;
 }
 
@@ -545,7 +446,6 @@ svn_stream_empty(apr_pool_t *pool)
   stream = svn_stream_create(NULL, pool);
   svn_stream_set_read(stream, read_handler_empty);
   svn_stream_set_write(stream, write_handler_empty);
-  svn_stream_set_reset(stream, reset_handler_empty);
   svn_stream_set_mark(stream, mark_handler_empty);
   svn_stream_set_seek(stream, seek_handler_empty);
   return stream;
@@ -625,12 +525,6 @@ write_handler_disown(void *baton, const 
 }
 
 static svn_error_t *
-reset_handler_disown(void *baton)
-{
-  return svn_stream_reset(baton);
-}
-
-static svn_error_t *
 mark_handler_disown(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
 {
   return svn_stream_mark(baton, mark, pool);
@@ -649,7 +543,6 @@ svn_stream_disown(svn_stream_t *stream, 
 
   svn_stream_set_read(s, read_handler_disown);
   svn_stream_set_write(s, write_handler_disown);
-  svn_stream_set_reset(s, reset_handler_disown);
   svn_stream_set_mark(s, mark_handler_disown);
   svn_stream_set_seek(s, seek_handler_disown);
 
@@ -707,19 +600,6 @@ close_handler_apr(void *baton)
 }
 
 static svn_error_t *
-reset_handler_apr(void *baton)
-{
-  apr_off_t offset;
-  struct baton_apr *btn = baton;
-
-  /* If we're reading from a range, reset to the start of the range.
-   * Otherwise, reset to the start of the file. */
-  offset = btn->start >= 0 ? btn->start : 0;
-
-  return svn_io_file_seek(btn->file, APR_SET, &offset, btn->pool);
-}
-
-static svn_error_t *
 mark_handler_apr(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
 {
   struct baton_apr *btn = baton;
@@ -736,10 +616,25 @@ static svn_error_t *
 seek_handler_apr(void *baton, svn_stream_mark_t *mark)
 {
   struct baton_apr *btn = baton;
-  struct mark_apr *mark_apr;
 
-  mark_apr = (struct mark_apr *)mark;
-  SVN_ERR(svn_io_file_seek(btn->file, APR_SET, &mark_apr->off, btn->pool));
+  if (mark != NULL)
+    {
+      struct mark_apr *mark_apr;
+
+      mark_apr = (struct mark_apr *)mark;
+      SVN_ERR(svn_io_file_seek(btn->file, APR_SET, &mark_apr->off, btn->pool));
+    }
+  else
+    {
+      apr_off_t offset;
+
+      /* If we're reading from a range, reset to the start of the range.
+       * Otherwise, reset to the start of the file. */
+      offset = btn->start >= 0 ? btn->start : 0;
+
+      SVN_ERR(svn_io_file_seek(btn->file, APR_SET, &offset, btn->pool));
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -817,7 +712,6 @@ svn_stream_from_aprfile2(apr_file_t *fil
   stream = svn_stream_create(baton, pool);
   svn_stream_set_read(stream, read_handler_apr);
   svn_stream_set_write(stream, write_handler_apr);
-  svn_stream_set_reset(stream, reset_handler_apr);
   svn_stream_set_mark(stream, mark_handler_apr);
   svn_stream_set_seek(stream, seek_handler_apr);
 
@@ -895,7 +789,6 @@ svn_stream_from_aprfile_range_readonly(a
   baton->end = end;
   stream = svn_stream_create(baton, pool);
   svn_stream_set_read(stream, read_range_handler_apr);
-  svn_stream_set_reset(stream, reset_handler_apr);
   svn_stream_set_mark(stream, mark_handler_apr);
   svn_stream_set_seek(stream, seek_handler_apr);
 
@@ -1424,20 +1317,13 @@ write_handler_stringbuf(void *baton, con
 }
 
 static svn_error_t *
-reset_handler_stringbuf(void *baton)
-{
-  struct stringbuf_stream_baton *btn = baton;
-  btn->amt_read = 0;
-  return SVN_NO_ERROR;
-}
-
-static svn_error_t *
 mark_handler_stringbuf(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
 {
   struct stringbuf_stream_baton *btn;
   struct stringbuf_stream_mark *stringbuf_stream_mark;
 
   btn = baton;
+
   stringbuf_stream_mark = apr_palloc(pool, sizeof(*stringbuf_stream_mark));
   stringbuf_stream_mark->pos = btn->amt_read;
   *mark = (svn_stream_mark_t *)stringbuf_stream_mark;
@@ -1447,12 +1333,18 @@ mark_handler_stringbuf(void *baton, svn_
 static svn_error_t *
 seek_handler_stringbuf(void *baton, svn_stream_mark_t *mark)
 {
-  struct stringbuf_stream_baton *btn;
-  struct stringbuf_stream_mark *stringbuf_stream_mark;
+  struct stringbuf_stream_baton *btn = baton;
+
+  if (mark != NULL)
+    {
+      struct stringbuf_stream_mark *stringbuf_stream_mark;
+
+      stringbuf_stream_mark = (struct stringbuf_stream_mark *)mark;
+      btn->amt_read = stringbuf_stream_mark->pos;
+    }
+  else
+    btn->amt_read = 0;
 
-  btn = baton;
-  stringbuf_stream_mark = (struct stringbuf_stream_mark *)mark;
-  btn->amt_read = stringbuf_stream_mark->pos;
   return SVN_NO_ERROR;
 }
 
@@ -1472,7 +1364,6 @@ svn_stream_from_stringbuf(svn_stringbuf_
   stream = svn_stream_create(baton, pool);
   svn_stream_set_read(stream, read_handler_stringbuf);
   svn_stream_set_write(stream, write_handler_stringbuf);
-  svn_stream_set_reset(stream, reset_handler_stringbuf);
   svn_stream_set_mark(stream, mark_handler_stringbuf);
   svn_stream_set_seek(stream, seek_handler_stringbuf);
   return stream;
@@ -1484,6 +1375,11 @@ struct string_stream_baton
   apr_size_t amt_read;
 };
 
+/* svn_stream_mark_t for streams backed by stringbufs. */
+struct string_stream_mark {
+    apr_size_t pos; 
+};
+
 static svn_error_t *
 read_handler_string(void *baton, char *buffer, apr_size_t *len)
 {
@@ -1496,6 +1392,38 @@ read_handler_string(void *baton, char *b
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+mark_handler_string(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
+{
+  struct string_stream_baton *btn;
+  struct string_stream_mark *marker;
+
+  btn = baton;
+
+  marker = apr_palloc(pool, sizeof(*marker));
+  marker->pos = btn->amt_read;
+  *mark = (svn_stream_mark_t *)marker;
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+seek_handler_string(void *baton, svn_stream_mark_t *mark)
+{
+  struct string_stream_baton *btn = baton;
+
+  if (mark != NULL)
+    {
+      struct string_stream_mark *marker;
+
+      marker = (struct string_stream_mark *)mark;
+      btn->amt_read = marker->pos;
+    }
+  else
+    btn->amt_read = 0;
+
+  return SVN_NO_ERROR;
+}
+
 svn_stream_t *
 svn_stream_from_string(const svn_string_t *str,
                        apr_pool_t *pool)
@@ -1511,6 +1439,8 @@ svn_stream_from_string(const svn_string_
   baton->amt_read = 0;
   stream = svn_stream_create(baton, pool);
   svn_stream_set_read(stream, read_handler_string);
+  svn_stream_set_mark(stream, mark_handler_string);
+  svn_stream_set_seek(stream, seek_handler_string);
   return stream;
 }
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/subst.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/subst.c Wed Aug 11 16:43:22 2010
@@ -1136,30 +1136,6 @@ translated_stream_close(void *baton)
   return SVN_NO_ERROR;
 }
 
-/* Implements svn_io_reset_fn_t. */
-static svn_error_t *
-translated_stream_reset(void *baton)
-{
-  struct translated_stream_baton *b = baton;
-  svn_error_t *err;
-
-  err = svn_stream_reset(b->stream);
-  if (err == NULL)
-    {
-      b->in_baton->newline_off = 0;
-      b->in_baton->keyword_off = 0;
-      b->in_baton->src_format_len = 0;
-      b->out_baton->newline_off = 0;
-      b->out_baton->keyword_off = 0;
-      b->out_baton->src_format_len = 0;
-
-      b->written = FALSE;
-      svn_stringbuf_setempty(b->readbuf);
-      b->readbuf_off = 0;
-    }
-
-  return svn_error_return(err);
-}
 
 /* svn_stream_mark_t for translation streams. */
 typedef struct
@@ -1201,23 +1177,43 @@ static svn_error_t *
 translated_stream_seek(void *baton, svn_stream_mark_t *mark)
 {
   struct translated_stream_baton *b = baton;
-  mark_translated_t *mt = (mark_translated_t *)mark;
 
-  /* Flush output buffer if necessary. */
-  if (b->written)
-    SVN_ERR(translate_chunk(b->stream, b->out_baton, NULL, 0, b->iterpool));
-
-  SVN_ERR(svn_stream_seek(b->stream, mt->mark));
-
-  /* Restore translation state, avoiding new allocations. */
-  *b->in_baton = *mt->saved_baton.in_baton;
-  *b->out_baton = *mt->saved_baton.out_baton;
-  b->written = mt->saved_baton.written;
-  svn_stringbuf_setempty(b->readbuf);
-  svn_stringbuf_appendbytes(b->readbuf, mt->saved_baton.readbuf->data, 
-                            mt->saved_baton.readbuf->len);
-  b->readbuf_off = mt->saved_baton.readbuf_off;
-  memcpy(b->buf, mt->saved_baton.buf, SVN__TRANSLATION_BUF_SIZE);
+  if (mark != NULL)
+    {
+      mark_translated_t *mt = (mark_translated_t *)mark;
+
+      /* Flush output buffer if necessary. */
+      if (b->written)
+        SVN_ERR(translate_chunk(b->stream, b->out_baton, NULL, 0,
+                                b->iterpool));
+
+      SVN_ERR(svn_stream_seek(b->stream, mt->mark));
+    
+      /* Restore translation state, avoiding new allocations. */
+      *b->in_baton = *mt->saved_baton.in_baton;
+      *b->out_baton = *mt->saved_baton.out_baton;
+      b->written = mt->saved_baton.written;
+      svn_stringbuf_setempty(b->readbuf);
+      svn_stringbuf_appendbytes(b->readbuf, mt->saved_baton.readbuf->data, 
+                                mt->saved_baton.readbuf->len);
+      b->readbuf_off = mt->saved_baton.readbuf_off;
+      memcpy(b->buf, mt->saved_baton.buf, SVN__TRANSLATION_BUF_SIZE);
+    }
+  else
+    {
+      SVN_ERR(svn_stream_reset(b->stream));
+
+      b->in_baton->newline_off = 0;
+      b->in_baton->keyword_off = 0;
+      b->in_baton->src_format_len = 0;
+      b->out_baton->newline_off = 0;
+      b->out_baton->keyword_off = 0;
+      b->out_baton->src_format_len = 0;
+
+      b->written = FALSE;
+      svn_stringbuf_setempty(b->readbuf);
+      b->readbuf_off = 0;
+    }
 
   return SVN_NO_ERROR;
 }
@@ -1321,7 +1317,6 @@ svn_subst_stream_translated(svn_stream_t
   svn_stream_set_read(s, translated_stream_read);
   svn_stream_set_write(s, translated_stream_write);
   svn_stream_set_close(s, translated_stream_close);
-  svn_stream_set_reset(s, translated_stream_reset);
   svn_stream_set_mark(s, translated_stream_mark);
   svn_stream_set_seek(s, translated_stream_seek);
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_crawler.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_crawler.c Wed Aug 11 16:43:22 2010
@@ -60,12 +60,16 @@
    last-commit-time.  Either way, set entry-timestamp to match that of
    the working file when all is finished.
 
+   If REMOVE_TEXT_CONFLICT is TRUE, remove an existing text conflict
+   from LOCAL_ABSPATH.
+
    Not that a valid access baton with a write lock to the directory of
    LOCAL_ABSPATH must be available in DB.*/
 static svn_error_t *
 restore_file(svn_wc__db_t *db,
              const char *local_abspath,
              svn_boolean_t use_commit_times,
+             svn_boolean_t remove_text_conflicts,
              apr_pool_t *scratch_pool)
 {
   svn_skel_t *work_item;
@@ -87,8 +91,79 @@ restore_file(svn_wc__db_t *db,
                          scratch_pool));
 
   /* Remove any text conflict */
-  return svn_error_return(svn_wc__resolve_text_conflict(db, local_abspath,
+  if (remove_text_conflicts)
+    SVN_ERR(svn_wc__resolve_text_conflict(db, local_abspath, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc_restore(svn_wc_context_t *wc_ctx,
+               const char *local_abspath,
+               svn_boolean_t use_commit_times,
+               apr_pool_t *scratch_pool)
+{
+  svn_wc__db_status_t status;
+  svn_wc__db_kind_t kind;
+  svn_node_kind_t disk_kind;
+
+  SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
+
+  if (disk_kind != svn_node_none)
+    return svn_error_createf(SVN_ERR_WC_PATH_FOUND, NULL,
+                             _("The existing node '%s' can not be restored."),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+
+
+  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL,
+                               wc_ctx->db, local_abspath,
+                               scratch_pool, scratch_pool));
+
+  switch (status)
+    {
+      case svn_wc__db_status_added:
+        SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, NULL,
+                                         NULL, NULL, NULL,
+                                         wc_ctx->db, local_abspath,
+                                         scratch_pool, scratch_pool));
+        if (status != svn_wc__db_status_added)
+          break; /* Has pristine version */
+      case svn_wc__db_status_deleted:
+      case svn_wc__db_status_not_present:
+      case svn_wc__db_status_absent:
+      case svn_wc__db_status_excluded:
+#ifndef SVN_WC__SINGLE_DB
+      case svn_wc__db_status_obstructed:
+      case svn_wc__db_status_obstructed_add:
+      case svn_wc__db_status_obstructed_delete:
+#endif
+        return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                                 _("The node '%s' can not be restored."),
+                                 svn_dirent_local_style(local_abspath,
                                                         scratch_pool));
+      default:
+        break;
+    }
+
+  if (kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_symlink)
+    SVN_ERR(restore_file(wc_ctx->db, local_abspath, use_commit_times, FALSE,
+                         scratch_pool));
+  else
+#ifdef SVN_WC__SINGLE_DB
+    SVN_ERR(svn_io_dir_make(local_abspath, APR_OS_DEFAULT, scratch_pool));
+#else
+     return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                                 _("The node '%s' can not be restored."),
+                                 svn_dirent_local_style(local_abspath,
+                                                        scratch_pool));
+#endif
+
+  return SVN_NO_ERROR;
 }
 
 /* Try to restore LOCAL_ABSPATH of node type KIND and if successfull,
@@ -113,15 +188,25 @@ restore_node(svn_boolean_t *restored,
 {
   *restored = FALSE;
 
-  /* Currently we can only restore files, but we will be able to restore
-     directories after we move to a single database and pristine store. */
   if (kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_symlink)
     {
-      /* ... recreate file from text-base, and ... */
-      SVN_ERR(restore_file(db, local_abspath, use_commit_times,
+      /* Recreate file from text-base */
+      SVN_ERR(restore_file(db, local_abspath, use_commit_times, TRUE,
                            scratch_pool));
 
       *restored = TRUE;
+    }
+#ifdef SVN_WC__SINGLE_DB
+  else if (kind == svn_wc__db_kind_dir)
+    {
+      /* Recreating a directory is just a mkdir */
+      SVN_ERR(svn_io_dir_make(local_abspath, APR_OS_DEFAULT, scratch_pool));
+      *restored = TRUE;
+    }
+#endif
+
+  if (*restored)
+    {
       /* ... report the restoration to the caller.  */
       if (notify_func != NULL)
         {
@@ -233,6 +318,7 @@ report_revisions_and_depths(svn_wc__db_t
   int i;
   const char *dir_repos_root, *dir_repos_relpath;
   svn_depth_t dir_depth;
+  svn_error_t *err;
 
 
   /* Get both the SVN Entries and the actual on-disk entries.   Also
@@ -241,7 +327,18 @@ report_revisions_and_depths(svn_wc__db_t
   dir_abspath = svn_dirent_join(anchor_abspath, dir_path, scratch_pool);
   SVN_ERR(svn_wc__db_base_get_children(&base_children, db, dir_abspath,
                                        scratch_pool, iterpool));
-  SVN_ERR(svn_io_get_dir_filenames(&dirents, dir_abspath, scratch_pool));
+
+  err = svn_io_get_dirents3(&dirents, dir_abspath, TRUE,
+                            scratch_pool, scratch_pool);
+
+  if (err && (APR_STATUS_IS_ENOENT(err->apr_err)
+              || SVN__APR_STATUS_IS_ENOTDIR(err->apr_err)))
+    {
+      svn_error_clear(err);
+      dirents = apr_hash_make(scratch_pool);
+    }
+  else
+    SVN_ERR(err);
 
   /*** Do the real reporting and recursing. ***/
 
@@ -278,7 +375,6 @@ report_revisions_and_depths(svn_wc__db_t
       svn_depth_t this_depth;
       svn_wc__db_lock_t *this_lock;
       svn_boolean_t this_switched;
-      svn_error_t *err;
 
       /* Clear the iteration subpool here because the loop has a bunch
          of 'continue' jump statements. */
@@ -392,10 +488,25 @@ report_revisions_and_depths(svn_wc__db_t
                                        NULL, NULL,
                                        db, this_abspath, iterpool, iterpool));
 
-          if (restore_files && wrk_status != svn_wc__db_status_added
+          if (wrk_status == svn_wc__db_status_added)
+            SVN_ERR(svn_wc__db_scan_addition(&wrk_status, NULL, NULL, NULL,
+                                             NULL, NULL, NULL, NULL, NULL,
+                                             db, this_abspath,
+                                             iterpool, iterpool));
+
+#ifndef SVN_WC__SINGLE_DB
+          if (wrk_status == svn_wc__db_status_obstructed
+              || wrk_status == svn_wc__db_status_obstructed_add
+              || wrk_status == svn_wc__db_status_obstructed_delete)
+            missing = TRUE;
+          else
+#endif
+          if (restore_files
+              && wrk_status != svn_wc__db_status_added
               && wrk_status != svn_wc__db_status_deleted
-              && wrk_status != svn_wc__db_status_obstructed_add
-              && wrk_status != svn_wc__db_status_obstructed_delete)
+              && wrk_status != svn_wc__db_status_excluded
+              && wrk_status != svn_wc__db_status_not_present
+              && wrk_status != svn_wc__db_status_absent)
             {
               svn_node_kind_t dirent_kind;
 
@@ -416,9 +527,7 @@ report_revisions_and_depths(svn_wc__db_t
                     missing = TRUE;
                 }
             }
-          else
-            missing = TRUE;
-
+#ifndef SVN_WC__SINGLE_DB
           /* If a node is still missing from disk here, we have no way to
              recreate it locally, so report as missing and move along.
              Again, don't bother if we're reporting everything, because the
@@ -431,6 +540,11 @@ report_revisions_and_depths(svn_wc__db_t
                                               iterpool));
               continue;
             }
+#else
+          /* With single-db, we always know about all children, so
+             never tell the server that we don't know, but want to know
+             about the missing child. */
+#endif
         }
 
       /* And finally prepare for reporting */
@@ -724,6 +838,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
   const char *repos_relpath=NULL, *repos_root=NULL;
   svn_depth_t target_depth = svn_depth_unknown;
   svn_wc__db_lock_t *target_lock = NULL;
+  svn_node_kind_t disk_kind;
   svn_boolean_t explicit_rev;
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
@@ -851,45 +966,69 @@ svn_wc_crawl_revisions5(svn_wc_context_t
   if (target_depth == svn_depth_unknown)
     target_depth = svn_depth_infinity;
 
-  /* The first call to the reporter merely informs it that the
-     top-level directory being updated is at BASE_REV.  Its PATH
-     argument is ignored. */
-  SVN_ERR(reporter->set_path(report_baton, "", target_rev, target_depth,
-                             start_empty, NULL, scratch_pool));
+  SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
 
-  /* ### status can NEVER be deleted. should examine why this was
-     ### ever here. we may have remapped into wc-ng incorrectly.  */
-  if (status != svn_wc__db_status_deleted)
+  /* Determine if there is a missing node that should be restored */
+  if (disk_kind == svn_node_none)
     {
-      apr_finfo_t info;
-      err = svn_io_stat(&info, local_abspath, APR_FINFO_MIN, scratch_pool);
-      if (err)
+      svn_wc__db_status_t wrk_status;
+      err = svn_wc__db_read_info(&wrk_status, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL,
+                                 db, local_abspath,
+                                 scratch_pool, scratch_pool);
+
+
+      if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
         {
-          if (APR_STATUS_IS_ENOENT(err->apr_err))
-            missing = TRUE;
           svn_error_clear(err);
-          err = NULL;
+          wrk_status = svn_wc__db_status_not_present;
         }
-    }
+      else
+        SVN_ERR(err);
 
-  if (missing && restore_files)
-    {
-      svn_boolean_t restored;
+      if (wrk_status == svn_wc__db_status_added)
+        SVN_ERR(svn_wc__db_scan_addition(&wrk_status, NULL, NULL, NULL, NULL,
+                                         NULL, NULL, NULL, NULL,
+                                         db, local_abspath,
+                                         scratch_pool, scratch_pool));
 
-      err = restore_node(&restored, wc_ctx->db, local_abspath,
-                         target_kind, use_commit_times,
-                         notify_func, notify_baton,
-                         scratch_pool);
+#ifndef SVN_WC__SINGLE_DB
+      if (wrk_status == svn_wc__db_status_obstructed
+          || wrk_status == svn_wc__db_status_obstructed_add
+          || wrk_status == svn_wc__db_status_obstructed_delete)
+        missing = TRUE;
+      else
+#endif
+      if (restore_files
+          && wrk_status != svn_wc__db_status_added
+          && wrk_status != svn_wc__db_status_deleted
+          && wrk_status != svn_wc__db_status_excluded
+          && wrk_status != svn_wc__db_status_not_present
+          && wrk_status != svn_wc__db_status_absent)
+        {
+          svn_boolean_t restored;
 
-      if (err)
-          goto abort_report;
+          SVN_ERR(restore_node(&restored, wc_ctx->db, local_abspath,
+                               target_kind, use_commit_times,
+                               notify_func, notify_baton,
+                               scratch_pool));
 
-      if (restored)
-        missing = FALSE;
+          if (!restored)
+            missing = TRUE;
+        }
     }
 
+  /* The first call to the reporter merely informs it that the
+     top-level directory being updated is at BASE_REV.  Its PATH
+     argument is ignored. */
+  SVN_ERR(reporter->set_path(report_baton, "", target_rev, target_depth,
+                             start_empty, NULL, scratch_pool));
+
   if (target_kind == svn_wc__db_kind_dir)
     {
+#ifndef SVN_WC__SINGLE_DB
       if (missing)
         {
           /* Report missing directories as deleted to retrieve them
@@ -898,7 +1037,9 @@ svn_wc_crawl_revisions5(svn_wc_context_t
           if (err)
             goto abort_report;
         }
-      else if (depth != svn_depth_empty)
+      else
+#endif
+      if (depth != svn_depth_empty)
         {
           /* Recursively crawl ROOT_DIRECTORY and report differing
              revisions. */
@@ -1100,21 +1241,20 @@ svn_wc__internal_transmit_text_deltas(co
 
   /* If the caller wants a copy of the working file translated to
    * repository-normal form, make the copy by tee-ing the stream and set
-   * *TEMPFILE to the path to it. */
+   * *TEMPFILE to the path to it.  This is only needed for the 1.6 API,
+   * 1.7 doesn't set TEMPFILE.  Even when using the 1.6 API this file
+   * is not used by the functions that would have used it when using
+   * the 1.6 code.  It's possible that 3rd party users (if there are any)
+   * might expect this file to be a text-base. */
   if (tempfile)
     {
       svn_stream_t *tempstream;
 
-      SVN_ERR(svn_wc__text_base_deterministic_tmp_path(tempfile,
-                                                       db, local_abspath,
-                                                       result_pool));
-
-      /* Make an untranslated copy of the working file in the
-         administrative tmp area because a) we need to detranslate eol
-         and keywords anyway, and b) after the commit, we're going to
-         copy the tmp file to become the new text base anyway. */
-      SVN_ERR(svn_stream_open_writable(&tempstream, *tempfile,
-                                       scratch_pool, scratch_pool));
+      /* It can't be the same location as in 1.6 because the admin directory
+         no longer exists. */
+      SVN_ERR(svn_stream_open_unique(&tempstream, tempfile,
+                                     NULL, svn_io_file_del_none,
+                                     result_pool, scratch_pool));
 
       /* Wrap the translated stream with a new stream that writes the
          translated contents into the new text base file as we read from it.
@@ -1300,12 +1440,10 @@ svn_wc__internal_transmit_text_deltas(co
                                                    result_pool);
   if (new_text_base_sha1_checksum)
     {
-#ifdef SVN_EXPERIMENTAL_PRISTINE
       SVN_ERR(svn_wc__db_pristine_install(db, new_pristine_tmp_abspath,
                                           local_sha1_checksum,
                                           local_md5_checksum,
                                           scratch_pool));
-#endif
       *new_text_base_sha1_checksum = svn_checksum_dup(local_sha1_checksum,
                                                       result_pool);
     }
@@ -1318,8 +1456,7 @@ svn_wc__internal_transmit_text_deltas(co
 }
 
 svn_error_t *
-svn_wc_transmit_text_deltas3(const char **tempfile,
-                             const svn_checksum_t **new_text_base_md5_checksum,
+svn_wc_transmit_text_deltas3(const svn_checksum_t **new_text_base_md5_checksum,
                              const svn_checksum_t **new_text_base_sha1_checksum,
                              svn_wc_context_t *wc_ctx,
                              const char *local_abspath,
@@ -1329,7 +1466,7 @@ svn_wc_transmit_text_deltas3(const char 
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool)
 {
-  return svn_wc__internal_transmit_text_deltas(tempfile,
+  return svn_wc__internal_transmit_text_deltas(NULL,
                                                new_text_base_md5_checksum,
                                                new_text_base_sha1_checksum,
                                                wc_ctx->db, local_abspath,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_files.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_files.c Wed Aug 11 16:43:22 2010
@@ -188,88 +188,6 @@ make_adm_subdir(const char *path,
 /*** Syncing files in the adm area. ***/
 
 
-#ifndef SVN_EXPERIMENTAL_PRISTINE
-svn_error_t *
-svn_wc__sync_text_base(svn_wc__db_t *db,
-                       const char *local_abspath,
-                       const char *tmp_text_base_abspath,
-                       apr_pool_t *scratch_pool)
-{
-  const char *base_path;
-
-  SVN_ERR(svn_wc__text_base_path(&base_path, db, local_abspath, scratch_pool));
-
-  SVN_ERR(svn_io_file_rename(tmp_text_base_abspath, base_path, scratch_pool));
-  SVN_ERR(svn_io_set_file_read_only(base_path, FALSE, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-#endif
-
-#ifndef SVN_EXPERIMENTAL_PRISTINE
-svn_error_t *
-svn_wc__text_base_path(const char **result_abspath,
-                       svn_wc__db_t *db,
-                       const char *local_abspath,
-                       apr_pool_t *pool)
-{
-  const char *newpath, *base_name;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  svn_dirent_split(&newpath, &base_name, local_abspath, pool);
-  *result_abspath = simple_extend(newpath,
-                                  FALSE,
-                                  SVN_WC__ADM_TEXT_BASE,
-                                  base_name,
-                                  SVN_WC__BASE_EXT,
-                                  pool);
-
-  return SVN_NO_ERROR;
-}
-#endif
-
-svn_error_t *
-svn_wc__text_base_deterministic_tmp_path(const char **result_abspath,
-                                         svn_wc__db_t *db,
-                                         const char *local_abspath,
-                                         apr_pool_t *pool)
-{
-  const char *newpath, *base_name;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  svn_dirent_split(&newpath, &base_name, local_abspath, pool);
-  *result_abspath = simple_extend(newpath, TRUE, SVN_WC__ADM_TEXT_BASE,
-                                  base_name, SVN_WC__BASE_EXT, pool);
-
-  return SVN_NO_ERROR;
-}
-
-#ifndef SVN_EXPERIMENTAL_PRISTINE
-svn_error_t *
-svn_wc__text_revert_path(const char **result_abspath,
-                         svn_wc__db_t *db,
-                         const char *local_abspath,
-                         apr_pool_t *pool)
-{
-  const char *newpath, *base_name;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  svn_dirent_split(&newpath, &base_name, local_abspath, pool);
-  *result_abspath = simple_extend(newpath,
-                                  FALSE,
-                                  SVN_WC__ADM_TEXT_BASE,
-                                  base_name,
-                                  SVN_WC__REVERT_EXT,
-                                  pool);
-
-  return SVN_NO_ERROR;
-}
-#endif
-
-
 svn_error_t *
 svn_wc__text_base_path_to_read(const char **result_abspath,
                                svn_wc__db_t *db,
@@ -277,7 +195,6 @@ svn_wc__text_base_path_to_read(const cha
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool)
 {
-#ifdef SVN_EXPERIMENTAL_PRISTINE
   const svn_checksum_t *checksum;
 
   SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL,
@@ -294,50 +211,8 @@ svn_wc__text_base_path_to_read(const cha
   SVN_ERR(svn_wc__db_pristine_get_path(result_abspath, db, local_abspath,
                                        checksum,
                                        result_pool, scratch_pool));
-#else
-  SVN_ERR(svn_wc__text_base_path(result_abspath, db, local_abspath,
-                                 result_pool));
-  /* Return an error if the file does not exist */
-  {
-    svn_node_kind_t kind;
-
-    SVN_ERR(svn_io_check_path(*result_abspath, &kind, result_pool));
-    if (kind != svn_node_file)
-      return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
-                               _("File '%s' has no text base"),
-                               svn_dirent_local_style(local_abspath,
-                                                      result_pool));
-  }
-#endif
-
-  return SVN_NO_ERROR;
-}
-
-
-#ifndef SVN_EXPERIMENTAL_PRISTINE
-svn_error_t *
-svn_wc__text_revert_path_to_read(const char **result_abspath,
-                                 svn_wc__db_t *db,
-                                 const char *local_abspath,
-                                 apr_pool_t *result_pool)
-{
-  SVN_ERR(svn_wc__text_revert_path(result_abspath, db, local_abspath,
-                                   result_pool));
-  /* Return an error if the file does not exist */
-  {
-    svn_node_kind_t kind;
-
-    SVN_ERR(svn_io_check_path(*result_abspath, &kind, result_pool));
-    if (kind != svn_node_file)
-      return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
-                               _("File '%s' has no text base"),
-                               svn_dirent_local_style(local_abspath,
-                                                      result_pool));
-  }
-
   return SVN_NO_ERROR;
 }
-#endif
 
 
 svn_error_t *
@@ -347,7 +222,6 @@ svn_wc__ultimate_base_text_path(const ch
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool)
 {
-#ifdef SVN_EXPERIMENTAL_PRISTINE
   const svn_checksum_t *checksum;
 
   SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
@@ -363,28 +237,6 @@ svn_wc__ultimate_base_text_path(const ch
   SVN_ERR(svn_wc__db_pristine_get_path(result_abspath, db, local_abspath,
                                        checksum,
                                        result_pool, scratch_pool));
-#else
-  svn_error_t *err;
-  svn_boolean_t replaced;
-
-  err = svn_wc__internal_is_replaced(&replaced, db, local_abspath,
-                                     scratch_pool);
-  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-    {
-      svn_error_clear(err);
-      replaced = FALSE;
-    }
-  else
-    SVN_ERR(err);
-
-  if (replaced)
-    SVN_ERR(svn_wc__text_revert_path(result_abspath, db, local_abspath,
-                                     result_pool));
-  else
-    SVN_ERR(svn_wc__text_base_path(result_abspath, db, local_abspath,
-                                   result_pool));
-#endif
-
   return SVN_NO_ERROR;
 }
 
@@ -420,7 +272,6 @@ svn_wc__get_ultimate_base_contents(svn_s
                                    apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool)
 {
-#ifdef SVN_EXPERIMENTAL_PRISTINE
   svn_wc__db_kind_t kind;
   svn_wc__db_status_t status;
   const svn_checksum_t *checksum;
@@ -444,34 +295,6 @@ svn_wc__get_ultimate_base_contents(svn_s
   SVN_ERR_ASSERT(checksum != NULL);
   SVN_ERR(svn_wc__db_pristine_read(contents, db, local_abspath,
                                    checksum, result_pool, scratch_pool));
-#else
-  const char *revert_base;
-  svn_error_t *err;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  /* If there's a WC-1 "revert base", open that. */
-  err = svn_wc__text_revert_path_to_read(&revert_base, db, local_abspath,
-                                         scratch_pool);
-  if (err && err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
-    {
-      svn_error_clear(err);
-
-      /* There's no "revert base", so open the "normal base". */
-      err = svn_wc__text_base_path_to_read(&revert_base, db, local_abspath,
-                                           scratch_pool, scratch_pool);
-      if (err && err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
-        {
-          svn_error_clear(err);
-          *contents = NULL;
-          return SVN_NO_ERROR;
-        }
-    }
-  SVN_ERR(err);
-  SVN_ERR(svn_stream_open_readonly(contents, revert_base,
-                                   result_pool, scratch_pool));
-#endif
-
   return SVN_NO_ERROR;
 }
 
@@ -542,47 +365,12 @@ svn_wc__get_pristine_contents(svn_stream
                    && status != svn_wc__db_status_obstructed_delete
                    && status != svn_wc__db_status_base_deleted);
 
-#ifdef SVN_EXPERIMENTAL_PRISTINE
   if (sha1_checksum)
     SVN_ERR(svn_wc__db_pristine_read(contents, db, local_abspath,
                                      sha1_checksum,
                                      result_pool, scratch_pool));
   else
     *contents = NULL;
-#else
-  {
-    const char *text_base;
-    svn_error_t *err, *err2;
-
-    err = svn_wc__text_base_path_to_read(&text_base, db, local_abspath,
-                                         scratch_pool, scratch_pool);
-    /* ### now for some ugly hackiness. right now, file externals will
-       ### sometimes put their pristine contents into the revert base,
-       ### because they think they're *replaced* nodes, rather than
-       ### simple BASE nodes. watch out for this scenario, and
-       ### compensate appropriately.  */
-    if (err)
-      {
-        svn_boolean_t file_external;
-
-        if (err->apr_err != SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
-          return svn_error_return(err);
-
-        err2 = svn_wc__internal_is_file_external(&file_external,
-                                                 db, local_abspath,
-                                                 scratch_pool);
-        if (err2 || !file_external)
-          return svn_error_return(svn_error_compose_create(err, err2));
-
-        svn_error_clear(err);
-
-        SVN_ERR(svn_wc__text_revert_path_to_read(&text_base, db, local_abspath,
-                                                 scratch_pool));
-      }
-    SVN_ERR(svn_stream_open_readonly(contents, text_base,
-                                     result_pool, scratch_pool));
-  }
-#endif
 
   return SVN_NO_ERROR;
 }
@@ -695,49 +483,6 @@ svn_wc__get_pristine_text_status(apr_fin
 }
 
 
-svn_error_t *
-svn_wc__prop_path(const char **prop_path,
-                  const char *path,
-                  svn_wc__db_kind_t node_kind,
-                  svn_wc__props_kind_t props_kind,
-                  apr_pool_t *pool)
-{
-  if (node_kind == svn_wc__db_kind_dir)
-    {
-      static const char * names[] = {
-        SVN_WC__ADM_DIR_PROP_BASE,    /* svn_wc__props_base */
-        SVN_WC__ADM_DIR_PROP_REVERT,  /* svn_wc__props_revert */
-        SVN_WC__ADM_DIR_PROPS         /* svn_wc__props_working */
-      };
-
-      *prop_path = simple_extend(path, FALSE, NULL, names[props_kind], NULL,
-                                 pool);
-    }
-  else  /* It's a file */
-    {
-      static const char * extensions[] = {
-        SVN_WC__BASE_EXT,     /* svn_wc__props_base */
-        SVN_WC__REVERT_EXT,   /* svn_wc__props_revert */
-        SVN_WC__WORK_EXT      /* svn_wc__props_working */
-      };
-
-      static const char * dirs[] = {
-        SVN_WC__ADM_PROP_BASE,  /* svn_wc__props_base */
-        SVN_WC__ADM_PROP_BASE,  /* svn_wc__props_revert */
-        SVN_WC__ADM_PROPS       /* svn_wc__props_working */
-      };
-
-      const char *base_name;
-
-      svn_dirent_split(prop_path, &base_name, path, pool);
-      *prop_path = simple_extend(*prop_path, FALSE, dirs[props_kind],
-                                 base_name, extensions[props_kind], pool);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
 /*** Opening and closing files in the adm area. ***/
 
 svn_error_t *
@@ -799,15 +544,7 @@ init_adm_tmp_area(const char *path, apr_
   /* SVN_WC__ADM_TMP */
   SVN_ERR(make_adm_subdir(path, SVN_WC__ADM_TMP, FALSE, pool));
 
-  /* SVN_WC__ADM_TMP/SVN_WC__ADM_TEXT_BASE */
-  SVN_ERR(make_adm_subdir(path, SVN_WC__ADM_TEXT_BASE, TRUE, pool));
-
-  /* SVN_WC__ADM_TMP/SVN_WC__ADM_PROP_BASE */
-  SVN_ERR(make_adm_subdir(path, SVN_WC__ADM_PROP_BASE, TRUE, pool));
-
-  /* SVN_WC__ADM_TMP/SVN_WC__ADM_PROPS */
-  return svn_error_return(make_adm_subdir(path, SVN_WC__ADM_PROPS, TRUE,
-                                          pool));
+  return SVN_NO_ERROR;
 }
 
 
@@ -831,21 +568,6 @@ init_adm(svn_wc__db_t *db,
 
   /** Make subdirectories. ***/
 
-#ifndef SVN_EXPERIMENTAL_PRISTINE
-  /* ### The absence of this directory is used to indicate to the
-     ### regression tests that SHA1 pristines are enabled.  This is a
-     ### temporary hack, to avoid bumping the wc format. */
-
-  /* SVN_WC__ADM_TEXT_BASE */
-  SVN_ERR(make_adm_subdir(local_abspath, SVN_WC__ADM_TEXT_BASE, FALSE, pool));
-#endif
-
-  /* SVN_WC__ADM_PROP_BASE */
-  SVN_ERR(make_adm_subdir(local_abspath, SVN_WC__ADM_PROP_BASE, FALSE, pool));
-
-  /* SVN_WC__ADM_PROPS */
-  SVN_ERR(make_adm_subdir(local_abspath, SVN_WC__ADM_PROPS, FALSE, pool));
-
   /* SVN_WC__ADM_PRISTINE */
   SVN_ERR(make_adm_subdir(local_abspath, SVN_WC__ADM_PRISTINE, FALSE, pool));
 
@@ -875,9 +597,11 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
                             svn_depth_t depth,
                             apr_pool_t *scratch_pool)
 {
-  const svn_wc_entry_t *entry;
   int format;
   const char *repos_relpath;
+  svn_wc__db_status_t status;
+  const char *db_repos_relpath, *db_repos_root_url, *db_repos_uuid;
+  svn_revnum_t db_revision;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(url != NULL);
@@ -885,7 +609,8 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
   SVN_ERR_ASSERT(repos_uuid != NULL);
   SVN_ERR_ASSERT(svn_uri_is_ancestor(repos_root_url, url));
 
-  SVN_ERR(svn_wc__internal_check_wc(&format, db, local_abspath, scratch_pool));
+  SVN_ERR(svn_wc__internal_check_wc(&format, db, local_abspath, TRUE,
+                                    scratch_pool));
 
   repos_relpath = svn_uri_is_child(repos_root_url, url, scratch_pool);
   if (repos_relpath == NULL)
@@ -900,40 +625,78 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
                                      repos_relpath, repos_root_url, repos_uuid,
                                      revision, depth, scratch_pool));
 
-  /* Now, get the existing url and repos for PATH. */
-  SVN_ERR(svn_wc__get_entry(&entry, db, local_abspath, FALSE, svn_node_unknown,
-                            FALSE, scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__db_read_info(&status, NULL,
+                               &db_revision, &db_repos_relpath,
+                               &db_repos_root_url, &db_repos_uuid,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL,
+                               db, local_abspath, scratch_pool, scratch_pool));
 
-  /* When the directory exists and is scheduled for deletion do not
-   * check the revision or the URL.  The revision can be any
+  /* When the directory exists and is scheduled for deletion or is not-present
+   * do not check the revision or the URL.  The revision can be any
    * arbitrary revision and the URL may differ if the add is
    * being driven from a merge which will have a different URL. */
-  if (entry->schedule != svn_wc_schedule_delete)
+  if (status != svn_wc__db_status_deleted
+      && status != svn_wc__db_status_obstructed_delete
+      && status != svn_wc__db_status_not_present)
     {
-      if (entry->revision != revision)
+      /* ### Should we match copyfrom_revision? */
+      if (db_revision != revision)
         return
           svn_error_createf(SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
                             _("Revision %ld doesn't match existing "
                               "revision %ld in '%s'"),
-                            revision, entry->revision, local_abspath);
+                            revision, db_revision, local_abspath);
+
+      if (!db_repos_root_url)
+        {
+          if (status == svn_wc__db_status_added)
+            SVN_ERR(svn_wc__db_scan_addition(NULL, NULL,
+                                             &db_repos_relpath,
+                                             &db_repos_root_url,
+                                             &db_repos_uuid,
+                                             NULL, NULL, NULL, NULL,
+                                             db, local_abspath,
+                                             scratch_pool, scratch_pool));
+          else
+            SVN_ERR(svn_wc__db_scan_base_repos(&db_repos_relpath,
+                                               &db_repos_root_url,
+                                               &db_repos_uuid,
+                                               db, local_abspath,
+                                               scratch_pool, scratch_pool));
+        }
 
       /* The caller gives us a URL which should match the entry. However,
          some callers compensate for an old problem in entry->url and pass
          the copyfrom_url instead. See ^/notes/api-errata/wc002.txt. As
          a result, we allow the passed URL to match copyfrom_url if it
-         does match the entry's primary URL.  */
-      /** ### comparing URLs, should they be canonicalized first? */
-      if (strcmp(entry->url, url) != 0
-          && (entry->copyfrom_url == NULL
-              || strcmp(entry->copyfrom_url, url) != 0)
-          && (!svn_uri_is_ancestor(repos_root_url, entry->url)
-              || strcmp(entry->uuid, repos_uuid) != 0))
+         does not match the entry's primary URL.  */
+      /* ### comparing URLs, should they be canonicalized first? */
+      if (strcmp(db_repos_uuid, repos_uuid)
+          || strcmp(db_repos_root_url, repos_root_url)
+          || !svn_relpath_is_ancestor(db_repos_relpath, repos_relpath))
         {
-          return
-            svn_error_createf(SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
-                              _("URL '%s' doesn't match existing "
-                                "URL '%s' in '%s'"),
-                              url, entry->url, local_abspath);
+          const char *copyfrom_root_url, *copyfrom_repos_relpath;
+
+          SVN_ERR(svn_wc__internal_get_copyfrom_info(&copyfrom_root_url,
+                                                     &copyfrom_repos_relpath,
+                                                     NULL, NULL, NULL,
+                                                     db, local_abspath,
+                                                     scratch_pool,
+                                                     scratch_pool));
+
+          if (copyfrom_root_url == NULL
+              || strcmp(copyfrom_root_url, repos_root_url)
+              || strcmp(copyfrom_repos_relpath, repos_relpath))
+            return
+              svn_error_createf(SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
+                                _("URL '%s' doesn't match existing "
+                                  "URL '%s' in '%s'"),
+                                url,
+                                svn_uri_join(db_repos_root_url,
+                                             db_repos_relpath, scratch_pool),
+                                local_abspath);
         }
     }
 
@@ -958,6 +721,8 @@ svn_wc_ensure_adm4(svn_wc_context_t *wc_
 svn_error_t *
 svn_wc__adm_destroy(svn_wc__db_t *db,
                     const char *dir_abspath,
+                    svn_cancel_func_t cancel_func,
+                    void *cancel_baton,
                     apr_pool_t *scratch_pool)
 {
   const char *adm_abspath;
@@ -966,12 +731,29 @@ svn_wc__adm_destroy(svn_wc__db_t *db,
 
   SVN_ERR(svn_wc__write_check(db, dir_abspath, scratch_pool));
 
+#ifdef SVN_WC__SINGLE_DB
+  SVN_ERR(svn_wc__db_get_wcroot(&adm_abspath, db, dir_abspath,
+                                scratch_pool, scratch_pool));
+#endif
+
+
   /* Well, the coast is clear for blowing away the administrative
      directory, which also removes the lock */
   SVN_ERR(svn_wc__db_temp_forget_directory(db, dir_abspath, scratch_pool));
 
+#ifndef SVN_WC__SINGLE_DB
   adm_abspath = svn_wc__adm_child(dir_abspath, NULL, scratch_pool);
   SVN_ERR(svn_io_remove_dir2(adm_abspath, FALSE, NULL, NULL, scratch_pool));
+#else
+  /* ### We should check if we are the only user of this DB!!! */
+
+  if (strcmp(adm_abspath, dir_abspath) == 0)
+    SVN_ERR(svn_io_remove_dir2(svn_wc__adm_child(adm_abspath, NULL,
+                                                 scratch_pool),
+                               FALSE,
+                               cancel_func, cancel_baton,
+                               scratch_pool));
+#endif
 
   return SVN_NO_ERROR;
 }