You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2012/07/12 22:24:57 UTC

svn commit: r1360909 [4/14] - in /subversion/branches/inheritable-props: ./ build/generator/ build/generator/templates/ notes/wc-ng/ subversion/bindings/javahl/native/ subversion/bindings/javahl/tests/org/apache/subversion/javahl/ subversion/bindings/j...

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/structure
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/structure?rev=1360909&r1=1360908&r2=1360909&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/structure (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/structure Thu Jul 12 20:24:53 2012
@@ -40,6 +40,9 @@ repository) is:
   revprops/           Subdirectory containing rev-props
     <shard>/          Shard directory, if sharding is in use (see below)
       <revnum>        File containing rev-props for <revnum>
+    <shard>.pack/     Pack directory, if the repo has been packed (see below)
+      <rev>.<count>   Pack file, if the repository has been packed (see below)
+      manifest        Pack manifest file, if a pack file exists (see below)
     revprops.db       SQLite database of the packed revision properties
   transactions/       Subdirectory containing transactions
     <txnid>.txn/      Directory containing transaction <txnid>
@@ -134,6 +137,7 @@ The formats are:
   Format 3, understood by Subversion 1.5+
   Format 4, understood by Subversion 1.6+
   Format 5, understood by Subversion 1.7-dev, never released
+  Format 6, understood by Subversion 1.8
 
 The differences between the formats are:
 
@@ -173,6 +177,12 @@ Revision changed paths list:
   Format 1-3: Does not contain the node's kind.
   Format 4+:  Contains the node's kind.
 
+Shard packing:
+  Format 4:   Applied to revision data only.
+  Format 5:   Revprops would be packed independently of revision data.
+  Format 6+:  Applied equally to revision data and revprop data
+    (i.e. same min packed revision)
+
 # Incomplete list.  See SVN_FS_FS__MIN_*_FORMAT
 
 
@@ -232,6 +242,79 @@ See r1143829 of this file:
 http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/structure?view=markup&pathrev=1143829
 
 
