You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2010/09/09 22:26:52 UTC

svn commit: r995566 [8/16] - in /subversion/branches/atomic-revprop: ./ build/ac-macros/ build/generator/ contrib/server-side/ notes/ notes/wc-ng/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversio...

Modified: subversion/branches/atomic-revprop/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_subr/dirent_uri.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_subr/dirent_uri.c Thu Sep  9 20:26:46 2010
@@ -34,6 +34,7 @@
 #include "svn_string.h"
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
+#include "svn_ctype.h"
 
 #include "dirent_uri.h"
 
@@ -549,7 +550,8 @@ canonicalize(path_type_t type, const cha
               case '/':
                 break;
               case '%':
-                if (!apr_isxdigit(*(src+1)) || !apr_isxdigit(*(src+2)))
+                if (!svn_ctype_isxdigit(*(src+1)) ||
+                    !svn_ctype_isxdigit(*(src+2)))
                   need_extra += 2;
                 else
                   src += 2;
@@ -585,7 +587,8 @@ canonicalize(path_type_t type, const cha
                 *(dst++) = '/';
                 break;
               case '%':
-                if (!apr_isxdigit(*(src+1)) || !apr_isxdigit(*(src+2)))
+                if (!svn_ctype_isxdigit(*(src+1)) ||
+                    !svn_ctype_isxdigit(*(src+2)))
                   {
                     *(dst++) = '%';
                     *(dst++) = '2';
@@ -1899,13 +1902,13 @@ svn_uri_is_canonical(const char *uri, ap
               char digitz[3];
               int val;
 
-              /* Can't use apr_isxdigit() because lower case letters are
+              /* Can't usesvn_ctype_isxdigit() because lower case letters are
                  not in our canonical format */
-              if (((*(ptr+1) < '0' || (*ptr+1) > '9')) 
-                  && (*(ptr+1) < 'A' || (*ptr+1) > 'F'))
+              if (((*(ptr+1) < '0' || *(ptr+1) > '9')) 
+                  && (*(ptr+1) < 'A' || *(ptr+1) > 'F'))
                 return FALSE;
-              else if (((*(ptr+2) < '0' || (*ptr+2) > '9')) 
-                  && (*(ptr+2) < 'A' || (*ptr+2) > 'F'))
+              else if (((*(ptr+2) < '0' || *(ptr+2) > '9')) 
+                  && (*(ptr+2) < 'A' || *(ptr+2) > 'F'))
                 return FALSE;
 
               digitz[0] = *(++ptr);

Modified: subversion/branches/atomic-revprop/subversion/libsvn_subr/hash.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_subr/hash.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_subr/hash.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_subr/hash.c Thu Sep  9 20:26:46 2010
@@ -344,11 +344,16 @@ svn_hash_read(apr_hash_t *hash,
         }
       else if ((buf[0] == 'K') && (buf[1] == ' '))
         {
+          size_t keylen;
+          int parsed_len;
+          void *keybuf;
+          
           /* Get the length of the key */
-          size_t keylen = (size_t) atoi(buf + 2);
+          SVN_ERR(svn_cstring_atoi(&parsed_len, buf + 2));
+          keylen = parsed_len;
 
           /* Now read that much into a buffer, + 1 byte for null terminator */
-          void *keybuf = apr_palloc(pool, keylen + 1);
+          keybuf = apr_palloc(pool, keylen + 1);
           SVN_ERR(svn_io_file_read_full(srcfile,
                                         keybuf, keylen, &num_read, pool));
           ((char *) keybuf)[keylen] = '\0';
@@ -365,12 +370,15 @@ svn_hash_read(apr_hash_t *hash,
           if ((buf[0] == 'V') && (buf[1] == ' '))
             {
               svn_string_t *value = apr_palloc(pool, sizeof(*value));
+              apr_size_t vallen;
+              void *valbuf;
 
               /* Get the length of the value */
-              apr_size_t vallen = atoi(buf + 2);
+              SVN_ERR(svn_cstring_atoi(&parsed_len, buf + 2));
+              vallen = parsed_len;
 
               /* Again, 1 extra byte for the null termination. */
-              void *valbuf = apr_palloc(pool, vallen + 1);
+              valbuf = apr_palloc(pool, vallen + 1);
               SVN_ERR(svn_io_file_read_full(srcfile,
                                             valbuf, vallen,
                                             &num_read, pool));
@@ -458,13 +466,7 @@ svn_hash_keys(apr_array_header_t **array
 
   for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
     {
-      const void *key;
-      const char *path;
-
-      apr_hash_this(hi, &key, NULL, NULL);
-      path = key;
-
-      APR_ARRAY_PUSH(*array, const char *) = path;
+      APR_ARRAY_PUSH(*array, const char *) = svn__apr_hash_index_key(hi);
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/atomic-revprop/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_subr/io.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_subr/io.c Thu Sep  9 20:26:46 2010
@@ -57,6 +57,7 @@
 #include "svn_utf.h"
 #include "svn_config.h"
 #include "svn_private_config.h"
+#include "svn_ctype.h"
 
 #include "private/svn_atomic.h"
 
@@ -1025,14 +1026,19 @@ svn_error_t *svn_io_file_create(const ch
 {
   apr_file_t *f;
   apr_size_t written;
+  svn_error_t *err;
 
   SVN_ERR(svn_io_file_open(&f, file,
                            (APR_WRITE | APR_CREATE | APR_EXCL),
                            APR_OS_DEFAULT,
                            pool));
-  SVN_ERR(svn_io_file_write_full(f, contents, strlen(contents),
-                                 &written, pool));
-  return svn_io_file_close(f, pool);
+  err= svn_io_file_write_full(f, contents, strlen(contents),
+                              &written, pool);
+
+
+  return svn_error_return(
+                        svn_error_compose_create(err,
+                                                 svn_io_file_close(f, pool)));
 }
 
 svn_error_t *svn_io_dir_file_copy(const char *src_path,
@@ -2868,12 +2874,19 @@ svn_io_write_unique(const char **tmp_pat
                     apr_pool_t *pool)
 {
   apr_file_t *new_file;
+  svn_error_t *err;
 
   SVN_ERR(svn_io_open_unique_file3(&new_file, tmp_path, dirpath,
                                    delete_when, pool, pool));
-  SVN_ERR(svn_io_file_write_full(new_file, buf, nbytes, NULL, pool));
-  SVN_ERR(svn_io_file_flush_to_disk(new_file, pool));
-  return svn_io_file_close(new_file, pool);
+
+  err = svn_io_file_write_full(new_file, buf, nbytes, NULL, pool);
+
+  if (!err)
+    err = svn_io_file_flush_to_disk(new_file, pool);
+
+  return svn_error_return(
+                  svn_error_compose_create(err,
+                                           svn_io_file_close(new_file, pool)));
 }
 
 
@@ -3437,15 +3450,17 @@ svn_io_read_version_file(int *version,
   apr_file_t *format_file;
   char buf[80];
   apr_size_t len;
+  svn_error_t *err;
 
   /* Read a chunk of data from PATH */
   SVN_ERR(svn_io_file_open(&format_file, path, APR_READ,
                            APR_OS_DEFAULT, pool));
   len = sizeof(buf);
-  SVN_ERR(svn_io_file_read(format_file, buf, &len, pool));
+  err = svn_io_file_read(format_file, buf, &len, pool);
 
   /* Close the file. */
-  SVN_ERR(svn_io_file_close(format_file, pool));
+  SVN_ERR(svn_error_compose_create(err,
+                                   svn_io_file_close(format_file, pool)));
 
   /* If there was no data in PATH, return an error. */
   if (len == 0)
@@ -3463,7 +3478,7 @@ svn_io_read_version_file(int *version,
 
         if (i > 0 && (c == '\r' || c == '\n'))
           break;
-        if (! apr_isdigit(c))
+        if (! svn_ctype_isdigit(c))
           return svn_error_createf
             (SVN_ERR_BAD_VERSION_FILE_FORMAT, NULL,
              _("First line of '%s' contains non-digit"),
@@ -3472,7 +3487,7 @@ svn_io_read_version_file(int *version,
   }
 
   /* Convert to integer. */
-  *version = atoi(buf);
+  SVN_ERR(svn_cstring_atoi(version, buf));
 
   return SVN_NO_ERROR;
 }
@@ -3486,48 +3501,65 @@ contents_identical_p(svn_boolean_t *iden
                      const char *file2,
                      apr_pool_t *pool)
 {
-  svn_error_t *err1;
-  svn_error_t *err2;
+  svn_error_t *err;
   apr_size_t bytes_read1, bytes_read2;
   char *buf1 = apr_palloc(pool, SVN__STREAM_CHUNK_SIZE);
   char *buf2 = apr_palloc(pool, SVN__STREAM_CHUNK_SIZE);
   apr_file_t *file1_h = NULL;
   apr_file_t *file2_h = NULL;
+  svn_boolean_t done1 = FALSE;
+  svn_boolean_t done2 = FALSE;
 
   SVN_ERR(svn_io_file_open(&file1_h, file1, APR_READ, APR_OS_DEFAULT,
                            pool));
-  SVN_ERR(svn_io_file_open(&file2_h, file2, APR_READ, APR_OS_DEFAULT,
-                           pool));
+
+  err = svn_io_file_open(&file2_h, file2, APR_READ, APR_OS_DEFAULT,
+                         pool);
+
+  if (err)
+    return svn_error_return(
+               svn_error_compose_create(err,
+                                        svn_io_file_close(file1_h, pool)));
 
   *identical_p = TRUE;  /* assume TRUE, until disproved below */
-  do
+  while (! (done1 || done2))
     {
-      err1 = svn_io_file_read_full(file1_h, buf1,
-                                   SVN__STREAM_CHUNK_SIZE, &bytes_read1, pool);
-      if (err1 && !APR_STATUS_IS_EOF(err1->apr_err))
-        return err1;
-
-      err2 = svn_io_file_read_full(file2_h, buf2,
-                                   SVN__STREAM_CHUNK_SIZE, &bytes_read2, pool);
-      if (err2 && !APR_STATUS_IS_EOF(err2->apr_err))
+      err = svn_io_file_read_full(file1_h, buf1,
+                                  SVN__STREAM_CHUNK_SIZE, &bytes_read1, pool);
+      if (err && APR_STATUS_IS_EOF(err->apr_err))
         {
-          svn_error_clear(err1);
-          return err2;
+          svn_error_clear(err);
+          err = NULL;
+          done1 = TRUE;
         }
+      else if (err)
+        break;
+
+      err = svn_io_file_read_full(file2_h, buf2,
+                                  SVN__STREAM_CHUNK_SIZE, &bytes_read2, pool);
+      if (err && APR_STATUS_IS_EOF(err->apr_err))
+        {
+          svn_error_clear(err);
+          err = NULL;
+          done2 = TRUE;
+        }
+      else if (err)
+        break;
 
       if ((bytes_read1 != bytes_read2)
+          || (done1 != done2)
           || (memcmp(buf1, buf2, bytes_read1)))
         {
           *identical_p = FALSE;
           break;
         }
-    } while (! err1 && ! err2);
-
-  svn_error_clear(err1);
-  svn_error_clear(err2);
+    }
 
-  SVN_ERR(svn_io_file_close(file1_h, pool));
-  return svn_io_file_close(file2_h, pool);
+  return svn_error_return(
+           svn_error_compose_create(
+                err,
+                svn_error_compose_create(svn_io_file_close(file1_h, pool),
+                                         svn_io_file_close(file2_h, pool))));
 }
 
 

Modified: subversion/branches/atomic-revprop/subversion/libsvn_subr/opt.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_subr/opt.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_subr/opt.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_subr/opt.c Thu Sep  9 20:26:46 2010
@@ -43,6 +43,7 @@
 #include "svn_utf.h"
 #include "svn_time.h"
 #include "svn_props.h"
+#include "svn_ctype.h"
 
 #include "private/svn_opt_private.h"
 
@@ -456,11 +457,11 @@ static char *parse_one_rev(svn_opt_revis
       revision->value.date = tm;
       return end + 1;
     }
-  else if (apr_isdigit(*str))
+  else if (svn_ctype_isdigit(*str))
     {
       /* It's a number. */
       end = str + 1;
-      while (apr_isdigit(*end))
+      while (svn_ctype_isdigit(*end))
         end++;
       save = *end;
       *end = '\0';
@@ -469,10 +470,10 @@ static char *parse_one_rev(svn_opt_revis
       *end = save;
       return end;
     }
-  else if (apr_isalpha(*str))
+  else if (svn_ctype_isalpha(*str))
     {
       end = str + 1;
-      while (apr_isalpha(*end))
+      while (svn_ctype_isalpha(*end))
         end++;
       save = *end;
       *end = '\0';

Modified: subversion/branches/atomic-revprop/subversion/libsvn_subr/path.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_subr/path.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_subr/path.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_subr/path.c Thu Sep  9 20:26:46 2010
@@ -727,7 +727,8 @@ svn_path_is_uri_safe(const char *path)
       /* Allow '%XX' (where each X is a hex digit) */
       if (path[i] == '%')
         {
-          if (apr_isxdigit(path[i + 1]) && apr_isxdigit(path[i + 2]))
+          if (svn_ctype_isxdigit(path[i + 1]) &&
+              svn_ctype_isxdigit(path[i + 2]))
             {
               i += 2;
               continue;
@@ -897,8 +898,8 @@ svn_path_uri_decode(const char *path, ap
            * RFC 2396, section 3.3  */
           c = ' ';
         }
-      else if (c == '%' && apr_isxdigit(path[i + 1])
-               && apr_isxdigit(path[i+2]))
+      else if (c == '%' && svn_ctype_isxdigit(path[i + 1])
+               && svn_ctype_isxdigit(path[i+2]))
         {
           char digitz[3];
           digitz[0] = path[++i];

Modified: subversion/branches/atomic-revprop/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_subr/sqlite.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_subr/sqlite.c Thu Sep  9 20:26:46 2010
@@ -71,6 +71,7 @@ struct svn_sqlite__db_t
   int nbr_statements;
   svn_sqlite__stmt_t **prepared_stmts;
   apr_pool_t *state_pool;
+  unsigned savepoint_nr;
 };
 
 struct svn_sqlite__stmt_t
@@ -273,11 +274,20 @@ vbindf(svn_sqlite__stmt_t *stmt, const c
             SVN_ERR(svn_sqlite__bind_blob(stmt, count, blob, blob_size));
             break;
 
+          case 'r':
+            SVN_ERR(svn_sqlite__bind_revnum(stmt, count,
+                                            va_arg(ap, svn_revnum_t)));
+            break;
+
           case 't':
             map = va_arg(ap, const svn_token_map_t *);
             SVN_ERR(svn_sqlite__bind_token(stmt, count, map, va_arg(ap, int)));
             break;
 
+          case 'n':
+            /* Skip this column: no binding */
+            break;
+
           default:
             SVN_ERR_MALFUNCTION();
         }
@@ -352,6 +362,20 @@ svn_sqlite__bind_token(svn_sqlite__stmt_
 }
 
 svn_error_t *
+svn_sqlite__bind_revnum(svn_sqlite__stmt_t *stmt,
+                        int slot,
+                        svn_revnum_t value)
+{
+  if (SVN_IS_VALID_REVNUM(value))
+    SQLITE_ERR(sqlite3_bind_int64(stmt->s3stmt, slot,
+                                  (sqlite_int64)value), stmt->db);
+  else
+    SQLITE_ERR(sqlite3_bind_null(stmt->s3stmt, slot), stmt->db);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_sqlite__bind_properties(svn_sqlite__stmt_t *stmt,
                             int slot,
                             const apr_hash_t *props,
@@ -1018,6 +1042,60 @@ svn_sqlite__with_transaction(svn_sqlite_
 }
 
 svn_error_t *
+svn_sqlite__with_lock(svn_sqlite__db_t *db,
+                      svn_sqlite__transaction_callback_t cb_func,
+                      void *cb_baton,
+                      apr_pool_t *scratch_pool)
+{
+  svn_error_t *err;
+
+#if SQLITE_VERSION_AT_LEAST(3,6,8)
+  svn_error_t *err2;
+  int savepoint = db->savepoint_nr++;
+  const char *release_stmt;
+
+  SVN_ERR(exec_sql(db,
+                   apr_psprintf(scratch_pool, "SAVEPOINT s%u;", savepoint)));
+#endif
+
+  err = cb_func(cb_baton, db, scratch_pool);
+
+#if SQLITE_VERSION_AT_LEAST(3,6,8)
+  release_stmt = apr_psprintf(scratch_pool, "RELEASE s%u;", savepoint);
+  err2 = exec_sql(db, release_stmt);
+
+  if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY)
+    {
+      /* Ok, we have a major problem. Some statement is still open, which
+         makes it impossible to release this savepoint.
+
+         ### See huge comment in svn_sqlite__with_transaction for
+             further details */
+
+      int i;
+
+      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, release_stmt),
+                      err2);
+    }
+
+  err = svn_error_compose_create(err, err2);
+#endif
+
+  return svn_error_return(err);
+}
+
+svn_error_t *
 svn_sqlite__hotcopy(const char *src_path,
                     const char *dst_path,
                     apr_pool_t *scratch_pool)

Modified: subversion/branches/atomic-revprop/subversion/libsvn_subr/svn_string.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_subr/svn_string.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_subr/svn_string.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_subr/svn_string.c Thu Sep  9 20:26:46 2010
@@ -1,5 +1,5 @@
 /*
- * svn_string.h:  routines to manipulate counted-length strings
+ * svn_string.c:  routines to manipulate counted-length strings
  *                (svn_stringbuf_t and svn_string_t) and C strings.
  *
  *
@@ -25,12 +25,16 @@
 
 
 
+#include <apr.h>
+
 #include <string.h>      /* for memcpy(), memcmp(), strlen() */
 #include <apr_lib.h>     /* for apr_isspace() */
 #include <apr_fnmatch.h>
 #include "svn_string.h"  /* loads "svn_types.h" and <apr_pools.h> */
 #include "svn_ctype.h"
+#include "private/svn_dep_compat.h"
 
+#include "svn_private_config.h"
 
 
 /* Our own realloc, since APR doesn't have one.  Note: this is a
@@ -84,7 +88,7 @@ string_first_non_whitespace(const char *
 
   for (i = 0; i < len; i++)
     {
-      if (! apr_isspace(str[i]))
+      if (! svn_ctype_isspace(str[i]))
         return i;
     }
 
@@ -460,7 +464,7 @@ svn_stringbuf_strip_whitespace(svn_strin
   str->blocksize -= offset;
 
   /* Now that we've trimmed the front, trim the end, wasting more RAM. */
-  while ((str->len > 0) && apr_isspace(str->data[str->len - 1]))
+  while ((str->len > 0) && svn_ctype_isspace(str->data[str->len - 1]))
     str->len--;
   str->data[str->len] = '\0';
 }
@@ -502,12 +506,12 @@ svn_cstring_split_append(apr_array_heade
     {
       if (chop_whitespace)
         {
-          while (apr_isspace(*p))
+          while (svn_ctype_isspace(*p))
             p++;
 
           {
             char *e = p + (strlen(p) - 1);
-            while ((e >= p) && (apr_isspace(*e)))
+            while ((e >= p) && (svn_ctype_isspace(*e)))
               e--;
             *(++e) = '\0';
           }
@@ -605,3 +609,88 @@ svn_cstring_casecmp(const char *str1, co
         return cmp;
     }
 }
+
+svn_error_t *
+svn_cstring_strtoui64(apr_uint64_t *n, const char *str,
+                      apr_uint64_t minval, apr_uint64_t maxval,
+                      int base)
+{
+  apr_int64_t parsed;
+
+  /* We assume errno is thread-safe. */
+  errno = 0; /* APR-0.9 doesn't always set errno */
+
+  /* ### We're throwing away half the number range here.
+   * ### Maybe implement our own number parser? */
+  parsed = apr_strtoi64(str, NULL, base);
+  if (errno != 0)
+    return svn_error_return(
+             svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+                               _("Could not convert '%s' into a number"),
+                               str));
+  if (parsed < 0 || parsed < minval || parsed > maxval)
+    return svn_error_return(
+             svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+                               _("Number '%s' is out of range"), str));
+  *n = parsed;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_cstring_atoui64(apr_uint64_t *n, const char *str)
+{
+  return svn_error_return(svn_cstring_strtoui64(n, str, 0,
+                                                APR_UINT64_MAX, 10));
+}
+
+svn_error_t *
+svn_cstring_atoui(unsigned int *n, const char *str)
+{
+  apr_uint64_t parsed;
+
+  SVN_ERR(svn_cstring_strtoui64(&parsed, str, 0, APR_UINT32_MAX, 10));
+  *n = (unsigned int)parsed;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_cstring_strtoi64(apr_int64_t *n, const char *str,
+                     apr_int64_t minval, apr_int64_t maxval,
+                     int base)
+{
+  apr_int64_t parsed;
+
+  /* We assume errno is thread-safe. */
+  errno = 0; /* APR-0.9 doesn't always set errno */
+
+  parsed = apr_strtoi64(str, NULL, base);
+  if (errno != 0)
+    return svn_error_return(
+             svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+                               _("Could not convert '%s' into a number"),
+                               str));
+  if (parsed < minval || parsed > maxval)
+    return svn_error_return(
+             svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+                               _("Number '%s' is out of range"), str));
+  *n = parsed;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_cstring_atoi64(apr_int64_t *n, const char *str)
+{
+  return svn_error_return(svn_cstring_strtoi64(n, str, APR_INT64_MIN,
+                                               APR_INT64_MAX, 10));
+}
+
+svn_error_t *
+svn_cstring_atoi(int *n, const char *str)
+{
+  apr_int64_t parsed;
+
+  SVN_ERR(svn_cstring_strtoi64(&parsed, str, APR_INT32_MIN,
+                               APR_INT32_MAX, 10));
+  *n = (int)parsed;
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/atomic-revprop/subversion/libsvn_subr/utf.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_subr/utf.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_subr/utf.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_subr/utf.c Thu Sep  9 20:26:46 2010
@@ -530,9 +530,9 @@ check_non_ascii(const char *data, apr_si
 
   for (; len > 0; --len, data++)
     {
-      if ((! apr_isascii(*data))
-          || ((! apr_isspace(*data))
-              && apr_iscntrl(*data)))
+      if ((! svn_ctype_isascii(*data))
+          || ((! svn_ctype_isspace(*data))
+              && svn_ctype_iscntrl(*data)))
         {
           /* Show the printable part of the data, followed by the
              decimal code of the questionable character.  Because if a

Modified: subversion/branches/atomic-revprop/subversion/libsvn_subr/validate.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_subr/validate.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_subr/validate.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_subr/validate.c Thu Sep  9 20:26:46 2010
@@ -27,11 +27,11 @@
 
 /*** Includes. ***/
 
-#include <apr_lib.h>
 #define APR_WANT_STRFUNC
 #include <apr_want.h>
 
 #include "svn_error.h"
+#include "svn_ctype.h"
 #include "svn_private_config.h"
 
 
@@ -63,9 +63,9 @@ svn_mime_type_validate(const char *mime_
   for (i = 0; i < len; i++)
     {
       if (&mime_type[i] != slash_pos
-        && (! apr_isascii(mime_type[i])
-            || apr_iscntrl(mime_type[i])
-            || apr_isspace(mime_type[i])
+         && (! svn_ctype_isascii(mime_type[i])
+            || svn_ctype_iscntrl(mime_type[i])
+            || svn_ctype_isspace(mime_type[i])
             || (strchr(tspecials, mime_type[i]) != NULL)))
         return svn_error_createf
           (SVN_ERR_BAD_MIME_TYPE, NULL,

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/adm_crawler.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/adm_crawler.c Thu Sep  9 20:26:46 2010
@@ -652,8 +652,10 @@ report_revisions_and_depths(svn_wc__db_t
              ### skip it right here. I guess with an obstruction, we
              ### can't really do anything with info the server might
              ### send, so maybe this is just fine.  */
+#ifdef SVN_WC__DB_SINGLE_DB
           if (this_status == svn_wc__db_status_obstructed)
             continue;
+#endif
 
           is_incomplete = (this_status == svn_wc__db_status_incomplete);
           start_empty = is_incomplete;

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/adm_files.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/adm_files.c Thu Sep  9 20:26:46 2010
@@ -357,13 +357,14 @@ svn_wc__get_pristine_contents(svn_stream
                                "because it has an unexpected status"),
                              svn_dirent_local_style(local_abspath,
                                                     scratch_pool));
+#ifndef SVN_WC__SINGLE_DB
   else
     /* We know that it is a file, so we can't hit the _obstructed stati.
        Also, we should never see _base_deleted here. */
     SVN_ERR_ASSERT(status != svn_wc__db_status_obstructed
                    && status != svn_wc__db_status_obstructed_add
-                   && status != svn_wc__db_status_obstructed_delete
-                   && status != svn_wc__db_status_base_deleted);
+                   && status != svn_wc__db_status_obstructed_delete);
+#endif
 
   if (sha1_checksum)
     SVN_ERR(svn_wc__db_pristine_read(contents, db, local_abspath,
@@ -638,8 +639,11 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
    * arbitrary revision and the URL may differ if the add is
    * being driven from a merge which will have a different URL. */
   if (status != svn_wc__db_status_deleted
+      && status != svn_wc__db_status_not_present
+#ifndef SVN_WC__SINGLE_DB
       && status != svn_wc__db_status_obstructed_delete
-      && status != svn_wc__db_status_not_present)
+#endif
+      )
     {
       /* ### Should we match copyfrom_revision? */
       if (db_revision != revision)

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/adm_ops.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/adm_ops.c Thu Sep  9 20:26:46 2010
@@ -54,7 +54,6 @@
 #include "wc.h"
 #include "adm_files.h"
 #include "entries.h"
-#include "lock.h"
 #include "props.h"
 #include "translate.h"
 #include "tree_conflicts.h"
@@ -152,7 +151,10 @@ process_committed_leaf(svn_wc__db_t *db,
   SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool));
 
   if (status == svn_wc__db_status_deleted
-      || status == svn_wc__db_status_obstructed_delete)
+#ifndef SVN_WC__SINGLE_DB
+      || status == svn_wc__db_status_obstructed_delete
+#endif
+      )
     {
       return svn_error_return(svn_wc__wq_add_deletion_postcommit(
                                 db, local_abspath, new_revnum, no_unlock,
@@ -247,11 +249,6 @@ svn_wc__process_committed_internal(svn_w
 {
   svn_wc__db_kind_t kind;
 
-  SVN_ERR_ASSERT((md5_checksum == NULL && sha1_checksum == NULL)
-                 || (md5_checksum != NULL && sha1_checksum != NULL
-                     && md5_checksum->kind == svn_checksum_md5
-                     && sha1_checksum->kind == svn_checksum_sha1));
-
   SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, TRUE, scratch_pool));
 
   SVN_ERR(process_committed_leaf(db, local_abspath, !top_of_recurse,
@@ -315,7 +312,10 @@ svn_wc__process_committed_internal(svn_w
                  of running the log for the replaced directory that was
                  created at the start of this function). */
               if (status == svn_wc__db_status_deleted
-                  || status == svn_wc__db_status_obstructed_delete)
+#ifndef SVN_WC__SINGLE_DB
+                  || status == svn_wc__db_status_obstructed_delete
+#endif
+                  )
                 {
                   svn_boolean_t replaced;
 
@@ -416,10 +416,6 @@ svn_wc_queue_committed3(svn_wc_committed
   committed_queue_item_t *cqi;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-  SVN_ERR_ASSERT((md5_checksum == NULL && sha1_checksum == NULL)
-                 || (md5_checksum != NULL && sha1_checksum != NULL
-                     && md5_checksum->kind == svn_checksum_md5
-                     && sha1_checksum->kind == svn_checksum_sha1));
 
   queue->have_recursive |= recurse;
 
@@ -799,14 +795,20 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
 
   if (kind == svn_wc__db_kind_dir)
     {
-      
+      /* ### NODE_DATA We recurse into the subtree here, which is fine,
+         except that we also need to record the op_depth to pass to
+         svn_wc__db_temp_op_delete(), which is determined by the original
+         path for which svn_wc_delete4() was called. We need a helper
+         function which receives the op_depth as an argument to apply to
+         the entire subtree.
+       */
       apr_pool_t *iterpool = svn_pool_create(pool);
       const apr_array_header_t *children;
       int i;
 
       SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath,
                                        pool, pool));
-      
+
       for (i = 0; i < children->nelts; i++)
         {
           const char *child_basename = APR_ARRAY_IDX(children, i, const char *);
@@ -967,7 +969,9 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
             node_exists = FALSE;
             break;
           case svn_wc__db_status_deleted:
+#ifndef SVN_WC__SINGLE_DB
           case svn_wc__db_status_obstructed_delete:
+#endif
             /* A working copy root should never have a WORKING_NODE */
             SVN_ERR_ASSERT(!is_wc_root);
             node_exists = FALSE;
@@ -1024,8 +1028,11 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
         || parent_status == svn_wc__db_status_not_present
         || parent_status == svn_wc__db_status_excluded
         || parent_status == svn_wc__db_status_absent
+#ifndef SVN_WC__SINGLE_DB
         || parent_status == svn_wc__db_status_obstructed
-        || parent_status == svn_wc__db_status_obstructed_add)
+        || parent_status == svn_wc__db_status_obstructed_add
+#endif
+        )
       {
         return
           svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, err,
@@ -1035,7 +1042,10 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
                                                    scratch_pool));
       }
     else if (parent_status == svn_wc__db_status_deleted
-             || parent_status == svn_wc__db_status_obstructed_delete)
+#ifndef SVN_WC__SINGLE_DB
+             || parent_status == svn_wc__db_status_obstructed_delete
+#endif
+             )
       {
         return
           svn_error_createf(SVN_ERR_WC_SCHEDULE_CONFLICT, NULL,
@@ -1462,10 +1472,12 @@ revert_entry(svn_depth_t *depth,
              svn_boolean_t *did_revert,
              apr_pool_t *pool)
 {
-  svn_wc__db_status_t status;
-  svn_wc__db_kind_t kind;
+  svn_wc__db_status_t status, base_status;
+  svn_wc__db_kind_t kind, base_kind;
   svn_boolean_t replaced;
   svn_boolean_t have_base;
+  svn_revnum_t base_revision;
+  svn_boolean_t is_add_root;
 
   /* Initialize this even though revert_admin_things() is guaranteed
      to set it, because we don't know that revert_admin_things() will
@@ -1479,14 +1491,37 @@ revert_entry(svn_depth_t *depth,
                                NULL, NULL,
                                db, local_abspath, pool, pool));
 
-  SVN_ERR(svn_wc__internal_is_replaced(&replaced, db, local_abspath, pool));
+  if (have_base)
+    SVN_ERR(svn_wc__db_base_get_info(&base_status, &base_kind, &base_revision,
+                                     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                     NULL, NULL, NULL, NULL, NULL,
+                                     db, local_abspath, pool, pool));
+
+  replaced = (status == svn_wc__db_status_added
+              && have_base
+              && base_status != svn_wc__db_status_not_present);
+
+  if (status == svn_wc__db_status_added)
+    {
+      const char *op_root_abspath;
+      SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL,
+                                       db, local_abspath, pool, pool));
+
+      is_add_root = (strcmp(op_root_abspath, local_abspath) == 0);
+    }
+  else
+#ifdef SVN_WC__SINGLE_DB
+    is_add_root = FALSE;
+#else
+    /* HACK: svn_wc__db_scan_addition doesn't allow this status! */
+    is_add_root = (status == svn_wc__db_status_obstructed_add);
+#endif
 
   /* Additions. */
-  if ((status == svn_wc__db_status_added
-       || status == svn_wc__db_status_obstructed_add)
-      && !replaced)
+  if (!replaced
+      && is_add_root)
     {
-      svn_revnum_t base_revision;
       const char *repos_relpath;
       const char *repos_root_url;
       const char *repos_uuid;
@@ -1498,31 +1533,19 @@ revert_entry(svn_depth_t *depth,
          The code below will then figure out the repository information, so
          that we can later insert a node for the same repository. */
 
-      if (have_base)
+      if (have_base
+          && base_status == svn_wc__db_status_not_present)
         {
-            svn_wc__db_status_t base_status;
-            SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL,
-                                             &base_revision, &repos_relpath,
-                                             &repos_root_url, &repos_uuid,
-                                             NULL, NULL, NULL, NULL, NULL,
-                                             NULL, NULL, NULL, NULL,
-                                             db, local_abspath,
-                                             pool, pool));
+          /* Remember the BASE revision. (already handled)  */
+          /* Remember the repository this node is associated with.  */
 
-            if (base_status == svn_wc__db_status_not_present)
-            {
-                /* Remember the BASE revision.  */
-                /* Remember the repository this node is associated with.  */
+          was_not_present = TRUE;
 
-                was_not_present = TRUE;
-
-                if (!repos_root_url)
-                  SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath,
-                                                     &repos_root_url,
-                                                     &repos_uuid,
-                                                     db, local_abspath,
-                                                     pool, pool));
-            }
+          SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath,
+                                             &repos_root_url,
+                                             &repos_uuid,
+                                             db, local_abspath,
+                                             pool, pool));
         }
 
       /* ### much of this is probably bullshit. we should be able to just
@@ -1546,7 +1569,7 @@ revert_entry(svn_depth_t *depth,
           /* Before single-db we didn't have to perform a recursive delete
              here. With single-db we really must delete missing nodes */
           if (disk_kind == svn_node_none
-              || svn_wc__adm_missing(db, local_abspath, pool))
+              || status == svn_wc__db_status_obstructed_add)
             {
               /* Schedule add but missing, just remove the entry
                  or it's missing an adm area in which case
@@ -1591,7 +1614,7 @@ revert_entry(svn_depth_t *depth,
                     db, local_abspath,
                     repos_relpath, repos_root_url, repos_uuid,
                     base_revision,
-                    kind,
+                    base_kind,
                     svn_wc__db_status_not_present,
                     NULL, NULL,
                     pool));
@@ -1601,7 +1624,8 @@ revert_entry(svn_depth_t *depth,
   /* Deletions and replacements. */
   else if (status == svn_wc__db_status_normal
            || status == svn_wc__db_status_deleted
-           || replaced)
+           || replaced
+           || (status == svn_wc__db_status_added && !is_add_root))
     {
       /* Revert the prop and text mods (if any). */
       SVN_ERR(revert_admin_things(&reverted, db, local_abspath,
@@ -1619,6 +1643,72 @@ revert_entry(svn_depth_t *depth,
   return SVN_NO_ERROR;
 }
 
+/* Verifies if an add (or copy) to LOCAL_ABSPATH can be reverted with depth
+ * DEPTH, without touching nodes that are filtered by DEPTH.
+ *
+ * Use ROOT_ABSPATH for generating error messages.
+ */
+static svn_error_t *
+verify_revert_depth(svn_wc__db_t *db,
+                    const char *local_abspath,
+                    svn_depth_t depth,
+                    const char *root_abspath,
+                    apr_pool_t *scratch_pool)
+{
+  const apr_array_header_t *children;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  int i;
+
+  SVN_ERR_ASSERT(depth >= svn_depth_empty && depth < svn_depth_infinity);
+
+  SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath,
+                                   scratch_pool, iterpool));
+
+  for (i = 0; i < children->nelts; i++)
+    {
+      const char *name = APR_ARRAY_IDX(children, i, const char *);
+      const char *child_abspath;
+      svn_wc__db_status_t status;
+      svn_wc__db_kind_t kind;
+
+      svn_pool_clear(iterpool);
+
+      child_abspath = svn_dirent_join(local_abspath, name, iterpool);
+
+      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,
+                                   db, child_abspath, iterpool, iterpool));
+
+      /* Not-here and deleted nodes won't be reverted by reverting an operation
+         on a parent, so we can just skip them for the depth check. */
+      if (status == svn_wc__db_status_not_present
+          || status == svn_wc__db_status_absent
+          || status == svn_wc__db_status_excluded
+          || status == svn_wc__db_status_deleted)
+        continue;
+
+      if (depth == svn_depth_empty
+          || (depth == svn_depth_files && kind == svn_wc__db_kind_dir))
+        {
+          return svn_error_createf(
+                        SVN_ERR_WC_INVALID_OPERATION_DEPTH, NULL,
+                        _("Can't revert '%s' with this depth, as that requires"
+                          " reverting '%s'."),
+                        svn_dirent_local_style(root_abspath, iterpool),
+                        svn_dirent_local_style(child_abspath, iterpool));
+        }
+
+      if (kind == svn_wc__db_kind_dir)
+        SVN_ERR(verify_revert_depth(db, child_abspath, svn_depth_empty,
+                                    root_abspath, iterpool));
+    }
+
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
 
 /* This is just the guts of svn_wc_revert4() save that it accepts a
    hash CHANGELIST_HASH whose keys are changelist names instead of an
@@ -1731,6 +1821,24 @@ revert_internal(svn_wc__db_t *db,
        _("Cannot revert '%s': unsupported node kind in working copy"),
        svn_dirent_local_style(local_abspath, pool));
 
+  /* Safeguard 4:  Make sure we don't revert deeper then asked */
+  if (status == svn_wc__db_status_added
+      && db_kind == svn_wc__db_kind_dir
+      && depth >= svn_depth_empty
+      && depth < svn_depth_infinity)
+    {
+      const char *op_root_abspath;
+      SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL,
+                                       db, local_abspath, pool, pool));
+
+      /* If this node is an operation root for a copy/add, then reverting
+         it will change its descendants, if it has any. */
+      if (strcmp(local_abspath, op_root_abspath) == 0)
+        SVN_ERR(verify_revert_depth(db, local_abspath, depth,
+                                    local_abspath, pool));
+    }
+
   /* If the entry passes changelist filtering, revert it!  */
   if (svn_wc__internal_changelist_match(db, local_abspath, changelist_hash,
                                         pool))
@@ -1948,6 +2056,7 @@ svn_wc__internal_remove_from_revision_co
 {
   svn_error_t *err;
   svn_boolean_t left_something = FALSE;
+  svn_wc__db_status_t status;
   svn_wc__db_kind_t kind;
 
   /* ### This whole function should be rewritten to run inside a transaction,
@@ -1966,7 +2075,11 @@ svn_wc__internal_remove_from_revision_co
   if (cancel_func)
     SVN_ERR(cancel_func(cancel_baton));
 
-  SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE, 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,
+                               db, local_abspath, scratch_pool, scratch_pool));
 
   if (kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_symlink)
     {
@@ -2058,7 +2171,9 @@ svn_wc__internal_remove_from_revision_co
 
     }  /* done with file case */
 #ifndef SVN_WC__SINGLE_DB
-  else if (svn_wc__adm_missing(db, local_abspath, scratch_pool))
+  else if (status == svn_wc__db_status_obstructed
+           || status == svn_wc__db_status_obstructed_add
+           || status == svn_wc__db_status_obstructed_delete)
     {
       /* The directory is missing  so don't try to recurse, in
          not existing administrative data, just delete the

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/ambient_depth_filter_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/ambient_depth_filter_editor.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/ambient_depth_filter_editor.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/ambient_depth_filter_editor.c Thu Sep  9 20:26:46 2010
@@ -29,7 +29,6 @@
 #include "svn_path.h"
 
 #include "wc.h"
-#include "lock.h"
 
 /*
      Notes on the general depth-filtering strategy.

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/copy.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/copy.c Thu Sep  9 20:26:46 2010
@@ -642,7 +642,9 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
                      svn_dirent_local_style(dst_abspath, scratch_pool));
 
           case svn_wc__db_status_deleted:
+#ifndef SVN_WC__SINGLE_DB
           case svn_wc__db_status_obstructed_delete:
+#endif
           case svn_wc__db_status_not_present:
             break; /* OK to add */
 

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/crop.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/crop.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/crop.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/crop.c Thu Sep  9 20:26:46 2010
@@ -251,7 +251,9 @@ svn_wc_exclude(svn_wc_context_t *wc_ctx,
         SVN_ERR_MALFUNCTION();
 
       case svn_wc__db_status_added:
+#ifndef SVN_WC__SINGLE_DB
       case svn_wc__db_status_obstructed_add:
+#endif
         /* Would have to check parents if we want to allow this */
         return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                                  _("Cannot exclude '%s': it is to be added "
@@ -259,7 +261,9 @@ svn_wc_exclude(svn_wc_context_t *wc_ctx,
                                  svn_dirent_local_style(local_abspath,
                                                         scratch_pool));
       case svn_wc__db_status_deleted:
+#ifndef SVN_WC__SINGLE_DB
       case svn_wc__db_status_obstructed_delete:
+#endif
         /* Would have to check parents if we want to allow this */
         return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                                  _("Cannot exclude '%s': it is to be deleted "
@@ -269,7 +273,9 @@ svn_wc_exclude(svn_wc_context_t *wc_ctx,
 
       case svn_wc__db_status_normal:
       case svn_wc__db_status_incomplete:
+#ifndef SVN_WC__SINGLE_DB
       case svn_wc__db_status_obstructed:
+#endif
       default:
         break; /* Ok to exclude */
     }
@@ -357,16 +363,22 @@ svn_wc_crop_tree2(svn_wc_context_t *wc_c
                                svn_dirent_local_style(local_abspath,
                                                       scratch_pool));
 
-    if (status == svn_wc__db_status_deleted ||
-        status == svn_wc__db_status_obstructed_delete)
+    if (status == svn_wc__db_status_deleted
+#ifndef SVN_WC__SINGLE_DB
+        || status == svn_wc__db_status_obstructed_delete
+#endif
+        )
       return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                                _("Cannot crop '%s': it is going to be removed "
                                  "from repository. Try commit instead"),
                                svn_dirent_local_style(local_abspath,
                                                       scratch_pool));
 
-    if (status == svn_wc__db_status_added ||
-        status == svn_wc__db_status_obstructed_add)
+    if (status == svn_wc__db_status_added
+#ifndef SVN_WC__SINGLE_DB
+        || status == svn_wc__db_status_obstructed_add
+#endif
+        )
       return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                                _("Cannot crop '%s': it is to be added "
                                  "to the repository. Try commit instead"),

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/deprecated.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/deprecated.c Thu Sep  9 20:26:46 2010
@@ -1789,6 +1789,7 @@ svn_wc_get_diff_editor5(svn_wc_adm_acces
                                    depth,
                                    ignore_ancestry,
                                    FALSE,
+                                   FALSE,
                                    use_text_base,
                                    reverse_order,
                                    changelists,
@@ -1940,6 +1941,7 @@ svn_wc_diff5(svn_wc_adm_access_t *anchor
                        depth,
                        ignore_ancestry,
                        FALSE,
+                       FALSE,
                        changelists,
                        NULL, NULL,
                        pool));

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/diff.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/diff.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/diff.c Thu Sep  9 20:26:46 2010
@@ -227,6 +227,9 @@ struct edit_baton {
   /* Should this diff not compare copied files with their source? */
   svn_boolean_t show_copies_as_adds;
 
+  /* Are we producing a git-style diff? */
+  svn_boolean_t use_git_diff_format;
+
   /* Possibly diff repos against text-bases instead of working files. */
   svn_boolean_t use_text_base;
 
@@ -350,6 +353,7 @@ make_edit_baton(struct edit_baton **edit
                 svn_depth_t depth,
                 svn_boolean_t ignore_ancestry,
                 svn_boolean_t show_copies_as_adds,
+                svn_boolean_t use_git_diff_format,
                 svn_boolean_t use_text_base,
                 svn_boolean_t reverse_order,
                 const apr_array_header_t *changelists,
@@ -373,6 +377,7 @@ make_edit_baton(struct edit_baton **edit
   eb->depth = depth;
   eb->ignore_ancestry = ignore_ancestry;
   eb->show_copies_as_adds = show_copies_as_adds;
+  eb->use_git_diff_format = use_git_diff_format;
   eb->use_text_base = use_text_base;
   eb->reverse_order = reverse_order;
   eb->changelist_hash = changelist_hash;
@@ -586,8 +591,7 @@ file_diff(struct dir_baton *db,
                                      NULL, NULL, NULL, NULL, NULL, NULL,
                                      eb->db, local_abspath, pool, pool));
 
-  replaced = ((status == svn_wc__db_status_added
-               || status == svn_wc__db_status_obstructed_add)
+  replaced = ((status == svn_wc__db_status_added)
               && have_base
               && base_status != svn_wc__db_status_not_present);
 
@@ -660,11 +664,15 @@ file_diff(struct dir_baton *db,
   * If the item is schedule-add *with history*, then we usually want
   * to see the usual working vs. text-base comparison, which will show changes
   * made since the file was copied.  But in case we're showing copies as adds,
-  * we need to compare the copied file to the empty file. */
+  * we need to compare the copied file to the empty file. If we're doing a git
+  * diff, and the file was copied, we need to report the file as added and
+  * diff it against the text base, so that a "copied" git diff header, and
+  * possibly a diff against the copy source, will be generated for it. */
   if ((! replaced && status == svn_wc__db_status_added) ||
      (replaced && ! eb->ignore_ancestry) ||
      ((status == svn_wc__db_status_copied ||
-       status == svn_wc__db_status_moved_here) && eb->show_copies_as_adds))
+       status == svn_wc__db_status_moved_here) &&
+         (eb->show_copies_as_adds || eb->use_git_diff_format)))
     {
       const char *translated = NULL;
       const char *working_mimetype;
@@ -689,7 +697,10 @@ file_diff(struct dir_baton *db,
               pool, pool));
 
       SVN_ERR(eb->callbacks->file_added(NULL, NULL, NULL, NULL, path,
-                                        empty_file,
+                                        (! eb->show_copies_as_adds &&
+                                         eb->use_git_diff_format &&
+                                         status != svn_wc__db_status_added) ?
+                                          textbase : empty_file,
                                         translated,
                                         0, revision,
                                         NULL,
@@ -701,16 +712,15 @@ file_diff(struct dir_baton *db,
     }
   else
     {
-      svn_boolean_t modified;
       const char *translated = NULL;
       apr_hash_t *baseprops;
       const char *base_mimetype;
       const char *working_mimetype;
       apr_hash_t *workingprops;
       apr_array_header_t *propchanges;
+      svn_boolean_t modified;
 
       /* Here we deal with showing pure modifications. */
-
       SVN_ERR(svn_wc__internal_text_modified_p(&modified, eb->db,
                                                local_abspath, FALSE, TRUE,
                                                pool));
@@ -1817,6 +1827,7 @@ svn_wc_get_diff_editor6(const svn_delta_
                         svn_depth_t depth,
                         svn_boolean_t ignore_ancestry,
                         svn_boolean_t show_copies_as_adds,
+                        svn_boolean_t use_git_diff_format,
                         svn_boolean_t use_text_base,
                         svn_boolean_t reverse_order,
                         const apr_array_header_t *changelists,
@@ -1836,6 +1847,7 @@ svn_wc_get_diff_editor6(const svn_delta_
                           anchor_path, target,
                           callbacks, callback_baton,
                           depth, ignore_ancestry, show_copies_as_adds,
+                          use_git_diff_format,
                           use_text_base, reverse_order, changelists,
                           cancel_func, cancel_baton,
                           result_pool));
@@ -1891,6 +1903,7 @@ svn_wc_diff6(svn_wc_context_t *wc_ctx,
              svn_depth_t depth,
              svn_boolean_t ignore_ancestry,
              svn_boolean_t show_copies_as_adds,
+             svn_boolean_t use_git_diff_format,
              const apr_array_header_t *changelists,
              svn_cancel_func_t cancel_func,
              void *cancel_baton,
@@ -1921,6 +1934,7 @@ svn_wc_diff6(svn_wc_context_t *wc_ctx,
                           target,
                           callbacks, callback_baton,
                           depth, ignore_ancestry, show_copies_as_adds,
+                          use_git_diff_format,
                           FALSE, FALSE, changelists,
                           cancel_func, cancel_baton,
                           pool));

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/entries.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/entries.c Thu Sep  9 20:26:46 2010
@@ -272,7 +272,10 @@ get_base_info_for_deleted(svn_wc_entry_t
                                    db, parent_abspath,
                                    scratch_pool, scratch_pool));
       if (parent_status == svn_wc__db_status_added
-          || parent_status == svn_wc__db_status_obstructed_add)
+#ifndef SVN_WC__SINGLE_DB
+          || parent_status == svn_wc__db_status_obstructed_add
+#endif
+          )
         SVN_ERR(svn_wc__db_scan_addition(NULL, NULL,
                                          &parent_repos_relpath,
                                          &entry->repos,
@@ -405,7 +408,10 @@ get_base_info_for_deleted(svn_wc_entry_t
                                        db, parent_abspath,
                                        scratch_pool, scratch_pool));
           if (parent_status == svn_wc__db_status_added
-              || parent_status == svn_wc__db_status_obstructed_add)
+#ifndef SVN_WC__SINGLE_DB
+              || parent_status == svn_wc__db_status_obstructed_add
+#endif
+              )
             SVN_ERR(svn_wc__db_scan_addition(&parent_status,
                                              NULL,
                                              NULL, NULL, NULL,
@@ -649,7 +655,10 @@ read_one_entry(const svn_wc_entry_t **ne
         }
     }
   else if (status == svn_wc__db_status_deleted
-           || status == svn_wc__db_status_obstructed_delete)
+#ifndef SVN_WC__SINGLE_DB
+           || status == svn_wc__db_status_obstructed_delete
+#endif
+           )
     {
 #ifdef SVN_WC__SINGLE_DB
       svn_node_kind_t path_kind;
@@ -690,7 +699,10 @@ read_one_entry(const svn_wc_entry_t **ne
 #endif
     }
   else if (status == svn_wc__db_status_added
-           || status == svn_wc__db_status_obstructed_add)
+#ifndef SVN_WC__SINGLE_DB
+           || status == svn_wc__db_status_obstructed_add
+#endif
+           )
     {
       svn_wc__db_status_t work_status;
       const char *op_root_abspath;
@@ -772,6 +784,7 @@ read_one_entry(const svn_wc_entry_t **ne
                   && !SVN_IS_VALID_REVNUM(entry->cmt_rev))
                 entry->revision = 0;
 
+#ifndef SVN_WC__SINGLE_DB
               if (status == svn_wc__db_status_obstructed_add)
                 entry->revision = SVN_INVALID_REVNUM;
 
@@ -781,6 +794,7 @@ read_one_entry(const svn_wc_entry_t **ne
                   && status == svn_wc__db_status_obstructed_add)
                 entry->schedule = svn_wc_schedule_normal;
               else
+#endif
                 entry->schedule = svn_wc_schedule_add;
             }
         }
@@ -789,6 +803,7 @@ read_one_entry(const svn_wc_entry_t **ne
          then we cannot begin a scan for data. The original node may
          have important data. Set up stuff to kill that idea off,
          and finish up this entry.  */
+#ifndef SVN_WC__SINGLE_DB
       if (status == svn_wc__db_status_obstructed_add)
         {
           entry->cmt_rev = SVN_INVALID_REVNUM;
@@ -796,6 +811,7 @@ read_one_entry(const svn_wc_entry_t **ne
           scanned_original_relpath = NULL;
         }
       else
+#endif
         {
           SVN_ERR(svn_wc__db_scan_addition(&work_status,
                                            &op_root_abspath,
@@ -993,12 +1009,14 @@ read_one_entry(const svn_wc_entry_t **ne
       entry->schedule = svn_wc_schedule_normal;
       entry->deleted = TRUE;
     }
+#ifndef SVN_WC__SINGLE_DB
   else if (status == svn_wc__db_status_obstructed)
     {
       /* ### set some values that should (hopefully) let this directory
          ### be usable.  */
       entry->revision = SVN_INVALID_REVNUM;
     }
+#endif
   else if (status == svn_wc__db_status_absent)
     {
       entry->absent = TRUE;
@@ -1049,6 +1067,14 @@ read_one_entry(const svn_wc_entry_t **ne
 
      ### the last three should probably have an "implied" REPOS_RELPATH
   */
+#ifdef SVN_WC__SINGLE_DB
+  SVN_ERR_ASSERT(repos_relpath != NULL
+                 || entry->schedule == svn_wc_schedule_delete
+                 || status == svn_wc__db_status_not_present
+                 || status == svn_wc__db_status_absent
+                 || status == svn_wc__db_status_excluded
+                 );
+#else
   SVN_ERR_ASSERT(repos_relpath != NULL
                  || entry->schedule == svn_wc_schedule_delete
                  || status == svn_wc__db_status_obstructed
@@ -1058,6 +1084,7 @@ read_one_entry(const svn_wc_entry_t **ne
                  || status == svn_wc__db_status_absent
                  || status == svn_wc__db_status_excluded
                  );
+#endif
   if (repos_relpath)
     entry->url = svn_path_url_add_component2(entry->repos,
                                              repos_relpath,
@@ -1614,7 +1641,8 @@ svn_wc_entries_read(apr_hash_t **entries
 }
 
 
-/* */
+/* No transaction required: called from write_entry which is itself
+   transaction-wrapped. */
 static svn_error_t *
 insert_base_node(svn_sqlite__db_t *sdb,
                  const db_base_node_t *base_node,
@@ -1622,6 +1650,9 @@ insert_base_node(svn_sqlite__db_t *sdb,
 {
   svn_sqlite__stmt_t *stmt;
 
+  /* ### NODE_DATA when switching to NODE_DATA, replace the
+     query below with STMT_INSERT_BASE_NODE_DATA_FOR_ENTRY_1
+     and adjust the parameters bound. Can't do that yet. */
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                     STMT_INSERT_BASE_NODE_FOR_ENTRY));
 
@@ -1650,13 +1681,16 @@ insert_base_node(svn_sqlite__db_t *sdb,
 
   SVN_ERR(svn_sqlite__bind_int64(stmt, 7, base_node->revision));
 
+#ifndef SVN_WC__SINGLE_DB
   /* ### in per-subdir operation, if we're about to write a directory and
      ### it is *not* "this dir", then we're writing a row in the parent
      ### directory about the child. note that in the kind.  */
-  /* ### kind might be "symlink" or "unknown" */
   if (base_node->kind == svn_node_dir && *base_node->local_relpath != '\0')
     SVN_ERR(svn_sqlite__bind_text(stmt, 8, "subdir"));
-  else if (base_node->kind == svn_node_none)
+  else
+#endif
+  /* ### kind might be "symlink" or "unknown" */
+  if (base_node->kind == svn_node_none)
     SVN_ERR(svn_sqlite__bind_text(stmt, 5, "unknown"));
   else
     SVN_ERR(svn_sqlite__bind_text(stmt, 8,
@@ -1686,7 +1720,69 @@ insert_base_node(svn_sqlite__db_t *sdb,
                                         scratch_pool));
 
   /* Execute and reset the insert clause. */
-  return svn_error_return(svn_sqlite__insert(NULL, stmt));
+  SVN_ERR(svn_sqlite__insert(NULL, stmt));
+
+#ifdef SVN_WC__NODE_DATA
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                    STMT_INSERT_BASE_NODE_DATA_FOR_ENTRY_2));
+
+  SVN_ERR(svn_sqlite__bind_int64(stmt, 1, base_node->wc_id));
+  SVN_ERR(svn_sqlite__bind_text(stmt, 2, base_node->local_relpath));
+
+  if (base_node->parent_relpath)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 3, base_node->parent_relpath));
+
+  if (base_node->presence == svn_wc__db_status_not_present)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 4, "not-present"));
+  else if (base_node->presence == svn_wc__db_status_normal)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 4, "normal"));
+  else if (base_node->presence == svn_wc__db_status_absent)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 4, "absent"));
+  else if (base_node->presence == svn_wc__db_status_incomplete)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 4, "incomplete"));
+  else if (base_node->presence == svn_wc__db_status_excluded)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 4, "excluded"));
+
+#ifndef SVN_WC__SINGLE_DB
+  /* ### in per-subdir operation, if we're about to write a directory and
+     ### it is *not* "this dir", then we're writing a row in the parent
+     ### directory about the child. note that in the kind.  */
+  if (base_node->kind == svn_node_dir && *base_node->local_relpath != '\0')
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5, "subdir"));
+  else
+#endif
+  /* ### kind might be "symlink" or "unknown" */
+  if (base_node->kind == svn_node_none)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5, "unknown"));
+  else
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5,
+                                  svn_node_kind_to_word(base_node->kind)));
+
+  if (base_node->checksum)
+    SVN_ERR(svn_sqlite__bind_checksum(stmt, 6, base_node->checksum,
+                                      scratch_pool));
+
+  /* ### strictly speaking, changed_rev should be valid for present nodes. */
+  if (SVN_IS_VALID_REVNUM(base_node->changed_rev))
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 7, base_node->changed_rev));
+  if (base_node->changed_date)
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 8, base_node->changed_date));
+  if (base_node->changed_author)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 9, base_node->changed_author));
+
+  SVN_ERR(svn_sqlite__bind_text(stmt, 10, svn_depth_to_word(base_node->depth)));
+
+  if (base_node->properties)
+    SVN_ERR(svn_sqlite__bind_properties(stmt, 11, base_node->properties,
+                                        scratch_pool));
+
+  /* Execute and reset the insert clause. */
+  SVN_ERR(svn_sqlite__insert(NULL, stmt));
+
+
+#endif
+  return SVN_NO_ERROR;
 }
 
 /* */
@@ -1697,6 +1793,9 @@ insert_working_node(svn_sqlite__db_t *sd
 {
   svn_sqlite__stmt_t *stmt;
 
+  /* ### NODE_DATA when switching to NODE_DATA, replace the
+     query below with STMT_INSERT_WORKING_NODE_DATA_2
+     and adjust the parameters bound. Can't do that yet. */
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_WORKING_NODE));
 
   SVN_ERR(svn_sqlite__bind_int64(stmt, 1, working_node->wc_id));
@@ -1715,13 +1814,16 @@ insert_working_node(svn_sqlite__db_t *sd
   else if (working_node->presence == svn_wc__db_status_excluded)
     SVN_ERR(svn_sqlite__bind_text(stmt, 4, "excluded"));
 
+#ifndef SVN_WC__SINGLE_DB
   /* ### in per-subdir operation, if we're about to write a directory and
      ### it is *not* "this dir", then we're writing a row in the parent
      ### directory about the child. note that in the kind.  */
   if (working_node->kind == svn_node_dir
       && *working_node->local_relpath != '\0')
     SVN_ERR(svn_sqlite__bind_text(stmt, 5, "subdir"));
-  else if (working_node->kind == svn_node_none)
+  else
+#endif
+  if (working_node->kind == svn_node_none)
     SVN_ERR(svn_sqlite__bind_text(stmt, 5, "unknown"));
   else
     SVN_ERR(svn_sqlite__bind_text(stmt, 5,
@@ -1770,7 +1872,81 @@ insert_working_node(svn_sqlite__db_t *sd
   /* ### we should bind 'symlink_target' (20) as appropriate.  */
 
   /* Execute and reset the insert clause. */
-  return svn_error_return(svn_sqlite__insert(NULL, stmt));
+  SVN_ERR(svn_sqlite__insert(NULL, stmt));
+
+#ifdef SVN_WC__NODE_DATA
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                    STMT_INSERT_WORKING_NODE_DATA_1));
+
+  SVN_ERR(svn_sqlite__bind_int64(stmt, 1, working_node->wc_id));
+  SVN_ERR(svn_sqlite__bind_text(stmt, 2, working_node->local_relpath));
+  SVN_ERR(svn_sqlite__bind_int64(stmt, 3,
+               (*working_node->local_relpath == '\0') ? 1 : 2));
+  SVN_ERR(svn_sqlite__bind_text(stmt, 4, working_node->parent_relpath));
+
+  /* ### need rest of values */
+  if (working_node->presence == svn_wc__db_status_normal)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5, "normal"));
+  else if (working_node->presence == svn_wc__db_status_not_present)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5, "not-present"));
+  else if (working_node->presence == svn_wc__db_status_base_deleted)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5, "base-deleted"));
+  else if (working_node->presence == svn_wc__db_status_incomplete)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5, "incomplete"));
+  else if (working_node->presence == svn_wc__db_status_excluded)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5, "excluded"));
+
+#ifndef SVN_WC__SINGLE_DB
+  /* ### in per-subdir operation, if we're about to write a directory and
+     ### it is *not* "this dir", then we're writing a row in the parent
+     ### directory about the child. note that in the kind.  */
+  if (working_node->kind == svn_node_dir
+      && *working_node->local_relpath != '\0')
+    SVN_ERR(svn_sqlite__bind_text(stmt, 6, "subdir"));
+  else
+#endif
+  if (working_node->kind == svn_node_none)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 6, "unknown"));
+  else
+    SVN_ERR(svn_sqlite__bind_text(stmt, 6,
+                                  svn_node_kind_to_word(working_node->kind)));
+
+  if (working_node->copyfrom_repos_path)
+    {
+      SVN_ERR(svn_sqlite__bind_int64(stmt, 7,
+                                     working_node->copyfrom_repos_id));
+      SVN_ERR(svn_sqlite__bind_text(stmt, 8,
+                                    working_node->copyfrom_repos_path));
+      SVN_ERR(svn_sqlite__bind_int64(stmt, 9, working_node->copyfrom_revnum));
+    }
+
+  if (working_node->checksum)
+    SVN_ERR(svn_sqlite__bind_checksum(stmt, 10, working_node->checksum,
+                                      scratch_pool));
+
+  if (SVN_IS_VALID_REVNUM(working_node->changed_rev))
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 11, working_node->changed_rev));
+  if (working_node->changed_date)
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 12, working_node->changed_date));
+  if (working_node->changed_author)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 13, working_node->changed_author));
+
+  SVN_ERR(svn_sqlite__bind_text(stmt, 14,
+                                svn_depth_to_word(working_node->depth)));
+
+  if (working_node->properties)
+    SVN_ERR(svn_sqlite__bind_properties(stmt, 15, working_node->properties,
+                                        scratch_pool));
+
+  /* ### we should bind 'symlink_target' (16) as appropriate.  */
+
+  /* Execute and reset the insert clause. */
+  SVN_ERR(svn_sqlite__insert(NULL, stmt));
+
+#endif
+
+  return SVN_NO_ERROR;
 }
 
 /* */
