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 2015/03/04 14:43:12 UTC
svn commit: r1663991 - /subversion/trunk/subversion/libsvn_wc/wc_db.c
Author: rhuijben
Date: Wed Mar 4 13:43:11 2015
New Revision: 1663991
URL: http://svn.apache.org/r1663991
Log:
Properly calculate the after-commit repository path of adds/replacements.
When a switched node is replaced (or a not present node has a different
repository path), the node was recorded as committed at a different
url then where it was actually committed.
A regression test (involving file externals) will be added shortly.
* subversion/libsvn_wc/wc_db.c
(determine_repos_info): Rename to...
(determine_commit_repos_info): ... this, to make it clear that it
follows commit rules. Properly follow the shadowing rules for
calculating the commit paths.
(commit_node): Update caller.
Modified:
subversion/trunk/subversion/libsvn_wc/wc_db.c
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1663991&r1=1663990&r2=1663991&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Mar 4 13:43:11 2015
@@ -11357,59 +11357,86 @@ svn_wc__db_global_relocate(svn_wc__db_t
}
-/* Set *REPOS_ID and *REPOS_RELPATH to the BASE repository location of
+/* Helper for commit_node()
+ Set *REPOS_ID and *REPOS_RELPATH to the BASE repository location of
(WCROOT, LOCAL_RELPATH), directly if its BASE row exists or implied from
its parent's BASE row if not. In the latter case, error if the parent
BASE row does not exist. */
static svn_error_t *
-determine_repos_info(apr_int64_t *repos_id,
- const char **repos_relpath,
- svn_wc__db_wcroot_t *wcroot,
- const char *local_relpath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+determine_commit_repos_info(apr_int64_t *repos_id,
+ const char **repos_relpath,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
- const char *repos_parent_relpath;
- const char *local_parent_relpath, *name;
-
- /* ### is it faster to fetch fewer columns? */
+ int op_depth;
/* Prefer the current node's repository information. */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_BASE_NODE));
+ STMT_SELECT_NODE_INFO));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
- if (have_row)
- {
- SVN_ERR_ASSERT(!svn_sqlite__column_is_null(stmt, 0));
- SVN_ERR_ASSERT(!svn_sqlite__column_is_null(stmt, 1));
+ if (!have_row)
+ return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND,
+ svn_sqlite__reset(stmt),
+ _("The node '%s' was not found."),
+ path_for_error_message(wcroot, local_relpath,
+ scratch_pool));
+
+ op_depth = svn_sqlite__column_int(stmt, 0);
- *repos_id = svn_sqlite__column_int64(stmt, 0);
- *repos_relpath = svn_sqlite__column_text(stmt, 1, result_pool);
+ if (op_depth > 0)
+ {
+ svn_wc__db_status_t presence = svn_sqlite__column_token(stmt, 3,
+ presence_map);
- return svn_error_trace(svn_sqlite__reset(stmt));
+ if (presence == svn_wc__db_status_base_deleted)
+ {
+ SVN_ERR(svn_sqlite__step_row(stmt)); /* There must be a row */
+ op_depth = svn_sqlite__column_int(stmt, 0);
+ }
+ else
+ {
+ const char *parent_repos_relpath;
+ const char *parent_relpath;
+ const char *name;
+
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ /* The repository relative path of an add/copy is based on its
+ ancestor, not on the shadowed base layer.
+
+ As this function is only used from the commit processing we know
+ the parent directory has only a BASE row, so we can just obtain
+ the information directly by recursing (once!) */
+
+ svn_relpath_split(&parent_relpath, &name, local_relpath,
+ scratch_pool);
+
+ SVN_ERR(determine_commit_repos_info(repos_id, &parent_repos_relpath,
+ wcroot, parent_relpath,
+ scratch_pool, scratch_pool));
+
+ *repos_relpath = svn_relpath_join(parent_repos_relpath, name,
+ result_pool);
+ return SVN_NO_ERROR;
+ }
}
- SVN_ERR(svn_sqlite__reset(stmt));
- /* This was a child node within this wcroot. We want to look at the
- BASE node of the directory. */
- svn_relpath_split(&local_parent_relpath, &name, local_relpath, scratch_pool);
-
- /* The REPOS_ID will be the same (### until we support mixed-repos) */
- SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL,
- &repos_parent_relpath, repos_id,
- NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- wcroot, local_parent_relpath,
- scratch_pool, scratch_pool));
+ SVN_ERR_ASSERT(op_depth == 0); /* And that row must be BASE */
- *repos_relpath = svn_relpath_join(repos_parent_relpath, name, result_pool);
+ SVN_ERR_ASSERT(!svn_sqlite__column_is_null(stmt, 1));
+ SVN_ERR_ASSERT(!svn_sqlite__column_is_null(stmt, 2));
- return SVN_NO_ERROR;
+ *repos_id = svn_sqlite__column_int64(stmt, 1);
+ *repos_relpath = svn_sqlite__column_text(stmt, 2, result_pool);
+
+ return svn_error_trace(svn_sqlite__reset(stmt));
}
static svn_error_t *
@@ -11616,9 +11643,9 @@ commit_node(svn_wc__db_wcroot_t *wcroot,
For existing nodes, we should retain the (potentially-switched)
repository information. */
- SVN_ERR(determine_repos_info(&repos_id, &repos_relpath,
- wcroot, local_relpath,
- scratch_pool, scratch_pool));
+ SVN_ERR(determine_commit_repos_info(&repos_id, &repos_relpath,
+ wcroot, local_relpath,
+ scratch_pool, scratch_pool));
/* ### is it better to select only the data needed? */
SVN_ERR(svn_sqlite__get_statement(&stmt_info, wcroot->sdb,