+Packing revision properties (format 6+)
+---------------------------
+
+Similarly to the revision data, packing will concatenate multiple
+revprops into a single file.  Since they are mutable data, we put an
+upper limit to the size of these files:  We will concatenate the data
+up to the limit and then use a new file for the following revisions.
+
+The limit can be set and changed at will in the configuration file. 
+It is 64kB by default.  Because a pack file must contain at least one
+complete property list, files containing just one revision may exceed
+that limit.
+
+Furthermore, pack files can be compressed which saves about 75% of
+disk space.  A configuration file flag enables the compression; it is
+off by default and may be switched on and off at will.  The pack size
+limit is always applied to the uncompressed data.  For this reason,
+the default is 256kB while compression has been enabled.
+
+Files are named after their start revision as "<rev>.<counter>" where
+counter will be increased whenever we rewrite a pack file due to a
+revprop change.  The manifest file contains the list of pack file
+names, one line for each revision.
+
+Many tools track repository global data in revision properties at 
+revision 0.  To minimize I/O overhead for those applications,  we
+will never pack that revision, i.e. its data is always being kept
+in revprops/0/0.
+
+Pack file format
+
+  Top level: <length><packed container>
+
+  We always apply data compression to the pack file - using the
+  SVN_DELTA_COMPRESSION_LEVEL_NONE level if compression is disabled.
+  <length> is being encoded using the variable-length svndiff integer
+  format.
+
+  container := header '\n' (revprops)+
+  header    := start_rev '\n' rev_count '\n' (size '\n')+
+
+  All numbers in the header are given as ASCII decimals.  rev_count
+  is the number of revisions packed into this container.  There must
+  be exactly as many "size" and serialized "revprops".  The "size"
+  values in the list are the length in bytes of the serialized
+  revprops of the respective revision.
+
+Writing to packed revprops
+
+  The old pack file is being read and the new revprops serialized.
+  If they fit into the same pack file, a temp file with the new
+  content gets written and moved into place just like an non-packed
+  revprop file would. No name change or manifest update required.
+
+  If they don't fit into the same pack file,  i.e. exceed the pack
+  size limit,  the pack will be split into 2 or 3 new packs just
+  before and / or after the modified revision.
+
+  In the current implementation, they will never be merged again.
+  To minimize fragmentation, the initial packing process will only
+  use about 90% of the limit, i.e. leave some room for growth.
+
+  When a pack file gets split, its counter is being increased
+  creating a new file and leaving the old content in place and
+  available for concurrent readers.  Only after the new manifest
+  file got moved into place, will the old pack files be deleted. 
+
+  Write access to revprops is being serialized by the global
+  filesystem write lock.  We only need to build a few retries into
+  the reader code to gracefully handle manifest changes and pack
+  file deletions.
+
+
 Node-revision IDs
 -----------------
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c?rev=1360909&r1=1360908&r2=1360909&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c Thu Jul 12 20:24:53 2012
@@ -3924,6 +3924,7 @@ svn_fs_fs__verify_root(svn_fs_root_t *ro
     const svn_fs_id_t *pred_id;
     dag_node_t *pred;
     svn_revnum_t pred_rev;
+    svn_revnum_t delta;
 
     /* Only r0 should have no predecessor. */
     SVN_ERR(svn_fs_fs__dag_get_predecessor_id(&pred_id, frd->root_dir));
@@ -3941,10 +3942,27 @@ svn_fs_fs__verify_root(svn_fs_root_t *ro
       {
         SVN_ERR(svn_fs_fs__dag_get_node(&pred, root->fs, pred_id, pool));
         SVN_ERR(svn_fs_fs__dag_get_revision(&pred_rev, pred, pool));
-        if (pred_rev+1 != root->rev)
-          /* Issue #4129. */
+
+        /* Issue #4129: bogus predecessors. */
+        /* Check 1: predecessor must be an earlier revision.
+         */
+        if (pred_rev >= root->rev)
+          return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                                   "r%ld's root node's predecessor is r%ld"
+                                   " but must be earlier revision",
+                                   root->rev, pred_rev);
+
+        /* Check 2: distances must be a power of 2.
+         * Note that this condition is not defined by the FSFS format but
+         * merely a byproduct of the current implementation. Therefore,
+         * it may help to spot corruptions for the time being but might
+         * need to be removed / relaxed in later versions.
+         */
+        delta = root->rev - pred_rev;
+        if (delta & (delta - 1))
           return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
-                                   "r%ld's root node's predecessor is r%ld",
+                                   "r%ld's root node's predecessor is r%ld"
+                                   " but the delta must be a power of 2",
                                    root->rev, pred_rev);
       }
   }

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/dump.c?rev=1360909&r1=1360908&r2=1360909&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/dump.c Thu Jul 12 20:24:53 2012
@@ -72,7 +72,8 @@ store_delta(apr_file_t **tempfile, svn_f
   /* Compute the delta and send it to the temporary file. */
   SVN_ERR(svn_fs_get_file_delta_stream(&delta_stream, oldroot, oldpath,
                                        newroot, newpath, pool));
-  svn_txdelta_to_svndiff2(&wh, &whb, temp_stream, 0, pool);
+  svn_txdelta_to_svndiff3(&wh, &whb, temp_stream, 0,
+                          SVN_DELTA_COMPRESSION_LEVEL_DEFAULT, pool);
   SVN_ERR(svn_txdelta_send_txstream(delta_stream, wh, whb, pool));
 
   /* Get the length of the temporary file and rewind it. */

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/fs-wrap.c?rev=1360909&r1=1360908&r2=1360909&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/fs-wrap.c Thu Jul 12 20:24:53 2012
@@ -660,8 +660,8 @@ svn_repos_fs_get_mergeinfo(svn_mergeinfo
      the change itself. */
   /* ### TODO(reint): ... but how about descendant merged-to paths? */
   if (readable_paths->nelts > 0)
-    SVN_ERR(svn_fs_get_mergeinfo(mergeinfo, root, readable_paths, inherit,
-                                 include_descendants, pool));
+    SVN_ERR(svn_fs_get_mergeinfo2(mergeinfo, root, readable_paths, inherit,
+                                  include_descendants, TRUE, pool, pool));
   else
     *mergeinfo = apr_hash_make(pool);
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c?rev=1360909&r1=1360908&r2=1360909&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c Thu Jul 12 20:24:53 2012
@@ -1564,7 +1564,8 @@ svn_repos_has_capability(svn_repos_t *re
 
       SVN_ERR(svn_fs_revision_root(&root, repos->fs, 0, pool));
       APR_ARRAY_PUSH(paths, const char *) = "";
-      err = svn_fs_get_mergeinfo(&ignored, root, paths, FALSE, FALSE, pool);
+      err = svn_fs_get_mergeinfo2(&ignored, root, paths, FALSE, FALSE,
+                                  TRUE, pool, pool);
 
       if (err)
         {

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/deprecated.c?rev=1360909&r1=1360908&r2=1360909&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/deprecated.c Thu Jul 12 20:24:53 2012
@@ -1056,14 +1056,6 @@ svn_path_canonicalize(const char *path, 
     return svn_dirent_canonicalize(path, pool);
 }
 
-svn_boolean_t
-svn_path_is_canonical(const char *path, apr_pool_t *pool)
-{
-  return svn_uri_is_canonical(path, pool) ||
-      svn_dirent_is_canonical(path, pool) ||
-      svn_relpath_is_canonical(path);
-}
-
 
 /*** From mergeinfo.c ***/
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/dirent_uri.c?rev=1360909&r1=1360908&r2=1360909&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/dirent_uri.c Thu Jul 12 20:24:53 2012
@@ -1562,10 +1562,32 @@ svn_dirent_get_absolute(const char **pab
                                APR_FILEPATH_NOTRELATIVE,
                                pool);
   if (apr_err)
-    return svn_error_createf(SVN_ERR_BAD_FILENAME,
-                             svn_error_create(apr_err, NULL, NULL),
-                             _("Couldn't determine absolute path of '%s'"),
-                             svn_dirent_local_style(relative, pool));
+    {
+      /* In some cases when the passed path or its ancestor(s) do not exist
+         or no longer exist apr returns an error.
+
+         In many of these cases we would like to return a path anyway, when the
+         passed path was already a safe absolute path. So check for that now to
+         avoid an error.
+
+         svn_dirent_is_absolute() doesn't perform the necessary checks to see
+         if the path doesn't need post processing to be in the canonical absolute
+         format.
+         */
+
+      if (svn_dirent_is_absolute(relative)
+          && svn_dirent_is_canonical(relative, pool)
+          && !svn_path_is_backpath_present(relative))
+        {
+          *pabsolute = apr_pstrdup(pool, relative);
+          return SVN_NO_ERROR;
+        }
+
+      return svn_error_createf(SVN_ERR_BAD_FILENAME,
+                               svn_error_create(apr_err, NULL, NULL),
+                               _("Couldn't determine absolute path of '%s'"),
+                               svn_dirent_local_style(relative, pool));
+    }
 
   SVN_ERR(svn_path_cstring_to_utf8(pabsolute, buffer, pool));
   *pabsolute = svn_dirent_canonicalize(*pabsolute, pool);

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/io.c?rev=1360909&r1=1360908&r2=1360909&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/io.c Thu Jul 12 20:24:53 2012
@@ -185,7 +185,7 @@ try_utf8_from_internal_style(const char 
   /* Special case. */
   if (path == NULL)
     return "(NULL)";
-  
+
   /* (try to) convert PATH to UTF-8. If that fails, continue with the plain
    * PATH because it is the best we have. It may actually be UTF-8 already.
    */
@@ -1311,6 +1311,43 @@ svn_io_filesizes_different_p(svn_boolean
 
 
 svn_error_t *
+svn_io_filesizes_three_different_p(svn_boolean_t *different_p12,
+                                   svn_boolean_t *different_p23,
+                                   svn_boolean_t *different_p13,
+                                   const char *file1,
+                                   const char *file2,
+                                   const char *file3,
+                                   apr_pool_t *scratch_pool)
+{
+  apr_finfo_t finfo1, finfo2, finfo3;
+  apr_status_t status1, status2, status3;
+  const char *file1_apr, *file2_apr, *file3_apr;
+
+  /* Not using svn_io_stat() because don't want to generate
+     svn_error_t objects for non-error conditions. */
+
+  SVN_ERR(cstring_from_utf8(&file1_apr, file1, scratch_pool));
+  SVN_ERR(cstring_from_utf8(&file2_apr, file2, scratch_pool));
+  SVN_ERR(cstring_from_utf8(&file3_apr, file3, scratch_pool));
+
+  /* Stat all three files */
+  status1 = apr_stat(&finfo1, file1_apr, APR_FINFO_MIN, scratch_pool);
+  status2 = apr_stat(&finfo2, file2_apr, APR_FINFO_MIN, scratch_pool);
+  status3 = apr_stat(&finfo3, file3_apr, APR_FINFO_MIN, scratch_pool);
+
+  /* If we got an error stat'ing a file, it could be because the
+     file was removed... or who knows.  Whatever the case, we
+     don't know if the filesizes are definitely different, so
+     assume that they're not. */
+  *different_p12 = !status1 && !status2 && finfo1.size != finfo2.size;
+  *different_p23 = !status2 && !status3 && finfo2.size != finfo3.size;
+  *different_p13 = !status1 && !status3 && finfo1.size != finfo3.size;
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
 svn_io_file_checksum2(svn_checksum_t **checksum,
                       const char *file,
                       svn_checksum_kind_t kind,
@@ -1994,7 +2031,7 @@ svn_io_unlock_open_file(apr_file_t *lock
   if (apr_err)
     return svn_error_wrap_apr(apr_err, _("Can't unlock file '%s'"),
                               try_utf8_from_internal_style(fname, pool));
-  
+
 /* On Windows and OS/2 file locks are automatically released when
    the file handle closes */
 #if !defined(WIN32) && !defined(__OS2__)
@@ -4076,6 +4113,138 @@ contents_identical_p(svn_boolean_t *iden
 
 
 
+/* Do a byte-for-byte comparison of FILE1, FILE2 and FILE3. */
+static svn_error_t *
+contents_three_identical_p(svn_boolean_t *identical_p12,
+                           svn_boolean_t *identical_p23,
+                           svn_boolean_t *identical_p13,
+                           const char *file1,
+                           const char *file2,
+                           const char *file3,
+                           apr_pool_t *scratch_pool)
+{
+  svn_error_t *err;
+  apr_size_t bytes_read1, bytes_read2, bytes_read3;
+  char *buf1 = apr_palloc(scratch_pool, SVN__STREAM_CHUNK_SIZE);
+  char *buf2 = apr_palloc(scratch_pool, SVN__STREAM_CHUNK_SIZE);
+  char *buf3 = apr_palloc(scratch_pool, SVN__STREAM_CHUNK_SIZE);
+  apr_file_t *file1_h;
+  apr_file_t *file2_h;
+  apr_file_t *file3_h;
+  svn_boolean_t eof1 = FALSE;
+  svn_boolean_t eof2 = FALSE;
+  svn_boolean_t eof3 = FALSE;
+  svn_boolean_t read_1, read_2, read_3;
+
+  SVN_ERR(svn_io_file_open(&file1_h, file1, APR_READ, APR_OS_DEFAULT,
+                           scratch_pool));
+
+  err = svn_io_file_open(&file2_h, file2, APR_READ, APR_OS_DEFAULT,
+                         scratch_pool);
+
+  if (err)
+    return svn_error_trace(
+               svn_error_compose_create(err,
+                                        svn_io_file_close(file1_h, scratch_pool)));
+
+  err = svn_io_file_open(&file3_h, file3, APR_READ, APR_OS_DEFAULT,
+                         scratch_pool);
+
+  if (err)
+      return svn_error_trace(
+               svn_error_compose_create(
+                    err,
+                    svn_error_compose_create(svn_io_file_close(file1_h,
+                                                          scratch_pool),
+                                             svn_io_file_close(file2_h,
+                                                          scratch_pool))));
+
+  /* assume TRUE, until disproved below */
+  *identical_p12 = *identical_p23 = *identical_p13 = TRUE;
+  /* We need to read as long as no error occurs, and as long as one of the
+   * flags could still change due to a read operation */
+  while (!err
+        && ((*identical_p12 && !eof1 && !eof2)
+            || (*identical_p23 && !eof2 && !eof3)
+            || (*identical_p13 && !eof1 && !eof3)))
+    {
+      read_1 = read_2 = read_3 = FALSE;
+
+      /* As long as a file is not at the end yet, and it is still
+       * potentially identical to another file, we read the next chunk.*/
+      if (!eof1 && (identical_p12 || identical_p13))
+        {
+          err = svn_io_file_read_full2(file1_h, buf1,
+                                   SVN__STREAM_CHUNK_SIZE, &bytes_read1,
+                                   &eof1, scratch_pool);
+          if (err)
+              break;
+          read_1 = TRUE;
+        }
+
+      if (!eof2 && (identical_p12 || identical_p23))
+        {
+          err = svn_io_file_read_full2(file2_h, buf2,
+                                   SVN__STREAM_CHUNK_SIZE, &bytes_read2,
+                                   &eof2, scratch_pool);
+          if (err)
+              break;
+          read_2 = TRUE;
+        }
+
+      if (!eof3 && (identical_p13 || identical_p23))
+        {
+          err = svn_io_file_read_full2(file3_h, buf3,
+                                   SVN__STREAM_CHUNK_SIZE, &bytes_read3,
+                                   &eof3, scratch_pool);
+          if (err)
+              break;
+          read_3 = TRUE;
+        }
+
+      /* If the files are still marked identical, and at least one of them
+       * is not at the end of file, we check whether they differ, and set
+       * their flag to false then. */
+      if (*identical_p12
+          && (read_1 || read_2)
+          && ((eof1 != eof2)
+              || (bytes_read1 != bytes_read2)
+              || memcmp(buf1, buf2, bytes_read1)))
+        {
+          *identical_p12 = FALSE;
+        }
+
+      if (*identical_p23
+          && (read_2 || read_3)
+          && ((eof2 != eof3)
+              || (bytes_read2 != bytes_read3)
+              || memcmp(buf2, buf3, bytes_read2)))
+        {
+          *identical_p23 = FALSE;
+        }
+
+      if (*identical_p13
+          && (read_1 || read_3)
+          && ((eof1 != eof3)
+              || (bytes_read1 != bytes_read3)
+              || memcmp(buf1, buf3, bytes_read3)))
+        {
+          *identical_p13 = FALSE;
+        }
+    }
+
+  return svn_error_trace(
+           svn_error_compose_create(
+                err,
+                svn_error_compose_create(
+                    svn_io_file_close(file1_h, scratch_pool),
+                    svn_error_compose_create(
+                        svn_io_file_close(file2_h, scratch_pool),
+                        svn_io_file_close(file3_h, scratch_pool)))));
+}
+
+
+
 svn_error_t *
 svn_io_files_contents_same_p(svn_boolean_t *same,
                              const char *file1,
@@ -4102,6 +4271,55 @@ svn_io_files_contents_same_p(svn_boolean
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_io_files_contents_three_same_p(svn_boolean_t *same12,
+                                   svn_boolean_t *same23,
+                                   svn_boolean_t *same13,
+                                   const char *file1,
+                                   const char *file2,
+                                   const char *file3,
+                                   apr_pool_t *scratch_pool)
+{
+  svn_boolean_t diff_size12, diff_size23, diff_size13;
+
+  SVN_ERR(svn_io_filesizes_three_different_p(&diff_size12,
+                                             &diff_size23,
+                                             &diff_size13,
+                                             file1,
+                                             file2,
+                                             file3,
+                                             scratch_pool));
+
+  if (diff_size12 && diff_size23 && diff_size13)
+    {
+      *same12 = *same23 = *same13 = FALSE;
+    }
+  else if (diff_size12 && diff_size23)
+    {
+      *same12 = *same23 = FALSE;
+      SVN_ERR(contents_identical_p(same13, file1, file3, scratch_pool));
+    }
+  else if (diff_size23 && diff_size13)
+    {
+      *same23 = *same13 = FALSE;
+      SVN_ERR(contents_identical_p(same12, file1, file2, scratch_pool));
+    }
+  else if (diff_size12 && diff_size13)
+    {
+      *same12 = *same13 = FALSE;
+      SVN_ERR(contents_identical_p(same23, file2, file3, scratch_pool));
+    }
+  else
+    {
+      SVN_ERR_ASSERT(!diff_size12 && !diff_size23 && !diff_size13);
+      SVN_ERR(contents_three_identical_p(same12, same23, same13,
+                                         file1, file2, file3,
+                                         scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
 #ifdef WIN32
 /* Counter value of file_mktemp request (used in a threadsafe way), to make
    sure that a single process normally never generates the same tempname
@@ -4351,3 +4569,86 @@ svn_io_open_unique_file3(apr_file_t **fi
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_io_file_readline(apr_file_t *file,
+                     svn_stringbuf_t **stringbuf,
+                     const char **eol,
+                     svn_boolean_t *eof,
+                     apr_size_t max_len,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
+{
+  svn_stringbuf_t *str;
+  const char *eol_str;
+  apr_size_t numbytes;
+  char c;
+  apr_size_t len;
+  svn_boolean_t found_eof;
+
+  str = svn_stringbuf_create_ensure(80, result_pool);
+
+  /* Read bytes into STR up to and including, but not storing,
+   * the next EOL sequence. */
+  eol_str = NULL;
+  numbytes = 1;
+  len = 0;
+  found_eof = FALSE;
+  while (!found_eof)
+    {
+      if (len < max_len)
+        SVN_ERR(svn_io_file_read_full2(file, &c, sizeof(c), &numbytes,
+                                       &found_eof, scratch_pool));
+      len++;
+      if (numbytes != 1 || len > max_len)
+        {
+          found_eof = TRUE;
+          break;
+        }
+
+      if (c == '\n')
+        {
+          eol_str = "\n";
+        }
+      else if (c == '\r')
+        {
+          eol_str = "\r";
+
+          if (!found_eof && len < max_len)
+            {
+              apr_off_t pos;
+
+              /* Check for "\r\n" by peeking at the next byte. */
+              pos = 0;
+              SVN_ERR(svn_io_file_seek(file, APR_CUR, &pos, scratch_pool));
+              SVN_ERR(svn_io_file_read_full2(file, &c, sizeof(c), &numbytes,
+                                             &found_eof, scratch_pool));
+              if (numbytes == 1 && c == '\n')
+                {
+                  eol_str = "\r\n";
+                  len++;
+                }
+              else
+                {
+                  /* Pretend we never peeked. */
+                  SVN_ERR(svn_io_file_seek(file, APR_SET, &pos, scratch_pool));
+                  found_eof = FALSE;
+                  numbytes = 1;
+                }
+            }
+        }
+      else
+        svn_stringbuf_appendbyte(str, c);
+
+      if (eol_str)
+        break;
+    }
+
+  if (eol)
+    *eol = eol_str;
+  if (eof)
+    *eof = found_eof;
+  *stringbuf = str;
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/path.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/path.c?rev=1360909&r1=1360908&r2=1360909&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/path.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/path.c Thu Jul 12 20:24:53 2012
@@ -91,16 +91,33 @@ is_canonical(const char *path,
 #endif
 
 
-char *svn_path_join(const char *base,
-                    const char *component,
-                    apr_pool_t *pool)
+/* functionality of svn_path_is_canonical but without the deprecation */
+static svn_boolean_t
+svn_path_is_canonical_internal(const char *path, apr_pool_t *pool)
+{
+  return svn_uri_is_canonical(path, pool) ||
+      svn_dirent_is_canonical(path, pool) ||
+      svn_relpath_is_canonical(path);
+}
+
+svn_boolean_t
+svn_path_is_canonical(const char *path, apr_pool_t *pool)
+{
+  return svn_path_is_canonical_internal(path, pool);
+}
+
+/* functionality of svn_path_join but without the deprecation */
+static char *
+svn_path_join_internal(const char *base,
+                       const char *component,
+                       apr_pool_t *pool)
 {
   apr_size_t blen = strlen(base);
   apr_size_t clen = strlen(component);
   char *path;
 
-  assert(svn_path_is_canonical(base, pool));
-  assert(svn_path_is_canonical(component, pool));
+  assert(svn_path_is_canonical_internal(base, pool));
+  assert(svn_path_is_canonical_internal(component, pool));
 
   /* If the component is absolute, then return it.  */
   if (*component == '/')
@@ -124,6 +141,13 @@ char *svn_path_join(const char *base,
   return path;
 }
 
+char *svn_path_join(const char *base,
+                    const char *component,
+                    apr_pool_t *pool)
+{
+  return svn_path_join_internal(base, component, pool);
+}
+
 char *svn_path_join_many(apr_pool_t *pool, const char *base, ...)
 {
 #define MAX_SAVED_LENGTHS 10
@@ -140,7 +164,7 @@ char *svn_path_join_many(apr_pool_t *poo
 
   total_len = strlen(base);
 
-  assert(svn_path_is_canonical(base, pool));
+  assert(svn_path_is_canonical_internal(base, pool));
 
   if (total_len == 1 && *base == '/')
     base_is_root = TRUE;
@@ -160,7 +184,7 @@ char *svn_path_join_many(apr_pool_t *poo
     {
       len = strlen(s);
 
-      assert(svn_path_is_canonical(s, pool));
+      assert(svn_path_is_canonical_internal(s, pool));
 
       if (SVN_PATH_IS_EMPTY(s))
         continue;
@@ -353,7 +377,7 @@ svn_path_dirname(const char *path, apr_p
 {
   apr_size_t len = strlen(path);
 
-  assert(svn_path_is_canonical(path, pool));
+  assert(svn_path_is_canonical_internal(path, pool));
 
   return apr_pstrmemdup(pool, path, previous_segment(path, len));
 }
@@ -365,7 +389,7 @@ svn_path_basename(const char *path, apr_
   apr_size_t len = strlen(path);
   apr_size_t start;
 
-  assert(svn_path_is_canonical(path, pool));
+  assert(svn_path_is_canonical_internal(path, pool));
 
   if (len == 1 && path[0] == '/')
     start = 0;
@@ -593,7 +617,7 @@ svn_path_decompose(const char *path,
   apr_array_header_t *components =
     apr_array_make(pool, 1, sizeof(const char *));
 
-  assert(svn_path_is_canonical(path, pool));
+  assert(svn_path_is_canonical_internal(path, pool));
 
   if (SVN_PATH_IS_EMPTY(path))
     return components;  /* ### Should we return a "" component? */

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/adm_ops.c?rev=1360909&r1=1360908&r2=1360909&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/adm_ops.c Thu Jul 12 20:24:53 2012
@@ -691,8 +691,8 @@ svn_wc__delete_many(svn_wc_context_t *wc
 
       /* Read conflicts, to allow deleting the markers after updating the DB */
       if (!keep_local && conflicted)
-        SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
-                                          scratch_pool, iterpool));
+        SVN_ERR(svn_wc__read_conflicts(&conflicts, db, local_abspath,
+                                       scratch_pool, iterpool));
 
     }
 
@@ -836,12 +836,13 @@ svn_wc__delete_internal(svn_wc_context_t
 
   /* Read conflicts, to allow deleting the markers after updating the DB */
   if (!keep_local && conflicted)
-    SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
-                                      scratch_pool, scratch_pool));
+    SVN_ERR(svn_wc__read_conflicts(&conflicts, db, local_abspath,
+                                   scratch_pool, scratch_pool));
 
   SVN_ERR(svn_wc__db_op_delete(db, local_abspath, moved_to_abspath,
-                               notify_func, notify_baton,
+                               NULL, NULL,
                                cancel_func, cancel_baton,
+                               notify_func, notify_baton,
                                pool));
 
   if (!keep_local && conflicted && conflicts != NULL)
@@ -1609,10 +1610,7 @@ revert_restore(svn_wc__db_t *db,
   svn_kind_t kind;
   svn_node_kind_t on_disk;
   svn_boolean_t notify_required;
-  const char *conflict_old;
-  const char *conflict_new;
-  const char *conflict_working;
-  const char *prop_reject;
+  const apr_array_header_t *conflict_files;
   svn_filesize_t recorded_size;
   apr_time_t recorded_mod_time;
   apr_finfo_t finfo;
@@ -1626,8 +1624,7 @@ revert_restore(svn_wc__db_t *db,
     SVN_ERR(cancel_func(cancel_baton));
 
   SVN_ERR(svn_wc__db_revert_list_read(&notify_required,
-                                      &conflict_old, &conflict_new,
-                                      &conflict_working, &prop_reject,
+                                      &conflict_files,
                                       &copied_here, &reverted_kind,
                                       db, local_abspath,
                                       scratch_pool, scratch_pool));
@@ -1894,14 +1891,17 @@ revert_restore(svn_wc__db_t *db,
       notify_required = TRUE;
     }
 
-  SVN_ERR(remove_conflict_file(&notify_required, conflict_old,
-                               local_abspath, scratch_pool));
-  SVN_ERR(remove_conflict_file(&notify_required, conflict_new,
-                               local_abspath, scratch_pool));
-  SVN_ERR(remove_conflict_file(&notify_required, conflict_working,
-                               local_abspath, scratch_pool));
-  SVN_ERR(remove_conflict_file(&notify_required, prop_reject,
-                               local_abspath, scratch_pool));
+  if (conflict_files)
+    {
+      int i;
+      for (i = 0; i < conflict_files->nelts; i++)
+        {
+          SVN_ERR(remove_conflict_file(&notify_required,
+                                       APR_ARRAY_IDX(conflict_files, i,
+                                                     const char *),
+                                       local_abspath, scratch_pool));
+        }
+    }
 
   if (notify_func && notify_required)
     notify_func(notify_baton,