You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2011/04/14 13:49:44 UTC
svn commit: r1092145 - in /subversion/trunk/subversion:
include/private/svn_wc_private.h libsvn_client/commit_util.c
libsvn_client/copy.c libsvn_client/merge.c libsvn_client/mergeinfo.c
libsvn_wc/node.c
Author: rhuijben
Date: Thu Apr 14 11:49:43 2011
New Revision: 1092145
URL: http://svn.apache.org/viewvc?rev=1092145&view=rev
Log:
Reduce the number of DB operations to retrieve a URL from libsvn_client,
by introducing a svn_wc__node_get_origin() function.
In several places we retrieved the url in more than one way to determine
which one to use, while generally wc_db can simply answer the question:
"Where did this node come from?"
* subversion/include/private/svn_wc_private.h
(svn_wc__node_get_origin): New function.
* subversion/libsvn_client/commit_util.c
(harvest_committables): Use svn_wc__node_get_origin() for simplification.
* subversion/libsvn_client/copy.c
(calculate_target_mergeinfo): Use Use svn_wc__node_get_origin() for
simplification.
* subversion/libsvn_client/merge.c
(get_full_mergeinfo): Get the origin instead of relying on a specific error.
* subversion/libsvn_client/mergeinfo.c
(svn_client__get_wc_or_repos_mergeinfo_catalog):
Use svn_wc__node_get_origin() instead of 3 (or more) db calls.
* subversion/libsvn_client/url.c
(svn_client__entry_location): Use svn_wc__node_get_origin() for all
common cases.
* subversion/libsvn_wc/node.c
(svn_wc__node_get_origin): New function.
Modified:
subversion/trunk/subversion/include/private/svn_wc_private.h
subversion/trunk/subversion/libsvn_client/commit_util.c
subversion/trunk/subversion/libsvn_client/copy.c
subversion/trunk/subversion/libsvn_client/merge.c
subversion/trunk/subversion/libsvn_client/mergeinfo.c
subversion/trunk/subversion/libsvn_wc/node.c
Modified: subversion/trunk/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_wc_private.h?rev=1092145&r1=1092144&r2=1092145&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_wc_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_wc_private.h Thu Apr 14 11:49:43 2011
@@ -321,6 +321,38 @@ svn_wc__node_get_url(const char **url,
apr_pool_t *scratch_pool);
/**
+ * Retrieves the origin of the node as it is known in the repository. For
+ * added nodes this retrieves where the node is copied from, and the repository
+ * location for other nodes.
+ *
+ * All output arguments may be NULL.
+ *
+ * If @a is_copy is not NULL, sets @a *is_copy to TRUE if the origin is a copy
+ * of the original node.
+ *
+ * If not NULL, sets @a revision, @a repos_relpath, @a repos_root_url and
+ * @a repos_uuid to the original (if a copy) or their current values.
+ *
+ * If @a scan_deleted is TRUE, determine the origin of the deleted node. If
+ * @a scan_deleted is FALSE, return NULL, SVN_INVALID_REVNUM or FALSE for
+ * deleted nodes.
+ *
+ * Allocate the result in @a result_pool. Perform temporary allocations in
+ * @a scratch_pool */
+svn_error_t *
+svn_wc__node_get_origin(svn_boolean_t *is_copy,
+ svn_revnum_t *revision,
+ const char **repos_relpath,
+ const char **repos_root_url,
+ const char **repos_uuid,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ svn_boolean_t scan_deleted,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+
+/**
* Set @a *repos_relpath to the corresponding repos_relpath for @a
* local_abspath, using @a wc_ctx. If the node is added, return the
* repos_relpath it will have in the repository.
Modified: subversion/trunk/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/commit_util.c?rev=1092145&r1=1092144&r2=1092145&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/commit_util.c (original)
+++ subversion/trunk/subversion/libsvn_client/commit_util.c Thu Apr 14 11:49:43 2011
@@ -504,26 +504,11 @@ harvest_committables(svn_wc_context_t *w
}
/* Further additions occur in copy mode. */
- if (copy_mode && !(state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
+ if (copy_mode
+ && (!is_added || copy_mode_root)
+ && !(state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
{
svn_revnum_t dir_rev;
- const char *node_copyfrom_relpath;
- svn_revnum_t node_copyfrom_rev;
-
- if (is_added)
- {
- SVN_ERR(svn_wc__node_get_copyfrom_info(NULL,
- &node_copyfrom_relpath,
- NULL, &node_copyfrom_rev,
- NULL,
- wc_ctx, local_abspath,
- scratch_pool, scratch_pool));
- }
- else
- {
- node_copyfrom_relpath = NULL;
- node_copyfrom_rev = SVN_INVALID_REVNUM;
- }
if (!copy_mode_root)
SVN_ERR(svn_wc__node_get_base_rev(&dir_rev, wc_ctx,
@@ -534,18 +519,15 @@ harvest_committables(svn_wc_context_t *w
if (copy_mode_root || node_rev != dir_rev)
{
state_flags |= SVN_CLIENT_COMMIT_ITEM_ADD;
- if (node_copyfrom_relpath)
- {
- state_flags |= SVN_CLIENT_COMMIT_ITEM_IS_COPY;
- cf_relpath = node_copyfrom_relpath;
- cf_rev = node_copyfrom_rev;
- }
- else if (node_rev != SVN_INVALID_REVNUM)
- {
- state_flags |= SVN_CLIENT_COMMIT_ITEM_IS_COPY;
- cf_relpath = node_relpath;
- cf_rev = node_rev;
- }
+
+ SVN_ERR(svn_wc__node_get_origin(NULL, &cf_rev,
+ &cf_relpath, NULL,
+ NULL,
+ wc_ctx, local_abspath, FALSE,
+ scratch_pool, scratch_pool));
+
+ if (cf_relpath)
+ state_flags |= SVN_CLIENT_COMMIT_ITEM_IS_COPY;
}
}
Modified: subversion/trunk/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/copy.c?rev=1092145&r1=1092144&r2=1092145&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/copy.c (original)
+++ subversion/trunk/subversion/libsvn_client/copy.c Thu Apr 14 11:49:43 2011
@@ -91,29 +91,24 @@ calculate_target_mergeinfo(svn_ra_sessio
bother checking. */
if (local_abspath)
{
- svn_boolean_t is_added;
- const char *is_copied;
+ const char *repos_root_url;
+ const char *repos_relpath;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- SVN_ERR(svn_wc__node_is_added(&is_added, ctx->wc_ctx,
- local_abspath, pool));
- if (is_added)
- SVN_ERR(svn_wc__node_get_copyfrom_info(&is_copied, NULL, NULL,
- NULL, NULL, ctx->wc_ctx,
- local_abspath, pool, pool));
+ SVN_ERR(svn_wc__node_get_origin(NULL, &src_revnum,
+ &repos_relpath, &repos_root_url,
+ NULL,
+ ctx->wc_ctx, local_abspath, FALSE,
+ pool, pool));
- if (is_added && ! is_copied)
+ if (repos_relpath)
{
- locally_added = TRUE;
+ src_url = svn_path_url_add_component2(repos_root_url, repos_relpath,
+ pool);
}
else
- {
- SVN_ERR(svn_client__entry_location(&src_url, &src_revnum,
- ctx->wc_ctx, local_abspath,
- svn_opt_revision_working,
- pool, pool));
- }
+ locally_added = TRUE;
}
if (! locally_added)
Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1092145&r1=1092144&r2=1092145&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Thu Apr 14 11:49:43 2011
@@ -3478,50 +3478,45 @@ get_full_mergeinfo(svn_mergeinfo_t *reco
if (implicit_mergeinfo)
{
- const char *session_url = NULL, *url;
+ const char *repos_root;
+ const char *repos_relpath;
+ const char *session_url = NULL;
svn_revnum_t target_rev;
- svn_error_t *err;
/* Assert that we have sane input. */
SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(start)
&& SVN_IS_VALID_REVNUM(end)
&& (start > end));
- *implicit_mergeinfo = NULL;
-
/* Retrieve the origin (original_*) of the node, or just the
url if the node was not copied. */
- err = svn_client__entry_location(&url, &target_rev,
- ctx->wc_ctx, target_abspath,
- svn_opt_revision_working,
- scratch_pool, scratch_pool);
-
- if (err)
+ SVN_ERR(svn_wc__node_get_origin(FALSE, &target_rev, &repos_relpath,
+ &repos_root, NULL,
+ ctx->wc_ctx, target_abspath, FALSE,
+ scratch_pool, scratch_pool));
+
+ if (! repos_relpath)
{
- if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
- {
- /* We've been asked to operate on a target which has no location
- * in the repository. Either it's unversioned (but attempts to
- * merge into unversioned targets should not get as far as here),
- * or it is locally added, in which case the target's implicit
- * mergeinfo is empty. */
- svn_error_clear(err);
- *implicit_mergeinfo = apr_hash_make(result_pool);
- }
- else
- return svn_error_return(err);
+ /* We've been asked to operate on a target which has no location
+ * in the repository. Either it's unversioned (but attempts to
+ * merge into unversioned targets should not get as far as here),
+ * or it is locally added, in which case the target's implicit
+ * mergeinfo is empty. */
+ *implicit_mergeinfo = apr_hash_make(result_pool);
}
-
- if (target_rev <= end)
+ else if (target_rev <= end)
{
/* We're asking about a range outside our natural history
altogether. That means our implicit mergeinfo is empty. */
*implicit_mergeinfo = apr_hash_make(result_pool);
}
-
- if (*implicit_mergeinfo == NULL)
+ else
{
svn_opt_revision_t peg_revision;
+ const char *url;
+
+ url = svn_path_url_add_component2(repos_root, repos_relpath,
+ scratch_pool);
/* Temporarily point our RA_SESSION at our target URL so we can
fetch so-called "implicit mergeinfo" (that is, natural
Modified: subversion/trunk/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/mergeinfo.c?rev=1092145&r1=1092144&r2=1092145&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/trunk/subversion/libsvn_client/mergeinfo.c Thu Apr 14 11:49:43 2011
@@ -533,23 +533,24 @@ svn_client__get_wc_or_repos_mergeinfo_ca
svn_revnum_t target_rev;
const char *local_abspath;
const char *repos_root;
- svn_boolean_t is_added;
+ const char *repos_relpath;
SVN_ERR(svn_dirent_get_absolute(&local_abspath, target_wcpath,
scratch_pool));
- SVN_ERR(svn_wc__node_is_added(&is_added, ctx->wc_ctx, local_abspath,
- scratch_pool));
- SVN_ERR(svn_wc__node_get_repos_info(&repos_root, NULL,
- ctx->wc_ctx, local_abspath, FALSE, FALSE,
- scratch_pool, scratch_pool));
/* We may get an entry with abbreviated information from TARGET_WCPATH's
parent if TARGET_WCPATH is missing. These limited entries do not have
a URL and without that we cannot get accurate mergeinfo for
TARGET_WCPATH. */
- SVN_ERR(svn_client__entry_location(&url, &target_rev, ctx->wc_ctx,
- local_abspath, svn_opt_revision_working,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__node_get_origin(NULL, &target_rev, &repos_relpath,
+ &repos_root, NULL,
+ ctx->wc_ctx, local_abspath, FALSE,
+ scratch_pool, scratch_pool));
+
+ if (repos_relpath)
+ url = svn_path_url_add_component2(repos_root, repos_relpath, scratch_pool);
+ else
+ url = NULL;
if (repos_only)
*target_mergeinfo_catalog = NULL;
@@ -568,7 +569,7 @@ svn_client__get_wc_or_repos_mergeinfo_ca
if (*target_mergeinfo_catalog == NULL)
{
/* No need to check the repos if this is a local addition. */
- if (!is_added)
+ if (url != NULL)
{
apr_hash_t *original_props;
Modified: subversion/trunk/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/node.c?rev=1092145&r1=1092144&r2=1092145&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/node.c (original)
+++ subversion/trunk/subversion/libsvn_wc/node.c Thu Apr 14 11:49:43 2011
@@ -1535,6 +1535,114 @@ svn_wc__get_absent_subtrees(apr_hash_t *
}
svn_error_t *
+svn_wc__node_get_origin(svn_boolean_t *is_copy,
+ svn_revnum_t *revision,
+ const char **repos_relpath,
+ const char **repos_root_url,
+ const char **repos_uuid,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ svn_boolean_t scan_deleted,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *original_repos_relpath;
+ const char *original_repos_root_url;
+ const char *original_repos_uuid;
+ svn_revnum_t original_revision;
+ svn_wc__db_status_t status;
+
+ const char *tmp_repos_relpath;
+
+ if (!repos_relpath)
+ repos_relpath = &tmp_repos_relpath;
+
+ SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, repos_relpath,
+ repos_root_url, repos_uuid, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ &original_repos_relpath,
+ &original_repos_root_url,
+ &original_repos_uuid, &original_revision,
+ NULL, NULL, is_copy, NULL, NULL,
+ wc_ctx->db, local_abspath,
+ result_pool, scratch_pool));
+
+ if (*repos_relpath)
+ {
+ return SVN_NO_ERROR; /* Returned BASE information */
+ }
+
+ if (status == svn_wc__db_status_deleted && !scan_deleted)
+ {
+ if (is_copy)
+ *is_copy = FALSE; /* Deletes are stored in working; default to FALSE */
+
+ return SVN_NO_ERROR; /* No info */
+ }
+
+ if (original_repos_relpath)
+ {
+ *repos_relpath = original_repos_relpath;
+ if (revision)
+ *revision = original_revision;
+ if (repos_root_url)
+ *repos_root_url = original_repos_root_url;
+ if (repos_uuid)
+ *repos_uuid = original_repos_uuid;
+
+ return SVN_NO_ERROR;
+ }
+
+ {
+ svn_boolean_t scan_working = FALSE;
+
+ if (status == svn_wc__db_status_added)
+ scan_working = TRUE;
+ else if (status == svn_wc__db_status_deleted)
+ /* Is this a BASE or a WORKING delete? */
+ SVN_ERR(svn_wc__db_info_below_working(NULL, &scan_working, NULL,
+ wc_ctx->db, local_abspath,
+ scratch_pool));
+
+ if (scan_working)
+ {
+ const char *op_root_abspath;
+
+ SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath, NULL,
+ NULL, NULL, &original_repos_relpath,
+ repos_root_url,
+ repos_uuid,
+ revision,
+ wc_ctx->db, local_abspath,
+ result_pool, scratch_pool));
+
+ if (status == svn_wc__db_status_added)
+ return SVN_NO_ERROR; /* Local addition */
+
+ *repos_relpath = svn_relpath_join(
+ original_repos_relpath,
+ svn_dirent_skip_ancestor(op_root_abspath,
+ local_abspath),
+ result_pool);
+ }
+ else /* Deleted, excluded, not-present, absent, ... */
+ {
+ if (is_copy)
+ *is_copy = FALSE;
+
+ SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, revision, repos_relpath,
+ repos_root_url, repos_uuid, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ wc_ctx->db, local_abspath,
+ result_pool, scratch_pool));
+ }
+
+ return SVN_NO_ERROR;
+ }
+}
+
+svn_error_t *
svn_wc__node_get_commit_status(svn_node_kind_t *kind,
svn_boolean_t *added,
svn_boolean_t *deleted,