@@ -2032,12 +2208,27 @@ write_entry(svn_wc__db_t *db,
         {
           base_node->kind = entry->kind;
 
-          if (entry->incomplete)
+#ifdef SVN_WC__SINGLE_DB
+          /* All subdirs are initially incomplete, they stop being
+             incomplete when the entries file in the subdir is
+             upgraded and remain incomplete if that doesn't happen. */
+          if (entry->kind == svn_node_dir
+              && strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR))
             {
-              /* ### nobody should have set the presence.  */
-              SVN_ERR_ASSERT(base_node->presence == svn_wc__db_status_normal);
               base_node->presence = svn_wc__db_status_incomplete;
             }
+          else
+#endif
+            {
+
+              if (entry->incomplete)
+                {
+                  /* ### nobody should have set the presence.  */
+                  SVN_ERR_ASSERT(base_node->presence
+                                 == svn_wc__db_status_normal);
+                  base_node->presence = svn_wc__db_status_incomplete;
+                }
+            }
         }
 
       if (entry->kind == svn_node_dir)
@@ -2153,6 +2344,17 @@ write_entry(svn_wc__db_t *db,
                                        svn_checksum_md5,
                                        entry->checksum, scratch_pool));
 
+#ifdef SVN_WC__SINGLE_DB
+      /* All subdirs start of incomplete, and stop being incomplete
+         when the entries file in the subdir is upgraded. */
+      if (entry->kind == svn_node_dir
+          && strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR))
+        {
+          working_node->presence = svn_wc__db_status_incomplete;
+          working_node->kind = svn_node_dir;
+        }
+      else
+#endif
       if (entry->schedule == svn_wc_schedule_delete)
         {
           if (entry->incomplete)
@@ -2227,7 +2429,8 @@ struct entries_write_baton
   svn_wc__db_t *db;
   apr_int64_t repos_id;
   apr_int64_t wc_id;
-  const char *local_abspath;
+  const char *dir_abspath;
+  const char *new_root_abspath;
   apr_hash_t *entries;
 };
 
