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(¬ify_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(¬ify_required, conflict_old,
- local_abspath, scratch_pool));
- SVN_ERR(remove_conflict_file(¬ify_required, conflict_new,
- local_abspath, scratch_pool));
- SVN_ERR(remove_conflict_file(¬ify_required, conflict_working,
- local_abspath, scratch_pool));
- SVN_ERR(remove_conflict_file(¬ify_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(¬ify_required,
+ APR_ARRAY_IDX(conflict_files, i,
+ const char *),
+ local_abspath, scratch_pool));
+ }
+ }
if (notify_func && notify_required)
notify_func(notify_baton,