summaryrefslogtreecommitdiff
path: root/subversion/libsvn_client
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2018-10-08 08:34:55 +0000
committerPeter Wemm <peter@FreeBSD.org>2018-10-08 08:34:55 +0000
commitf3520a04ffc9f2c22dc693226fd2a480a4192da1 (patch)
tree19339c70c87a08c32b01175500d4284f409925ee /subversion/libsvn_client
parent3faf8d6bffc5d0fb2525ba37bb504c53366caf9d (diff)
Notes
Diffstat (limited to 'subversion/libsvn_client')
-rw-r--r--subversion/libsvn_client/conflicts.c71
-rw-r--r--subversion/libsvn_client/update.c150
2 files changed, 142 insertions, 79 deletions
diff --git a/subversion/libsvn_client/conflicts.c b/subversion/libsvn_client/conflicts.c
index 0fd9a2bbec5e..f571f3c35324 100644
--- a/subversion/libsvn_client/conflicts.c
+++ b/subversion/libsvn_client/conflicts.c
@@ -2624,6 +2624,10 @@ conflict_tree_get_details_local_missing(svn_client_conflict_t *conflict,
svn_revnum_t related_peg_rev;
const char *repos_root_url;
const char *repos_uuid;
+ const char *url, *corrected_url;
+ svn_ra_session_t *ra_session;
+ svn_client__pathrev_t *yca_loc;
+ svn_revnum_t end_rev;
SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
&old_repos_relpath, &old_rev, NULL, conflict,
@@ -2660,51 +2664,62 @@ conflict_tree_get_details_local_missing(svn_client_conflict_t *conflict,
(old_rev < new_rev ? old_repos_relpath : new_repos_relpath),
(old_rev < new_rev ? old_rev : new_rev),
conflict, ctx, scratch_pool, scratch_pool));
-
+
+ /* Set END_REV to our best guess of the nearest YCA revision. */
+ url = svn_path_url_add_component2(repos_root_url, related_repos_relpath,
+ scratch_pool);
+ SVN_ERR(svn_client__open_ra_session_internal(&ra_session,
+ &corrected_url,
+ url, NULL, NULL,
+ FALSE,
+ FALSE,
+ ctx,
+ scratch_pool,
+ scratch_pool));
+ SVN_ERR(find_nearest_yca(&yca_loc, related_repos_relpath, related_peg_rev,
+ parent_repos_relpath, parent_peg_rev,
+ repos_root_url, repos_uuid, ra_session, ctx,
+ scratch_pool, scratch_pool));
+ if (yca_loc)
+ {
+ end_rev = yca_loc->rev;
+
+ /* END_REV must be smaller than PARENT_PEG_REV, else the call to
+ * find_revision_for_suspected_deletion() below will abort. */
+ if (end_rev >= parent_peg_rev)
+ end_rev = parent_peg_rev > 0 ? parent_peg_rev - 1 : 0;
+ }
+ else
+ end_rev = 0; /* ### We might walk through all of history... */
+
SVN_ERR(find_revision_for_suspected_deletion(
&deleted_rev, &deleted_rev_author, &replacing_node_kind, &moves,
conflict, deleted_basename, parent_repos_relpath,
- parent_peg_rev, 0, related_repos_relpath, related_peg_rev,
+ parent_peg_rev, end_rev, related_repos_relpath, related_peg_rev,
ctx, conflict->pool, scratch_pool));
/* If the victim was not deleted then check if the related path was moved. */
if (deleted_rev == SVN_INVALID_REVNUM)
{
const char *victim_abspath;
- svn_ra_session_t *ra_session;
- const char *url, *corrected_url;
- svn_client__pathrev_t *yca_loc;
- svn_revnum_t end_rev;
svn_node_kind_t related_node_kind;
/* ### The following describes all moves in terms of forward-merges,
* should do we something else for reverse-merges? */
victim_abspath = svn_client_conflict_get_local_abspath(conflict);
- url = svn_path_url_add_component2(repos_root_url, related_repos_relpath,
- scratch_pool);
- SVN_ERR(svn_client__open_ra_session_internal(&ra_session,
- &corrected_url,
- url, NULL, NULL,
- FALSE,
- FALSE,
- ctx,
- scratch_pool,
- scratch_pool));
- /* Set END_REV to our best guess of the nearest YCA revision. */
- SVN_ERR(find_nearest_yca(&yca_loc, related_repos_relpath, related_peg_rev,
- parent_repos_relpath, parent_peg_rev,
- repos_root_url, repos_uuid, ra_session, ctx,
- scratch_pool, scratch_pool));
- if (yca_loc == NULL)
- return SVN_NO_ERROR;
- end_rev = yca_loc->rev;
+ if (yca_loc)
+ {
+ end_rev = yca_loc->rev;
- /* END_REV must be smaller than RELATED_PEG_REV, else the call
- to find_moves_in_natural_history() below will error out. */
- if (end_rev >= related_peg_rev)
- end_rev = related_peg_rev > 0 ? related_peg_rev - 1 : 0;
+ /* END_REV must be smaller than RELATED_PEG_REV, else the call
+ to find_moves_in_natural_history() below will error out. */
+ if (end_rev >= related_peg_rev)
+ end_rev = related_peg_rev > 0 ? related_peg_rev - 1 : 0;
+ }
+ else
+ end_rev = 0; /* ### We might walk through all of history... */
SVN_ERR(svn_ra_check_path(ra_session, "", related_peg_rev,
&related_node_kind, scratch_pool));
diff --git a/subversion/libsvn_client/update.c b/subversion/libsvn_client/update.c
index 3895aa29d658..602f7e317b57 100644
--- a/subversion/libsvn_client/update.c
+++ b/subversion/libsvn_client/update.c
@@ -182,6 +182,88 @@ record_conflict(svn_wc_conflict_result_t **result,
return SVN_NO_ERROR;
}
+/* Perform post-update processing of externals defined below LOCAL_ABSPATH. */
+static svn_error_t *
+handle_externals(svn_boolean_t *timestamp_sleep,
+ const char *local_abspath,
+ svn_depth_t depth,
+ const char *repos_root_url,
+ svn_ra_session_t *ra_session,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_t *new_externals;
+ apr_hash_t *new_depths;
+
+ SVN_ERR(svn_wc__externals_gather_definitions(&new_externals,
+ &new_depths,
+ ctx->wc_ctx, local_abspath,
+ depth,
+ scratch_pool, scratch_pool));
+
+ SVN_ERR(svn_client__handle_externals(new_externals,
+ new_depths,
+ repos_root_url, local_abspath,
+ depth, timestamp_sleep, ra_session,
+ ctx, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+/* Try to reuse the RA session by reparenting it to the anchor_url.
+ * This code is probably overly cautious since we only use this
+ * currently when parents are missing and so all the anchor_urls
+ * have to be in the same repo.
+ * Note that ra_session_p is an (optional) input parameter as well
+ * as an output parameter. */
+static svn_error_t *
+reuse_ra_session(svn_ra_session_t **ra_session_p,
+ const char **corrected_url,
+ const char *anchor_url,
+ const char *anchor_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_ra_session_t *ra_session = *ra_session_p;
+
+ if (ra_session)
+ {
+ svn_error_t *err = svn_ra_reparent(ra_session, anchor_url, scratch_pool);
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_RA_ILLEGAL_URL)
+ {
+ /* session changed repos, can't reuse it */
+ svn_error_clear(err);
+ ra_session = NULL;
+ }
+ else
+ {
+ return svn_error_trace(err);
+ }
+ }
+ else
+ {
+ *corrected_url = NULL;
+ }
+ }
+
+ /* Open an RA session for the URL if one isn't already available */
+ if (!ra_session)
+ {
+ SVN_ERR(svn_client__open_ra_session_internal(&ra_session, corrected_url,
+ anchor_url,
+ anchor_abspath, NULL,
+ TRUE /* write_dav_props */,
+ TRUE /* read_dav_props */,
+ ctx,
+ result_pool, scratch_pool));
+ *ra_session_p = ra_session;
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* This is a helper for svn_client__update_internal(), which see for
an explanation of most of these parameters. Some stuff that's
unique is as follows:
@@ -320,6 +402,18 @@ update_internal(svn_revnum_t *result_rev,
ctx->notify_func2, ctx->notify_baton2,
scratch_pool));
+ if (!ignore_externals)
+ {
+ /* We may now be able to remove externals below LOCAL_ABSPATH. */
+ SVN_ERR(reuse_ra_session(ra_session_p, &corrected_url,
+ anchor_url, anchor_abspath,
+ ctx, result_pool, scratch_pool));
+ ra_session = *ra_session_p;
+ SVN_ERR(handle_externals(timestamp_sleep, local_abspath, depth,
+ repos_root_url, ra_session, ctx,
+ scratch_pool));
+ }
+
/* Target excluded, we are done now */
return SVN_NO_ERROR;
}
@@ -373,44 +467,9 @@ update_internal(svn_revnum_t *result_rev,
ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
}
- /* Try to reuse the RA session by reparenting it to the anchor_url.
- * This code is probably overly cautious since we only use this
- * currently when parents are missing and so all the anchor_urls
- * have to be in the same repo. */
- if (ra_session)
- {
- svn_error_t *err = svn_ra_reparent(ra_session, anchor_url, scratch_pool);
- if (err)
- {
- if (err->apr_err == SVN_ERR_RA_ILLEGAL_URL)
- {
- /* session changed repos, can't reuse it */
- svn_error_clear(err);
- ra_session = NULL;
- }
- else
- {
- return svn_error_trace(err);
- }
- }
- else
- {
- corrected_url = NULL;
- }
- }
-
- /* Open an RA session for the URL if one isn't already available */
- if (!ra_session)
- {
- SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
- anchor_url,
- anchor_abspath, NULL,
- TRUE /* write_dav_props */,
- TRUE /* read_dav_props */,
- ctx,
- result_pool, scratch_pool));
- *ra_session_p = ra_session;
- }
+ SVN_ERR(reuse_ra_session(ra_session_p, &corrected_url, anchor_url,
+ anchor_abspath, ctx, result_pool, scratch_pool));
+ ra_session = *ra_session_p;
/* If we got a corrected URL from the RA subsystem, we'll need to
relocate our working copy first. */
@@ -513,19 +572,8 @@ update_internal(svn_revnum_t *result_rev,
if ((SVN_DEPTH_IS_RECURSIVE(depth) || cropping_target)
&& (! ignore_externals))
{
- apr_hash_t *new_externals;
- apr_hash_t *new_depths;
- SVN_ERR(svn_wc__externals_gather_definitions(&new_externals,
- &new_depths,
- ctx->wc_ctx, local_abspath,
- depth,
- scratch_pool, scratch_pool));
-
- SVN_ERR(svn_client__handle_externals(new_externals,
- new_depths,
- repos_root_url, local_abspath,
- depth, timestamp_sleep, ra_session,
- ctx, scratch_pool));
+ SVN_ERR(handle_externals(timestamp_sleep, local_abspath, depth,
+ repos_root_url, ra_session, ctx, scratch_pool));
}
/* Let everyone know we're finished here (unless we're asked not to). */