You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2013/02/23 02:25:44 UTC
svn commit: r1449262 [4/25] - in /subversion/branches/ev2-export: ./ build/
build/ac-macros/ build/generator/ build/generator/swig/
build/generator/templates/ build/win32/
contrib/server-side/fsfsfixer/fixer/ contrib/server-side/svncutter/ notes/
notes...
Modified: subversion/branches/ev2-export/subversion/libsvn_client/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/diff_local.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/diff_local.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/diff_local.c Sat Feb 23 01:25:38 2013
@@ -287,9 +287,16 @@ arbitrary_diff_walker(void *baton, const
const apr_finfo_t *finfo,
apr_pool_t *scratch_pool);
-/* Produce a diff between two arbitrary directories at LOCAL_ABSPATH1 and
- * LOCAL_ABSPATH2, using the provided diff callbacks to show file changes
- * and, for versioned nodes, property changes.
+/* Another forward declaration. */
+static svn_error_t *
+arbitrary_diff_this_dir(struct arbitrary_diff_walker_baton *b,
+ const char *local_abspath,
+ svn_depth_t depth,
+ apr_pool_t *scratch_pool);
+
+/* Produce a diff of depth DEPTH between two arbitrary directories at
+ * LOCAL_ABSPATH1 and LOCAL_ABSPATH2, using the provided diff callbacks
+ * to show file changes and, for versioned nodes, property changes.
*
* If ROOT_ABSPATH1 and ROOT_ABSPATH2 are not NULL, show paths in diffs
* relative to these roots, rather than relative to LOCAL_ABSPATH1 and
@@ -300,6 +307,7 @@ do_arbitrary_dirs_diff(const char *local
const char *local_abspath2,
const char *root_abspath1,
const char *root_abspath2,
+ svn_depth_t depth,
const svn_wc_diff_callbacks4_t *callbacks,
void *diff_baton,
svn_client_ctx_t *ctx,
@@ -331,22 +339,25 @@ do_arbitrary_dirs_diff(const char *local
NULL, svn_io_file_del_on_pool_cleanup,
scratch_pool, scratch_pool));
- SVN_ERR(svn_io_dir_walk2(b.recursing_within_added_subtree ? local_abspath2
- : local_abspath1,
- 0, arbitrary_diff_walker, &b, scratch_pool));
-
+ if (depth <= svn_depth_immediates)
+ SVN_ERR(arbitrary_diff_this_dir(&b, local_abspath1, depth, scratch_pool));
+ else if (depth == svn_depth_infinity)
+ SVN_ERR(svn_io_dir_walk2(b.recursing_within_added_subtree ? local_abspath2
+ : local_abspath1,
+ 0, arbitrary_diff_walker, &b, scratch_pool));
return SVN_NO_ERROR;
}
-/* An implementation of svn_io_walk_func_t.
- * Note: LOCAL_ABSPATH is the path being crawled and can be on either side
+/* Produce a diff of depth DEPTH for the directory at LOCAL_ABSPATH,
+ * using information from the arbitrary_diff_walker_baton B.
+ * LOCAL_ABSPATH is the path being crawled and can be on either side
* of the diff depending on baton->recursing_within_added_subtree. */
static svn_error_t *
-arbitrary_diff_walker(void *baton, const char *local_abspath,
- const apr_finfo_t *finfo,
- apr_pool_t *scratch_pool)
+arbitrary_diff_this_dir(struct arbitrary_diff_walker_baton *b,
+ const char *local_abspath,
+ svn_depth_t depth,
+ apr_pool_t *scratch_pool)
{
- struct arbitrary_diff_walker_baton *b = baton;
const char *local_abspath1;
const char *local_abspath2;
svn_node_kind_t kind1;
@@ -359,12 +370,6 @@ arbitrary_diff_walker(void *baton, const
int i;
apr_pool_t *iterpool;
- if (b->ctx->cancel_func)
- SVN_ERR(b->ctx->cancel_func(b->ctx->cancel_baton));
-
- if (finfo->filetype != APR_DIR)
- return SVN_NO_ERROR;
-
if (b->recursing_within_adm_dir)
{
if (svn_dirent_skip_ancestor(b->adm_dir_abspath, local_abspath))
@@ -398,12 +403,15 @@ arbitrary_diff_walker(void *baton, const
scratch_pool);
SVN_ERR(svn_io_check_resolved_path(local_abspath2, &kind2, scratch_pool));
- if (kind1 == svn_node_dir)
- SVN_ERR(svn_io_get_dirents3(&dirents1, local_abspath1,
- TRUE, /* only_check_type */
- scratch_pool, scratch_pool));
- else
- dirents1 = apr_hash_make(scratch_pool);
+ if (depth > svn_depth_empty)
+ {
+ if (kind1 == svn_node_dir)
+ SVN_ERR(svn_io_get_dirents3(&dirents1, local_abspath1,
+ TRUE, /* only_check_type */
+ scratch_pool, scratch_pool));
+ else
+ dirents1 = apr_hash_make(scratch_pool);
+ }
if (kind2 == svn_node_dir)
{
@@ -425,14 +433,20 @@ arbitrary_diff_walker(void *baton, const
b->diff_baton,
scratch_pool));
- /* Read directory entries. */
- SVN_ERR(svn_io_get_dirents3(&dirents2, local_abspath2,
- TRUE, /* only_check_type */
- scratch_pool, scratch_pool));
+ if (depth > svn_depth_empty)
+ {
+ /* Read directory entries. */
+ SVN_ERR(svn_io_get_dirents3(&dirents2, local_abspath2,
+ TRUE, /* only_check_type */
+ scratch_pool, scratch_pool));
+ }
}
- else
+ else if (depth > svn_depth_empty)
dirents2 = apr_hash_make(scratch_pool);
+ if (depth <= svn_depth_empty)
+ return SVN_NO_ERROR;
+
/* Compare dirents1 to dirents2 and show added/deleted/changed files. */
merged_dirents = apr_hash_merge(scratch_pool, dirents1, dirents2,
NULL, NULL);
@@ -482,7 +496,25 @@ arbitrary_diff_walker(void *baton, const
if (dirent1->kind == svn_node_dir &&
dirent2->kind == svn_node_dir)
- continue;
+ {
+ if (depth == svn_depth_immediates)
+ {
+ /* Not using the walker, so show property diffs on these dirs. */
+ SVN_ERR(do_arbitrary_dirs_diff(child1_abspath, child2_abspath,
+ b->root1_abspath, b->root2_abspath,
+ svn_depth_empty,
+ b->callbacks, b->diff_baton,
+ b->ctx, iterpool));
+ }
+ else
+ {
+ /* Either the walker will visit these directories (with
+ * depth=infinity) and they will be processed as 'this dir'
+ * later, or we're showing file children only (depth=files). */
+ continue;
+ }
+
+ }
/* Files that exist only in dirents1. */
if (dirent1->kind == svn_node_file &&
@@ -521,10 +553,14 @@ arbitrary_diff_walker(void *baton, const
/* Directories that only exist in dirents2. These aren't crawled
* by this walker so we have to crawl them separately. */
- if (dirent2->kind == svn_node_dir &&
+ if (depth > svn_depth_files &&
+ dirent2->kind == svn_node_dir &&
(dirent1->kind == svn_node_file || dirent1->kind == svn_node_none))
SVN_ERR(do_arbitrary_dirs_diff(child1_abspath, child2_abspath,
b->root1_abspath, b->root2_abspath,
+ depth <= svn_depth_immediates
+ ? svn_depth_empty
+ : svn_depth_infinity ,
b->callbacks, b->diff_baton,
b->ctx, iterpool));
}
@@ -534,14 +570,32 @@ arbitrary_diff_walker(void *baton, const
return SVN_NO_ERROR;
}
-/* Produce a diff between two files or two directories at LOCAL_ABSPATH1
- * and LOCAL_ABSPATH2, using the provided diff callbacks to show changes
- * in files. The files and directories involved may be part of a working
- * copy or they may be unversioned. For versioned files, show property
- * changes, too. */
+/* An implementation of svn_io_walk_func_t.
+ * Note: LOCAL_ABSPATH is the path being crawled and can be on either side
+ * of the diff depending on baton->recursing_within_added_subtree. */
+static svn_error_t *
+arbitrary_diff_walker(void *baton, const char *local_abspath,
+ const apr_finfo_t *finfo,
+ apr_pool_t *scratch_pool)
+{
+ struct arbitrary_diff_walker_baton *b = baton;
+
+ if (b->ctx->cancel_func)
+ SVN_ERR(b->ctx->cancel_func(b->ctx->cancel_baton));
+
+ if (finfo->filetype != APR_DIR)
+ return SVN_NO_ERROR;
+
+ SVN_ERR(arbitrary_diff_this_dir(b, local_abspath, svn_depth_infinity,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_client__arbitrary_nodes_diff(const char *local_abspath1,
const char *local_abspath2,
+ svn_depth_t depth,
const svn_wc_diff_callbacks4_t *callbacks,
void *diff_baton,
svn_client_ctx_t *ctx,
@@ -558,6 +612,9 @@ svn_client__arbitrary_nodes_diff(const c
_("'%s' is not the same node kind as '%s'"),
local_abspath1, local_abspath2);
+ if (depth == svn_depth_unknown)
+ depth = svn_depth_infinity;
+
if (kind1 == svn_node_file)
SVN_ERR(do_arbitrary_files_diff(local_abspath1, local_abspath2,
svn_dirent_basename(local_abspath1,
@@ -567,7 +624,7 @@ svn_client__arbitrary_nodes_diff(const c
ctx, scratch_pool));
else if (kind1 == svn_node_dir)
SVN_ERR(do_arbitrary_dirs_diff(local_abspath1, local_abspath2,
- NULL, NULL,
+ NULL, NULL, depth,
callbacks, diff_baton,
ctx, scratch_pool));
else
Modified: subversion/branches/ev2-export/subversion/libsvn_client/diff_summarize.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/diff_summarize.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/diff_summarize.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/diff_summarize.c Sat Feb 23 01:25:38 2013
@@ -77,6 +77,8 @@ send_summary(struct summarize_baton_t *b
case svn_client_diff_summarize_kind_deleted:
summarize_kind = svn_client_diff_summarize_kind_added;
break;
+ default:
+ break;
}
}
@@ -180,6 +182,9 @@ cb_dir_closed(svn_wc_notify_state_t *con
struct summarize_baton_t *b = diff_baton;
svn_boolean_t prop_change;
+ if (! svn_relpath_skip_ancestor(b->target, path))
+ return SVN_NO_ERROR;
+
prop_change = apr_hash_get(b->prop_changes, path, APR_HASH_KEY_STRING) != NULL;
if (dir_was_added || prop_change)
SVN_ERR(send_summary(b, path,
Modified: subversion/branches/ev2-export/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/externals.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/externals.c Sat Feb 23 01:25:38 2013
@@ -212,9 +212,21 @@ switch_dir_external(const char *local_ab
To do so, we need to know the repository root URL of the
external working copy as it currently sits. */
- SVN_ERR(svn_wc__node_get_repos_info(&repos_root_url, &repos_uuid,
- ctx->wc_ctx, local_abspath,
- pool, subpool));
+ err = svn_wc__node_get_repos_info(NULL, NULL,
+ &repos_root_url, &repos_uuid,
+ ctx->wc_ctx, local_abspath,
+ pool, subpool);
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND
+ && err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ repos_root_url = NULL;
+ repos_uuid = NULL;
+ }
+
if (repos_root_url)
{
/* If the new external target URL is not obviously a
@@ -315,7 +327,8 @@ switch_dir_external(const char *local_ab
FALSE, FALSE, timestamp_sleep,
ctx, pool));
- SVN_ERR(svn_wc__node_get_repos_info(&repos_root_url,
+ SVN_ERR(svn_wc__node_get_repos_info(NULL, NULL,
+ &repos_root_url,
&repos_uuid,
ctx->wc_ctx, local_abspath,
pool, pool));
@@ -739,6 +752,7 @@ handle_external_item_change(svn_client_c
const char *local_repos_root_url;
const char *local_repos_uuid;
const char *ext_repos_relpath;
+ svn_error_t *err;
/*
* The working copy library currently requires that all files
@@ -749,11 +763,22 @@ handle_external_item_change(svn_client_c
* sure both URLs point to the same repository. See issue #4087.
*/
- SVN_ERR(svn_wc__node_get_repos_info(&local_repos_root_url,
- &local_repos_uuid,
- ctx->wc_ctx,
- parent_dir_abspath,
- scratch_pool, scratch_pool));
+ err = svn_wc__node_get_repos_info(NULL, NULL,
+ &local_repos_root_url,
+ &local_repos_uuid,
+ ctx->wc_ctx, parent_dir_abspath,
+ scratch_pool, scratch_pool);
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND
+ && err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ local_repos_root_url = NULL;
+ local_repos_uuid = NULL;
+ }
+
ext_repos_relpath = svn_uri_skip_ancestor(new_loc->repos_root_url,
new_url, scratch_pool);
if (local_repos_uuid == NULL || local_repos_root_url == NULL ||
@@ -991,12 +1016,12 @@ svn_client__handle_externals(apr_hash_t
* external and the DEFINING_ABSPATH which we can remove? */
parent_abspath = item_abspath;
do {
- svn_wc_status3_t *parent_status;
+ svn_node_kind_t kind;
parent_abspath = svn_dirent_dirname(parent_abspath, iterpool);
- SVN_ERR(svn_wc_status3(&parent_status, ctx->wc_ctx, parent_abspath,
- iterpool, iterpool));
- if (parent_status->node_status == svn_wc_status_unversioned)
+ SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, parent_abspath, FALSE,
+ iterpool));
+ if (kind == svn_node_none)
{
svn_error_t *err;
@@ -1051,7 +1076,7 @@ svn_client__export_externals(apr_hash_t
SVN_ERR(svn_wc_parse_externals_description3(&items, local_abspath,
desc_text, FALSE,
- scratch_pool));
+ iterpool));
if (! items->nelts)
continue;
@@ -1116,187 +1141,3 @@ svn_client__export_externals(apr_hash_t
return SVN_NO_ERROR;
}
-
-svn_error_t *
-svn_client__do_external_status(svn_client_ctx_t *ctx,
- apr_hash_t *external_map,
- svn_depth_t depth,
- svn_boolean_t get_all,
- svn_boolean_t update,
- svn_boolean_t no_ignore,
- const char *anchor_abspath,
- const char *anchor_relpath,
- svn_client_status_func_t status_func,
- void *status_baton,
- apr_pool_t *scratch_pool)
-{
- apr_hash_index_t *hi;
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
- /* Loop over the hash of new values (we don't care about the old
- ones). This is a mapping of versioned directories to property
- values. */
- for (hi = apr_hash_first(scratch_pool, external_map);
- hi;
- hi = apr_hash_next(hi))
- {
- svn_node_kind_t external_kind;
- const char *local_abspath = svn__apr_hash_index_key(hi);
- const char *defining_abspath = svn__apr_hash_index_val(hi);
- svn_node_kind_t kind;
- svn_opt_revision_t opt_rev;
- const char *status_path;
-
- svn_pool_clear(iterpool);
-
- /* Obtain information on the expected external. */
- SVN_ERR(svn_wc__read_external_info(&external_kind, NULL, NULL, NULL,
- &opt_rev.value.number,
- ctx->wc_ctx, defining_abspath,
- local_abspath, FALSE,
- iterpool, iterpool));
-
- if (external_kind != svn_node_dir)
- continue;
-
- SVN_ERR(svn_io_check_path(local_abspath, &kind, iterpool));
- if (kind != svn_node_dir)
- continue;
-
- if (SVN_IS_VALID_REVNUM(opt_rev.value.number))
- opt_rev.kind = svn_opt_revision_number;
- else
- opt_rev.kind = svn_opt_revision_unspecified;
-
- /* Tell the client we're starting an external status set. */
- if (ctx->notify_func2)
- ctx->notify_func2(
- ctx->notify_baton2,
- svn_wc_create_notify(local_abspath,
- svn_wc_notify_status_external,
- iterpool), iterpool);
-
- status_path = local_abspath;
- if (anchor_abspath)
- {
- status_path = svn_dirent_join(anchor_relpath,
- svn_dirent_skip_ancestor(anchor_abspath,
- status_path),
- iterpool);
- }
-
- /* And then do the status. */
- SVN_ERR(svn_client_status5(NULL, ctx, status_path, &opt_rev, depth,
- get_all, update, no_ignore, FALSE, FALSE,
- NULL, status_func, status_baton,
- iterpool));
- }
-
- /* Destroy SUBPOOL and (implicitly) ITERPOOL. */
- svn_pool_destroy(iterpool);
-
- return SVN_NO_ERROR;
-}
-
-/* Walk through all the external items and list them. */
-static svn_error_t *
-list_external_items(apr_array_header_t *external_items,
- const char *externals_parent_url,
- svn_depth_t depth,
- apr_uint32_t dirent_fields,
- svn_boolean_t fetch_locks,
- svn_client_list_func2_t list_func,
- void *baton,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool)
-{
- const char *externals_parent_repos_root_url;
- apr_pool_t *iterpool;
- int i;
-
- SVN_ERR(svn_client_get_repos_root(&externals_parent_repos_root_url,
- NULL /* uuid */,
- externals_parent_url, ctx,
- scratch_pool, scratch_pool));
-
- iterpool = svn_pool_create(scratch_pool);
-
- for (i = 0; i < external_items->nelts; i++)
- {
- const char *resolved_url;
-
- svn_wc_external_item2_t *item =
- APR_ARRAY_IDX(external_items, i, svn_wc_external_item2_t *);
-
- svn_pool_clear(iterpool);
-
- SVN_ERR(svn_wc__resolve_relative_external_url(
- &resolved_url,
- item,
- externals_parent_repos_root_url,
- externals_parent_url,
- iterpool, iterpool));
-
- /* List the external */
- SVN_ERR(wrap_external_error(ctx, item->target_dir,
- svn_client__list_internal(
- resolved_url,
- &item->peg_revision,
- &item->revision,
- depth, dirent_fields,
- fetch_locks,
- TRUE,
- externals_parent_url,
- item->target_dir,
- list_func, baton, ctx,
- iterpool),
- iterpool));
-
- }
- svn_pool_destroy(iterpool);
-
- return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_client__list_externals(apr_hash_t *externals,
- svn_depth_t depth,
- apr_uint32_t dirent_fields,
- svn_boolean_t fetch_locks,
- svn_client_list_func2_t list_func,
- void *baton,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool)
-{
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- apr_hash_index_t *hi;
-
- for (hi = apr_hash_first(scratch_pool, externals);
- hi;
- hi = apr_hash_next(hi))
- {
- const char *externals_parent_url = svn__apr_hash_index_key(hi);
- svn_string_t *externals_desc = svn__apr_hash_index_val(hi);
- apr_array_header_t *external_items;
-
- svn_pool_clear(iterpool);
-
- SVN_ERR(svn_wc_parse_externals_description3(&external_items,
- externals_parent_url,
- externals_desc->data,
- FALSE, iterpool));
-
- if (! external_items->nelts)
- continue;
-
- SVN_ERR(list_external_items(external_items, externals_parent_url, depth,
- dirent_fields, fetch_locks, list_func,
- baton, ctx, iterpool));
-
- }
- svn_pool_destroy(iterpool);
-
- return SVN_NO_ERROR;
-}
-
Modified: subversion/branches/ev2-export/subversion/libsvn_client/import.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/import.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/import.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/import.c Sat Feb 23 01:25:38 2013
@@ -679,13 +679,10 @@ svn_client_import5(const char *path,
const char *local_abspath;
apr_array_header_t *new_entries = apr_array_make(scratch_pool, 4,
sizeof(const char *));
- const char *temp;
- const char *dir;
apr_hash_t *commit_revprops;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
apr_hash_t *autoprops = NULL;
apr_array_header_t *global_ignores;
- apr_hash_t *local_ignores_hash;
apr_array_header_t *local_ignores_arr;
const char *edit_relpath;
const char *repos_root;
@@ -744,11 +741,12 @@ svn_client_import5(const char *path,
while (kind == svn_node_none)
{
+ const char *dir;
+
svn_pool_clear(iterpool);
- svn_uri_split(&temp, &dir, url, scratch_pool);
+ svn_uri_split(&url, &dir, url, scratch_pool);
APR_ARRAY_PUSH(new_entries, const char *) = dir;
- url = temp;
SVN_ERR(svn_ra_reparent(ra_session, url, iterpool));
SVN_ERR(svn_ra_check_path(ra_session, "", SVN_INVALID_REVNUM, &kind,
@@ -756,37 +754,21 @@ svn_client_import5(const char *path,
}
/* Reverse the order of the components we added to our NEW_ENTRIES array. */
- if (new_entries->nelts)
- {
- int i, j;
- const char *component;
- for (i = 0; i < (new_entries->nelts / 2); i++)
- {
- j = new_entries->nelts - i - 1;
- component =
- APR_ARRAY_IDX(new_entries, i, const char *);
- APR_ARRAY_IDX(new_entries, i, const char *) =
- APR_ARRAY_IDX(new_entries, j, const char *);
- APR_ARRAY_IDX(new_entries, j, const char *) =
- component;
- }
- }
+ svn_sort__array_reverse(new_entries, scratch_pool);
/* The repository doesn't know about the reserved administrative
directory. */
- if (new_entries->nelts
- /* What's this, what's this? This assignment is here because we
- use the value to construct the error message just below. It
- may not be aesthetically pleasing, but it's less ugly than
- calling APR_ARRAY_IDX twice. */
- && svn_wc_is_adm_dir(temp = APR_ARRAY_IDX(new_entries,
- new_entries->nelts - 1,
- const char *),
- scratch_pool))
- return svn_error_createf
- (SVN_ERR_CL_ADM_DIR_RESERVED, NULL,
- _("'%s' is a reserved name and cannot be imported"),
- svn_dirent_local_style(temp, scratch_pool));
+ if (new_entries->nelts)
+ {
+ const char *last_component
+ = APR_ARRAY_IDX(new_entries, new_entries->nelts - 1, const char *);
+
+ if (svn_wc_is_adm_dir(last_component, scratch_pool))
+ return svn_error_createf
+ (SVN_ERR_CL_ADM_DIR_RESERVED, NULL,
+ _("'%s' is a reserved name and cannot be imported"),
+ svn_dirent_local_style(last_component, scratch_pool));
+ }
SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table,
log_msg, ctx, scratch_pool));
@@ -812,6 +794,7 @@ svn_client_import5(const char *path,
{
svn_opt_revision_t rev;
apr_array_header_t *config_ignores;
+ apr_hash_t *local_ignores_hash;
SVN_ERR(svn_client__get_inherited_ignores(&global_ignores, url, ctx,
scratch_pool, iterpool));
Modified: subversion/branches/ev2-export/subversion/libsvn_client/list.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/list.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/list.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/list.c Sat Feb 23 01:25:38 2013
@@ -33,8 +33,36 @@
#include "private/svn_fspath.h"
#include "private/svn_ra_private.h"
+#include "private/svn_wc_private.h"
#include "svn_private_config.h"
+/* Prototypes for referencing before declaration */
+static svn_error_t *
+list_externals(apr_hash_t *externals,
+ svn_depth_t depth,
+ apr_uint32_t dirent_fields,
+ svn_boolean_t fetch_locks,
+ svn_client_list_func2_t list_func,
+ void *baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
+
+static svn_error_t *
+list_internal(const char *path_or_url,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *revision,
+ svn_depth_t depth,
+ apr_uint32_t dirent_fields,
+ svn_boolean_t fetch_locks,
+ svn_boolean_t include_externals,
+ const char *external_parent_url,
+ const char *external_target,
+ svn_client_list_func2_t list_func,
+ void *baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+
/* Get the directory entries of DIR at REV (relative to the root of
RA_SESSION), getting at least the fields specified by DIRENT_FIELDS.
Use the cancellation function/baton of CTX to check for cancellation.
@@ -273,20 +301,53 @@ svn_client__ra_stat_compatible(svn_ra_se
return SVN_NO_ERROR;
}
-svn_error_t *
-svn_client__list_internal(const char *path_or_url,
- const svn_opt_revision_t *peg_revision,
- const svn_opt_revision_t *revision,
- svn_depth_t depth,
- apr_uint32_t dirent_fields,
- svn_boolean_t fetch_locks,
- svn_boolean_t include_externals,
- const char *external_parent_url,
- const char *external_target,
- svn_client_list_func2_t list_func,
- void *baton,
- svn_client_ctx_t *ctx,
- apr_pool_t *pool)
+/* List the file/directory entries for PATH_OR_URL at REVISION.
+ The actual node revision selected is determined by the path as
+ it exists in PEG_REVISION.
+
+ If DEPTH is svn_depth_infinity, then list all file and directory entries
+ recursively. Else if DEPTH is svn_depth_files, list all files under
+ PATH_OR_URL (if any), but not subdirectories. Else if DEPTH is
+ svn_depth_immediates, list all files and include immediate
+ subdirectories (at svn_depth_empty). Else if DEPTH is
+ svn_depth_empty, just list PATH_OR_URL with none of its entries.
+
+ DIRENT_FIELDS controls which fields in the svn_dirent_t's are
+ filled in. To have them totally filled in use SVN_DIRENT_ALL,
+ otherwise simply bitwise OR together the combination of SVN_DIRENT_*
+ fields you care about.
+
+ If FETCH_LOCKS is TRUE, include locks when reporting directory entries.
+
+ If INCLUDE_EXTERNALS is TRUE, also list all external items
+ reached by recursion. DEPTH value passed to the original list target
+ applies for the externals also. EXTERNAL_PARENT_URL is url of the
+ directory which has the externals definitions. EXTERNAL_TARGET is the
+ target subdirectory of externals definitions.
+
+ Report directory entries by invoking LIST_FUNC/BATON.
+ Pass EXTERNAL_PARENT_URL and EXTERNAL_TARGET to LIST_FUNC when external
+ items are listed, otherwise both are set to NULL.
+
+ Use authentication baton cached in CTX to authenticate against the
+ repository.
+
+ Use POOL for all allocations.
+*/
+static svn_error_t *
+list_internal(const char *path_or_url,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *revision,
+ svn_depth_t depth,
+ apr_uint32_t dirent_fields,
+ svn_boolean_t fetch_locks,
+ svn_boolean_t include_externals,
+ const char *external_parent_url,
+ const char *external_target,
+ svn_client_list_func2_t list_func,
+ void *baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
{
svn_ra_session_t *ra_session;
svn_client__pathrev_t *loc;
@@ -361,14 +422,145 @@ svn_client__list_internal(const char *pa
{
/* The 'externals' hash populated by get_dir_contents() is processed
here. */
- SVN_ERR(svn_client__list_externals(externals, depth, dirent_fields,
- fetch_locks, list_func, baton,
- ctx, pool));
+ SVN_ERR(list_externals(externals, depth, dirent_fields,
+ fetch_locks, list_func, baton,
+ ctx, pool));
}
return SVN_NO_ERROR;
}
+static svn_error_t *
+wrap_list_error(const svn_client_ctx_t *ctx,
+ const char *target_abspath,
+ svn_error_t *err,
+ apr_pool_t *scratch_pool)
+{
+ if (err && err->apr_err != SVN_ERR_CANCELLED)
+ {
+ if (ctx->notify_func2)
+ {
+ svn_wc_notify_t *notifier = svn_wc_create_notify(
+ target_abspath,
+ svn_wc_notify_failed_external,
+ scratch_pool);
+ notifier->err = err;
+ ctx->notify_func2(ctx->notify_baton2, notifier, scratch_pool);
+ }
+ svn_error_clear(err);
+ return SVN_NO_ERROR;
+ }
+
+ return err;
+}
+
+
+/* Walk through all the external items and list them. */
+static svn_error_t *
+list_external_items(apr_array_header_t *external_items,
+ const char *externals_parent_url,
+ svn_depth_t depth,
+ apr_uint32_t dirent_fields,
+ svn_boolean_t fetch_locks,
+ svn_client_list_func2_t list_func,
+ void *baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *externals_parent_repos_root_url;
+ apr_pool_t *iterpool;
+ int i;
+
+ SVN_ERR(svn_client_get_repos_root(&externals_parent_repos_root_url,
+ NULL /* uuid */,
+ externals_parent_url, ctx,
+ scratch_pool, scratch_pool));
+
+ iterpool = svn_pool_create(scratch_pool);
+
+ for (i = 0; i < external_items->nelts; i++)
+ {
+ const char *resolved_url;
+
+ svn_wc_external_item2_t *item =
+ APR_ARRAY_IDX(external_items, i, svn_wc_external_item2_t *);
+
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_wc__resolve_relative_external_url(
+ &resolved_url,
+ item,
+ externals_parent_repos_root_url,
+ externals_parent_url,
+ iterpool, iterpool));
+
+ /* List the external */
+ SVN_ERR(wrap_list_error(ctx, item->target_dir,
+ list_internal(resolved_url,
+ &item->peg_revision,
+ &item->revision,
+ depth, dirent_fields,
+ fetch_locks,
+ TRUE,
+ externals_parent_url,
+ item->target_dir,
+ list_func, baton, ctx,
+ iterpool),
+ iterpool));
+
+ }
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+/* List external items defined on each external in EXTERNALS, a const char *
+ externals_parent_url(url of the directory which has the externals
+ definitions) of all externals mapping to the svn_string_t * externals_desc
+ (externals description text). All other options are the same as those
+ passed to svn_client_list(). */
+static svn_error_t *
+list_externals(apr_hash_t *externals,
+ svn_depth_t depth,
+ apr_uint32_t dirent_fields,
+ svn_boolean_t fetch_locks,
+ svn_client_list_func2_t list_func,
+ void *baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ apr_hash_index_t *hi;
+
+ for (hi = apr_hash_first(scratch_pool, externals);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *externals_parent_url = svn__apr_hash_index_key(hi);
+ svn_string_t *externals_desc = svn__apr_hash_index_val(hi);
+ apr_array_header_t *external_items;
+
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_wc_parse_externals_description3(&external_items,
+ externals_parent_url,
+ externals_desc->data,
+ FALSE, iterpool));
+
+ if (! external_items->nelts)
+ continue;
+
+ SVN_ERR(list_external_items(external_items, externals_parent_url, depth,
+ dirent_fields, fetch_locks, list_func,
+ baton, ctx, iterpool));
+
+ }
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+
svn_error_t *
svn_client_list3(const char *path_or_url,
const svn_opt_revision_t *peg_revision,
@@ -383,11 +575,11 @@ svn_client_list3(const char *path_or_url
apr_pool_t *pool)
{
- return svn_error_trace(svn_client__list_internal(path_or_url, peg_revision,
- revision,
- depth, dirent_fields,
- fetch_locks,
- include_externals,
- NULL, NULL, list_func,
- baton, ctx, pool));
+ return svn_error_trace(list_internal(path_or_url, peg_revision,
+ revision,
+ depth, dirent_fields,
+ fetch_locks,
+ include_externals,
+ NULL, NULL, list_func,
+ baton, ctx, pool));
}
Modified: subversion/branches/ev2-export/subversion/libsvn_client/locking_commands.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/locking_commands.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/locking_commands.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/locking_commands.c Sat Feb 23 01:25:38 2013
@@ -189,6 +189,14 @@ condense_targets(const char **common_par
return SVN_NO_ERROR;
}
+/* Lock info. Used in organize_lock_targets.
+ ### Maybe return this instead of the ugly hashes? */
+struct wc_lock_item_t
+{
+ svn_revnum_t revision;
+ const char *lock_token;
+};
+
/* Set *COMMON_PARENT_URL to the nearest common parent URL of all TARGETS.
* If TARGETS are local paths, then the entry for each path is examined
* and *COMMON_PARENT is set to the common parent URL for all the
@@ -225,7 +233,7 @@ organize_lock_targets(const char **commo
const apr_array_header_t *targets,
svn_boolean_t do_lock,
svn_boolean_t force,
- svn_client_ctx_t *ctx,
+ svn_wc_context_t *wc_ctx,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -234,6 +242,7 @@ organize_lock_targets(const char **commo
apr_hash_t *rel_targets_ret = apr_hash_make(result_pool);
apr_hash_t *rel_fs_paths = NULL;
apr_array_header_t *rel_targets;
+ apr_hash_t *wc_info = apr_hash_make(scratch_pool);
svn_boolean_t url_mode;
int i;
@@ -289,20 +298,38 @@ organize_lock_targets(const char **commo
sizeof(const char *));
for (i = 0; i < rel_targets->nelts; i++)
{
- const char *rel_target, *local_abspath, *target_url;
+ const char *rel_target;
+ const char *repos_relpath;
+ const char *repos_root_url;
+ const char *target_url;
+ struct wc_lock_item_t *wli;
+ const char *local_abspath;
svn_pool_clear(iterpool);
rel_target = APR_ARRAY_IDX(rel_targets, i, const char *);
- local_abspath = svn_dirent_join(common_dirent, rel_target, iterpool);
- SVN_ERR(svn_wc__node_get_url(&target_url, ctx->wc_ctx, local_abspath,
- scratch_pool, iterpool));
- if (! target_url)
- return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
- _("'%s' has no URL"),
+ local_abspath = svn_dirent_join(common_dirent, rel_target, scratch_pool);
+ wli = apr_pcalloc(scratch_pool, sizeof(*wli));
+
+ SVN_ERR(svn_wc__node_get_base(&wli->revision, &repos_relpath,
+ &repos_root_url, NULL,
+ &wli->lock_token,
+ wc_ctx, local_abspath,
+ result_pool, iterpool));
+
+ /* Node exists in BASE? */
+ if (! repos_root_url || !repos_relpath)
+ return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+ _("The node '%s' was not found."),
svn_dirent_local_style(local_abspath,
iterpool));
+ apr_hash_set(wc_info, local_abspath, APR_HASH_KEY_STRING, wli);
+
+ target_url = svn_path_url_add_component2(repos_root_url,
+ repos_relpath,
+ scratch_pool);
+
APR_ARRAY_PUSH(target_urls, const char *) = target_url;
}
@@ -320,7 +347,8 @@ organize_lock_targets(const char **commo
rel_fs_paths = apr_hash_make(result_pool);
for (i = 0; i < rel_targets->nelts; i++)
{
- const char *rel_target, *rel_url, *abs_path;
+ const char *rel_target, *rel_url;
+ const char *local_abspath;
svn_pool_clear(iterpool);
@@ -336,35 +364,49 @@ organize_lock_targets(const char **commo
revision of the dirent target with which it is associated
(if our caller is locking) or to a (possible empty) lock
token string (if the caller is unlocking). */
- abs_path = svn_dirent_join(common_dirent, rel_target, iterpool);
+ local_abspath = svn_dirent_join(common_dirent, rel_target, iterpool);
if (do_lock) /* Lock. */
{
svn_revnum_t *revnum;
+ struct wc_lock_item_t *wli;
revnum = apr_palloc(result_pool, sizeof(* revnum));
- SVN_ERR(svn_wc__node_get_base(revnum, NULL, NULL, NULL,
- ctx->wc_ctx, abs_path,
- result_pool, iterpool));
+
+ wli = apr_hash_get(wc_info, local_abspath, APR_HASH_KEY_STRING);
+
+ SVN_ERR_ASSERT(wli != NULL);
+
+ *revnum = wli->revision;
+
apr_hash_set(rel_targets_ret, rel_url,
APR_HASH_KEY_STRING, revnum);
}
else /* Unlock. */
{
- const char *lock_token = NULL;
+ const char *lock_token;
+ struct wc_lock_item_t *wli;
/* If not forcing the unlock, get the lock token. */
if (! force)
{
- SVN_ERR(svn_wc__node_get_lock_info(&lock_token, NULL, NULL,
- NULL, ctx->wc_ctx,
- abs_path, result_pool,
- iterpool));
- if (! lock_token)
+ wli = apr_hash_get(wc_info, local_abspath,
+ APR_HASH_KEY_STRING);
+
+ SVN_ERR_ASSERT(wli != NULL);
+
+ if (! wli->lock_token)
return svn_error_createf(
SVN_ERR_CLIENT_MISSING_LOCK_TOKEN, NULL,
_("'%s' is not locked in this working copy"),
- abs_path);
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+
+ lock_token = wli->lock_token
+ ? apr_pstrdup(result_pool, wli->lock_token)
+ : NULL;
}
+ else
+ lock_token = NULL;
/* If breaking a lock, we shouldn't pass any lock token. */
apr_hash_set(rel_targets_ret, rel_url, APR_HASH_KEY_STRING,
@@ -444,7 +486,7 @@ svn_client_lock(const apr_array_header_t
SVN_ERR(organize_lock_targets(&common_parent_url, &base_dir, &path_revs,
&urls_to_paths, targets, TRUE, steal_lock,
- ctx, pool, pool));
+ ctx->wc_ctx, pool, pool));
/* Open an RA session to the common parent of TARGETS. */
if (base_dir)
@@ -484,7 +526,7 @@ svn_client_unlock(const apr_array_header
SVN_ERR(organize_lock_targets(&common_parent_url, &base_dir, &path_tokens,
&urls_to_paths, targets, FALSE, break_lock,
- ctx, pool, pool));
+ ctx->wc_ctx, pool, pool));
/* Open an RA session. */
if (base_dir)