@@ -2240,11 +2443,12 @@ entries_write_new_cb(void *baton,
 {
   struct entries_write_baton *ewb = baton;
   svn_wc__db_t *db = ewb->db;
-  const char *local_abspath = ewb->local_abspath;
+  const char *dir_abspath = ewb->dir_abspath;
+  const char *new_root_abspath = ewb->new_root_abspath;
   const svn_wc_entry_t *this_dir;
   apr_hash_index_t *hi;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-  const char *repos_root;
+  const char *repos_root, *old_root_abspath, *dir_relpath;
 
   /* Get a copy of the "this dir" entry for comparison purposes. */
   this_dir = apr_hash_get(ewb->entries, SVN_WC_ENTRY_THIS_DIR,
@@ -2254,13 +2458,24 @@ entries_write_new_cb(void *baton,
   if (! this_dir)
     return svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL,
                              _("No default entry in directory '%s'"),
-                             svn_dirent_local_style(local_abspath,
+                             svn_dirent_local_style(dir_abspath,
                                                     iterpool));
   repos_root = this_dir->repos;
 
+  old_root_abspath = svn_dirent_get_longest_ancestor(dir_abspath,
+                                                     new_root_abspath,
+                                                     scratch_pool);
+
+  SVN_ERR_ASSERT(old_root_abspath[0]);
+
+  dir_relpath = svn_dirent_skip_ancestor(old_root_abspath, dir_abspath);
+
   /* Write out "this dir" */
   SVN_ERR(write_entry(db, sdb, ewb->wc_id, ewb->repos_id, repos_root,
-                      this_dir, SVN_WC_ENTRY_THIS_DIR, local_abspath,
+                      this_dir,
+                      dir_relpath,
+                      svn_dirent_join(new_root_abspath, dir_relpath,
+                                      scratch_pool),
                       this_dir, FALSE, FALSE, iterpool));
 
   for (hi = apr_hash_first(scratch_pool, ewb->entries); hi;
@@ -2268,7 +2483,7 @@ entries_write_new_cb(void *baton,
     {
       const char *name = svn__apr_hash_index_key(hi);
       const svn_wc_entry_t *this_entry = svn__apr_hash_index_val(hi);
-      const char *child_abspath;
+      const char *child_abspath, *child_relpath;
 
       svn_pool_clear(iterpool);
 
@@ -2278,9 +2493,14 @@ entries_write_new_cb(void *baton,
 
       /* Write the entry. Pass TRUE for create locks, because we still
          use this function for upgrading old working copies. */
-      child_abspath = svn_dirent_join(local_abspath, name, iterpool);
+      child_abspath = svn_dirent_join(dir_abspath, name, iterpool);
+      child_relpath = svn_dirent_skip_ancestor(old_root_abspath, child_abspath);
       SVN_ERR(write_entry(db, sdb, ewb->wc_id, ewb->repos_id, repos_root,
-                          this_entry, name, child_abspath, this_dir,
+                          this_entry,
+                          child_relpath,
+                          svn_dirent_join(new_root_abspath, child_relpath,
+                                          scratch_pool),
+                          this_dir,
                           FALSE, TRUE,
                           iterpool));
     }
@@ -2295,7 +2515,8 @@ svn_wc__write_upgraded_entries(svn_wc__d
                                svn_sqlite__db_t *sdb,
                                apr_int64_t repos_id,
                                apr_int64_t wc_id,
-                               const char *local_abspath,
+                               const char *dir_abspath,
+                               const char *new_root_abspath,
                                apr_hash_t *entries,
                                apr_pool_t *scratch_pool)
 {
@@ -2304,7 +2525,8 @@ svn_wc__write_upgraded_entries(svn_wc__d
   ewb.db = db;
   ewb.repos_id = repos_id;
   ewb.wc_id = wc_id;
-  ewb.local_abspath = local_abspath;
+  ewb.dir_abspath = dir_abspath;
+  ewb.new_root_abspath = new_root_abspath;
   ewb.entries = entries;
 
   /* Run this operation in a transaction to speed up SQLite.
@@ -2601,6 +2823,7 @@ svn_wc_walk_entries3(const char *path,
        walk_baton, pool);
 }
 
+#ifndef SVN_WC__SINGLE_DB
 svn_error_t *
 svn_wc__temp_mark_missing_not_present(const char *local_abspath,
                                       svn_wc_context_t *wc_ctx,
@@ -2649,3 +2872,4 @@ svn_wc__temp_mark_missing_not_present(co
                              "path is marked 'missing'"),
                            svn_dirent_local_style(local_abspath, scratch_pool));
 }
+#endif

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/entries.h
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/entries.h?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/entries.h (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/entries.h Thu Sep  9 20:26:46 2010
@@ -105,6 +105,7 @@ svn_wc__write_upgraded_entries(svn_wc__d
                                apr_int64_t repos_id,
                                apr_int64_t wc_id,
                                const char *dir_abspath,
+                               const char *new_root_abspath,
                                apr_hash_t *entries,
                                apr_pool_t *scratch_pool);
 

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/lock.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/lock.c Thu Sep  9 20:26:46 2010
@@ -629,38 +629,57 @@ close_single(svn_wc_adm_access_t *adm_ac
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_wc__adm_available(svn_boolean_t *available,
-                      svn_wc__db_kind_t *kind,
-                      svn_boolean_t *obstructed,
-                      svn_wc__db_t *db,
-                      const char *local_abspath,
-                      apr_pool_t *scratch_pool)
+/* Retrieves the KIND of LOCAL_ABSPATH and whether its administrative data is
+   available in the working copy.
+
+   *AVAILABLE is set to TRUE when the node and its metadata are available,
+   otherwise to FALSE (due to obstruction, missing, absence, exclusion,
+   or a "not-present" child).
+
+   *OBSTRUCTED is set to TRUE when the node is not available because
+   it is obstructed/missing, otherwise to FALSE.
+
+   KIND and OBSTRUCTED can be NULL.
+
+   ### note: this function should go away when we move to a single
+   ### adminstrative area.  */
+static svn_error_t *
+adm_available(svn_boolean_t *available,
+              svn_wc__db_kind_t *kind,
+              svn_boolean_t *obstructed,
+              svn_wc__db_t *db,
+              const char *local_abspath,
+              apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t status;
-  svn_depth_t depth;
 
   if (kind)
     *kind = svn_wc__db_kind_unknown;
 
   SVN_ERR(svn_wc__db_read_info(&status, kind, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, &depth, 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 (obstructed)
+#ifndef SVN_WC__SINGLE_DB
     *obstructed = (status == svn_wc__db_status_obstructed ||
                    status == svn_wc__db_status_obstructed_add ||
                    status == svn_wc__db_status_obstructed_delete);
+#else
+    *obstructed = FALSE;
+#endif
 
-  *available = !(status == svn_wc__db_status_obstructed ||
-                 status == svn_wc__db_status_obstructed_add ||
-                 status == svn_wc__db_status_obstructed_delete ||
-                 status == svn_wc__db_status_absent ||
-                 status == svn_wc__db_status_excluded ||
-                 status == svn_wc__db_status_not_present ||
-                 depth == svn_depth_exclude);
+  *available = !(status == svn_wc__db_status_absent
+                 || status == svn_wc__db_status_excluded
+                 || status == svn_wc__db_status_not_present
+#ifndef SVN_WC__SINGLE_DB
+                 || status == svn_wc__db_status_obstructed
+                 || status == svn_wc__db_status_obstructed_add
+                 || status == svn_wc__db_status_obstructed_delete
+#endif
+                 );
 
   return SVN_NO_ERROR;
 }
@@ -720,12 +739,12 @@ do_open(svn_wc_adm_access_t **adm_access
 
           node_abspath = svn_dirent_join(local_abspath, name, iterpool);
 
-          SVN_ERR(svn_wc__adm_available(&available,
-                                        &kind,
-                                        &obstructed,
-                                        db,
-                                        node_abspath,
-                                        scratch_pool));
+          SVN_ERR(adm_available(&available,
+                                &kind,
+                                &obstructed,
+                                db,
+                                node_abspath,
+                                scratch_pool));
 
           if (kind != svn_wc__db_kind_dir)
             continue;
@@ -1338,8 +1357,8 @@ open_anchor(svn_wc_adm_access_t **anchor
           svn_boolean_t available, obstructed;
           svn_wc__db_kind_t kind;
 
-          err = svn_wc__adm_available(&available, &kind, &obstructed,
-                                      db, local_abspath, pool);
+          err = adm_available(&available, &kind, &obstructed,
+                              db, local_abspath, pool);
 
           if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
             svn_error_clear(err);
@@ -1562,36 +1581,6 @@ svn_wc__adm_get_db(const svn_wc_adm_acce
   return adm_access->db;
 }
 
-
-svn_boolean_t
-svn_wc__adm_missing(svn_wc__db_t *db,
-                    const char *local_abspath,
-                    apr_pool_t *scratch_pool)
-{
-  const svn_wc_adm_access_t *look;
-  svn_boolean_t available, obstructed;
-  svn_wc__db_kind_t kind;
-
-  look = get_from_shared(local_abspath, db, scratch_pool);
-
-  if (look != NULL)
-    return IS_MISSING(look);
-
-  /* When we switch to a single database an access baton can't be
-     missing, but until then it can. But if there are no access batons we
-     would always return FALSE.
-     For this case we check if an access baton could be opened
-
-*/
-
-  /* This check must match the check in do_open() */
-  svn_error_clear(svn_wc__adm_available(&available, &kind, &obstructed,
-                                        db, local_abspath,
-                                        scratch_pool));
-
-  return (kind == svn_wc__db_kind_dir) && !available && obstructed;
-}
-
 #ifndef SVN_WC__SINGLE_DB
 static svn_error_t *
 acquire_locks_recursively(svn_wc_context_t *wc_ctx,

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/lock.h
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/lock.h?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/lock.h (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/lock.h Thu Sep  9 20:26:46 2010
@@ -49,39 +49,6 @@ void svn_wc__adm_access_set_entries(svn_
    be NULL.  */
 apr_hash_t *svn_wc__adm_access_entries(svn_wc_adm_access_t *adm_access);
 
-
-/* Returns TRUE if LOCAL_ABSPATH is a working copy directory that is obstructed
-   or missing such that an access baton is not available for LOCAL_ABSPATH.
-   This means DB must also include the parent of LOCAL_ABSPATH.
-
-   This function falls back to using svn_wc__adm_available() if no access batons
-   for LOCAL_ABSPATH are stored in DB. */
-svn_boolean_t svn_wc__adm_missing(svn_wc__db_t *db,
-                                  const char *local_abspath,
-                                  apr_pool_t *scratch_pool);
-
-/* Retrieves the KIND of LOCAL_ABSPATH and whether its administrative data is
-   available in the working copy.
-
-   *AVAILABLE is set to TRUE when the node and its metadata are available,
-   otherwise to FALSE (due to obstruction, missing, absence, exclusion,
-   or a "not-present" child).
-
-   *OBSTRUCTED is set to TRUE when the node is not available because
-   it is obstructed/missing, otherwise to FALSE.
-
-   KIND and OBSTRUCTED can be NULL.
-
-   ### note: this function should go away when we move to a single
-   ### adminstrative area.  */
-svn_error_t *
-svn_wc__adm_available(svn_boolean_t *available,
-                      svn_wc__db_kind_t *kind,
-                      svn_boolean_t *obstructed,
-                      svn_wc__db_t *db,
-                      const char *local_abspath,
-                      apr_pool_t *scratch_pool);
-
 /* Same as svn_wc__adm_retrieve_internal, but takes a DB and an absolute
    directory path.  */
 svn_wc_adm_access_t *
@@ -101,14 +68,6 @@ svn_wc__internal_check_wc(int *wc_format
                           svn_boolean_t check_path,
                           apr_pool_t *scratch_pool);
 
-
-/* Ensure LOCAL_ABSPATH is still locked in DB.  Returns the error
- * SVN_ERR_WC_NOT_LOCKED if this is not the case.
- */
-svn_error_t *svn_wc__write_check(svn_wc__db_t *db,
-                                 const char *local_abspath,
-                                 apr_pool_t *scratch_pool);
-
 /* Return the working copy database associated with this access baton. */
 svn_wc__db_t *
 svn_wc__adm_get_db(const svn_wc_adm_access_t *adm_access);

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/merge.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/merge.c Thu Sep  9 20:26:46 2010
@@ -30,7 +30,6 @@
 #include "wc.h"
 #include "adm_files.h"
 #include "translate.h"
-#include "lock.h"
 #include "workqueue.h"
 
 #include "private/svn_skel.h"