You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/11/26 19:55:54 UTC
svn commit: r1039511 [3/5] - in /subversion/branches/performance: ./ build/
subversion/bindings/swig/perl/native/ subversion/bindings/swig/ruby/test/
subversion/include/ subversion/include/private/ subversion/libsvn_client/
subversion/libsvn_delta/ sub...
Modified: subversion/branches/performance/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/dirent_uri.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/dirent_uri.c Fri Nov 26 18:55:51 2010
@@ -63,7 +63,13 @@ typedef enum {
type_relpath
} path_type_t;
-
+
+/**** Forward declarations *****/
+
+static svn_boolean_t
+relpath_is_canonical(const char *relpath);
+
+
/**** Internal implementation functions *****/
/* Return an internal-style new path based on PATH, allocated in POOL.
@@ -1189,8 +1195,8 @@ svn_relpath_join(const char *base,
apr_size_t clen = strlen(component);
char *path;
- assert(svn_relpath_is_canonical(base, pool));
- assert(svn_relpath_is_canonical(component, pool));
+ assert(relpath_is_canonical(base));
+ assert(relpath_is_canonical(component));
/* If either is empty return the other */
if (blen == 0)
@@ -1316,7 +1322,7 @@ svn_relpath_dirname(const char *relpath,
{
apr_size_t len = strlen(relpath);
- assert(svn_relpath_is_canonical(relpath, pool));
+ assert(relpath_is_canonical(relpath));
return apr_pstrmemdup(pool, relpath,
relpath_previous_segment(relpath, len));
@@ -1329,7 +1335,7 @@ svn_relpath_basename(const char *relpath
apr_size_t len = strlen(relpath);
apr_size_t start;
- assert(!pool || svn_relpath_is_canonical(relpath, pool));
+ assert(relpath_is_canonical(relpath));
start = len;
while (start > 0 && relpath[start - 1] != '/')
@@ -1422,6 +1428,9 @@ svn_relpath_get_longest_ancestor(const c
const char *relpath2,
apr_pool_t *pool)
{
+ assert(relpath_is_canonical(relpath1));
+ assert(relpath_is_canonical(relpath2));
+
return apr_pstrndup(pool, relpath1,
get_longest_ancestor_length(type_relpath, relpath1,
relpath2, pool));
@@ -1497,6 +1506,9 @@ svn_relpath_is_child(const char *parent_
const char *child_relpath,
apr_pool_t *pool)
{
+ /* assert(relpath_is_canonical(parent_relpath)); */
+ /* assert(relpath_is_canonical(child_relpath)); */
+
return is_child(type_relpath, parent_relpath, child_relpath, pool);
}
@@ -1517,6 +1529,9 @@ svn_dirent_is_ancestor(const char *paren
svn_boolean_t
svn_relpath_is_ancestor(const char *parent_relpath, const char *child_relpath)
{
+ assert(relpath_is_canonical(parent_relpath));
+ assert(relpath_is_canonical(child_relpath));
+
return is_ancestor(type_relpath, parent_relpath, child_relpath);
}
@@ -1563,15 +1578,15 @@ svn_relpath_skip_ancestor(const char *pa
{
apr_size_t len = strlen(parent_relpath);
+ assert(relpath_is_canonical(parent_relpath));
+ assert(relpath_is_canonical(child_relpath));
+
if (0 != memcmp(parent_relpath, child_relpath, len))
return child_relpath; /* parent_relpath is no ancestor of child_relpath */
if (child_relpath[len] == 0)
return ""; /* parent_relpath == child_relpath */
- if (len == 1 && child_relpath[0] == '/')
- return child_relpath + 1;
-
if (child_relpath[len] == '/')
return child_relpath + len + 1;
@@ -1737,12 +1752,11 @@ svn_dirent_is_canonical(const char *dire
}
#endif /* SVN_USE_DOS_PATHS */
- return svn_relpath_is_canonical(ptr, pool);
+ return relpath_is_canonical(ptr);
}
-svn_boolean_t
-svn_relpath_is_canonical(const char *relpath,
- apr_pool_t *pool)
+static svn_boolean_t
+relpath_is_canonical(const char *relpath)
{
const char *ptr = relpath, *seg = relpath;
@@ -1787,6 +1801,13 @@ svn_relpath_is_canonical(const char *rel
}
svn_boolean_t
+svn_relpath_is_canonical(const char *relpath,
+ apr_pool_t *pool)
+{
+ return relpath_is_canonical(relpath);
+}
+
+svn_boolean_t
svn_uri_is_canonical(const char *uri, apr_pool_t *pool)
{
const char *ptr = uri, *seg = uri;
@@ -2444,3 +2465,167 @@ svn_uri_get_file_url_from_dirent(const c
return SVN_NO_ERROR;
}
+
+
+/* ------------------------ The fspath API ------------------------ */
+
+svn_boolean_t
+svn_fspath__is_canonical(const char *fspath)
+{
+ return fspath[0] == '/' && relpath_is_canonical(fspath + 1);
+}
+
+
+const char *
+svn_fspath__is_child(const char *parent_fspath,
+ const char *child_fspath,
+ apr_pool_t *pool)
+{
+ const char *result;
+ assert(svn_fspath__is_canonical(parent_fspath));
+ assert(svn_fspath__is_canonical(child_fspath));
+
+#ifdef FSPATH_USE_URI
+ result = svn_uri_is_child(parent_fspath, child_fspath, pool);
+#else
+ result = svn_relpath_is_child(parent_fspath + 1, child_fspath + 1, pool);
+#endif
+
+ assert(result == NULL || svn_relpath_is_canonical(result, pool));
+ return result;
+}
+
+const char *
+svn_fspath__skip_ancestor(const char *parent_fspath,
+ const char *child_fspath)
+{
+ const char *result;
+ assert(svn_fspath__is_canonical(parent_fspath));
+ assert(svn_fspath__is_canonical(child_fspath));
+
+#ifdef FSPATH_USE_URI
+ result = svn_uri_skip_ancestor(parent_fspath, child_fspath);
+#else
+ if (svn_relpath_is_ancestor(parent_fspath + 1, child_fspath + 1))
+ result = svn_relpath_skip_ancestor(parent_fspath + 1, child_fspath + 1);
+ else
+ result = child_fspath;
+#endif
+
+ assert(svn_relpath_is_canonical(result, NULL)
+ || strcmp(result, child_fspath) == 0);
+ return result;
+}
+
+svn_boolean_t
+svn_fspath__is_ancestor(const char *parent_fspath,
+ const char *child_fspath)
+{
+ assert(svn_fspath__is_canonical(parent_fspath));
+ assert(svn_fspath__is_canonical(child_fspath));
+
+#ifdef FSPATH_USE_URI
+ return svn_uri_is_ancestor(parent_fspath, child_fspath);
+#else
+ return svn_relpath_is_ancestor(parent_fspath + 1, child_fspath + 1);
+#endif
+}
+
+
+const char *
+svn_fspath__dirname(const char *fspath,
+ apr_pool_t *pool)
+{
+ const char *result;
+ assert(svn_fspath__is_canonical(fspath));
+
+#ifdef FSPATH_USE_URI
+ result = svn_uri_dirname(fspath, pool);
+#else
+ result = apr_pstrcat(pool, "/", svn_relpath_dirname(fspath + 1, pool),
+ (char *)NULL);
+#endif
+
+ assert(svn_fspath__is_canonical(result));
+ return result;
+}
+
+
+const char *
+svn_fspath__basename(const char *fspath,
+ apr_pool_t *pool)
+{
+ const char *result;
+ assert(svn_fspath__is_canonical(fspath));
+
+#ifdef FSPATH_USE_URI
+ result = svn_uri_basename(fspath, pool);
+#else
+ result = svn_relpath_basename(fspath + 1, pool);
+#endif
+
+ assert(strchr(result, '/') == NULL);
+ return result;
+}
+
+void
+svn_fspath__split(const char **dirpath,
+ const char **base_name,
+ const char *fspath,
+ apr_pool_t *result_pool)
+{
+ assert(dirpath != base_name);
+
+ if (dirpath)
+ *dirpath = svn_fspath__dirname(fspath, result_pool);
+
+ if (base_name)
+ *base_name = svn_fspath__basename(fspath, result_pool);
+}
+
+char *
+svn_fspath__join(const char *fspath,
+ const char *relpath,
+ apr_pool_t *result_pool)
+{
+ char *result;
+ assert(svn_fspath__is_canonical(fspath));
+ assert(svn_relpath_is_canonical(relpath, result_pool));
+
+#ifdef FSPATH_USE_URI
+ result = svn_uri_join(fspath, relpath, result_pool);
+#else
+ if (relpath[0] == '\0')
+ result = apr_pstrdup(result_pool, fspath);
+ else if (fspath[1] == '\0')
+ result = apr_pstrcat(result_pool, "/", relpath, (char *)NULL);
+ else
+ result = apr_pstrcat(result_pool, fspath, "/", relpath, (char *)NULL);
+#endif
+
+ assert(svn_fspath__is_canonical(result));
+ return result;
+}
+
+char *
+svn_fspath__get_longest_ancestor(const char *fspath1,
+ const char *fspath2,
+ apr_pool_t *result_pool)
+{
+ char *result;
+ assert(svn_fspath__is_canonical(fspath1));
+ assert(svn_fspath__is_canonical(fspath2));
+
+#ifdef FSPATH_USE_URI
+ result = svn_uri_get_longest_ancestor(fspath1, fspath2, result_pool);
+#else
+ result = apr_pstrcat(result_pool, "/",
+ svn_relpath_get_longest_ancestor(fspath1 + 1,
+ fspath2 + 1,
+ result_pool),
+ NULL);
+#endif
+
+ assert(svn_fspath__is_canonical(result));
+ return result;
+}
Modified: subversion/branches/performance/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/mergeinfo.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/mergeinfo.c Fri Nov 26 18:55:51 2010
@@ -1760,7 +1760,7 @@ svn_mergeinfo__remove_prefix_from_catalo
apr_ssize_t padding = 0;
SVN_ERR_ASSERT(klen >= prefix_len);
- SVN_ERR_ASSERT(svn_uri_is_ancestor(prefix_path, original_path));
+ SVN_ERR_ASSERT(svn_fspath__is_ancestor(prefix_path, original_path));
/* If the ORIGINAL_PATH doesn't match the PREFIX_PATH exactly
and we're not simply removing a single leading slash (such as
@@ -1809,33 +1809,28 @@ svn_mergeinfo__add_prefix_to_catalog(svn
svn_error_t *
svn_mergeinfo__add_suffix_to_mergeinfo(svn_mergeinfo_t *out_mergeinfo,
svn_mergeinfo_t mergeinfo,
- const char *suffix,
+ const char *suffix_relpath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- if (!suffix || svn_dirent_is_absolute(suffix))
- {
- *out_mergeinfo = svn_mergeinfo_dup(mergeinfo, result_pool);
- }
- else
- {
- apr_hash_index_t *hi;
- const char *canonical_suffix = svn_uri_canonicalize(suffix,
- scratch_pool);
- *out_mergeinfo = apr_hash_make(result_pool);
+ apr_hash_index_t *hi;
- for (hi = apr_hash_first(scratch_pool, mergeinfo);
- hi;
- hi = apr_hash_next(hi))
- {
- const char *path = svn__apr_hash_index_key(hi);
- apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
+ SVN_ERR_ASSERT(suffix_relpath && svn_relpath_is_canonical(suffix_relpath,
+ scratch_pool));
- apr_hash_set(*out_mergeinfo,
- svn_dirent_join(path, canonical_suffix, result_pool),
- APR_HASH_KEY_STRING,
- svn_rangelist_dup(rangelist, result_pool));
- }
+ *out_mergeinfo = apr_hash_make(result_pool);
+
+ for (hi = apr_hash_first(scratch_pool, mergeinfo);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *path = svn__apr_hash_index_key(hi);
+ apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
+
+ apr_hash_set(*out_mergeinfo,
+ svn_dirent_join(path, suffix_relpath, result_pool),
+ APR_HASH_KEY_STRING,
+ svn_rangelist_dup(rangelist, result_pool));
}
return SVN_NO_ERROR;
Modified: subversion/branches/performance/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/copy.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/copy.c Fri Nov 26 18:55:51 2010
@@ -214,8 +214,6 @@ copy_versioned_file(svn_wc__db_t *db,
svn_skel_t *work_items = NULL;
const char *dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
const char *tmpdir_abspath;
- const char *tmp_dst_abspath;
- svn_node_kind_t kind;
SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db, dst_abspath,
scratch_pool, scratch_pool));
@@ -230,7 +228,10 @@ copy_versioned_file(svn_wc__db_t *db,
copy recursively if it's a dir. */
if (!metadata_only)
{
- SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &kind, src_abspath,
+ const char *tmp_dst_abspath;
+ svn_node_kind_t disk_kind;
+
+ SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind, src_abspath,
tmpdir_abspath,
TRUE, /* recursive */
cancel_func, cancel_baton, scratch_pool));
@@ -294,21 +295,22 @@ copy_versioned_dir(svn_wc__db_t *db,
svn_skel_t *work_items = NULL;
const char *dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
const char *tmpdir_abspath;
- const char *tmp_dst_abspath;
const apr_array_header_t *versioned_children;
- apr_hash_t *children;
- svn_node_kind_t kind;
+ apr_hash_t *disk_children;
+ svn_node_kind_t disk_kind;
apr_pool_t *iterpool;
int i;
/* Prepare a temp copy of the single filesystem node (usually a dir). */
if (!metadata_only)
{
+ const char *tmp_dst_abspath;
+
SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db,
dst_abspath,
scratch_pool, scratch_pool));
- SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &kind, src_abspath,
+ SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind, src_abspath,
tmpdir_abspath, FALSE, /* recursive */
cancel_func, cancel_baton, scratch_pool));
if (tmp_dst_abspath)
@@ -338,12 +340,14 @@ copy_versioned_dir(svn_wc__db_t *db,
(*notify_func)(notify_baton, notify, scratch_pool);
}
- if (!metadata_only && kind == svn_node_dir)
+ if (!metadata_only && disk_kind == svn_node_dir)
/* All filesystem children, versioned and unversioned. We're only
interested in their names, so we can pass TRUE as the only_check_type
param. */
- SVN_ERR(svn_io_get_dirents3(&children, src_abspath, TRUE,
+ SVN_ERR(svn_io_get_dirents3(&disk_children, src_abspath, TRUE,
scratch_pool, scratch_pool));
+ else
+ disk_children = NULL;
/* Copy all the versioned children */
SVN_ERR(svn_wc__db_read_children(&versioned_children, db, src_abspath,
@@ -385,21 +389,22 @@ copy_versioned_dir(svn_wc__db_t *db,
svn_dirent_local_style(child_src_abspath,
scratch_pool));
- if (!metadata_only && kind == svn_node_dir)
+ if (disk_children)
/* Remove versioned child as it has been handled */
- apr_hash_set(children, child_name, APR_HASH_KEY_STRING, NULL);
+ apr_hash_set(disk_children, child_name, APR_HASH_KEY_STRING, NULL);
}
/* Copy all the remaining filesystem children, which are unversioned. */
- if (!metadata_only && kind == svn_node_dir)
+ if (disk_children)
{
apr_hash_index_t *hi;
- for (hi = apr_hash_first(scratch_pool, children); hi;
+ for (hi = apr_hash_first(scratch_pool, disk_children); hi;
hi = apr_hash_next(hi))
{
const char *name = svn__apr_hash_index_key(hi);
const char *unver_src_abspath, *unver_dst_abspath;
+ const char *tmp_dst_abspath;
if (svn_wc_is_adm_dir(name, iterpool))
continue;
@@ -411,8 +416,8 @@ copy_versioned_dir(svn_wc__db_t *db,
unver_src_abspath = svn_dirent_join(src_abspath, name, iterpool);
unver_dst_abspath = svn_dirent_join(dst_abspath, name, iterpool);
- SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &kind, unver_src_abspath,
- tmpdir_abspath,
+ SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind,
+ unver_src_abspath, tmpdir_abspath,
TRUE, /* recursive */
cancel_func, cancel_baton, iterpool));
if (tmp_dst_abspath)
@@ -437,120 +442,6 @@ copy_versioned_dir(svn_wc__db_t *db,
}
-#ifdef SVN_WC__OP_DEPTH
-/*
-A plan for copying a versioned node, recursively, with proper op-depths.
-
-Each DB change mentioned in a separate step is intended to change the WC
-from one valid state to another and must be exectuted within a DB txn.
-Several such changes can be batched together in a bigger txn if we don't
-want clients to be able to see intermediate states.
-
-TODO: We will probably want to notify all copied paths rather than just the
- root path, some time in the future. It may be difficult to get the list
- of visited paths directly, because the metadata copying is performed
- within a single SQL statement. We could walk the destination tree after
- copying, taking care to include any 'excluded' nodes but ignore any
- 'deleted' paths that may be left over from a replaced sub-tree.
-
-copy_versioned_tree:
- # Copy a versioned file/dir SRC_PATH to DST_PATH, recursively.
-
- # This function takes care to copy both the metadata tree and the disk
- # tree as they are, even if they are different node kinds and so different
- # tree shapes.
-
- src_op_depth = working_op_depth_of(src_path)
- src_depth = relpath_depth(src_path)
- dst_depth = relpath_depth(dst_path)
-
- # The source tree has in the NODES table, by design:
- # - zero or more rows below SRC_OP_DEPTH (these are uninteresting);
- # - one or more rows at SRC_OP_DEPTH;
- # - no rows with SRC_OP_DEPTH < row.op_depth <= SRC_DEPTH;
- # - zero or more rows above SRC_DEPTH (modifications);
- # and SRC_OP_DEPTH <= SRC_DEPTH.
-
- Copy single NODES row from src_path@src_op_depth to dst_path@dst_depth.
- Copy all rows of descendent paths in == src_op_depth to == dst_depth.
- Copy all rows of descendent paths in > src_depth to > dst_depth,
- adjusting op_depth by (dst_depth - src_depth).
-
- Copy disk node recursively (if it exists, and whatever its kind).
- Copy ACTUAL_NODE rows (props and any other actual metadata).
-
- # ### Are there no scenarios in which we would want to decrease dst_depth
- # and so subsume the destination into an existing op? I guess not.
-
-*/
-
-/* Copy the working version of the versioned tree at SRC_ABSPATH to
- * DST_ABSPATH, recursively. If METADATA_ONLY is true, then don't copy it
- * on disk, only in metadata, and don't care whether it already exists on
- * disk. */
-static svn_error_t *
-copy_versioned_tree(svn_wc__db_t *db,
- const char *src_abspath,
- const char *dst_abspath,
- svn_boolean_t metadata_only,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
- svn_wc_notify_func2_t notify_func,
- void *notify_baton,
- apr_pool_t *scratch_pool)
-{
- svn_skel_t *work_item = NULL;
-
- /* Prepare a copy of the on-disk tree (if it exists, and whatever its kind),
- * in a temporary location. */
- if (! metadata_only)
- {
- const char *tmpdir_abspath;
- const char *tmp_dst_abspath;
- svn_node_kind_t kind;
-
- SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db, dst_abspath,
- scratch_pool, scratch_pool));
-
- SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &kind, src_abspath,
- tmpdir_abspath,
- TRUE, /* recursive */
- cancel_func, cancel_baton,
- scratch_pool));
- if (tmp_dst_abspath)
- {
- SVN_ERR(svn_wc__wq_build_file_move(&work_item, db,
- tmp_dst_abspath, dst_abspath,
- scratch_pool, scratch_pool));
- }
- }
-
- /* Copy single NODES row from src_path@src_op_depth to dst_path@dst_depth. */
- /* Copy all rows of descendent paths in == src_op_depth to == dst_depth. */
- /* Copy all rows of descendent paths in > src_depth to > dst_depth,
- adjusting op_depth by (dst_depth - src_depth). */
- /* Copy ACTUAL_NODE rows (props and any other actual metadata). */
- SVN_ERR(svn_wc__db_op_copy_tree(db, src_abspath, dst_abspath,
- work_item, scratch_pool));
-
- SVN_ERR(svn_wc__wq_run(db, dst_abspath, cancel_func, cancel_baton,
- scratch_pool));
-
- /* Notify */
- if (notify_func)
- {
- svn_wc_notify_t *notify
- = svn_wc_create_notify(dst_abspath, svn_wc_notify_add,
- scratch_pool);
- notify->kind = svn_node_dir;
- (*notify_func)(notify_baton, notify, scratch_pool);
- }
-
- return SVN_NO_ERROR;
-}
-#endif
-
-
/* Public Interface */
svn_error_t *
@@ -718,17 +609,6 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
scratch_pool));
}
-#ifdef SVN_WC__OP_DEPTH
- if (svn_wc__db_same_db(db, src_abspath, dst_abspath, scratch_pool))
- {
- SVN_ERR(copy_versioned_tree(db, src_abspath, dst_abspath,
- metadata_only,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- scratch_pool));
- }
- else
-#endif
if (src_db_kind == svn_wc__db_kind_file
|| src_db_kind == svn_wc__db_kind_symlink)
{
Modified: subversion/branches/performance/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/entries.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/entries.c Fri Nov 26 18:55:51 2010
@@ -74,6 +74,7 @@ typedef struct {
typedef struct {
apr_int64_t wc_id;
const char *local_relpath;
+ apr_int64_t op_depth;
const char *parent_relpath;
svn_wc__db_status_t presence;
svn_node_kind_t kind; /* ### should switch to svn_wc__db_kind_t */
@@ -1620,8 +1621,7 @@ insert_working_node(svn_sqlite__db_t *sd
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "isisnnnnsnrisnnni",
working_node->wc_id, working_node->local_relpath,
- (working_node->parent_relpath == NULL
- ? (apr_int64_t)1 : (apr_int64_t)2),
+ working_node->op_depth,
working_node->parent_relpath,
/* Setting depth for files? */
svn_depth_to_word(working_node->depth),
@@ -1660,7 +1660,7 @@ insert_working_node(svn_sqlite__db_t *sd
SVN_ERR(svn_sqlite__bind_checksum(stmt, 14, working_node->checksum,
scratch_pool));
- if (working_node->properties)
+ if (working_node->properties) /* ### Never set, props done later */
SVN_ERR(svn_sqlite__bind_properties(stmt, 15, working_node->properties,
scratch_pool));
@@ -1712,13 +1712,20 @@ insert_actual_node(svn_sqlite__db_t *sdb
return svn_error_return(svn_sqlite__insert(NULL, stmt));
}
+struct write_baton {
+ db_base_node_t *base;
+ db_working_node_t *work;
+};
+
/* Write the information for ENTRY to WC_DB. The WC_ID, REPOS_ID and
REPOS_ROOT will all be used for writing ENTRY.
### transitioning from straight sql to using the wc_db APIs. For the
### time being, we'll need both parameters. */
static svn_error_t *
-write_entry(svn_wc__db_t *db,
+write_entry(struct write_baton **entry_node,
+ struct write_baton *parent_node,
+ svn_wc__db_t *db,
svn_sqlite__db_t *sdb,
apr_int64_t wc_id,
apr_int64_t repos_id,
@@ -1727,6 +1734,7 @@ write_entry(svn_wc__db_t *db,
const char *entry_abspath,
const svn_wc_entry_t *this_dir,
svn_boolean_t create_locks,
+ apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
db_base_node_t *base_node = NULL;
@@ -1739,34 +1747,118 @@ write_entry(svn_wc__db_t *db,
else
parent_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
+ /* This is how it should work, it doesn't work like this yet because
+ we need proper op_depth to layer the working nodes.
+
+ Using "svn add", "svn rm", "svn cp" only files can be replaced
+ pre-wcng; directories can only be normal, deleted or added.
+ Files cannot be replaced within a deleted directory, so replaced
+ files can only exist in a normal directory, or a directory that
+ is added+copied. In a normal directory a replaced file needs a
+ base node and a working node, in an added+copied directory a
+ replaced file needs two working nodes at different op-depths.
+
+ With just the above operations the conversion for files and
+ directories is straightforward:
+
+ pre-wcng wcng
+ parent child parent child
+
+ normal normal base base
+ add+copied normal+copied work work
+ normal+copied normal+copied work work
+ normal delete base base+work
+ delete delete base+work base+work
+ add+copied delete work work
+ normal add base work
+ add add work work
+ add+copied add work work
+ normal add+copied base work
+ add add+copied work work
+ add+copied add+copied work work
+ normal replace base base+work
+ add+copied replace work work+work
+ normal replace+copied base base+work
+ add+copied replace+copied work work+work
+
+ However "svn merge" make this more complicated. The pre-wcng
+ "svn merge" is capable of replacing a directory, that is it can
+ mark the whole tree deleted, and then copy another tree on top.
+ The entries then represent the replacing tree overlayed on the
+ deleted tree.
+
+ original replace schedule in
+ tree tree combined tree
+
+ A A replace+copied
+ A/f delete+copied
+ A/g A/g replace+copied
+ A/h add+copied
+ A/B A/B replace+copied
+ A/B/f delete+copied
+ A/B/g A/B/g replace+copied
+ A/B/h add+copied
+ A/C delete+copied
+ A/C/f delete+copied
+ A/D add+copied
+ A/D/f add+copied
+
+ The original tree could be normal tree, or an add+copied tree.
+ Committing such a merge generally worked, but making further tree
+ modifications before commit sometimes failed.
+
+ The root of the replace is handled like the file replace:
+
+ pre-wcng wcng
+ parent child parent child
+
+ normal replace+copied base base+work
+ add+copied replace+copied work work+work
+
+ although obviously the node is a directory rather then a file.
+ There are then more conversion states where the parent is
+ replaced.
+
+ pre-wcng wcng
+ parent child parent child
+
+ replace+copied add [base|work]+work work
+ replace+copied add+copied [base|work]+work work
+ replace+copied delete+copied [base|work]+work [base|work]+work
+ delete+copied delete+copied [base|work]+work [base|work]+work
+ replace+copied replace+copied [base|work]+work [base|work]+work
+ */
+
switch (entry->schedule)
{
case svn_wc_schedule_normal:
if (entry->copied)
- working_node = MAYBE_ALLOC(working_node, scratch_pool);
+ working_node = MAYBE_ALLOC(working_node, result_pool);
else
- base_node = MAYBE_ALLOC(base_node, scratch_pool);
+ base_node = MAYBE_ALLOC(base_node, result_pool);
break;
case svn_wc_schedule_add:
- working_node = MAYBE_ALLOC(working_node, scratch_pool);
+ working_node = MAYBE_ALLOC(working_node, result_pool);
break;
case svn_wc_schedule_delete:
- working_node = MAYBE_ALLOC(working_node, scratch_pool);
+ working_node = MAYBE_ALLOC(working_node, result_pool);
/* If the entry is part of a REPLACED (not COPIED) subtree,
then it needs a BASE node. */
- if (! (entry->copied
- || (this_dir->copied
- && (this_dir->schedule == svn_wc_schedule_add ||
- this_dir->schedule == svn_wc_schedule_delete ||
- this_dir->schedule == svn_wc_schedule_replace))))
- base_node = MAYBE_ALLOC(base_node, scratch_pool);
+ if (parent_node->base
+ && (! (entry->copied
+ || (this_dir->copied
+ && (this_dir->schedule == svn_wc_schedule_add ||
+ this_dir->schedule == svn_wc_schedule_delete ||
+ this_dir->schedule == svn_wc_schedule_replace)))))
+ base_node = MAYBE_ALLOC(base_node, result_pool);
break;
case svn_wc_schedule_replace:
- working_node = MAYBE_ALLOC(working_node, scratch_pool);
- base_node = MAYBE_ALLOC(base_node, scratch_pool);
+ working_node = MAYBE_ALLOC(working_node, result_pool);
+ if (parent_node->base)
+ base_node = MAYBE_ALLOC(base_node, result_pool);
break;
}
@@ -1774,14 +1866,14 @@ write_entry(svn_wc__db_t *db,
BASE node to indicate the not-present node. */
if (entry->deleted)
{
- base_node = MAYBE_ALLOC(base_node, scratch_pool);
+ base_node = MAYBE_ALLOC(base_node, result_pool);
}
if (entry->copied)
{
/* Make sure we get a WORKING_NODE inserted. The copyfrom information
will occur here or on a parent, as appropriate. */
- working_node = MAYBE_ALLOC(working_node, scratch_pool);
+ working_node = MAYBE_ALLOC(working_node, result_pool);
if (entry->copyfrom_url)
{
@@ -1796,60 +1888,31 @@ write_entry(svn_wc__db_t *db,
{
/* copyfrom_repos_path is NOT a URI. decode into repos path. */
working_node->copyfrom_repos_path =
- svn_path_uri_decode(relative_url, scratch_pool);
+ svn_path_uri_decode(relative_url, result_pool);
}
working_node->copyfrom_revnum = entry->copyfrom_rev;
+#ifdef SVN_WC__OP_DEPTH
+ working_node->op_depth
+ = svn_wc__db_op_depth_for_upgrade(local_relpath);
+#else
+ working_node->op_depth = 2; /* ### temporary op_depth */
+#endif
}
- else
+ else if (parent_node->work && parent_node->work->copyfrom_repos_path)
{
- const char *parent_abspath = svn_dirent_dirname(entry_abspath,
- scratch_pool);
- const char *op_root_abspath;
- const char *original_repos_relpath;
- svn_revnum_t original_revision;
- svn_error_t *err;
-
- /* The parent will *always* have info in the WORKING tree, since
- we've been designated as COPIED but do not have our own
- COPYFROM information. Therefore, our parent or a more distant
- ancestor has that information. Grab the data. */
- err = svn_wc__db_scan_addition(
- NULL,
- &op_root_abspath,
- NULL, NULL, NULL,
- &original_repos_relpath, NULL, NULL, &original_revision,
- db,
- parent_abspath,
- scratch_pool, scratch_pool);
-
- /* We could be reading the entries while in a transitional state
- during an add/copy operation. The scan_addition *does* throw
- errors sometimes. So clear anything that may come out of it,
- and perform the copyfrom construction only when it looks like
- we have a good/real set of return values. */
- svn_error_clear(err);
-
- /* We may have been copied from a mixed-rev working copy. We need
- to simulate additional copies around revision changes. The old
- code could separately store the revision, but NG needs to create
- copies at each change. */
- if (err == NULL
- && op_root_abspath != NULL
- && original_repos_relpath != NULL
- && SVN_IS_VALID_REVNUM(original_revision)
- /* above is valid result testing. below is the key test. */
- && original_revision != entry->revision)
- {
- const char *relpath_to_entry = svn_dirent_is_child(
- op_root_abspath, entry_abspath, NULL);
- const char *new_copyfrom_relpath = svn_relpath_join(
- original_repos_relpath, relpath_to_entry, scratch_pool);
-
- working_node->copyfrom_repos_id = repos_id;
- working_node->copyfrom_repos_path = new_copyfrom_relpath;
- working_node->copyfrom_revnum = entry->revision;
- }
+ working_node->copyfrom_repos_id = repos_id;
+ working_node->copyfrom_repos_path
+ = svn_relpath_join(parent_node->work->copyfrom_repos_path,
+ svn_relpath_basename(local_relpath, NULL),
+ result_pool);
+ working_node->copyfrom_revnum = parent_node->work->copyfrom_revnum;
+ working_node->op_depth = parent_node->work->op_depth;
}
+ else
+ return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
+ _("No copyfrom URL for '%s'"),
+ svn_dirent_local_style(local_relpath,
+ scratch_pool));
}
if (entry->keep_local)
@@ -1896,9 +1959,10 @@ write_entry(svn_wc__db_t *db,
if (entry->file_external_path != NULL)
{
- base_node = MAYBE_ALLOC(base_node, scratch_pool);
+ base_node = MAYBE_ALLOC(base_node, result_pool);
}
+
/* Insert the base node. */
if (base_node)
{
@@ -1954,7 +2018,7 @@ write_entry(svn_wc__db_t *db,
base_node->checksum = NULL;
else
SVN_ERR(svn_checksum_parse_hex(&base_node->checksum, svn_checksum_md5,
- entry->checksum, scratch_pool));
+ entry->checksum, result_pool));
if (this_dir->repos)
{
@@ -1971,7 +2035,7 @@ write_entry(svn_wc__db_t *db,
base_node->repos_relpath = "";
else
base_node->repos_relpath = svn_path_uri_decode(relative_url,
- scratch_pool);
+ result_pool);
}
else
{
@@ -1984,7 +2048,7 @@ write_entry(svn_wc__db_t *db,
base_node->repos_relpath =
svn_dirent_join(svn_path_uri_decode(base_path, scratch_pool),
entry->name,
- scratch_pool);
+ result_pool);
}
}
@@ -2061,7 +2125,7 @@ write_entry(svn_wc__db_t *db,
else
SVN_ERR(svn_checksum_parse_hex(&working_node->checksum,
svn_checksum_md5,
- entry->checksum, scratch_pool));
+ entry->checksum, result_pool));
/* All subdirs start of incomplete, and stop being incomplete
when the entries file in the subdir is upgraded. */
@@ -2087,7 +2151,8 @@ write_entry(svn_wc__db_t *db,
/* If the entry is part of a COPIED (not REPLACED) subtree,
then the deletion is referring to the WORKING node, not
the BASE node. */
- if (entry->copied
+ if (!base_node
+ || entry->copied
|| (this_dir->copied
&& this_dir->schedule == svn_wc_schedule_add))
working_node->presence = svn_wc__db_status_not_present;
@@ -2122,6 +2187,19 @@ write_entry(svn_wc__db_t *db,
working_node->changed_date = entry->cmt_date;
working_node->changed_author = entry->cmt_author;
+ if (!entry->copied)
+ {
+ if (parent_node->work)
+ working_node->op_depth = parent_node->work->op_depth;
+ else
+#ifdef SVN_WC__OP_DEPTH
+ working_node->op_depth
+ = svn_wc__db_op_depth_for_upgrade(local_relpath);
+#else
+ working_node->op_depth = 2; /* ### temporary op_depth */
+#endif
+ }
+
SVN_ERR(insert_working_node(sdb, working_node, scratch_pool));
}
@@ -2137,6 +2215,13 @@ write_entry(svn_wc__db_t *db,
SVN_ERR(insert_actual_node(sdb, actual_node, scratch_pool));
}
+ if (entry_node)
+ {
+ *entry_node = apr_palloc(result_pool, sizeof(*entry_node));
+ (*entry_node)->base = base_node;
+ (*entry_node)->work = working_node;
+ }
+
return SVN_NO_ERROR;
}
@@ -2148,6 +2233,9 @@ struct entries_write_baton
const char *dir_abspath;
const char *new_root_abspath;
apr_hash_t *entries;
+ struct write_baton *parent_node;
+ struct write_baton *dir_node;
+ apr_pool_t *result_pool;
};
/* Writes entries inside a sqlite transaction
@@ -2185,12 +2273,11 @@ entries_write_new_cb(void *baton,
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,
- this_dir,
- dir_relpath,
+ SVN_ERR(write_entry(&ewb->dir_node, ewb->parent_node, db, sdb,
+ ewb->wc_id, ewb->repos_id, this_dir, dir_relpath,
svn_dirent_join(new_root_abspath, dir_relpath,
scratch_pool),
- this_dir, FALSE, iterpool));
+ this_dir, FALSE, ewb->result_pool, iterpool));
for (hi = apr_hash_first(scratch_pool, ewb->entries); hi;
hi = apr_hash_next(hi))
@@ -2209,14 +2296,12 @@ entries_write_new_cb(void *baton,
use this function for upgrading old working copies. */
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,
- this_entry,
- child_relpath,
+ SVN_ERR(write_entry(NULL, ewb->dir_node, db, sdb,
+ ewb->wc_id, ewb->repos_id,
+ this_entry, child_relpath,
svn_dirent_join(new_root_abspath, child_relpath,
scratch_pool),
- this_dir,
- TRUE,
- iterpool));
+ this_dir, TRUE, iterpool, iterpool));
}
svn_pool_destroy(iterpool);
@@ -2225,13 +2310,16 @@ entries_write_new_cb(void *baton,
svn_error_t *
-svn_wc__write_upgraded_entries(svn_wc__db_t *db,
+svn_wc__write_upgraded_entries(void **dir_baton,
+ void *parent_baton,
+ svn_wc__db_t *db,
svn_sqlite__db_t *sdb,
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 *result_pool,
apr_pool_t *scratch_pool)
{
struct entries_write_baton ewb;
@@ -2242,12 +2330,17 @@ svn_wc__write_upgraded_entries(svn_wc__d
ewb.dir_abspath = dir_abspath;
ewb.new_root_abspath = new_root_abspath;
ewb.entries = entries;
+ ewb.parent_node = parent_baton;
+ ewb.result_pool = result_pool;
/* Run this operation in a transaction to speed up SQLite.
See http://www.sqlite.org/faq.html#q19 for more details */
- return svn_error_return(
- svn_sqlite__with_transaction(sdb, entries_write_new_cb, &ewb,
- scratch_pool));
+ SVN_ERR(svn_sqlite__with_transaction(sdb, entries_write_new_cb, &ewb,
+ scratch_pool));
+
+ *dir_baton = ewb.dir_node;
+
+ return SVN_NO_ERROR;
}
Modified: subversion/branches/performance/subversion/libsvn_wc/entries.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/entries.h?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/entries.h (original)
+++ subversion/branches/performance/subversion/libsvn_wc/entries.h Fri Nov 26 18:55:51 2010
@@ -87,15 +87,21 @@ svn_wc__read_entries_old(apr_hash_t **en
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-/* For internal use by upgrade.c to write entries in the wc-ng format. */
+/* For internal use by upgrade.c to write entries in the wc-ng format.
+ Return in DIR_BATON the baton to be passed as PARENT_BATON when
+ upgrading child directories. Pass a NULL PARENT_BATON when upgrading
+ the root directory. */
svn_error_t *
-svn_wc__write_upgraded_entries(svn_wc__db_t *db,
+svn_wc__write_upgraded_entries(void **dir_baton,
+ void *parent_baton,
+ svn_wc__db_t *db,
svn_sqlite__db_t *sdb,
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 *result_pool,
apr_pool_t *scratch_pool);
/* Parse a file external specification in the NULL terminated STR and
Modified: subversion/branches/performance/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/status.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/status.c Fri Nov 26 18:55:51 2010
@@ -782,8 +782,8 @@ send_status_structure(const struct walk_
/* repos_lock still uses the deprecated filesystem absolute path
format */
repos_lock = apr_hash_get(wb->repos_locks,
- svn_uri_join("/", repos_relpath,
- scratch_pool),
+ svn_fspath__join("/", repos_relpath,
+ scratch_pool),
APR_HASH_KEY_STRING);
}
}
@@ -2187,10 +2187,10 @@ close_file(void *file_baton,
const char *repos_relpath = svn_relpath_join(dir_repos_relpath,
fb->name, pool);
- repos_lock = apr_hash_get(fb->edit_baton->wb.repos_locks,
- svn_uri_join("/", repos_relpath,
- pool),
- APR_HASH_KEY_STRING);
+ repos_lock = apr_hash_get(fb->edit_baton->wb.repos_locks,
+ svn_fspath__join("/", repos_relpath,
+ pool),
+ APR_HASH_KEY_STRING);
}
}
}
Modified: subversion/branches/performance/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/upgrade.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/upgrade.c Fri Nov 26 18:55:51 2010
@@ -1156,7 +1156,9 @@ struct upgrade_data_t {
Uses SCRATCH_POOL for all temporary allocation. */
static svn_error_t *
-upgrade_to_wcng(svn_wc__db_t *db,
+upgrade_to_wcng(void **dir_baton,
+ void *parent_baton,
+ svn_wc__db_t *db,
const char *dir_abspath,
int old_format,
svn_wc_upgrade_get_repos_info_t repos_info_func,
@@ -1258,11 +1260,11 @@ upgrade_to_wcng(svn_wc__db_t *db,
scratch_pool));
}
- SVN_ERR(svn_wc__write_upgraded_entries(db, data->sdb,
+ SVN_ERR(svn_wc__write_upgraded_entries(dir_baton, parent_baton, db, data->sdb,
data->repos_id, data->wc_id,
dir_abspath, data->root_abspath,
entries,
- scratch_pool));
+ result_pool, scratch_pool));
/***** WC PROPS *****/
@@ -1453,7 +1455,8 @@ svn_wc__upgrade_sdb(int *result_format,
/* */
static svn_error_t *
-upgrade_working_copy(svn_wc__db_t *db,
+upgrade_working_copy(void *parent_baton,
+ svn_wc__db_t *db,
const char *dir_abspath,
svn_wc_upgrade_get_repos_info_t repos_info_func,
void *repos_info_baton,
@@ -1463,8 +1466,10 @@ upgrade_working_copy(svn_wc__db_t *db,
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
+ apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
+ void *dir_baton;
int old_format;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
apr_array_header_t *subdirs;
@@ -1507,7 +1512,7 @@ upgrade_working_copy(svn_wc__db_t *db,
}
- SVN_ERR(upgrade_to_wcng(db, dir_abspath, old_format,
+ SVN_ERR(upgrade_to_wcng(&dir_baton, parent_baton, db, dir_abspath, old_format,
repos_info_func, repos_info_baton,
repos_cache, data, scratch_pool, iterpool));
@@ -1523,12 +1528,12 @@ upgrade_working_copy(svn_wc__db_t *db,
svn_pool_clear(iterpool);
- SVN_ERR(upgrade_working_copy(db, child_abspath,
+ SVN_ERR(upgrade_working_copy(dir_baton, db, child_abspath,
repos_info_func, repos_info_baton,
repos_cache, data,
cancel_func, cancel_baton,
notify_func, notify_baton,
- iterpool));
+ iterpool, iterpool));
}
svn_pool_destroy(iterpool);
@@ -1611,12 +1616,12 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
scratch_pool, scratch_pool));
/* Upgrade the pre-wcng into a wcng in a temporary location. */
- SVN_ERR(upgrade_working_copy(db, local_abspath,
+ SVN_ERR(upgrade_working_copy(NULL, db, local_abspath,
repos_info_func, repos_info_baton,
apr_hash_make(scratch_pool), &data,
cancel_func, cancel_baton,
notify_func, notify_baton,
- scratch_pool));
+ scratch_pool, scratch_pool));
/* A workqueue item to move the pristine dir into place */
pristine_from = svn_wc__adm_child(data.root_abspath, PRISTINE_STORAGE_RELPATH,
Modified: subversion/branches/performance/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/wc-queries.sql?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/performance/subversion/libsvn_wc/wc-queries.sql Fri Nov 26 18:55:51 2010
@@ -132,9 +132,9 @@ INSERT OR REPLACE INTO nodes (
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14,
?15, ?16, ?17, ?18, ?19);
--- STMT_SELECT_BASE_NODE_CHILDREN
+-- STMT_SELECT_OP_DEPTH_CHILDREN
SELECT local_relpath FROM nodes
-WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = 0;
+WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = ?3;
-- STMT_SELECT_NODE_CHILDREN
SELECT local_relpath FROM nodes
Modified: subversion/branches/performance/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/wc_db.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/wc_db.c Fri Nov 26 18:55:51 2010
@@ -128,6 +128,11 @@ APR_INLINE static int relpath_depth(cons
return n;
}
+int svn_wc__db_op_depth_for_upgrade(const char *local_relpath)
+{
+ return relpath_depth(local_relpath);
+}
+
typedef struct insert_base_baton_t {
/* common to all insertions into BASE */
svn_wc__db_status_t status;
@@ -274,10 +279,12 @@ read_info(svn_wc__db_status_t *status,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+#ifndef SVN_WC__OP_DEPTH
static svn_error_t *
elide_copyfrom(svn_wc__db_pdh_t *pdh,
const char *local_relpath,
apr_pool_t *scratch_pool);
+#endif
static svn_error_t *
scan_addition(svn_wc__db_status_t *status,
@@ -302,6 +309,9 @@ scan_deletion(const char **base_del_relp
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+static svn_error_t *
+convert_to_working_status(svn_wc__db_status_t *working_status,
+ svn_wc__db_status_t status);
/* Return the absolute path, in local path style, of LOCAL_RELPATH in WCROOT. */
static const char *
@@ -1055,13 +1065,10 @@ add_children_to_hash(apr_hash_t *childre
}
-/* Return in *CHILDREN all of the children of the directory LOCAL_RELPATH.
- If BASE_ONLY is true, then *only* the children from BASE_NODE are
- returned (those in WORKING_NODE are ignored). The result children are
- allocated in RESULT_POOL. */
+/* Return in *CHILDREN all of the children of the directory LOCAL_RELPATH,
+ of any status, in all op-depths in the NODES table. */
static svn_error_t *
gather_children(const apr_array_header_t **children,
- svn_boolean_t base_only,
svn_wc__db_pdh_t *pdh,
const char *local_relpath,
apr_pool_t *result_pool,
@@ -1070,23 +1077,55 @@ gather_children(const apr_array_header_t
apr_hash_t *names_hash = apr_hash_make(scratch_pool);
apr_array_header_t *names_array;
- /* All of the names get allocated in RESULT_POOL. For !base_only it
+ /* All of the names get allocated in RESULT_POOL. It
appears to be faster to use the hash to remove duplicates than to
use DISTINCT in the SQL query. */
- if (base_only)
- SVN_ERR(add_children_to_hash(names_hash, STMT_SELECT_BASE_NODE_CHILDREN,
- pdh->wcroot->sdb, pdh->wcroot->wc_id,
- local_relpath, result_pool));
- else
- SVN_ERR(add_children_to_hash(names_hash, STMT_SELECT_NODE_CHILDREN,
- pdh->wcroot->sdb, pdh->wcroot->wc_id,
- local_relpath, result_pool));
+ SVN_ERR(add_children_to_hash(names_hash, STMT_SELECT_NODE_CHILDREN,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id,
+ local_relpath, result_pool));
SVN_ERR(svn_hash_keys(&names_array, names_hash, result_pool));
*children = names_array;
return SVN_NO_ERROR;
}
+/* Set *CHILDREN to a new array of (const char *) names of the repository
+ children of the directory PDH:LOCAL_RELPATH - that is, the children at
+ the same op-depth. */
+static svn_error_t *
+gather_repo_children(const apr_array_header_t **children,
+ svn_wc__db_pdh_t *pdh,
+ const char *local_relpath,
+ apr_int64_t op_depth,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *result
+ = apr_array_make(result_pool, 0, sizeof(const char *));
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+ STMT_SELECT_OP_DEPTH_CHILDREN));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isi", pdh->wcroot->wc_id, local_relpath,
+ op_depth));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ while (have_row)
+ {
+ const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+
+ /* Allocate the name in RESULT_POOL so we won't have to copy it. */
+ APR_ARRAY_PUSH(result, const char *)
+ = svn_relpath_basename(child_relpath, result_pool);
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ *children = result;
+ return SVN_NO_ERROR;
+}
+
/* */
static svn_error_t *
@@ -2156,8 +2195,8 @@ svn_wc__db_base_get_children(const apr_a
scratch_pool, scratch_pool));
VERIFY_USABLE_PDH(pdh);
- return gather_children(children, TRUE,
- pdh, local_relpath, result_pool, scratch_pool);
+ return gather_repo_children(children, pdh, local_relpath, 0,
+ result_pool, scratch_pool);
}
@@ -2916,9 +2955,9 @@ get_info_for_copy(apr_int64_t *copyfrom_
}
else if (*status == svn_wc__db_status_deleted)
{
- const char *work_del_relpath;
+ const char *base_del_relpath, *work_del_relpath;
- SVN_ERR(scan_deletion(NULL, NULL, NULL, &work_del_relpath,
+ SVN_ERR(scan_deletion(&base_del_relpath, NULL, NULL, &work_del_relpath,
pdh, local_relpath, scratch_pool, scratch_pool));
if (work_del_relpath)
{
@@ -2939,19 +2978,21 @@ get_info_for_copy(apr_int64_t *copyfrom_
local_relpath),
result_pool);
}
- else
+ else if (base_del_relpath)
{
- *copyfrom_relpath = repos_relpath;
- *copyfrom_rev = revision;
- if (!repos_root_url || !repos_uuid)
- SVN_ERR(scan_upwards_for_repos(copyfrom_id, NULL,
- pdh->wcroot, local_relpath,
- result_pool, scratch_pool));
- else
- SVN_ERR(fetch_repos_id(copyfrom_id,
- repos_root_url, repos_uuid,
- pdh->wcroot->sdb, scratch_pool));
+ SVN_ERR(base_get_info(NULL, NULL, copyfrom_rev, copyfrom_relpath,
+ &repos_root_url, &repos_uuid,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ pdh, base_del_relpath,
+ result_pool, scratch_pool));
+
+ SVN_ERR(fetch_repos_id(copyfrom_id,
+ repos_root_url, repos_uuid,
+ pdh->wcroot->sdb, scratch_pool));
}
+ else
+ SVN_ERR_MALFUNCTION();
}
else
{
@@ -2965,6 +3006,20 @@ get_info_for_copy(apr_int64_t *copyfrom_
return SVN_NO_ERROR;
}
+static svn_error_t *
+op_depth_of(apr_int64_t *op_depth,
+ svn_wc__db_pdh_t *pdh,
+ const char *local_relpath);
+
+static svn_error_t *
+op_depth_for_copy(apr_int64_t *op_depth,
+ apr_int64_t copyfrom_repos_id,
+ const char *copyfrom_relpath,
+ svn_revnum_t copyfrom_revision,
+ svn_wc__db_pdh_t *pdh,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool);
+
/* Like svn_wc__db_op_copy(), but with PDH+LOCAL_RELPATH instead of
* DB+LOCAL_ABSPATH. */
static svn_error_t *
@@ -2972,7 +3027,6 @@ db_op_copy(svn_wc__db_pdh_t *src_pdh,
const char *src_relpath,
svn_wc__db_pdh_t *dst_pdh,
const char *dst_relpath,
- apr_int64_t dst_op_depth,
const svn_skel_t *work_items,
apr_pool_t *scratch_pool)
{
@@ -2981,6 +3035,7 @@ db_op_copy(svn_wc__db_pdh_t *src_pdh,
svn_wc__db_status_t status, dst_status;
svn_boolean_t have_work;
apr_int64_t copyfrom_id;
+ apr_int64_t dst_op_depth;
svn_wc__db_kind_t kind;
const apr_array_header_t *children;
@@ -2988,6 +3043,10 @@ db_op_copy(svn_wc__db_pdh_t *src_pdh,
&status, &kind, &have_work,
src_pdh, src_relpath, scratch_pool, scratch_pool));
+ SVN_ERR(op_depth_for_copy(&dst_op_depth, copyfrom_id,
+ copyfrom_relpath, copyfrom_rev,
+ dst_pdh, dst_relpath, scratch_pool));
+
SVN_ERR_ASSERT(kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_dir);
/* ### New status, not finished, see notes/wc-ng/copying */
@@ -3021,8 +3080,13 @@ db_op_copy(svn_wc__db_pdh_t *src_pdh,
}
if (kind == svn_wc__db_kind_dir)
- SVN_ERR(gather_children(&children, FALSE, src_pdh, src_relpath,
- scratch_pool, scratch_pool));
+ {
+ apr_int64_t src_op_depth;
+
+ SVN_ERR(op_depth_of(&src_op_depth, src_pdh, src_relpath));
+ SVN_ERR(gather_repo_children(&children, src_pdh, src_relpath,
+ src_op_depth, scratch_pool, scratch_pool));
+ }
else
children = NULL;
@@ -3062,6 +3126,10 @@ db_op_copy(svn_wc__db_pdh_t *src_pdh,
dst_relpath, dst_parent_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
+ /* Insert incomplete children, if relevant.
+ The children are part of the same op and so have the same op_depth.
+ (The only time we'd want a different depth is during a recursive
+ simple add, but we never insert children here during a simple add.) */
if (kind == svn_wc__db_kind_dir)
SVN_ERR(insert_incomplete_children(dst_pdh->wcroot->sdb,
dst_pdh->wcroot->wc_id,
@@ -3082,8 +3150,10 @@ db_op_copy(svn_wc__db_pdh_t *src_pdh,
scratch_pool));
}
+#ifndef SVN_WC__OP_DEPTH
/* ### Should do this earlier and insert the node with the right values. */
SVN_ERR(elide_copyfrom(dst_pdh, dst_relpath, scratch_pool));
+#endif
SVN_ERR(add_work_items(dst_pdh->wcroot->sdb, work_items, scratch_pool));
@@ -3100,10 +3170,6 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
{
svn_wc__db_pdh_t *src_pdh, *dst_pdh;
const char *src_relpath, *dst_relpath;
-#ifdef SVN_WC__OP_DEPTH
- const char *dst_op_root_relpath;
-#endif
- apr_int64_t dst_op_depth;
SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
@@ -3120,55 +3186,13 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
scratch_pool, scratch_pool));
VERIFY_USABLE_PDH(dst_pdh);
-#ifdef SVN_WC__OP_DEPTH
- SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&dst_pdh, &dst_op_root_relpath,
- db, dst_op_root_abspath,
- svn_sqlite__mode_readwrite,
- scratch_pool, scratch_pool));
- dst_op_depth = relpath_depth(dst_op_root_relpath);
-#else
- dst_op_depth = 2; /* ### temporary op_depth */
-#endif
-
/* ### This should all happen in one transaction. */
SVN_ERR(db_op_copy(src_pdh, src_relpath, dst_pdh, dst_relpath,
- dst_op_depth, work_items, scratch_pool));
+ work_items, scratch_pool));
return SVN_NO_ERROR;
}
-svn_boolean_t
-svn_wc__db_same_db(svn_wc__db_t *db,
- const char *src_abspath,
- const char *dst_abspath,
- apr_pool_t *scratch_pool)
-{
- svn_error_t *err;
- svn_wc__db_pdh_t *src_pdh, *dst_pdh;
- const char *src_relpath, *dst_relpath;
-
- err = svn_wc__db_pdh_parse_local_abspath(&src_pdh, &src_relpath, db,
- src_abspath,
- svn_sqlite__mode_readonly,
- scratch_pool, scratch_pool);
- if (err)
- {
- src_pdh = NULL;
- svn_error_clear(err);
- }
- err = svn_wc__db_pdh_parse_local_abspath(&dst_pdh, &dst_relpath, db,
- dst_abspath,
- svn_sqlite__mode_readonly,
- scratch_pool, scratch_pool);
- if (err)
- {
- dst_pdh = NULL;
- svn_error_clear(err);
- }
-
- return (src_pdh && dst_pdh && src_pdh->wcroot == dst_pdh->wcroot);
-}
-
/* Set *OP_DEPTH to the highest op depth of PDH:LOCAL_RELPATH. */
static svn_error_t *
op_depth_of(apr_int64_t *op_depth,
@@ -3222,169 +3246,65 @@ catch_copy_of_absent(svn_wc__db_pdh_t *p
}
-/*
- * Copy single NODES row from src_path@src_op_depth to dst_path@dst_depth.
- * Copy all rows of descendent paths in == src_op_depth to == dst_depth.
- * Copy all rows of descendent paths in > src_depth to > dst_depth,
- * adjusting op_depth by (dst_depth - src_depth).
- *
- * ### TODO: Return a list of copied nodes. */
-static svn_error_t *
-copy_nodes_rows(svn_wc__db_pdh_t *src_pdh,
- const char *src_relpath,
- svn_wc__db_pdh_t *dst_pdh,
- const char *dst_relpath,
- apr_pool_t *scratch_pool)
-{
- apr_int64_t src_op_depth;
- apr_int64_t src_depth = relpath_depth(src_relpath);
- apr_int64_t dst_depth = relpath_depth(dst_relpath);
- svn_sqlite__stmt_t *stmt;
- const char *dst_parent_relpath = svn_relpath_dirname(dst_relpath,
- scratch_pool);
-
- SVN_ERR(op_depth_of(&src_op_depth, src_pdh, src_relpath));
-
- if (src_op_depth == 0)
- SVN_ERR(catch_copy_of_absent(src_pdh, src_relpath, scratch_pool));
-
- /* Root node */
- SVN_ERR(svn_sqlite__get_statement(&stmt, src_pdh->wcroot->sdb,
- STMT_COPY_NODES_ROW));
- SVN_ERR(svn_sqlite__bindf(stmt, "isissi",
- src_pdh->wcroot->wc_id,
- src_relpath,
- src_op_depth,
- dst_relpath,
- dst_parent_relpath,
- dst_depth));
- SVN_ERR(svn_sqlite__step_done(stmt));
-
- /* Descendants at same depth */
- SVN_ERR(svn_sqlite__get_statement(&stmt, src_pdh->wcroot->sdb,
- STMT_COPY_NODES_AT_SAME_OP_DEPTH));
- SVN_ERR(svn_sqlite__bindf(stmt, "isisii",
- src_pdh->wcroot->wc_id,
- construct_like_arg(src_relpath, scratch_pool),
- src_op_depth,
- dst_relpath,
- dst_depth,
- (apr_int64_t)(strlen(src_relpath) + 1)));
- SVN_ERR(svn_sqlite__step_done(stmt));
-
- /* Descendants at greater depths */
- SVN_ERR(svn_sqlite__get_statement(&stmt, src_pdh->wcroot->sdb,
- STMT_COPY_NODES_AT_GREATER_OP_DEPTH));
- SVN_ERR(svn_sqlite__bindf(stmt, "isisii",
- src_pdh->wcroot->wc_id,
- construct_like_arg(src_relpath, scratch_pool),
- src_depth,
- dst_relpath,
- dst_depth,
- (apr_int64_t)(strlen(src_relpath) + 1)));
- SVN_ERR(svn_sqlite__step_done(stmt));
-
- return SVN_NO_ERROR;
-}
-
-/* */
-static svn_error_t *
-copy_actual_rows(svn_wc__db_pdh_t *src_pdh,
- const char *src_relpath,
- svn_wc__db_pdh_t *dst_pdh,
- const char *dst_relpath,
- apr_pool_t *scratch_pool)
+/* If COPYFROM_REPOS_ID+COPYFROM_RELPATH+COPYFROM_REVISION "match" the copyfrom
+ information for the parent of LOCAL_RELPATH then set *OP_DEPTH to
+ the op_depth of the parent, otherwise set *OP_DEPTH to the op_depth
+ of LOCAL_RELPATH. */
+static svn_error_t *
+op_depth_for_copy(apr_int64_t *op_depth,
+ apr_int64_t copyfrom_repos_id,
+ const char *copyfrom_relpath,
+ svn_revnum_t copyfrom_revision,
+ svn_wc__db_pdh_t *pdh,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool)
{
+#ifdef SVN_WC__OP_DEPTH
+ const char *parent_relpath, *name;
svn_sqlite__stmt_t *stmt;
- const char *src_parent_relpath = svn_relpath_dirname(src_relpath,
- scratch_pool);
- const char *dst_parent_relpath = svn_relpath_dirname(dst_relpath,
- scratch_pool);
-
- /* ### Copying changelist is OK for a move but what about a copy? */
- SVN_ERR(svn_sqlite__get_statement(&stmt, dst_pdh->wcroot->sdb,
- STMT_COPY_ACTUAL_NODE_ROWS));
- SVN_ERR(svn_sqlite__bindf(stmt, "issssii",
- src_pdh->wcroot->wc_id, src_relpath,
- construct_like_arg(src_relpath, scratch_pool),
- dst_relpath, dst_parent_relpath,
- (apr_int64_t)(strlen(src_relpath) + 1),
- (apr_int64_t)(strlen(src_parent_relpath) + 1)));
- SVN_ERR(svn_sqlite__step_done(stmt));
-
- return SVN_NO_ERROR;
-}
-
-
-struct copy_tree_baton_t
-{
- svn_wc__db_pdh_t *src_pdh, *dst_pdh;
- const char *src_relpath, *dst_relpath;
- const svn_skel_t *work_items;
-};
-
-/* */
-static svn_error_t *
-db_op_copy_tree(void *baton,
- svn_sqlite__db_t *sdb,
- apr_pool_t *scratch_pool)
-{
- struct copy_tree_baton_t *b = baton;
-
- SVN_ERR(copy_nodes_rows(b->src_pdh, b->src_relpath,
- b->dst_pdh, b->dst_relpath,
- scratch_pool));
-
- SVN_ERR(copy_actual_rows(b->src_pdh, b->src_relpath,
- b->dst_pdh, b->dst_relpath,
- scratch_pool));
-
- SVN_ERR(add_work_items(b->dst_pdh->wcroot->sdb, b->work_items, scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_wc__db_op_copy_tree(svn_wc__db_t *db,
- const char *src_abspath,
- const char *dst_abspath,
- const svn_skel_t *work_items,
- apr_pool_t *scratch_pool)
-{
- struct copy_tree_baton_t b;
- SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
- SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
-
- SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&b.src_pdh, &b.src_relpath, db,
- src_abspath,
- svn_sqlite__mode_readwrite,
- scratch_pool, scratch_pool));
- VERIFY_USABLE_PDH(b.src_pdh);
-
- SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&b.dst_pdh, &b.dst_relpath, db,
- dst_abspath,
- svn_sqlite__mode_readwrite,
- scratch_pool, scratch_pool));
- VERIFY_USABLE_PDH(b.dst_pdh);
-
- b.work_items = work_items;
-
- SVN_ERR_ASSERT(b.src_pdh->wcroot == b.dst_pdh->wcroot);
- /* ASSERT(presence == normal) */
+ svn_boolean_t have_row;
- SVN_ERR(svn_sqlite__with_transaction(b.dst_pdh->wcroot->sdb,
- db_op_copy_tree, &b, scratch_pool));
+ *op_depth = relpath_depth(local_relpath);
- /* ### Do we sometimes need to elide copy-from info and/or other fields on
- * the destination root node? See elide_copyfrom(). */
+ if (!copyfrom_relpath)
+ return SVN_NO_ERROR;
- /* ### Do we need to flush entries?
- * SVN_ERR(flush_entries(db, b.dst_pdh, dst_abspath, scratch_pool)); */
+ svn_relpath_split(&parent_relpath, &name, local_relpath, scratch_pool);
+ SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+ STMT_SELECT_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, parent_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (have_row)
+ {
+ svn_wc__db_status_t status = svn_sqlite__column_token(stmt, 1,
+ presence_map);
+ SVN_ERR(convert_to_working_status(&status, status));
+ if (status == svn_wc__db_status_added)
+ {
+ apr_int64_t parent_copyfrom_repos_id
+ = svn_sqlite__column_int64(stmt, 10);
+ const char *parent_copyfrom_relpath
+ = svn_sqlite__column_text(stmt, 11, NULL);
+ svn_revnum_t parent_copyfrom_revision
+ = svn_sqlite__column_revnum(stmt, 12);
+
+ if (parent_copyfrom_repos_id == copyfrom_repos_id
+ && copyfrom_revision == parent_copyfrom_revision
+ && !strcmp(svn_relpath_join(parent_copyfrom_relpath, name,
+ scratch_pool),
+ copyfrom_relpath))
+ *op_depth = svn_sqlite__column_int64(stmt, 0);
+ }
+ }
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+#else
+ *op_depth = 2; /* temporary op_depth */
+#endif
return SVN_NO_ERROR;
}
-
svn_error_t *
svn_wc__db_op_copy_dir(svn_wc__db_t *db,
const char *local_abspath,
@@ -3442,7 +3362,10 @@ svn_wc__db_op_copy_dir(svn_wc__db_t *db,
iwb.original_revnum = original_revision;
}
- iwb.op_depth = 2; /* ### temporary op_depth */
+ /* ### Should we do this inside the transaction? */
+ SVN_ERR(op_depth_for_copy(&iwb.op_depth, iwb.original_repos_id,
+ original_repos_relpath, original_revision,
+ pdh, local_relpath, scratch_pool));
iwb.children = children;
iwb.depth = depth;
@@ -3516,16 +3439,10 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db
iwb.original_revnum = original_revision;
}
-#ifdef SVN_WC__OP_DEPTH
- iwb.op_depth = relpath_depth(local_relpath);
-
- /* ### TODO? If the WC parent dir is already a copy from
- * dirname(original_repos_relpath)@original_revision, then this is a
- * redundant copy as far is the repos is concerned, so it should share
- * the same op_depth. But that's a degenerate case. Is it needed? */
-#else
- iwb.op_depth = 2; /* ### temporary op_depth */
-#endif
+ /* ### Should we do this inside the transaction? */
+ SVN_ERR(op_depth_for_copy(&iwb.op_depth, iwb.original_repos_id,
+ original_repos_relpath, original_revision,
+ pdh, local_relpath, scratch_pool));
iwb.checksum = checksum;
@@ -3594,7 +3511,10 @@ svn_wc__db_op_copy_symlink(svn_wc__db_t
iwb.original_revnum = original_revision;
}
- iwb.op_depth = 2; /* ### temporary op_depth */
+ /* ### Should we do this inside the transaction? */
+ SVN_ERR(op_depth_for_copy(&iwb.op_depth, iwb.original_repos_id,
+ original_repos_relpath, original_revision,
+ pdh, local_relpath, scratch_pool));
iwb.target = target;
@@ -5773,7 +5693,7 @@ svn_wc__db_read_children(const apr_array
scratch_pool, scratch_pool));
VERIFY_USABLE_PDH(pdh);
- return gather_children(children, FALSE,
+ return gather_children(children,
pdh, local_relpath, result_pool, scratch_pool);
}
@@ -8836,8 +8756,8 @@ make_copy_txn(void *baton,
SVN_ERR(svn_sqlite__reset(stmt));
/* Get the BASE children, as WORKING children don't need modifications */
- SVN_ERR(svn_wc__db_base_get_children(&children, mcb->db, mcb->local_abspath,
- scratch_pool, iterpool));
+ SVN_ERR(gather_repo_children(&children, mcb->pdh, mcb->local_relpath, 0,
+ scratch_pool, iterpool));
for (i = 0; i < children->nelts; i++)
{
@@ -8955,6 +8875,7 @@ svn_wc__db_temp_op_make_copy(svn_wc__db_
return SVN_NO_ERROR;
}
+#ifndef SVN_WC__OP_DEPTH
/* Return the copyfrom info for LOCAL_ABSPATH resolving inheritance. */
static svn_error_t *
get_copyfrom(apr_int64_t *copyfrom_repos_id,
@@ -9007,8 +8928,10 @@ get_copyfrom(apr_int64_t *copyfrom_repos
return SVN_NO_ERROR;
}
+#endif
+#ifndef SVN_WC__OP_DEPTH
static svn_error_t *
elide_copyfrom(svn_wc__db_pdh_t *pdh,
const char *local_relpath,
@@ -9112,6 +9035,7 @@ svn_wc__db_temp_elide_copyfrom(svn_wc__d
return SVN_NO_ERROR;
}
+#endif
svn_error_t *
Modified: subversion/branches/performance/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/wc_db.h?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/performance/subversion/libsvn_wc/wc_db.h Fri Nov 26 18:55:51 2010
@@ -1011,35 +1011,6 @@ svn_wc__db_pristine_repair(svn_wc__db_t
@{
*/
-/* Return TRUE if SRC_ABSPATH and DST_ABSPATH are versioned paths in the
- * same DB; FALSE otherwise. */
-svn_boolean_t
-svn_wc__db_same_db(svn_wc__db_t *db,
- const char *src_abspath,
- const char *dst_abspath,
- apr_pool_t *scratch_pool);
-
-/* Copy the tree at SRC_ABSPATH (in NODES and ACTUAL_NODE tables) to
- * DST_ABSPATH.
- *
- * SRC_ABSPATH and DST_ABSPATH must be in the same WC. SRC_ABSPATH must
- * exist, and must not be excluded/absent/not-present. The parent of
- * DST_ABSPATH must be a versioned directory. DST_ABSPATH must be in a
- * state suitable for creating a new node: nonexistent or deleted.
- *
- * Preserve changelist associations in the copy. Preserve all node states
- * including excluded/absent/not-present.
- *
- * Copy the metadata only: do not look at or copy the nodes on disk.
- *
- * Add WORK_ITEMS to the work queue. */
-svn_error_t *
-svn_wc__db_op_copy_tree(svn_wc__db_t *db,
- const char *src_abspath,
- const char *dst_abspath,
- const svn_skel_t *work_items,
- apr_pool_t *scratch_pool);
-
/* Copy the node at SRC_ABSPATH (in NODES and ACTUAL_NODE tables) to
* DST_ABSPATH, both in DB but not necessarily in the same WC. The parent
* of DST_ABSPATH must be a versioned directory.
@@ -2388,12 +2359,14 @@ svn_wc__db_temp_op_make_copy(svn_wc__db_
apr_pool_t *scratch_pool);
+#ifndef SVN_WC__OP_DEPTH
/* Elide the copyfrom information for LOCAL_ABSPATH if it can be derived
from the parent node. */
svn_error_t *
svn_wc__db_temp_elide_copyfrom(svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *scratch_pool);
+#endif
/* Return the serialized file external info (from BASE) for LOCAL_ABSPATH.
@@ -2477,6 +2450,9 @@ svn_wc__db_drop_root(svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *scratch_pool);
+/* Return the OP_DEPTH for LOCAL_RELPATH. */
+int svn_wc__db_op_depth_for_upgrade(const char *local_relpath);
+
/* @} */
Modified: subversion/branches/performance/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/workqueue.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/workqueue.c Fri Nov 26 18:55:51 2010
@@ -1516,12 +1516,14 @@ run_file_install(svn_wc__db_t *db,
FALSE /* ignore_enoent */,
scratch_pool));
+#ifndef SVN_WC__OP_DEPTH
/* ### there used to be a call to entry_modify() above, to set the
### TRANSLATED_SIZE and LAST_MOD_TIME values. that function elided
### copyfrom information that snuck into the database. it should
### not be there in the first place, but we can manually get rid
### of the erroneous, inheritable copyfrom data. */
SVN_ERR(svn_wc__db_temp_elide_copyfrom(db, local_abspath, scratch_pool));
+#endif
}
return SVN_NO_ERROR;
Modified: subversion/branches/performance/subversion/mod_dav_svn/reports/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/reports/mergeinfo.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/reports/mergeinfo.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/reports/mergeinfo.c Fri Nov 26 18:55:51 2010
@@ -50,6 +50,7 @@ dav_svn__get_mergeinfo_report(const dav_
dav_error *derr = NULL;
apr_xml_elem *child;
svn_mergeinfo_catalog_t catalog;
+ svn_boolean_t validate_inherited_mergeinfo = FALSE;
svn_boolean_t include_descendants = FALSE;
dav_svn__authz_read_baton arb;
const dav_svn_repos *repos = resource->info->repos;
@@ -99,6 +100,12 @@ dav_svn__get_mergeinfo_report(const dav_
resource->pool);
(*((const char **)(apr_array_push(paths)))) = target;
}
+ else if (strcmp(child->name, SVN_DAV__VALIDATE_INHERITED) == 0)
+ {
+ const char *word = dav_xml_get_cdata(child, resource->pool, 1);
+ if (strcmp(word, "yes") == 0)
+ validate_inherited_mergeinfo = TRUE;
+ }
else if (strcmp(child->name, SVN_DAV__INCLUDE_DESCENDANTS) == 0)
{
const char *word = dav_xml_get_cdata(child, resource->pool, 1);
@@ -117,10 +124,11 @@ dav_svn__get_mergeinfo_report(const dav_
/* Build mergeinfo brigade */
bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
- serr = svn_repos_fs_get_mergeinfo(&catalog, repos->repos, paths, rev,
- inherit, include_descendants,
- dav_svn__authz_read_func(&arb),
- &arb, resource->pool);
+ serr = svn_repos_fs_get_mergeinfo2(&catalog, repos->repos, paths, rev,
+ inherit, validate_inherited_mergeinfo,
+ include_descendants,
+ dav_svn__authz_read_func(&arb),
+ &arb, resource->pool);
if (serr)
{
derr = dav_svn__convert_err(serr, HTTP_BAD_REQUEST, serr->message,
@@ -197,6 +205,22 @@ dav_svn__get_mergeinfo_report(const dav_
}
}
+ if (validate_inherited_mergeinfo)
+ {
+ serr = dav_svn__brigade_puts(bb, output,
+ "<S:" SVN_DAV__VALIDATE_INHERITED ">"
+ "yes"
+ "</S:" SVN_DAV__VALIDATE_INHERITED ">"
+ DEBUG_CR);
+ if (serr)
+ {
+ derr = dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+ "Error ending REPORT response.",
+ resource->pool);
+ goto cleanup;
+ }
+ }
+
if ((serr = dav_svn__brigade_puts(bb, output,
"</S:" SVN_DAV__MERGEINFO_REPORT ">"
DEBUG_CR)))
Modified: subversion/branches/performance/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/repos.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/repos.c Fri Nov 26 18:55:51 2010
@@ -1420,7 +1420,6 @@ cleanup_fs_access(void *data)
/* Helper func to construct a special 'parentpath' private resource. */
static dav_error *
get_parentpath_resource(request_rec *r,
- const char *root_path,
dav_resource **resource)
{
const char *new_uri;
@@ -1915,7 +1914,7 @@ get_resource(request_rec *r,
if (strcmp(parentpath, uri) == 0)
{
- err = get_parentpath_resource(r, root_path, resource);
+ err = get_parentpath_resource(r, resource);
if (err)
return err;
return NULL;
Modified: subversion/branches/performance/subversion/svn/add-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/svn/add-cmd.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/svn/add-cmd.c (original)
+++ subversion/branches/performance/subversion/svn/add-cmd.c Fri Nov 26 18:55:51 2010
@@ -71,10 +71,8 @@ svn_cl__add(apr_getopt_t *os,
const char *target = APR_ARRAY_IDX(targets, i, const char *);
if (svn_path_is_url(target))
- return svn_error_return(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
- NULL,
- _("'%s' is not a local path"),
- target));
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("'%s' is not a local path"), target);
}
iterpool = svn_pool_create(pool);
Modified: subversion/branches/performance/subversion/svn/changelist-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/svn/changelist-cmd.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/svn/changelist-cmd.c (original)
+++ subversion/branches/performance/subversion/svn/changelist-cmd.c Fri Nov 26 18:55:51 2010
@@ -76,10 +76,8 @@ svn_cl__changelist(apr_getopt_t *os,
const char *target = APR_ARRAY_IDX(targets, i, const char *);
if (svn_path_is_url(target))
- return svn_error_return(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
- NULL,
- _("'%s' is not a local path"),
- target));
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("'%s' is not a local path"), target);
}
if (opt_state->quiet)
Modified: subversion/branches/performance/subversion/svn/cleanup-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/svn/cleanup-cmd.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/svn/cleanup-cmd.c (original)
+++ subversion/branches/performance/subversion/svn/cleanup-cmd.c Fri Nov 26 18:55:51 2010
@@ -64,10 +64,8 @@ svn_cl__cleanup(apr_getopt_t *os,
const char *target = APR_ARRAY_IDX(targets, i, const char *);
if (svn_path_is_url(target))
- return svn_error_return(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
- NULL,
- _("'%s' is not a local path"),
- target));
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("'%s' is not a local path"), target);
}
SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, pool));
Modified: subversion/branches/performance/subversion/svn/export-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/svn/export-cmd.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/svn/export-cmd.c (original)
+++ subversion/branches/performance/subversion/svn/export-cmd.c Fri Nov 26 18:55:51 2010
@@ -86,10 +86,9 @@ svn_cl__export(apr_getopt_t *os,
}
if (svn_path_is_url(to))
- return svn_error_return(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
- NULL,
- _("'%s' is not a local path"),
- to));
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("'%s' is not a local path"), to);
+
if (! opt_state->quiet)
SVN_ERR(svn_cl__notifier_mark_export(ctx->notify_baton2));
Modified: subversion/branches/performance/subversion/svn/import-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/svn/import-cmd.c?rev=1039511&r1=1039510&r2=1039511&view=diff
==============================================================================
--- subversion/branches/performance/subversion/svn/import-cmd.c (original)
+++ subversion/branches/performance/subversion/svn/import-cmd.c Fri Nov 26 18:55:51 2010
@@ -101,10 +101,9 @@ svn_cl__import(apr_getopt_t *os,
}
if (svn_path_is_url(path))
- return svn_error_return(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
- NULL,
- _("'%s' is not a local path"),
- path));
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("'%s' is not a local path"), path);
+
if (! svn_path_is_url(url))
return svn_error_createf
(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,