You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2010/11/02 18:28:34 UTC
svn commit: r1030136 - in /subversion/trunk/subversion: include/svn_path.h
include/svn_wc.h libsvn_client/copy.c libsvn_wc/adm_ops.c
Author: julianfoad
Date: Tue Nov 2 17:28:21 2010
New Revision: 1030136
URL: http://svn.apache.org/viewvc?rev=1030136&view=rev
Log:
Split out from svn_wc_add4() the functionality for integrating a nested
checkout as a scheduled copy.
* subversion/include/svn_wc.h
(svn_wc__integrate_nested_wc_as_copy): New function.
* subversion/libsvn_wc/adm_ops.c
(integrate_nested_wc_as_copy): New function, extracted from ...
(svn_wc_add4): ... here.
(svn_wc__integrate_nested_wc_as_copy): New function.
* subversion/libsvn_client/copy.c
(repos_to_wc_copy_single): Use the new function instead of svn_wc_add4().
Modified:
subversion/trunk/subversion/include/svn_path.h
subversion/trunk/subversion/include/svn_wc.h
subversion/trunk/subversion/libsvn_client/copy.c
subversion/trunk/subversion/libsvn_wc/adm_ops.c
Modified: subversion/trunk/subversion/include/svn_path.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_path.h?rev=1030136&r1=1030135&r2=1030136&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_path.h (original)
+++ subversion/trunk/subversion/include/svn_path.h Tue Nov 2 17:28:21 2010
@@ -243,6 +243,7 @@ svn_path_split(const char *path,
* directory -- that is, if prepending it as a component to an existing
* path would result in no meaningful change.
*/
+/* J: For RELPATHs only. Doc should just not say "or ... that is ...". */
int
svn_path_is_empty(const char *path);
@@ -286,6 +287,7 @@ svn_path_is_canonical(const char *path,
/** Return an integer greater than, equal to, or less than 0, according
* as @a path1 is greater than, equal to, or less than @a path2.
*/
+/* J: Should be per path kind. */
int
svn_path_compare_paths(const char *path1, const char *path2);
@@ -416,6 +418,7 @@ svn_path_condense_targets(const char **p
* between saying "i'm in foo, update bar" and "i'm in foo/bar,
* update '.'"
*/
+/* J: Ought to be specific to OSPATHs or URLPATHs. */
svn_error_t *
svn_path_remove_redundancies(apr_array_header_t **pcondensed_targets,
const apr_array_header_t *targets,
@@ -427,6 +430,7 @@ svn_path_remove_redundancies(apr_array_h
* absolute, the first component will be a lone dir separator (the
* root directory).
*/
+/* J: Separate per path kind, or only for RELPATH. */
apr_array_header_t *
svn_path_decompose(const char *path, apr_pool_t *pool);
@@ -439,6 +443,7 @@ svn_path_decompose(const char *path, apr
*
* @since New in 1.5.
*/
+/* J: Per path kind, or only for RELPATH. */
const char *
svn_path_compose(const apr_array_header_t *components, apr_pool_t *pool);
@@ -458,6 +463,7 @@ svn_path_is_single_path_component(const
*
* @since New in 1.1.
*/
+/* J: Per path kind. */
svn_boolean_t
svn_path_is_backpath_present(const char *path);
@@ -524,6 +530,7 @@ svn_path_is_ancestor(const char *path1,
*
* @since New in 1.2.
*/
+/* J: Should it check a single component? Start with "/"? */
svn_error_t *
svn_path_check_valid(const char *path, apr_pool_t *pool);
@@ -535,6 +542,7 @@ svn_path_check_valid(const char *path, a
*/
/** Return TRUE iff @a path looks like a valid absolute URL. */
+/* J: OK as is. */
svn_boolean_t
svn_path_is_url(const char *path);
@@ -545,10 +553,12 @@ svn_path_is_uri_safe(const char *path);
/** Return a URI-encoded copy of @a path, allocated in @a pool. (@a
path can be an arbitrary UTF-8 string and does not have to be a
canonical path.) */
+/* J: Input must be valid URL/URI syntax, as it is parsed. */
const char *
svn_path_uri_encode(const char *path, apr_pool_t *pool);
/** Return a URI-decoded copy of @a path, allocated in @a pool. */
+/* J: OK as is. */
const char *
svn_path_uri_decode(const char *path, apr_pool_t *pool);
@@ -579,6 +589,7 @@ svn_path_uri_decode(const char *path, ap
*
* @since New in 1.6.
*/
+/* J: Replace "component" by "RELPATH". Another API can join 2 URLs. */
const char *
svn_path_url_add_component2(const char *url,
const char *component,
@@ -627,12 +638,14 @@ svn_path_uri_autoescape(const char *uri,
*/
/** Convert @a path_utf8 from UTF-8 to the internal encoding used by APR. */
+/* J: OSPATH only. */
svn_error_t *
svn_path_cstring_from_utf8(const char **path_apr,
const char *path_utf8,
apr_pool_t *pool);
/** Convert @a path_apr from the internal encoding used by APR to UTF-8. */
+/* J: OSPATH only. */
svn_error_t *
svn_path_cstring_to_utf8(const char **path_utf8,
const char *path_apr,
Modified: subversion/trunk/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_wc.h?rev=1030136&r1=1030135&r2=1030136&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_wc.h (original)
+++ subversion/trunk/subversion/include/svn_wc.h Tue Nov 2 17:28:21 2010
@@ -4222,7 +4222,7 @@ svn_wc_delete(const char *path,
* If @a local_abspath does not exist as file, directory or symlink, return
* #SVN_ERR_WC_PATH_NOT_FOUND.
*
- * This is equivalent to svn_wc_add4() case 2a.
+ * This is a replacement for svn_wc_add4() case 2a.
*
* ### TODO: Allow the caller to provide the node's properties?
*
@@ -4236,6 +4236,28 @@ svn_wc_add_from_disk(svn_wc_context_t *w
apr_pool_t *scratch_pool);
/**
+ * Convert the nested pristine working copy rooted at @a local_abspath into
+ * a copied subtree in the outer working copy.
+ *
+ * @a local_abspath must be the root of a nested working copy that has no
+ * local modifications. The parent directory of @a local_abspath must be a
+ * versioned directory in the outer WC, and must belong to the same
+ * repository as the nested WC. The nested WC will be integrated into the
+ * parent's WC, and will no longer be a separate WC.
+ *
+ * Call @a notify_func (if it is not @c NULL) with the @a notify_baton and
+ * the path.
+ *
+ * This is a replacement for svn_wc_add4() case 1.
+ */
+svn_error_t *
+svn_wc__integrate_nested_wc_as_copy(svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ apr_pool_t *scratch_pool);
+
+/**
* Put @a local_abspath under version control by registering it as addition
* or copy in the database containing its parent. The new node is scheduled
* for addition to the repository below its parent node.
@@ -4272,6 +4294,9 @@ svn_wc_add_from_disk(svn_wc_context_t *w
* When the @a local_abspath has been added, then @a notify_func will be
* called (if it is not @c NULL) with the @a notify_baton and the path.
*
+ * @note For case 1, prefer svn_wc__integrate_nested_wc_as_copy().
+ * @note For case 2a, prefer svn_wc_add_from_disk().
+ *
* @since New in 1.7.
*/
svn_error_t *
Modified: subversion/trunk/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/copy.c?rev=1030136&r1=1030135&r2=1030136&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/copy.c (original)
+++ subversion/trunk/subversion/libsvn_client/copy.c Tue Nov 2 17:28:21 2010
@@ -1449,10 +1449,10 @@ repos_to_wc_copy_single(svn_client__copy
/* Schedule dst_path for addition in parent, with copy history.
(This function also recursively puts a 'copied' flag on every
entry). */
- SVN_ERR(svn_wc_add4(ctx->wc_ctx, dst_abspath, svn_depth_infinity,
- pair->src_abspath_or_url, pair->src_revnum,
- ctx->cancel_func, ctx->cancel_baton,
- ctx->notify_func2, ctx->notify_baton2, pool));
+ SVN_ERR(svn_wc__integrate_nested_wc_as_copy(ctx->wc_ctx, dst_abspath,
+ ctx->notify_func2,
+ ctx->notify_baton2,
+ pool));
/* ### Recording of implied mergeinfo should really occur
### *before* the notification callback is invoked by
Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1030136&r1=1030135&r2=1030136&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Tue Nov 2 17:28:21 2010
@@ -953,6 +953,68 @@ check_can_add_node(svn_node_kind_t *kind
return SVN_NO_ERROR;
}
+/* Convert the nested pristine working copy rooted at LOCAL_ABSPATH into
+ * a copied subtree in the outer working copy.
+ *
+ * LOCAL_ABSPATH must be the root of a nested working copy that has no
+ * local modifications. The parent directory of LOCAL_ABSPATH must be a
+ * versioned directory in the outer WC, and must belong to the same
+ * repository as the nested WC. The nested WC will be integrated into the
+ * parent's WC, and will no longer be a separate WC. */
+static svn_error_t *
+integrate_nested_wc_as_copy(svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_t *db = wc_ctx->db;
+ const char *moved_abspath;
+
+ /* Drop any references to the wc that is to be rewritten */
+ SVN_ERR(svn_wc__db_drop_root(db, local_abspath, scratch_pool));
+
+ /* Move the admin dir from the wc to a temporary location: MOVED_ABSPATH */
+ {
+ const char *tmpdir_abspath, *moved_adm_abspath, *adm_abspath;
+
+ SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db,
+ svn_dirent_dirname(local_abspath,
+ scratch_pool),
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_io_open_unique_file3(NULL, &moved_abspath, tmpdir_abspath,
+ svn_io_file_del_on_close,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_io_dir_make(moved_abspath, APR_OS_DEFAULT, scratch_pool));
+
+ adm_abspath = svn_wc__adm_child(local_abspath, "", scratch_pool);
+ moved_adm_abspath = svn_wc__adm_child(moved_abspath, "", scratch_pool);
+ SVN_ERR(svn_io_file_move(adm_abspath, moved_adm_abspath, scratch_pool));
+ }
+
+ /* Copy entries from temporary location into the main db */
+ SVN_ERR(svn_wc_copy3(wc_ctx, moved_abspath, local_abspath,
+ TRUE /* metadata_only */,
+ NULL, NULL, NULL, NULL, scratch_pool));
+
+ /* Cleanup the temporary admin dir */
+ SVN_ERR(svn_wc__db_drop_root(db, moved_abspath, scratch_pool));
+ SVN_ERR(svn_io_remove_dir2(moved_abspath, FALSE, NULL, NULL,
+ scratch_pool));
+
+ /* The subdir is now part of our parent working copy. Our caller assumes
+ that we return the new node locked, so obtain a lock if we didn't
+ receive the lock via our depth infinity lock */
+ {
+ svn_boolean_t owns_lock;
+ SVN_ERR(svn_wc__db_wclock_owns_lock(&owns_lock, db, local_abspath,
+ FALSE, scratch_pool));
+ if (!owns_lock)
+ SVN_ERR(svn_wc__db_wclock_obtain(db, local_abspath, 0, FALSE,
+ scratch_pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_wc_add4(svn_wc_context_t *wc_ctx,
const char *local_abspath,
@@ -1083,50 +1145,8 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
}
else /* Case 1: Integrating a separate WC into this one, in place */
{
- const char *moved_abspath;
-
- /* Drop any references to the wc that is to be rewritten */
- SVN_ERR(svn_wc__db_drop_root(db, local_abspath, scratch_pool));
-
- /* Move the admin dir from the wc to a temporary location: MOVED_ABSPATH */
- {
- const char *tmpdir_abspath, *moved_adm_abspath, *adm_abspath;
-
- SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db,
- svn_dirent_dirname(local_abspath,
- scratch_pool),
- scratch_pool, scratch_pool));
- SVN_ERR(svn_io_open_unique_file3(NULL, &moved_abspath, tmpdir_abspath,
- svn_io_file_del_on_close,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_io_dir_make(moved_abspath, APR_OS_DEFAULT, scratch_pool));
-
- adm_abspath = svn_wc__adm_child(local_abspath, "", scratch_pool);
- moved_adm_abspath = svn_wc__adm_child(moved_abspath, "", scratch_pool);
- SVN_ERR(svn_io_file_move(adm_abspath, moved_adm_abspath, scratch_pool));
- }
-
- /* Copy entries from temporary location into the main db */
- SVN_ERR(svn_wc_copy3(wc_ctx, moved_abspath, local_abspath,
- TRUE /* metadata_only */,
- NULL, NULL, NULL, NULL, scratch_pool));
-
- /* Cleanup the temporary admin dir */
- SVN_ERR(svn_wc__db_drop_root(db, moved_abspath, scratch_pool));
- SVN_ERR(svn_io_remove_dir2(moved_abspath, FALSE, NULL, NULL,
- scratch_pool));
-
- /* The subdir is now part of our parent working copy. Our caller assumes
- that we return the new node locked, so obtain a lock if we didn't
- receive the lock via our depth infinity lock */
- {
- svn_boolean_t owns_lock;
- SVN_ERR(svn_wc__db_wclock_owns_lock(&owns_lock, db, local_abspath,
- FALSE, scratch_pool));
- if (!owns_lock)
- SVN_ERR(svn_wc__db_wclock_obtain(db, local_abspath, 0, FALSE,
- scratch_pool));
- }
+ SVN_ERR(integrate_nested_wc_as_copy(wc_ctx, local_abspath,
+ scratch_pool));
}
/* Report the addition to the caller. */
@@ -1143,6 +1163,45 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
}
svn_error_t *
+svn_wc__integrate_nested_wc_as_copy(svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_t *db = wc_ctx->db;
+ svn_boolean_t is_wc_root;
+
+ /* Precondition: LOCAL_ABSPATH is the root of a separate WC. */
+ SVN_ERR(svn_wc__check_wc_root(&is_wc_root, NULL, NULL,
+ db, local_abspath, scratch_pool));
+ if (! is_wc_root)
+ return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+ _("'%s' is not a WC root"),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+
+ /* Precondition: parent(LOCAL_ABSPATH) is a versioned directory in an
+ * acceptable state. */
+ SVN_ERR(check_can_add_to_parent(NULL, NULL, wc_ctx, local_abspath,
+ scratch_pool, scratch_pool));
+
+ SVN_ERR(integrate_nested_wc_as_copy(wc_ctx, local_abspath, scratch_pool));
+
+ /* Report the addition to the caller. */
+ if (notify_func != NULL)
+ {
+ svn_wc_notify_t *notify
+ = svn_wc_create_notify(local_abspath, svn_wc_notify_add, scratch_pool);
+
+ notify->kind = svn_node_dir;
+ (*notify_func)(notify_baton, notify, scratch_pool);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_wc_add_from_disk(svn_wc_context_t *wc_ctx,
const char *local_abspath,
svn_wc_notify_func2_t notify_func,