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 2010/08/10 20:06:33 UTC
svn commit: r984153 [13/39] - in /subversion/branches/ignore-mergeinfo: ./
build/ build/ac-macros/ build/generator/ build/generator/templates/
build/hudson/ build/hudson/jobs/subversion-1.6.x-solaris/
build/hudson/jobs/subversion-1.6.x-ubuntu/ build/hu...
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/copy.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/copy.c Tue Aug 10 18:06:17 2010
@@ -70,33 +70,30 @@
/* Obtain the implied mergeinfo and the existing mergeinfo of the
source path, combine them and return the result in
- *TARGET_MERGEINFO. ADM_ACCESS may be NULL, if SRC_PATH_OR_URL is an
- URL. If NO_REPOS_ACCESS is set, this function is disallowed from
- consulting the repository about anything. RA_SESSION may be NULL but
- only if NO_REPOS_ACCESS is true. */
+ *TARGET_MERGEINFO. One of LOCAL_ABSPATH and SRC_URL must be valid,
+ the other must be NULL. */
static svn_error_t *
calculate_target_mergeinfo(svn_ra_session_t *ra_session,
apr_hash_t **target_mergeinfo,
- svn_wc_adm_access_t *adm_access,
- const char *src_path_or_url,
+ const char *local_abspath,
+ const char *src_url,
svn_revnum_t src_revnum,
- svn_boolean_t no_repos_access,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
const svn_wc_entry_t *entry = NULL;
svn_boolean_t locally_added = FALSE;
- const char *src_url;
apr_hash_t *src_mergeinfo = NULL;
+ SVN_ERR_ASSERT((local_abspath && !src_url) || (!local_abspath && src_url));
+
/* If we have a schedule-add WC path (which was not copied from
elsewhere), it doesn't have any repository mergeinfo, so don't
bother checking. */
- if (adm_access)
+ if (local_abspath)
{
- const char *local_abspath;
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, src_path_or_url, pool));
SVN_ERR(svn_wc__get_entry_versioned(&entry, ctx->wc_ctx, local_abspath,
svn_node_unknown, FALSE, FALSE,
pool, pool));
@@ -112,42 +109,23 @@ calculate_target_mergeinfo(svn_ra_sessio
pool, pool));
}
}
- else
- {
- src_url = src_path_or_url;
- }
if (! locally_added)
{
- if (! no_repos_access)
- {
- /* Fetch any existing (explicit) mergeinfo. We'll temporarily
- reparent to the target URL here, just to keep the code simple.
- We could, as an alternative, first see if the target URL was a
- child of the session URL and use the relative "remainder",
- falling back to this reparenting as necessary. */
- const char *old_session_url = NULL;
- SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
- ra_session, src_url, pool));
- SVN_ERR(svn_client__get_repos_mergeinfo(ra_session, &src_mergeinfo,
- "", src_revnum,
- svn_mergeinfo_inherited,
- TRUE, pool));
- if (old_session_url)
- SVN_ERR(svn_ra_reparent(ra_session, old_session_url, pool));
- }
- else
- {
- svn_boolean_t inherited;
- const char *local_abspath;
-
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, src_path_or_url,
- pool));
- SVN_ERR(svn_client__get_wc_mergeinfo(&src_mergeinfo, &inherited,
- svn_mergeinfo_inherited,
- local_abspath, NULL,
- NULL, ctx, pool, pool));
- }
+ /* Fetch any existing (explicit) mergeinfo. We'll temporarily
+ reparent to the target URL here, just to keep the code simple.
+ We could, as an alternative, first see if the target URL was a
+ child of the session URL and use the relative "remainder",
+ falling back to this reparenting as necessary. */
+ const char *old_session_url = NULL;
+ SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
+ ra_session, src_url, pool));
+ SVN_ERR(svn_client__get_repos_mergeinfo(ra_session, &src_mergeinfo,
+ "", src_revnum,
+ svn_mergeinfo_inherited,
+ TRUE, pool));
+ if (old_session_url)
+ SVN_ERR(svn_ra_reparent(ra_session, old_session_url, pool));
}
*target_mergeinfo = src_mergeinfo;
@@ -177,7 +155,7 @@ extend_wc_mergeinfo(const char *target_a
return svn_error_return(
svn_client__record_wc_mergeinfo(target_abspath, wc_mergeinfo,
- ctx, pool));
+ FALSE, ctx, pool));
}
/* Find the longest common ancestor of paths in COPY_PAIRS. If
@@ -258,63 +236,126 @@ get_copy_pair_ancestors(const apr_array_
}
-/* Copy each COPY_PAIR->SRC into COPY_PAIR->DST. Use POOL for temporary
- allocations. */
+struct do_wc_to_wc_copies_with_write_lock_baton {
+ const apr_array_header_t *copy_pairs;
+ svn_client_ctx_t *ctx;
+ const char *dst_parent;
+};
+
+/* The guts of do_wc_to_wc_copies */
static svn_error_t *
-do_wc_to_wc_copies(const apr_array_header_t *copy_pairs,
- svn_client_ctx_t *ctx,
- apr_pool_t *pool)
+do_wc_to_wc_copies_with_write_lock(void *baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
+ struct do_wc_to_wc_copies_with_write_lock_baton *b = baton;
int i;
- apr_pool_t *iterpool = svn_pool_create(pool);
- const char *dst_parent;
- svn_wc_adm_access_t *dst_access;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
svn_error_t *err = SVN_NO_ERROR;
- get_copy_pair_ancestors(copy_pairs, NULL, &dst_parent, NULL, pool);
- if (copy_pairs->nelts == 1)
- dst_parent = svn_dirent_dirname(dst_parent, pool);
-
- /* Because all copies are to the same destination directory, we can open
- the directory once, and use it for each copy. */
- /* ### If we didn't potentially use DST_ACCESS as the SRC_ACCESS, we
- ### could use a read lock here. */
- SVN_ERR(svn_wc__adm_open_in_context(&dst_access, ctx->wc_ctx, dst_parent,
- TRUE, -1, ctx->cancel_func, ctx->cancel_baton,
- pool));
-
- for (i = 0; i < copy_pairs->nelts; i++)
+ for (i = 0; i < b->copy_pairs->nelts; i++)
{
- const char *dst_parent_abspath;
const char *dst_abspath;
- svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
+ svn_client__copy_pair_t *pair = APR_ARRAY_IDX(b->copy_pairs, i,
svn_client__copy_pair_t *);
svn_pool_clear(iterpool);
/* Check for cancellation */
- if (ctx->cancel_func)
- SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+ if (b->ctx->cancel_func)
+ SVN_ERR(b->ctx->cancel_func(b->ctx->cancel_baton));
/* Perform the copy */
- SVN_ERR(svn_dirent_get_absolute(&pair->src_abs, pair->src, pool));
- SVN_ERR(svn_dirent_get_absolute(&dst_parent_abspath, pair->dst_parent,
- pool));
- dst_abspath = svn_dirent_join(dst_parent_abspath, pair->base_name,
+ dst_abspath = svn_dirent_join(pair->dst_parent_abspath, pair->base_name,
iterpool);
- err = svn_wc_copy3(ctx->wc_ctx, pair->src_abs, dst_abspath,
- ctx->cancel_func, ctx->cancel_baton,
- ctx->notify_func2, ctx->notify_baton2, iterpool);
+ err = svn_wc_copy3(b->ctx->wc_ctx, pair->src, dst_abspath,
+ b->ctx->cancel_func, b->ctx->cancel_baton,
+ b->ctx->notify_func2, b->ctx->notify_baton2, iterpool);
if (err)
break;
}
svn_pool_destroy(iterpool);
- svn_io_sleep_for_timestamps(dst_parent, pool);
+ svn_io_sleep_for_timestamps(b->dst_parent, scratch_pool);
SVN_ERR(err);
+ return SVN_NO_ERROR;
+}
- return svn_error_return(svn_wc_adm_close2(dst_access, pool));
+/* Copy each COPY_PAIR->SRC into COPY_PAIR->DST. Use POOL for temporary
+ allocations. */
+static svn_error_t *
+do_wc_to_wc_copies(const apr_array_header_t *copy_pairs,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ const char *dst_parent, *dst_parent_abspath;
+ struct do_wc_to_wc_copies_with_write_lock_baton baton;
+
+ get_copy_pair_ancestors(copy_pairs, NULL, &dst_parent, NULL, pool);
+ if (copy_pairs->nelts == 1)
+ dst_parent = svn_dirent_dirname(dst_parent, pool);
+
+ SVN_ERR(svn_dirent_get_absolute(&dst_parent_abspath, dst_parent, pool));
+
+ baton.copy_pairs = copy_pairs;
+ baton.ctx = ctx;
+ baton.dst_parent = dst_parent;
+ SVN_ERR(svn_wc__call_with_write_lock(do_wc_to_wc_copies_with_write_lock,
+ &baton, ctx->wc_ctx, dst_parent_abspath,
+ pool, pool));
+
+ return SVN_NO_ERROR;
}
+struct do_wc_to_wc_moves_with_locks_baton {
+ svn_client_ctx_t *ctx;
+ svn_client__copy_pair_t *pair;
+ const char *dst_parent_abspath;
+ svn_boolean_t lock_src;
+ svn_boolean_t lock_dst;
+};
+
+/* The locked bit of do_wc_to_wc_moves. */
+static svn_error_t *
+do_wc_to_wc_moves_with_locks2(void *baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ struct do_wc_to_wc_moves_with_locks_baton *b = baton;
+ const char *dst_abspath;
+
+ dst_abspath = svn_dirent_join(b->dst_parent_abspath, b->pair->base_name,
+ scratch_pool);
+
+ SVN_ERR(svn_wc_copy3(b->ctx->wc_ctx, b->pair->src, dst_abspath,
+ b->ctx->cancel_func, b->ctx->cancel_baton,
+ b->ctx->notify_func2, b->ctx->notify_baton2,
+ scratch_pool));
+
+ SVN_ERR(svn_wc_delete4(b->ctx->wc_ctx, b->pair->src, FALSE, FALSE,
+ b->ctx->cancel_func, b->ctx->cancel_baton,
+ b->ctx->notify_func2, b->ctx->notify_baton2,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* Wrapper to add an optional second lock */
+static svn_error_t *
+do_wc_to_wc_moves_with_locks1(void *baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ struct do_wc_to_wc_moves_with_locks_baton *b = baton;
+
+ if (b->lock_dst)
+ SVN_ERR(svn_wc__call_with_write_lock(do_wc_to_wc_moves_with_locks2, b,
+ b->ctx->wc_ctx, b->dst_parent_abspath,
+ result_pool, scratch_pool));
+ else
+ SVN_ERR(do_wc_to_wc_moves_with_locks2(b, result_pool, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
/* Move each COPY_PAIR->SRC into COPY_PAIR->DST, deleting COPY_PAIR->SRC
afterwards. Use POOL for temporary allocations. */
@@ -330,14 +371,8 @@ do_wc_to_wc_moves(const apr_array_header
for (i = 0; i < copy_pairs->nelts; i++)
{
- svn_wc_adm_access_t *src_access;
- svn_wc_adm_access_t *dst_access;
- svn_boolean_t close_dst_access = FALSE;
- svn_boolean_t close_src_access = FALSE;
- const char *src_parent;
const char *src_parent_abspath;
- const char *dst_abspath;
- const char *dst_parent_abspath;
+ struct do_wc_to_wc_moves_with_locks_baton baton;
svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
svn_client__copy_pair_t *);
@@ -347,83 +382,46 @@ do_wc_to_wc_moves(const apr_array_header
if (ctx->cancel_func)
SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
- src_parent = svn_dirent_dirname(pair->src, iterpool);
- SVN_ERR(svn_dirent_get_absolute(&src_parent_abspath, src_parent,
- iterpool));
- SVN_ERR(svn_dirent_get_absolute(&dst_parent_abspath, pair->dst_parent,
- iterpool));
+ src_parent_abspath = svn_dirent_dirname(pair->src, iterpool);
- /* We now need to open the right combination of batons.
+ /* We now need to lock the right combination of batons.
Four cases:
1) src_parent == dst_parent
2) src_parent is parent of dst_parent
3) dst_parent is parent of src_parent
- 4) src_parent and dst_parent are disjoint */
- if (strcmp(src_parent_abspath, dst_parent_abspath) == 0)
+ 4) src_parent and dst_parent are disjoint
+ We can handle 1) as either 2) or 3) */
+ if (strcmp(src_parent_abspath, pair->dst_parent_abspath) == 0
+ || svn_dirent_is_child(src_parent_abspath, pair->dst_parent_abspath,
+ iterpool))
{
- SVN_ERR(svn_wc__adm_open_in_context(&src_access, ctx->wc_ctx,
- src_parent, TRUE, -1,
- ctx->cancel_func,
- ctx->cancel_baton, iterpool));
- dst_access = src_access;
- close_src_access = TRUE;
+ baton.lock_src = TRUE;
+ baton.lock_dst = FALSE;
}
- else if (svn_dirent_is_child(src_parent_abspath, dst_parent_abspath,
+ else if (svn_dirent_is_child(pair->dst_parent_abspath, src_parent_abspath,
iterpool))
{
- SVN_ERR(svn_wc__adm_open_in_context(&src_access, ctx->wc_ctx,
- src_parent, TRUE, -1,
- ctx->cancel_func,
- ctx->cancel_baton, iterpool));
- SVN_ERR(svn_wc_adm_retrieve(&dst_access, src_access,
- pair->dst_parent, iterpool));
- close_src_access = TRUE;
- }
- else if (svn_dirent_is_child(dst_parent_abspath, src_parent_abspath,
- iterpool))
- {
- SVN_ERR(svn_wc__adm_open_in_context(&dst_access, ctx->wc_ctx,
- pair->dst_parent, TRUE, -1,
- ctx->cancel_func,
- ctx->cancel_baton, iterpool));
- SVN_ERR(svn_wc_adm_retrieve(&src_access, dst_access, src_parent,
- iterpool));
- close_dst_access = TRUE;
+ baton.lock_src = FALSE;
+ baton.lock_dst = TRUE;
}
else
{
- SVN_ERR(svn_wc__adm_open_in_context(&src_access, ctx->wc_ctx,
- src_parent, TRUE, -1,
- ctx->cancel_func,
- ctx->cancel_baton, iterpool));
- SVN_ERR(svn_wc__adm_open_in_context(&dst_access, ctx->wc_ctx,
- pair->dst_parent, TRUE, -1,
- ctx->cancel_func,
- ctx->cancel_baton, iterpool));
- close_dst_access = TRUE;
- close_src_access = TRUE;
+ baton.lock_src = TRUE;
+ baton.lock_dst = TRUE;
}
/* Perform the copy and then the delete. */
- SVN_ERR(svn_dirent_get_absolute(&pair->src_abs, pair->src, pool));
- dst_abspath = svn_dirent_join(dst_parent_abspath, pair->base_name,
- iterpool);
- err = svn_wc_copy3(ctx->wc_ctx, pair->src_abs, dst_abspath,
- ctx->cancel_func, ctx->cancel_baton,
- ctx->notify_func2, ctx->notify_baton2, iterpool);
- if (err)
- break;
+ baton.ctx = ctx;
+ baton.pair = pair;
+ baton.dst_parent_abspath = pair->dst_parent_abspath;
+ if (baton.lock_src)
+ SVN_ERR(svn_wc__call_with_write_lock(do_wc_to_wc_moves_with_locks1,
+ &baton,
+ ctx->wc_ctx, src_parent_abspath,
+ iterpool, iterpool));
+ else
+ SVN_ERR(do_wc_to_wc_moves_with_locks1(&baton, iterpool, iterpool));
- /* Perform the delete. */
- SVN_ERR(svn_wc_delete4(ctx->wc_ctx, pair->src_abs, FALSE, FALSE,
- ctx->cancel_func, ctx->cancel_baton,
- ctx->notify_func2, ctx->notify_baton2,
- iterpool));
-
- if (close_dst_access)
- SVN_ERR(svn_wc_adm_close2(dst_access, iterpool));
- if (close_src_access)
- SVN_ERR(svn_wc_adm_close2(src_access, iterpool));
}
svn_pool_destroy(iterpool);
@@ -469,22 +467,24 @@ wc_to_wc_copy(const apr_array_header_t *
_("Path '%s' already exists"),
svn_dirent_local_style(pair->dst, pool));
- svn_dirent_split(pair->dst, &pair->dst_parent, &pair->base_name, pool);
+ svn_dirent_split(pair->dst, &pair->dst_parent_abspath, &pair->base_name,
+ pool);
/* Make sure the destination parent is a directory and produce a clear
error message if it is not. */
- SVN_ERR(svn_io_check_path(pair->dst_parent, &dst_parent_kind, iterpool));
+ SVN_ERR(svn_io_check_path(pair->dst_parent_abspath, &dst_parent_kind,
+ iterpool));
if (make_parents && dst_parent_kind == svn_node_none)
{
- SVN_ERR(svn_client__make_local_parents(pair->dst_parent, TRUE, ctx,
- iterpool));
+ SVN_ERR(svn_client__make_local_parents(pair->dst_parent_abspath,
+ TRUE, ctx, iterpool));
}
else if (dst_parent_kind != svn_node_dir)
{
return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
_("Path '%s' is not a directory"),
- svn_dirent_local_style(pair->dst_parent,
- pool));
+ svn_dirent_local_style(
+ pair->dst_parent_abspath, pool));
}
}
@@ -667,9 +667,9 @@ find_absent_parents1(svn_ra_session_t *r
found. Push each nonexistent URL onto the array NEW_DIRS,
allocating in POOL. Raise an error if the existing node is not a
directory.
-
+
Set *TOP_DST_URL and the RA session's root to the existing node's URL.
-
+
### Multiple requests for HEAD (SVN_INVALID_REVNUM) make this
### implementation susceptible to race conditions. */
static svn_error_t *
@@ -781,12 +781,13 @@ repos_to_repos_copy(svn_commit_info_t **
pair->src, &pair->src_peg_revision,
&pair->src_op_revision,
&dead_end_rev, ctx, pool));
-
+
/* Go ahead and grab mergeinfo from the source, too. */
SVN_ERR(svn_client__ensure_ra_session_url(&ignored_url, ra_session,
pair->src, pool));
- SVN_ERR(calculate_target_mergeinfo(ra_session, &mergeinfo, NULL, pair->src,
- pair->src_revnum, FALSE, ctx, pool));
+ SVN_ERR(calculate_target_mergeinfo(ra_session, &mergeinfo, NULL,
+ pair->src,
+ pair->src_revnum, ctx, pool));
if (mergeinfo)
SVN_ERR(svn_mergeinfo_to_string(&info->mergeinfo, mergeinfo, pool));
@@ -1141,7 +1142,6 @@ wc_to_repos_copy(svn_commit_info_t **com
void *edit_baton;
void *commit_baton;
apr_hash_t *committables;
- svn_wc_adm_access_t *adm_access;
apr_array_header_t *commit_items;
const svn_wc_entry_t *entry;
apr_pool_t *iterpool;
@@ -1149,15 +1149,13 @@ wc_to_repos_copy(svn_commit_info_t **com
apr_hash_t *commit_revprops;
int i;
- /* Find the common root of all the source paths, and probe the wc. */
+ /* Find the common root of all the source paths */
get_copy_pair_ancestors(copy_pairs, &top_src_path, NULL, NULL, pool);
- SVN_ERR(svn_wc__adm_probe_in_context(&adm_access, ctx->wc_ctx, top_src_path,
- FALSE, -1, ctx->cancel_func,
- ctx->cancel_baton, pool));
-
- /* The commit process uses absolute paths, so we need to open the access
- baton using absolute paths, and so we really need to use absolute
- paths everywhere. */
+
+ /* Do we need to lock the working copy? 1.6 didn't take a write
+ lock, but what happens if the working copy changes during the copy
+ operation? */
+
iterpool = svn_pool_create(pool);
for (i = 0; i < copy_pairs->nelts; i++)
@@ -1166,8 +1164,7 @@ wc_to_repos_copy(svn_commit_info_t **com
svn_client__copy_pair_t *);
svn_pool_clear(iterpool);
/* Sanity check if the source path is versioned. */
- SVN_ERR(svn_dirent_get_absolute(&pair->src_abs, pair->src, pool));
- SVN_ERR(svn_wc__get_entry_versioned(&entry, ctx->wc_ctx, pair->src_abs,
+ SVN_ERR(svn_wc__get_entry_versioned(&entry, ctx->wc_ctx, pair->src,
svn_node_unknown, FALSE, FALSE,
iterpool, iterpool));
}
@@ -1193,8 +1190,7 @@ wc_to_repos_copy(svn_commit_info_t **com
}
SVN_ERR(svn_client__open_ra_session_internal(&ra_session, top_dst_url,
- svn_wc_adm_access_path(
- adm_access),
+ top_src_path,
NULL, TRUE, TRUE, ctx, pool));
/* If requested, determine the nearest existing parent of the destination,
@@ -1216,7 +1212,7 @@ wc_to_repos_copy(svn_commit_info_t **com
svn_pool_clear(iterpool);
- SVN_ERR(svn_wc__get_entry_versioned(&entry, ctx->wc_ctx, pair->src_abs,
+ SVN_ERR(svn_wc__get_entry_versioned(&entry, ctx->wc_ctx, pair->src,
svn_node_unknown, FALSE, FALSE,
iterpool, iterpool));
pair->src_revnum = entry->revision;
@@ -1272,7 +1268,7 @@ wc_to_repos_copy(svn_commit_info_t **com
if (! message)
{
svn_pool_destroy(iterpool);
- return svn_error_return(svn_wc_adm_close2(adm_access, pool));
+ return SVN_NO_ERROR;
}
}
else
@@ -1295,7 +1291,7 @@ wc_to_repos_copy(svn_commit_info_t **com
SVN_CLIENT__SINGLE_REPOS_NAME,
APR_HASH_KEY_STRING)))
{
- return svn_error_return(svn_wc_adm_close2(adm_access, pool));
+ return SVN_NO_ERROR;
}
/* If we are creating intermediate directories, tack them onto the list
@@ -1335,10 +1331,10 @@ wc_to_repos_copy(svn_commit_info_t **com
info known to the WC and the repository. */
item->outgoing_prop_changes = apr_array_make(pool, 1,
sizeof(svn_prop_t *));
- SVN_ERR(calculate_target_mergeinfo(ra_session, &mergeinfo, adm_access,
- pair->src, pair->src_revnum,
- FALSE, ctx, iterpool));
- SVN_ERR(svn_wc__get_entry_versioned(&entry, ctx->wc_ctx, pair->src_abs,
+ SVN_ERR(calculate_target_mergeinfo(ra_session, &mergeinfo, pair->src,
+ NULL, SVN_INVALID_REVNUM,
+ ctx, iterpool));
+ SVN_ERR(svn_wc__get_entry_versioned(&entry, ctx->wc_ctx, pair->src,
svn_node_unknown, FALSE, FALSE,
pool, pool));
SVN_ERR(svn_client__parse_mergeinfo(&wc_mergeinfo, ctx->wc_ctx,
@@ -1397,8 +1393,7 @@ wc_to_repos_copy(svn_commit_info_t **com
svn_pool_destroy(iterpool);
- /* It's only a read lock, so unlocking is harmless. */
- return svn_error_return(svn_wc_adm_close2(adm_access, pool));
+ return SVN_NO_ERROR;
}
/* Peform each individual copy operation for a repos -> wc copy. A
@@ -1474,7 +1469,7 @@ repos_to_wc_copy_single(svn_client__copy
### source path. */
SVN_ERR(calculate_target_mergeinfo(ra_session, &src_mergeinfo, NULL,
pair->src, src_revnum,
- FALSE, ctx, pool));
+ ctx, pool));
SVN_ERR(extend_wc_mergeinfo(dst_abspath, src_mergeinfo, ctx, pool));
}
else /* different repositories */
@@ -1532,7 +1527,7 @@ repos_to_wc_copy_single(svn_client__copy
SVN_ERR(calculate_target_mergeinfo(ra_session, &src_mergeinfo,
NULL, pair->src, src_revnum,
- FALSE, ctx, pool));
+ ctx, pool));
SVN_ERR(extend_wc_mergeinfo(dst_abspath, src_mergeinfo, ctx, pool));
/* Ideally, svn_wc_add_repos_file3() would take a notify function
@@ -1554,6 +1549,137 @@ repos_to_wc_copy_single(svn_client__copy
return SVN_NO_ERROR;
}
+static svn_error_t*
+repos_to_wc_copy_locked(const apr_array_header_t *copy_pairs,
+ const char *top_dst_path,
+ svn_boolean_t ignore_externals,
+ svn_ra_session_t *ra_session,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ int i;
+ const char *src_uuid = NULL, *dst_uuid = NULL;
+ svn_boolean_t same_repositories;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ /* We've already checked for physical obstruction by a working file.
+ But there could also be logical obstruction by an entry whose
+ working file happens to be missing.*/
+ for (i = 0; i < copy_pairs->nelts; i++)
+ {
+ svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
+ svn_client__copy_pair_t *);
+ const svn_wc_entry_t *ent;
+ const char *dst_abspath;
+
+ svn_pool_clear(iterpool);
+ SVN_ERR(svn_dirent_get_absolute(&dst_abspath, pair->dst, iterpool));
+
+ SVN_ERR(svn_wc__maybe_get_entry(&ent, ctx->wc_ctx, dst_abspath,
+ svn_node_unknown, TRUE, FALSE,
+ iterpool, iterpool));
+ if (ent)
+ {
+ /* TODO(#2843): Rework the error report. Maybe we can simplify the
+ condition. Currently, the first is about hidden items and the
+ second is for missing items. */
+ if (ent->depth == svn_depth_exclude
+ || ent->absent)
+ {
+ return svn_error_createf
+ (SVN_ERR_ENTRY_EXISTS,
+ NULL, _("'%s' is already under version control"),
+ svn_dirent_local_style(pair->dst, iterpool));
+ }
+ else if ((ent->kind != svn_node_dir) &&
+ (ent->schedule != svn_wc_schedule_delete)
+ && ! ent->deleted)
+ return svn_error_createf
+ (SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
+ _("Entry for '%s' exists (though the working file is missing)"),
+ svn_dirent_local_style(pair->dst, iterpool));
+ }
+ }
+
+ /* Decide whether the two repositories are the same or not. */
+ {
+ svn_error_t *src_err, *dst_err;
+ const char *parent;
+ const char *parent_abspath;
+
+ /* Get the repository uuid of SRC_URL */
+ src_err = svn_ra_get_uuid2(ra_session, &src_uuid, scratch_pool);
+ if (src_err && src_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)
+ return svn_error_return(src_err);
+
+ /* Get repository uuid of dst's parent directory, since dst may
+ not exist. ### TODO: we should probably walk up the wc here,
+ in case the parent dir has an imaginary URL. */
+ if (copy_pairs->nelts == 1)
+ parent = svn_dirent_dirname(top_dst_path, scratch_pool);
+ else
+ parent = top_dst_path;
+
+ SVN_ERR(svn_dirent_get_absolute(&parent_abspath, parent, scratch_pool));
+ dst_err = svn_client_uuid_from_path2(&dst_uuid, parent_abspath, ctx,
+ scratch_pool, scratch_pool);
+ if (dst_err && dst_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)
+ return dst_err;
+
+ /* If either of the UUIDs are nonexistent, then at least one of
+ the repositories must be very old. Rather than punish the
+ user, just assume the repositories are different, so no
+ copy-history is attempted. */
+ if (src_err || dst_err || (! src_uuid) || (! dst_uuid))
+ same_repositories = FALSE;
+
+ else
+ same_repositories = (strcmp(src_uuid, dst_uuid) == 0);
+ }
+
+ /* Perform the move for each of the copy_pairs. */
+ for (i = 0; i < copy_pairs->nelts; i++)
+ {
+ /* Check for cancellation */
+ if (ctx->cancel_func)
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(repos_to_wc_copy_single(APR_ARRAY_IDX(copy_pairs, i,
+ svn_client__copy_pair_t *),
+ same_repositories,
+ ignore_externals,
+ ra_session, ctx, iterpool));
+ }
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+struct repos_to_wc_copy_baton {
+ const apr_array_header_t *copy_pairs;
+ const char *top_dst_path;
+ svn_boolean_t ignore_externals;
+ svn_ra_session_t *ra_session;
+ svn_client_ctx_t *ctx;
+};
+
+/* Implements svn_wc__with_write_lock_func_t. */
+static svn_error_t *
+repos_to_wc_copy_cb(void *baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ struct repos_to_wc_copy_baton *b = baton;
+
+ SVN_ERR(repos_to_wc_copy_locked(b->copy_pairs, b->top_dst_path,
+ b->ignore_externals, b->ra_session,
+ b->ctx, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *
repos_to_wc_copy(const apr_array_header_t *copy_pairs,
svn_boolean_t make_parents,
@@ -1562,11 +1688,10 @@ repos_to_wc_copy(const apr_array_header_
apr_pool_t *pool)
{
svn_ra_session_t *ra_session;
- svn_wc_adm_access_t *adm_access;
const char *top_src_url, *top_dst_path;
- const char *src_uuid = NULL, *dst_uuid = NULL;
- svn_boolean_t same_repositories;
apr_pool_t *iterpool = svn_pool_create(pool);
+ const char *lock_abspath;
+ struct repos_to_wc_copy_baton baton;
int i;
/* Get the real path for the source, based upon its peg revision. */
@@ -1594,8 +1719,16 @@ repos_to_wc_copy(const apr_array_header_
}
get_copy_pair_ancestors(copy_pairs, &top_src_url, &top_dst_path, NULL, pool);
+ lock_abspath = top_dst_path;
if (copy_pairs->nelts == 1)
- top_src_url = svn_uri_dirname(top_src_url, pool);
+ {
+ svn_node_kind_t kind;
+ top_src_url = svn_uri_dirname(top_src_url, pool);
+ SVN_ERR(svn_wc__node_get_kind(&kind, ctx->wc_ctx, top_dst_path, FALSE,
+ pool));
+ if (kind != svn_node_dir)
+ lock_abspath = svn_dirent_dirname(top_dst_path, pool);
+ }
/* Open a repository session to the longest common src ancestor. We do not
(yet) have a working copy, so we don't have a corresponding path and
@@ -1670,105 +1803,18 @@ repos_to_wc_copy(const apr_array_header_
svn_dirent_local_style(dst_parent, pool));
}
}
+ svn_pool_destroy(iterpool);
- /* Probe the wc at the longest common dst ancestor. */
- SVN_ERR(svn_wc__adm_probe_in_context(&adm_access, ctx->wc_ctx, top_dst_path,
- TRUE, -1, ctx->cancel_func,
- ctx->cancel_baton, pool));
-
- /* We've already checked for physical obstruction by a working file.
- But there could also be logical obstruction by an entry whose
- working file happens to be missing.*/
- for (i = 0; i < copy_pairs->nelts; i++)
- {
- svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
- svn_client__copy_pair_t *);
- const svn_wc_entry_t *ent;
- const char *dst_abspath;
-
- svn_pool_clear(iterpool);
- SVN_ERR(svn_dirent_get_absolute(&dst_abspath, pair->dst, iterpool));
-
- SVN_ERR(svn_wc__maybe_get_entry(&ent, ctx->wc_ctx, dst_abspath,
- svn_node_unknown, TRUE, FALSE,
- iterpool, iterpool));
- if (ent)
- {
- /* TODO(#2843): Rework the error report. Maybe we can simplify the
- condition. Currently, the first is about hidden items and the
- second is for missing items. */
- if (ent->depth == svn_depth_exclude
- || ent->absent)
- {
- return svn_error_createf
- (SVN_ERR_ENTRY_EXISTS,
- NULL, _("'%s' is already under version control"),
- svn_dirent_local_style(pair->dst, pool));
- }
- else if ((ent->kind != svn_node_dir) &&
- (ent->schedule != svn_wc_schedule_delete)
- && ! ent->deleted)
- return svn_error_createf
- (SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
- _("Entry for '%s' exists (though the working file is missing)"),
- svn_dirent_local_style(pair->dst, pool));
- }
- }
-
- /* Decide whether the two repositories are the same or not. */
- {
- svn_error_t *src_err, *dst_err;
- const char *parent;
- const char *parent_abspath;
-
- /* Get the repository uuid of SRC_URL */
- src_err = svn_ra_get_uuid2(ra_session, &src_uuid, pool);
- if (src_err && src_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)
- return svn_error_return(src_err);
-
- /* Get repository uuid of dst's parent directory, since dst may
- not exist. ### TODO: we should probably walk up the wc here,
- in case the parent dir has an imaginary URL. */
- if (copy_pairs->nelts == 1)
- parent = svn_dirent_dirname(top_dst_path, pool);
- else
- parent = top_dst_path;
-
- SVN_ERR(svn_dirent_get_absolute(&parent_abspath, parent, pool));
- dst_err = svn_client_uuid_from_path2(&dst_uuid, parent_abspath, ctx, pool,
- pool);
- if (dst_err && dst_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)
- return dst_err;
-
- /* If either of the UUIDs are nonexistent, then at least one of
- the repositories must be very old. Rather than punish the
- user, just assume the repositories are different, so no
- copy-history is attempted. */
- if (src_err || dst_err || (! src_uuid) || (! dst_uuid))
- same_repositories = FALSE;
-
- else
- same_repositories = (strcmp(src_uuid, dst_uuid) == 0);
- }
-
- /* Perform the move for each of the copy_pairs. */
- for (i = 0; i < copy_pairs->nelts; i++)
- {
- /* Check for cancellation */
- if (ctx->cancel_func)
- SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
-
- svn_pool_clear(iterpool);
+ baton.copy_pairs = copy_pairs;
+ baton.top_dst_path = top_dst_path;
+ baton.ignore_externals = ignore_externals;
+ baton.ra_session = ra_session;
+ baton.ctx = ctx;
- SVN_ERR(repos_to_wc_copy_single(APR_ARRAY_IDX(copy_pairs, i,
- svn_client__copy_pair_t *),
- same_repositories,
- ignore_externals,
- ra_session, ctx, iterpool));
- }
-
- svn_pool_destroy(iterpool);
- return svn_error_return(svn_wc_adm_close2(adm_access, pool));
+ SVN_ERR(svn_wc__call_with_write_lock(repos_to_wc_copy_cb, &baton,
+ ctx->wc_ctx, lock_abspath,
+ pool, pool));
+ return SVN_NO_ERROR;
}
#define NEED_REPOS_REVNUM(revision) \
@@ -1800,6 +1846,8 @@ try_copy(svn_commit_info_t **commit_info
srcs_are_urls = svn_path_is_url(APR_ARRAY_IDX(sources, 0,
svn_client_copy_source_t *)->path);
dst_is_url = svn_path_is_url(dst_path_in);
+ if (!dst_is_url)
+ SVN_ERR(svn_dirent_get_absolute(&dst_path_in, dst_path_in, pool));
/* If we have multiple source paths, it implies the dst_path is a
directory we are moving or copying into. Populate the COPY_PAIRS
@@ -1818,7 +1866,10 @@ try_copy(svn_commit_info_t **commit_info
svn_pool_clear(iterpool);
- pair->src = apr_pstrdup(pool, source->path);
+ if (src_is_url)
+ pair->src = apr_pstrdup(pool, source->path);
+ else
+ SVN_ERR(svn_dirent_get_absolute(&pair->src, source->path, pool));
pair->src_op_revision = *source->revision;
pair->src_peg_revision = *source->peg_revision;
@@ -1853,8 +1904,12 @@ try_copy(svn_commit_info_t **commit_info
svn_client__copy_pair_t *pair = apr_palloc(pool, sizeof(*pair));
svn_client_copy_source_t *source =
APR_ARRAY_IDX(sources, 0, svn_client_copy_source_t *);
+ svn_boolean_t src_is_url = svn_path_is_url(source->path);
- pair->src = apr_pstrdup(pool, source->path);
+ if (src_is_url)
+ pair->src = apr_pstrdup(pool, source->path);
+ else
+ SVN_ERR(svn_dirent_get_absolute(&pair->src, source->path, pool));
pair->src_op_revision = *source->revision;
pair->src_peg_revision = *source->peg_revision;
@@ -2072,7 +2127,7 @@ try_copy(svn_commit_info_t **commit_info
/* Public Interfaces */
svn_error_t *
svn_client_copy5(svn_commit_info_t **commit_info_p,
- apr_array_header_t *sources,
+ const apr_array_header_t *sources,
const char *dst_path,
svn_boolean_t copy_as_child,
svn_boolean_t make_parents,
@@ -2148,7 +2203,7 @@ svn_client_copy5(svn_commit_info_t **com
svn_error_t *
svn_client_move5(svn_commit_info_t **commit_info_p,
- apr_array_header_t *src_paths,
+ const apr_array_header_t *src_paths,
const char *dst_path,
svn_boolean_t force,
svn_boolean_t move_as_child,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/delete.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/delete.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/delete.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/delete.c Tue Aug 10 18:06:17 2010
@@ -287,6 +287,30 @@ svn_client__wc_delete(const char *path,
return SVN_NO_ERROR;
}
+/* Callback baton for delete_with_write_lock_baton. */
+struct delete_with_write_lock_baton
+{
+ const char *path;
+ svn_boolean_t force;
+ svn_boolean_t keep_local;
+ svn_client_ctx_t *ctx;
+};
+
+/* Implements svn_wc__with_write_lock_func_t. */
+static svn_error_t *
+delete_with_write_lock_func(void *baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ struct delete_with_write_lock_baton *args = baton;
+
+ /* Let the working copy library handle the PATH. */
+ return svn_client__wc_delete(args->path, args->force,
+ FALSE, args->keep_local,
+ args->ctx->notify_func2,
+ args->ctx->notify_baton2,
+ args->ctx, scratch_pool);
+}
svn_error_t *
svn_client_delete3(svn_commit_info_t **commit_info_p,
@@ -311,28 +335,24 @@ svn_client_delete3(svn_commit_info_t **c
for (i = 0; i < paths->nelts; i++)
{
- svn_wc_adm_access_t *adm_access;
+ struct delete_with_write_lock_baton dwwlb;
const char *path = APR_ARRAY_IDX(paths, i, const char *);
- const char *parent_path;
+ const char *local_abspath;
svn_pool_clear(subpool);
- parent_path = svn_dirent_dirname(path, subpool);
/* See if the user wants us to stop. */
if (ctx->cancel_func)
SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
- /* Let the working copy library handle the PATH. */
- SVN_ERR(svn_wc__adm_open_in_context(&adm_access, ctx->wc_ctx,
- parent_path, TRUE, -1,
- ctx->cancel_func,
- ctx->cancel_baton, subpool));
- SVN_ERR(svn_client__wc_delete(path, force,
- FALSE, keep_local,
- ctx->notify_func2,
- ctx->notify_baton2,
- ctx, subpool));
- SVN_ERR(svn_wc_adm_close2(adm_access, subpool));
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, subpool));
+ dwwlb.path = path;
+ dwwlb.force = force;
+ dwwlb.keep_local = keep_local;
+ dwwlb.ctx = ctx;
+ SVN_ERR(svn_wc__call_with_write_lock(delete_with_write_lock_func,
+ &dwwlb, ctx->wc_ctx,
+ local_abspath, pool, subpool));
}
svn_pool_destroy(subpool);
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/deprecated.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/deprecated.c Tue Aug 10 18:06:17 2010
@@ -412,7 +412,7 @@ svn_client_commit(svn_client_commit_info
svn_error_t *
svn_client_copy4(svn_commit_info_t **commit_info_p,
- apr_array_header_t *sources,
+ const apr_array_header_t *sources,
const char *dst_path,
svn_boolean_t copy_as_child,
svn_boolean_t make_parents,
@@ -1653,7 +1653,7 @@ svn_client_switch(svn_revnum_t *result_r
svn_opt_revision_t peg_revision;
peg_revision.kind = svn_opt_revision_unspecified;
return svn_client__switch_internal(result_rev, path, switch_url,
- &peg_revision, revision, NULL,
+ &peg_revision, revision,
SVN_DEPTH_INFINITY_OR_FILES(recurse),
FALSE, NULL, FALSE, FALSE, FALSE, ctx,
pool);
@@ -1862,7 +1862,7 @@ svn_client_mergeinfo_log_merged(const ch
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- return svn_client_mergeinfo_log(path_or_url, TRUE, peg_revision,
+ return svn_client_mergeinfo_log(TRUE, path_or_url, peg_revision,
merge_source_path_or_url,
src_peg_revision,
log_receiver, log_receiver_baton,
@@ -1883,7 +1883,7 @@ svn_client_mergeinfo_log_eligible(const
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- return svn_client_mergeinfo_log(path_or_url, FALSE, peg_revision,
+ return svn_client_mergeinfo_log(FALSE, path_or_url, peg_revision,
merge_source_path_or_url,
src_peg_revision,
log_receiver, log_receiver_baton,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/diff.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/diff.c Tue Aug 10 18:06:17 2010
@@ -126,8 +126,8 @@ display_mergeinfo_diff(const char *old_m
for (hi = apr_hash_first(pool, deleted);
hi; hi = apr_hash_next(hi))
{
- const char *from_path = svn_apr_hash_index_key(hi);
- apr_array_header_t *merge_revarray = svn_apr_hash_index_val(hi);
+ const char *from_path = svn__apr_hash_index_key(hi);
+ apr_array_header_t *merge_revarray = svn__apr_hash_index_val(hi);
svn_string_t *merge_revstr;
SVN_ERR(svn_rangelist_to_string(&merge_revstr, merge_revarray, pool));
@@ -141,8 +141,8 @@ display_mergeinfo_diff(const char *old_m
for (hi = apr_hash_first(pool, added);
hi; hi = apr_hash_next(hi))
{
- const char *from_path = svn_apr_hash_index_key(hi);
- apr_array_header_t *merge_revarray = svn_apr_hash_index_val(hi);
+ const char *from_path = svn__apr_hash_index_key(hi);
+ apr_array_header_t *merge_revarray = svn__apr_hash_index_val(hi);
svn_string_t *merge_revstr;
SVN_ERR(svn_rangelist_to_string(&merge_revstr, merge_revarray, pool));
@@ -1299,7 +1299,7 @@ diff_repos_repos(const struct diff_param
Otherwise, we just use "". */
SVN_ERR(svn_client__get_diff_editor
(drr.base_path ? drr.base_path : "",
- ctx->wc_ctx, callbacks, callback_baton, diff_param->depth,
+ NULL, callbacks, callback_baton, diff_param->depth,
FALSE /* doesn't matter for diff */, extra_ra_session, drr.rev1,
NULL /* no notify_func */, NULL /* no notify_baton */,
ctx->cancel_func, ctx->cancel_baton,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/export.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/export.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/export.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/export.c Tue Aug 10 18:06:17 2010
@@ -128,23 +128,43 @@ copy_one_versioned_file(const char *from
else if (err)
return svn_error_return(err);
- /* Only export 'added' files when the revision is WORKING.
- Otherwise, skip the 'added' files, since they didn't exist
- in the BASE revision and don't have an associated text-base.
-
- Don't export 'deleted' files and directories unless it's a
+ /* Don't export 'deleted' files and directories unless it's a
revision other than WORKING. These files and directories
don't really exist in WORKING. */
- if ((revision->kind != svn_opt_revision_working &&
- entry->schedule == svn_wc_schedule_add) ||
- (revision->kind == svn_opt_revision_working &&
- entry->schedule == svn_wc_schedule_delete))
+ if (revision->kind == svn_opt_revision_working
+ && entry->schedule == svn_wc_schedule_delete)
return SVN_NO_ERROR;
if (revision->kind != svn_opt_revision_working)
{
+ /* Only export 'added' files when the revision is WORKING. This is not
+ WORKING, so skip the 'added' files, since they didn't exist
+ in the BASE revision and don't have an associated text-base.
+
+ 'replaced' files are technically the same as 'added' files.
+ ### TODO: Handle replaced nodes properly.
+ ### svn_opt_revision_base refers to the "new"
+ ### base of the node. That means, if a node is locally
+ ### replaced, export skips this node, as if it was locally
+ ### added, because svn_opt_revision_base refers to the base
+ ### of the added node, not to the node that was deleted.
+ ### In contrast, when the node is copied-here or moved-here,
+ ### the copy/move source's content will be exported.
+ ### It is currently not possible to export the revert-base
+ ### when a node is locally replaced. We need a new
+ ### svn_opt_revision_ enum value for proper distinction
+ ### between revert-base and commit-base.
+
+ Copied-/moved-here nodes have a base, so export both added and
+ replaced files when they involve a copy-/move-here.
+
+ We get all this for free from evaluating SOURCE == NULL:
+ */
SVN_ERR(svn_wc_get_pristine_contents2(&source, wc_ctx, from_abspath,
scratch_pool, scratch_pool));
+ if (source == NULL)
+ return SVN_NO_ERROR;
+
SVN_ERR(svn_wc_get_prop_diffs2(NULL, &props, wc_ctx, from_abspath,
scratch_pool, scratch_pool));
}
@@ -294,15 +314,23 @@ copy_versioned_files(const char *from,
svn_node_unknown, FALSE, FALSE,
pool, pool));
- /* Only export 'added' files when the revision is WORKING.
- Otherwise, skip the 'added' files, since they didn't exist
- in the BASE revision and don't have an associated text-base.
+ /* Only export 'added' and 'replaced' files when the revision is WORKING;
+ when the revision is BASE (i.e. != WORKING), only export 'added' and
+ 'replaced' files when they are part of a copy-/move-here. Otherwise, skip
+ them, since they don't have an associated text-base. This condition for
+ added/replaced simply is an optimization. Added and replaced files would
+ be handled similarly by svn_wc_get_pristine_contents2(), which would
+ return NULL if they have no base associated.
+ TODO: We may prefer not to duplicate this condition and rather use
+ svn_wc_get_pristine_contents2() or a dedicated new function instead.
Don't export 'deleted' files and directories unless it's a
revision other than WORKING. These files and directories
don't really exist in WORKING. */
- if ((revision->kind != svn_opt_revision_working &&
- entry->schedule == svn_wc_schedule_add) ||
+ if ((revision->kind != svn_opt_revision_working
+ && (entry->schedule == svn_wc_schedule_add
+ || entry->schedule == svn_wc_schedule_replace)
+ && !entry->copied) ||
(revision->kind == svn_opt_revision_working &&
entry->schedule == svn_wc_schedule_delete))
return SVN_NO_ERROR;
@@ -464,7 +492,7 @@ copy_versioned_files(const char *from,
* Create PATH if it does not exist and is not obstructed, and invoke
* NOTIFY_FUNC with NOTIFY_BATON on PATH.
*
- * If PATH exists but is a file, then error with SVN_ERR_WC_NOT_DIRECTORY.
+ * If PATH exists but is a file, then error with SVN_ERR_WC_NOT_WORKING_COPY.
*
* If PATH is a already a directory, then error with
* SVN_ERR_WC_OBSTRUCTED_UPDATE, unless FORCE, in which case just
@@ -960,8 +988,8 @@ svn_client_export5(svn_revnum_t *result_
* with information. */
for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
{
- const char *propname = svn_apr_hash_index_key(hi);
- const svn_string_t *propval = svn_apr_hash_index_val(hi);
+ const char *propname = svn__apr_hash_index_key(hi);
+ const svn_string_t *propval = svn__apr_hash_index_val(hi);
SVN_ERR(change_file_prop(fb, propname, propval, pool));
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/externals.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/externals.c Tue Aug 10 18:06:17 2010
@@ -53,10 +53,6 @@ struct handle_external_item_change_baton
/* The directory that has this externals property. */
const char *parent_dir;
- /* Access baton for parent_dir. If the external is an export, this
- this must be NULL, otherwise it must be non-NULL. */
- svn_wc_adm_access_t *adm_access;
-
/* The URL for the directory that has this externals property. */
const char *parent_dir_url;
@@ -80,41 +76,37 @@ struct handle_external_item_change_baton
};
-/* Remove the directory at PATH from revision control, and do the same
- * to any revision controlled directories underneath PATH (including
- * directories not referred to by parent svn administrative areas);
- * then if PATH is empty afterwards, remove it, else rename it to a
+struct relegate_dir_external_with_write_lock_baton {
+ const char *local_abspath;
+ svn_wc_context_t *wc_ctx;
+ svn_cancel_func_t cancel_func;
+ void *cancel_baton;
+};
+
+/* Note: All arguments are in the baton above.
+ *
+ * Remove the directory at LOCAL_ABSPATH from revision control, and do the
+ * same to any revision controlled directories underneath LOCAL_ABSPATH
+ * (including directories not referred to by parent svn administrative areas);
+ * then if LOCAL_ABSPATH is empty afterwards, remove it, else rename it to a
* unique name in the same parent directory.
*
* Pass CANCEL_FUNC, CANCEL_BATON to svn_wc_remove_from_revision_control.
*
- * Use POOL for all temporary allocation.
- *
- * Note: this function is not passed a svn_wc_adm_access_t. Instead,
- * it separately opens the object being deleted, so that if there is a
- * lock on that object, the object cannot be deleted.
+ * Use SCRATCH_POOL for all temporary allocation.
*/
static svn_error_t *
-relegate_dir_external(const char *path,
- svn_wc_context_t *wc_ctx,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
- apr_pool_t *pool)
+relegate_dir_external(void *baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
+ struct relegate_dir_external_with_write_lock_baton *b = baton;
svn_error_t *err = SVN_NO_ERROR;
- const char *local_abspath;
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
- SVN_ERR(svn_wc__acquire_write_lock(NULL, wc_ctx, local_abspath, NULL, pool));
- err = svn_wc_remove_from_revision_control2(wc_ctx, local_abspath,
+ err = svn_wc_remove_from_revision_control2(b->wc_ctx, b->local_abspath,
TRUE, FALSE,
- cancel_func, cancel_baton,
- pool);
-
- /* ### Ugly. Unlock only if not going to return an error. Revisit */
- if (!err || err->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD)
- SVN_ERR(svn_wc__release_write_lock(wc_ctx, local_abspath, pool));
-
+ b->cancel_func, b->cancel_baton,
+ scratch_pool);
if (err && (err->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD))
{
const char *parent_dir;
@@ -124,12 +116,13 @@ relegate_dir_external(const char *path,
svn_error_clear(err);
err = SVN_NO_ERROR;
- svn_dirent_split(path, &parent_dir, &dirname, pool);
+ svn_dirent_split(b->local_abspath, &parent_dir, &dirname, scratch_pool);
/* Reserve the new dir name. */
SVN_ERR(svn_io_open_uniquely_named(NULL, &new_path,
parent_dir, dirname, ".OLD",
- svn_io_file_del_none, pool, pool));
+ svn_io_file_del_none,
+ scratch_pool, scratch_pool));
/* Sigh... We must fall ever so slightly from grace.
@@ -150,10 +143,10 @@ relegate_dir_external(const char *path,
no big deal.
*/
/* Do our best, but no biggy if it fails. The rename will fail. */
- svn_error_clear(svn_io_remove_file2(new_path, TRUE, pool));
+ svn_error_clear(svn_io_remove_file2(new_path, TRUE, scratch_pool));
/* Rename. */
- SVN_ERR(svn_io_file_rename(path, new_path, pool));
+ SVN_ERR(svn_io_file_rename(b->local_abspath, new_path, scratch_pool));
}
return svn_error_return(err);
@@ -238,7 +231,7 @@ switch_dir_external(const char *path,
SVN_ERR(svn_client__switch_internal(NULL, path, url,
peg_revision, revision,
- NULL, svn_depth_infinity,
+ svn_depth_infinity,
TRUE, timestamp_sleep,
FALSE, FALSE, TRUE, ctx,
subpool));
@@ -258,12 +251,21 @@ switch_dir_external(const char *path,
svn_pool_destroy(subpool);
if (kind == svn_node_dir)
- /* Buh-bye, old and busted ... */
- SVN_ERR(relegate_dir_external(path,
- ctx->wc_ctx,
- ctx->cancel_func,
- ctx->cancel_baton,
- pool));
+ {
+ struct relegate_dir_external_with_write_lock_baton baton;
+
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
+
+ baton.local_abspath = local_abspath;
+ baton.wc_ctx = ctx->wc_ctx;
+ baton.cancel_func = ctx->cancel_func;
+ baton.cancel_baton = ctx->cancel_baton;
+
+ /* Buh-bye, old and busted ... */
+ SVN_ERR(svn_wc__call_with_write_lock(relegate_dir_external, &baton,
+ ctx->wc_ctx, local_abspath,
+ pool, pool));
+ }
else
{
/* The target dir might have multiple components. Guarantee
@@ -287,7 +289,6 @@ switch_file_external(const char *path,
const char *url,
const svn_opt_revision_t *peg_revision,
const svn_opt_revision_t *revision,
- svn_wc_adm_access_t *adm_access,
svn_ra_session_t *ra_session,
const char *ra_session_url,
svn_revnum_t ra_revnum,
@@ -297,7 +298,6 @@ switch_file_external(const char *path,
apr_pool_t *pool)
{
apr_pool_t *subpool = svn_pool_create(pool);
- svn_wc_adm_access_t *target_adm_access;
const char *anchor;
const char *anchor_abspath;
const char *local_abspath;
@@ -310,9 +310,14 @@ switch_file_external(const char *path,
svn_boolean_t unlink_file = FALSE;
svn_boolean_t revert_file = FALSE;
svn_boolean_t remove_from_revision_control = FALSE;
- svn_boolean_t close_adm_access = FALSE;
+ svn_boolean_t locked_here;
svn_error_t *err = NULL;
+ /* See if the user wants last-commit timestamps instead of current ones. */
+ SVN_ERR(svn_config_get_bool(cfg, &use_commit_times,
+ SVN_CONFIG_SECTION_MISCELLANY,
+ SVN_CONFIG_OPTION_USE_COMMIT_TIMES, FALSE));
+
/* There must be a working copy to place the file external into. */
SVN_ERR(svn_wc_get_actual_target2(&anchor, &target, ctx->wc_ctx, path,
subpool, subpool));
@@ -323,52 +328,42 @@ switch_file_external(const char *path,
baton. If this fails and returns SVN_ERR_WC_NOT_LOCKED, then try
to get a new access baton to support inserting a file external
into a directory external. */
- err = svn_wc_adm_retrieve(&target_adm_access, adm_access, anchor, subpool);
- if (err)
- {
- if (err->apr_err == SVN_ERR_WC_NOT_LOCKED)
- {
- const char *dest_wc_repos_root_url;
- svn_opt_revision_t peg_rev;
+ SVN_ERR(svn_wc_locked2(&locked_here, NULL, ctx->wc_ctx, anchor_abspath,
+ subpool));
+ if (!locked_here)
+ {
+ const char *dest_wc_repos_root_url;
+ svn_opt_revision_t peg_rev;
+
+ /* Check that the repository root URL for the newly opened
+ wc is the same as the file external. */
+ peg_rev.kind = svn_opt_revision_base;
+ SVN_ERR(svn_client__get_repos_root(&dest_wc_repos_root_url,
+ anchor_abspath, &peg_rev,
+ ctx, subpool, subpool));
- svn_error_clear(err);
- close_adm_access = TRUE;
- SVN_ERR(svn_wc__adm_open_in_context(&target_adm_access, ctx->wc_ctx,
- anchor, TRUE, -1,
- ctx->cancel_func,
- ctx->cancel_baton, subpool));
-
- /* Check that the repository root URL for the newly opened
- wc is the same as the file external. */
- peg_rev.kind = svn_opt_revision_base;
- SVN_ERR(svn_client__get_repos_root(&dest_wc_repos_root_url,
- anchor_abspath, &peg_rev,
- ctx, subpool, subpool));
-
- if (0 != strcmp(repos_root_url, dest_wc_repos_root_url))
- return svn_error_createf
- (SVN_ERR_RA_REPOS_ROOT_URL_MISMATCH, NULL,
- _("Cannot insert a file external from '%s' into a working "
- "copy from a different repository rooted at '%s'"),
- url, dest_wc_repos_root_url);
- }
- else
- return svn_error_return(err);
+ if (0 != strcmp(repos_root_url, dest_wc_repos_root_url))
+ return svn_error_createf
+ (SVN_ERR_RA_REPOS_ROOT_URL_MISMATCH, NULL,
+ _("Cannot insert a file external from '%s' into a working "
+ "copy from a different repository rooted at '%s'"),
+ url, dest_wc_repos_root_url);
+
+ SVN_ERR(svn_wc__acquire_write_lock(NULL, ctx->wc_ctx, anchor_abspath,
+ subpool, subpool));
}
- SVN_ERR(svn_wc__maybe_get_entry(&entry, ctx->wc_ctx, local_abspath,
- svn_node_unknown, FALSE, FALSE, subpool,
- subpool));
+ err = svn_wc__maybe_get_entry(&entry, ctx->wc_ctx, local_abspath,
+ svn_node_unknown, FALSE, FALSE, subpool,
+ subpool);
+ if (err)
+ goto cleanup;
+
/* Only one notification is done for the external, so don't notify
for any following steps. Use the following trick to add the file
then switch it to the external URL. */
- /* See if the user wants last-commit timestamps instead of current ones. */
- SVN_ERR(svn_config_get_bool(cfg, &use_commit_times,
- SVN_CONFIG_SECTION_MISCELLANY,
- SVN_CONFIG_OPTION_USE_COMMIT_TIMES, FALSE));
-
/* If there is a versioned item with this name, ensure it's a file
external before working with it. If there is no entry in the
working copy, then create an empty file and add it to the working
@@ -377,8 +372,9 @@ switch_file_external(const char *path,
{
if (! entry->file_external_path)
{
- if (close_adm_access)
- SVN_ERR(svn_wc_adm_close2(target_adm_access, subpool));
+ if (!locked_here)
+ SVN_ERR(svn_wc__release_write_lock(ctx->wc_ctx, anchor_abspath,
+ subpool));
return svn_error_createf
(SVN_ERR_CLIENT_FILE_EXTERNAL_OVERWRITE_VERSIONED, 0,
@@ -399,9 +395,12 @@ switch_file_external(const char *path,
conflict on the directory. To prevent resolving a conflict
due to another change on the directory, do not allow a file
external to be added when one exists. */
- SVN_ERR(svn_wc_conflicted_p3(&text_conflicted, &prop_conflicted,
- &tree_conflicted, ctx->wc_ctx,
- anchor_abspath, subpool));
+ err = svn_wc_conflicted_p3(&text_conflicted, &prop_conflicted,
+ &tree_conflicted, ctx->wc_ctx,
+ anchor_abspath, subpool);
+ if (err)
+ goto cleanup;
+
if (text_conflicted || prop_conflicted || tree_conflicted)
return svn_error_createf
(SVN_ERR_WC_FOUND_CONFLICT, 0,
@@ -411,11 +410,14 @@ switch_file_external(const char *path,
/* Try to create an empty file. If there is a file already
there, then don't touch it. */
- SVN_ERR(svn_io_file_open(&f,
- local_abspath,
- APR_WRITE | APR_CREATE | APR_EXCL,
- APR_OS_DEFAULT,
- subpool));
+ err = svn_io_file_open(&f,
+ local_abspath,
+ APR_WRITE | APR_CREATE | APR_EXCL,
+ APR_OS_DEFAULT,
+ subpool);
+ if (err)
+ goto cleanup;
+
unlink_file = TRUE;
err = svn_io_file_close(f, pool);
if (err)
@@ -440,7 +442,7 @@ switch_file_external(const char *path,
}
err = svn_client__switch_internal(NULL, path, url, peg_revision, revision,
- target_adm_access, svn_depth_empty,
+ svn_depth_empty,
FALSE, /* depth_is_sticky */
timestamp_sleep,
TRUE, /* ignore_externals */
@@ -462,8 +464,8 @@ switch_file_external(const char *path,
remove_from_revision_control = TRUE;
}
- if (close_adm_access)
- SVN_ERR(svn_wc_adm_close2(target_adm_access, subpool));
+ if (!locked_here)
+ SVN_ERR(svn_wc__release_write_lock(ctx->wc_ctx, anchor_abspath, subpool));
svn_pool_destroy(subpool);
return SVN_NO_ERROR;
@@ -495,8 +497,9 @@ switch_file_external(const char *path,
if (unlink_file)
svn_error_clear(svn_io_remove_file2(path, TRUE, subpool));
- if (close_adm_access)
- SVN_ERR(svn_wc_adm_close2(target_adm_access, subpool));
+ if (!locked_here)
+ svn_error_clear(svn_wc__release_write_lock(ctx->wc_ctx, anchor_abspath,
+ subpool));
svn_pool_destroy(subpool);
return svn_error_return(err);
@@ -871,7 +874,6 @@ handle_external_item_change(const void *
new_item->url,
&new_item->peg_revision,
&new_item->revision,
- ib->adm_access,
ra_session,
ra_cache.ra_session_url,
ra_cache.ra_revnum,
@@ -895,7 +897,7 @@ handle_external_item_change(const void *
svn_error_t *err;
const char *remove_target_abspath;
- svn_boolean_t lock_existed;
+ svn_boolean_t lock_existed;
SVN_ERR(svn_dirent_get_absolute(&remove_target_abspath,
path,
@@ -907,7 +909,7 @@ handle_external_item_change(const void *
if (! lock_existed)
{
SVN_ERR(svn_wc__acquire_write_lock(NULL, ib->ctx->wc_ctx,
- remove_target_abspath,
+ remove_target_abspath,
ib->iter_pool,
ib->iter_pool));
}
@@ -939,7 +941,7 @@ handle_external_item_change(const void *
if (! lock_existed
&& (! err || err->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD))
{
- svn_error_t *err2 = svn_wc__release_write_lock(ib->ctx->wc_ctx,
+ svn_error_t *err2 = svn_wc__release_write_lock(ib->ctx->wc_ctx,
remove_target_abspath,
ib->iter_pool);
if (err2)
@@ -988,7 +990,6 @@ handle_external_item_change(const void *
new_item->url,
&new_item->peg_revision,
&new_item->revision,
- ib->adm_access,
ra_session,
ra_cache.ra_session_url,
ra_cache.ra_revnum,
@@ -1061,7 +1062,6 @@ struct handle_externals_desc_change_bato
const char *to_path;
/* Passed through to handle_external_item_change_baton. */
- svn_wc_adm_access_t *adm_access;
svn_client_ctx_t *ctx;
const char *repos_root_url;
svn_boolean_t *timestamp_sleep;
@@ -1089,11 +1089,9 @@ handle_externals_desc_change(const void
svn_wc_external_item2_t *item;
const char *ambient_depth_w;
svn_depth_t ambient_depth;
-
- if (cb->is_export)
- SVN_ERR_ASSERT(!cb->adm_access);
- else
- SVN_ERR_ASSERT(cb->adm_access);
+ const char *url;
+ const char *abs_parent_dir;
+ svn_error_t *err;
if (cb->ambient_depths)
{
@@ -1159,25 +1157,44 @@ handle_externals_desc_change(const void
ib.new_desc = new_desc_hash;
ib.parent_dir = (const char *) key;
ib.repos_root_url = cb->repos_root_url;
- ib.adm_access = cb->adm_access;
ib.ctx = cb->ctx;
ib.is_export = cb->is_export;
ib.timestamp_sleep = cb->timestamp_sleep;
ib.pool = cb->pool;
ib.iter_pool = svn_pool_create(cb->pool);
- /* Get the URL of the parent directory by appending a portion of
- parent_dir to from_url. from_url is the URL for to_path and
- to_path is a substring of parent_dir, so append any characters in
- parent_dir past strlen(to_path) to from_url (making sure to move
- past a '/' in parent_dir, otherwise svn_path_url_add_component()
- will error. */
- len = strlen(cb->to_path);
- if (ib.parent_dir[len] == '/')
- ++len;
- ib.parent_dir_url = svn_path_url_add_component2(cb->from_url,
- ib.parent_dir + len,
- cb->pool);
+ SVN_ERR(svn_dirent_get_absolute(&abs_parent_dir, ib.parent_dir,
+ cb->pool));
+
+ err = svn_wc__node_get_url(&url, cb->ctx->wc_ctx,
+ abs_parent_dir, cb->pool, cb->pool);
+
+ /* If we're doing an 'svn export' the current dir will not be a
+ working copy. We can't get the parent_dir. */
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY ||
+ err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ {
+ /* Get the URL of the parent directory by appending a portion of
+ parent_dir to from_url. from_url is the URL for to_path and
+ to_path is a substring of parent_dir, so append any characters in
+ parent_dir past strlen(to_path) to from_url (making sure to move
+ past a '/' in parent_dir, otherwise svn_path_url_add_component()
+ will error. */
+ len = strlen(cb->to_path);
+ if (ib.parent_dir[len] == '/')
+ ++len;
+ ib.parent_dir_url = svn_path_url_add_component2(cb->from_url,
+ ib.parent_dir + len,
+ cb->pool);
+ svn_error_clear(err);
+ }
+ else
+ return svn_error_return(err);
+ }
+ else
+ ib.parent_dir_url = url;
/* We must use a custom version of svn_hash_diff so that the diff
entries are processed in the order they were originally specified
@@ -1217,8 +1234,7 @@ handle_externals_desc_change(const void
svn_error_t *
-svn_client__handle_externals(svn_wc_adm_access_t *adm_access,
- apr_hash_t *externals_old,
+svn_client__handle_externals(apr_hash_t *externals_old,
apr_hash_t *externals_new,
apr_hash_t *ambient_depths,
const char *from_url,
@@ -1243,7 +1259,6 @@ svn_client__handle_externals(svn_wc_adm_
cb.from_url = from_url;
cb.to_path = to_path;
cb.repos_root_url = repos_root_url;
- cb.adm_access = adm_access;
cb.ctx = ctx;
cb.timestamp_sleep = timestamp_sleep;
cb.is_export = FALSE;
@@ -1271,7 +1286,6 @@ svn_client__fetch_externals(apr_hash_t *
cb.externals_old = apr_hash_make(pool);
cb.requested_depth = requested_depth;
cb.ambient_depths = NULL;
- cb.adm_access = NULL;
cb.ctx = ctx;
cb.from_url = from_url;
cb.to_path = to_path;
@@ -1308,8 +1322,8 @@ svn_client__do_external_status(apr_hash_
hi = apr_hash_next(hi))
{
apr_array_header_t *exts;
- const char *path = svn_apr_hash_index_key(hi);
- const char *propval = svn_apr_hash_index_val(hi);
+ const char *path = svn__apr_hash_index_key(hi);
+ const char *propval = svn__apr_hash_index_val(hi);
apr_pool_t *iterpool;
int i;
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/info.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/info.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/info.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/info.c Tue Aug 10 18:06:17 2010
@@ -219,8 +219,8 @@ push_dir_info(svn_ra_session_t *ra_sessi
{
const char *path, *URL, *fs_path;
svn_lock_t *lock;
- const char *name = svn_apr_hash_index_key(hi);
- svn_dirent_t *the_ent = svn_apr_hash_index_val(hi);
+ const char *name = svn__apr_hash_index_key(hi);
+ svn_dirent_t *the_ent = svn__apr_hash_index_val(hi);
svn_pool_clear(subpool);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/locking_commands.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/locking_commands.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/locking_commands.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/locking_commands.c Tue Aug 10 18:06:17 2010
@@ -362,7 +362,7 @@ fetch_tokens(svn_ra_session_t *ra_sessio
for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi))
{
- const char *path = svn_apr_hash_index_key(hi);
+ const char *path = svn__apr_hash_index_key(hi);
svn_lock_t *lock;
svn_pool_clear(iterpool);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/log.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/log.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/log.c Tue Aug 10 18:06:17 2010
@@ -322,6 +322,7 @@ svn_client_log5(const apr_array_header_t
pre_15_receiver_baton_t rb = {0};
apr_pool_t *iterpool;
int i;
+ svn_opt_revision_t peg_rev;
if (revision_ranges->nelts == 0)
{
@@ -330,6 +331,11 @@ svn_client_log5(const apr_array_header_t
_("Missing required revision specification"));
}
+ /* Make a copy of PEG_REVISION, we may need to change it to a
+ default value. */
+ peg_rev.kind = peg_revision->kind;
+ peg_rev.value = peg_revision->value;
+
/* Use the passed URL, if there is one. */
url_or_path = APR_ARRAY_IDX(targets, 0, const char *);
session_opt_rev.kind = svn_opt_revision_unspecified;
@@ -358,7 +364,7 @@ svn_client_log5(const apr_array_header_t
/* Default to any specified peg revision. Otherwise, if the
* first target is an URL, then we default to HEAD:0. Lastly,
* the default is BASE:0 since WC@HEAD may not exist. */
- if (peg_revision->kind == svn_opt_revision_unspecified)
+ if (peg_rev.kind == svn_opt_revision_unspecified)
{
if (svn_path_is_url(url_or_path))
range->start.kind = svn_opt_revision_head;
@@ -366,7 +372,7 @@ svn_client_log5(const apr_array_header_t
range->start.kind = svn_opt_revision_base;
}
else
- range->start = *peg_revision;
+ range->start = peg_rev;
if (range->end.kind == svn_opt_revision_unspecified)
{
@@ -439,6 +445,11 @@ svn_client_log5(const apr_array_header_t
_("When specifying working copy paths, only "
"one target may be given"));
+ /* An unspecified PEG_REVISION for a working copy path defautls
+ to svn_opt_revision_working. */
+ if (peg_rev.kind == svn_opt_revision_unspecified)
+ peg_rev.kind = svn_opt_revision_working;
+
/* Get URLs for each target */
target_urls = apr_array_make(pool, 1, sizeof(const char *));
real_targets = apr_array_make(pool, 1, sizeof(const char *));
@@ -486,14 +497,14 @@ svn_client_log5(const apr_array_header_t
/* If this is a revision type that requires access to the working copy,
* we use our initial target path to figure out where to root the RA
* session, otherwise we use our URL. */
- if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_revision->kind))
+ if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_rev.kind))
SVN_ERR(svn_path_condense_targets(&ra_target, NULL, targets, TRUE, pool));
else
ra_target = url_or_path;
SVN_ERR(svn_client__ra_session_from_path(&ra_session, &ignored_revnum,
&actual_url, ra_target, NULL,
- peg_revision, &session_opt_rev,
+ &peg_rev, &session_opt_rev,
ctx, pool));
SVN_ERR(svn_ra_has_capability(ra_session, &has_log_revprops,