You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2011/12/18 18:36:29 UTC
svn commit: r1220465 [2/13] - in /subversion/branches/file-handle-cache: ./
build/ build/ac-macros/ contrib/client-side/emacs/
contrib/server-side/mod_dontdothat/ notes/
subversion/bindings/javahl/tests/org/apache/subversion/javahl/
subversion/bindings...
Modified: subversion/branches/file-handle-cache/subversion/include/svn_dirent_uri.h
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/include/svn_dirent_uri.h?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/include/svn_dirent_uri.h (original)
+++ subversion/branches/file-handle-cache/subversion/include/svn_dirent_uri.h Sun Dec 18 17:36:24 2011
@@ -122,6 +122,10 @@
* source -- such as from the network -- is converted to a dirent it
* should be tested with svn_dirent_is_under_root() before you can
* assume the path to be a safe local path.
+ *
+ * MEMORY ALLOCATION: A function documented as allocating the result
+ * in a pool may instead return a static string such as "." or "". If
+ * the result is equal to an input, it will duplicate the input.
*/
#ifndef SVN_DIRENT_URI_H
@@ -141,34 +145,39 @@ extern "C" {
/** Convert @a dirent from the local style to the canonical internal style.
* "Local style" means native path separators and "." for the empty path.
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.6.
*/
const char *
svn_dirent_internal_style(const char *dirent,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Convert @a dirent from the internal style to the local style.
* "Local style" means native path separators and "." for the empty path.
* If the input is not canonical, the output may not be canonical.
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.6.
*/
const char *
svn_dirent_local_style(const char *dirent,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Convert @a relpath from the local style to the canonical internal style.
* "Local style" means native path separators and "." for the empty path.
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.7.
*/
const char *
svn_relpath__internal_style(const char *relpath,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
-/** Join a base dirent (@a base) with a component (@a component), allocated in
- * @a pool.
+/** Join a base dirent (@a base) with a component (@a component).
*
* If either @a base or @a component is the empty string, then the other
* argument will be copied and returned. If both are the empty string then
@@ -181,15 +190,17 @@ svn_relpath__internal_style(const char *
* dirents. Only for "internal" canonicalized dirents, since it uses '/'
* for the separator.
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.6.
*/
char *
svn_dirent_join(const char *base,
const char *component,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
-/** Join multiple components onto a @a base dirent, allocated in @a pool. The
- * components are terminated by a @c NULL.
+/** Join multiple components onto a @a base dirent. The components are
+ * terminated by a @c NULL.
*
* If any component is the empty string, it will be ignored.
*
@@ -198,26 +209,30 @@ svn_dirent_join(const char *base,
*
* See svn_dirent_join() for further notes about joining dirents.
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.6.
*/
char *
-svn_dirent_join_many(apr_pool_t *pool,
+svn_dirent_join_many(apr_pool_t *result_pool,
const char *base,
...);
-/** Join a base relpath (@a base) with a component (@a component), allocating
- * the result in @a pool. @a component need not be a single component.
+/** Join a base relpath (@a base) with a component (@a component).
+ * @a component need not be a single component.
*
* If either @a base or @a component is the empty path, then the other
* argument will be copied and returned. If both are the empty path the
* empty path is returned.
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.7.
*/
char *
svn_relpath_join(const char *base,
const char *component,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Gets the name of the specified canonicalized @a dirent as it is known
* within its parent directory. If the @a dirent is root, return "". The
@@ -225,8 +240,8 @@ svn_relpath_join(const char *base,
*
* Example: svn_dirent_basename("/foo/bar") -> "bar"
*
- * The returned basename will be allocated in @a pool. If @a pool is NULL
- * a pointer to the basename in @a dirent is returned.
+ * If @a result_pool is NULL, return a pointer to the basename in @a dirent,
+ * otherwise allocate the result in @a result_pool.
*
* @note If an empty string is passed, then an empty string will be returned.
*
@@ -234,7 +249,7 @@ svn_relpath_join(const char *base,
*/
const char *
svn_dirent_basename(const char *dirent,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Get the dirname of the specified canonicalized @a dirent, defined as
* the dirent with its basename removed.
@@ -242,16 +257,15 @@ svn_dirent_basename(const char *dirent,
* If @a dirent is root ("/", "X:/", "//server/share/") or "", it is returned
* unchanged.
*
- * The returned dirname will be allocated in @a pool.
+ * Allocate the result in @a result_pool.
*
* @since New in 1.6.
*/
char *
svn_dirent_dirname(const char *dirent,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
-/** Divide the canonicalized @a dirent into @a *dirpath and @a
- * *base_name, allocated in @a pool.
+/** Divide the canonicalized @a dirent into @a *dirpath and @a *base_name.
*
* If @a dirpath or @a base_name is NULL, then don't set that one.
*
@@ -272,16 +286,17 @@ svn_dirent_dirname(const char *dirent,
* - <pre>"X:foo" ==> "X:" and "foo"</pre>
* Posix: - <pre>"X:foo" ==> "" and "X:foo"</pre>
*
+ * Allocate the results in @a result_pool.
+ *
* @since New in 1.7.
*/
void
svn_dirent_split(const char **dirpath,
const char **base_name,
const char *dirent,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
-/** Divide the canonicalized @a relpath into @a *dirpath and @a
- * *base_name, allocated in @a pool.
+/** Divide the canonicalized @a relpath into @a *dirpath and @a *base_name.
*
* If @a dirpath or @a base_name is NULL, then don't set that one.
*
@@ -296,13 +311,15 @@ svn_dirent_split(const char **dirpath,
* - <pre>"bar" ==> "" and "bar"</pre>
* - <pre>"" ==> "" and ""</pre>
*
+ * Allocate the results in @a result_pool.
+ *
* @since New in 1.7.
*/
void
svn_relpath_split(const char **dirpath,
const char **base_name,
const char *relpath,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Get the basename of the specified canonicalized @a relpath. The
* basename is defined as the last component of the relpath. If the @a
@@ -311,8 +328,8 @@ svn_relpath_split(const char **dirpath,
*
* Example: svn_relpath_basename("/trunk/foo/bar") -> "bar"
*
- * The returned basename will be allocated in @a pool. If @a
- * pool is NULL a pointer to the basename in @a relpath is returned.
+ * If @a result_pool is NULL, return a pointer to the basename in @a relpath,
+ * otherwise allocate the result in @a result_pool.
*
* @note If an empty string is passed, then an empty string will be returned.
*
@@ -320,24 +337,24 @@ svn_relpath_split(const char **dirpath,
*/
const char *
svn_relpath_basename(const char *relpath,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Get the dirname of the specified canonicalized @a relpath, defined as
* the relpath with its basename removed.
*
* If @a relpath is empty, "" is returned.
*
- * The returned relpath will be allocated in @a pool.
+ * Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
char *
svn_relpath_dirname(const char *relpath,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Divide the canonicalized @a uri into a uri @a *dirpath and a
- * (URI-decoded) relpath @a *base_name, allocated in @a pool.
+ * (URI-decoded) relpath @a *base_name.
*
* If @a dirpath or @a base_name is NULL, then don't set that one.
*
@@ -350,28 +367,30 @@ svn_relpath_dirname(const char *relpath,
* Examples:
* - <pre>"http://server/foo/bar" ==> "http://server/foo" and "bar"</pre>
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.7.
*/
void
svn_uri_split(const char **dirpath,
const char **base_name,
const char *uri,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Get the (URI-decoded) basename of the specified canonicalized @a
* uri. The basename is defined as the last component of the uri. If
- * the @a uri is root then that is returned. Otherwise, the returned
- * value will have no slashes in it.
+ * the @a uri is root, return "". The returned value will have no
+ * slashes in it.
*
* Example: svn_uri_basename("http://server/foo/bar") -> "bar"
*
- * The returned basename will be allocated in @a pool.
+ * Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
const char *
svn_uri_basename(const char *uri,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Get the dirname of the specified canonicalized @a uri, defined as
* the uri with its basename removed.
@@ -379,13 +398,13 @@ svn_uri_basename(const char *uri,
* If @a uri is root (e.g. "http://server"), it is returned
* unchanged.
*
- * The returned dirname will be allocated in @a pool.
+ * Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
char *
svn_uri_dirname(const char *uri,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Return TRUE if @a dirent is considered absolute on the platform at
* hand. E.g. '/foo' on Posix platforms or 'X:/foo', '//server/share/foo'
@@ -431,13 +450,13 @@ svn_uri_is_root(const char *uri,
*
* and possibly other semantically inoperative transformations.
*
- * The returned dirent may be allocated statically or from @a pool.
+ * Allocate the result in @a result_pool.
*
* @since New in 1.6.
*/
const char *
svn_dirent_canonicalize(const char *dirent,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Return a new relpath like @a relpath, but transformed such that some types
@@ -450,13 +469,13 @@ svn_dirent_canonicalize(const char *dire
*
* and possibly other semantically inoperative transformations.
*
- * The returned relpath may be allocated statically or from @a pool.
+ * Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
const char *
svn_relpath_canonicalize(const char *relpath,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Return a new uri like @a uri, but transformed such that some types
@@ -474,16 +493,17 @@ svn_relpath_canonicalize(const char *rel
*
* and possibly other semantically inoperative transformations.
*
- * The returned uri may be allocated statically or from @a pool.
+ * Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
const char *
svn_uri_canonicalize(const char *uri,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
-/** Return @c TRUE iff @a dirent is canonical. Use @a pool for temporary
- * allocations.
+/** Return @c TRUE iff @a dirent is canonical.
+ *
+ * Use @a scratch_pool for temporary allocations.
*
* @note The test for canonicalization is currently defined as
* "looks exactly the same as @c svn_dirent_canonicalize() would make
@@ -494,7 +514,7 @@ svn_uri_canonicalize(const char *uri,
*/
svn_boolean_t
svn_dirent_is_canonical(const char *dirent,
- apr_pool_t *pool);
+ apr_pool_t *scratch_pool);
/** Return @c TRUE iff @a relpath is canonical.
*
@@ -504,37 +524,42 @@ svn_dirent_is_canonical(const char *dire
svn_boolean_t
svn_relpath_is_canonical(const char *relpath);
-/** Return @c TRUE iff @a uri is canonical. Use @a pool for temporary
- * allocations.
+/** Return @c TRUE iff @a uri is canonical.
+ *
+ * Use @a scratch_pool for temporary allocations.
*
* @see svn_uri_canonicalize()
* @since New in 1.7.
*/
svn_boolean_t
svn_uri_is_canonical(const char *uri,
- apr_pool_t *pool);
+ apr_pool_t *scratch_pool);
/** Return the longest common dirent shared by two canonicalized dirents,
* @a dirent1 and @a dirent2. If there's no common ancestor, return the
* empty path.
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.6.
*/
char *
svn_dirent_get_longest_ancestor(const char *dirent1,
const char *dirent2,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Return the longest common path shared by two relative paths,
* @a relpath1 and @a relpath2. If there's no common ancestor, return the
* empty path.
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.7.
*/
char *
svn_relpath_get_longest_ancestor(const char *relpath1,
const char *relpath2,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Return the longest common path shared by two canonicalized uris,
* @a uri1 and @a uri2. If there's no common ancestor, return the
@@ -544,37 +569,35 @@ svn_relpath_get_longest_ancestor(const c
* resources), and (b) share a common ancestor in their path
* component, i.e. 'protocol://' is not a sufficient ancestor.
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.7.
*/
char *
svn_uri_get_longest_ancestor(const char *uri1,
const char *uri2,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Convert @a relative canonicalized dirent to an absolute dirent and
- * return the results in @a *pabsolute, allocated in @a pool.
+ * return the results in @a *pabsolute.
* Raise SVN_ERR_BAD_FILENAME if the absolute dirent cannot be determined.
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.6.
*/
svn_error_t *
svn_dirent_get_absolute(const char **pabsolute,
const char *relative,
- apr_pool_t *pool);
-
-/** Similar to svn_uri_skip_ancestor(), except that if @a child_uri is
- * the same as @a parent_uri, it is not considered a child, so the result
- * is @c NULL; an empty string is never returned.
- */
-const char *
-svn_uri__is_child(const char *parent_uri,
- const char *child_uri,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Similar to svn_dirent_skip_ancestor(), except that if @a child_dirent is
* the same as @a parent_dirent, it is not considered a child, so the result
* is @c NULL; an empty string is never returned.
*
+ * If @a result_pool is NULL, return a pointer into @a child_dirent, otherwise
+ * allocate the result in @a result_pool.
+ *
* ### TODO: Deprecate, as the semantics are trivially
* obtainable from *_skip_ancestor().
*
@@ -583,7 +606,7 @@ svn_uri__is_child(const char *parent_uri
const char *
svn_dirent_is_child(const char *parent_dirent,
const char *child_dirent,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Return TRUE if @a parent_dirent is an ancestor of @a child_dirent or
* the dirents are equal, and FALSE otherwise.
@@ -633,6 +656,7 @@ svn_relpath_skip_ancestor(const char *pa
/** Return the URI-decoded relative path of @a child_uri that is below
* @a parent_uri, or just "" if @a parent_uri is equal to @a child_uri. If
* @a child_uri is not below or equal to @a parent_uri, return NULL.
+ *
* Allocate the result in @a result_pool.
*
* @since New in 1.7.
@@ -670,8 +694,8 @@ svn_uri_skip_ancestor(const char *parent
* If there are no items in @a targets, set @a *pcommon and (if
* applicable) @a *pcondensed_targets to @c NULL.
*
- * Allocates @a *pcommon and @a *targets in @a result_pool. All
- * intermediate allocations will be performed in @a scratch_pool.
+ * Allocate the results in @a result_pool. Use @a scratch_pool for
+ * temporary allocations.
*
* @since New in 1.7.
*/
@@ -711,8 +735,8 @@ svn_dirent_condense_targets(const char *
* If there are no items in @a targets, set @a *pcommon and (if
* applicable) @a *pcondensed_targets to @c NULL.
*
- * Allocate @a *pcommon and @a *targets in @a result_pool. Temporary
- * allocations will be performed in @a scratch_pool.
+ * Allocate the results in @a result_pool. Use @a scratch_pool for
+ * temporary allocations.
*
* @since New in 1.7.
*/
@@ -729,12 +753,14 @@ svn_uri_condense_targets(const char **pc
* it resolves to a path above @a base_path, or if @a path is an absolute
* path, then set @a *under_root to @c FALSE. Otherwise, set @a *under_root
* to @c TRUE and, if @a result_path is not @c NULL, set @a *result_path to
- * the resulting path, allocated in @a result_pool.
+ * the resulting path.
*
* @a path need not be canonical. @a base_path must be canonical and
* @a *result_path will be canonical.
*
- * Note: Use of this function is strongly encouraged. Do not roll your own.
+ * Allocate the result in @a result_pool.
+ *
+ * @note Use of this function is strongly encouraged. Do not roll your own.
* (http://cve.mitre.org/cgi-bin/cvename.cgi?name=2007-3846)
*
* @since New in 1.7.
@@ -749,22 +775,26 @@ svn_dirent_is_under_root(svn_boolean_t *
/** Set @a *dirent to the path corresponding to the file:// URL @a url, using
* the platform-specific file:// rules.
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.7.
*/
svn_error_t *
svn_uri_get_dirent_from_file_url(const char **dirent,
const char *url,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/** Set @a *url to a file:// URL, corresponding to @a dirent using the
* platform specific dirent and file:// rules.
*
+ * Allocate the result in @a result_pool.
+ *
* @since New in 1.7.
*/
svn_error_t *
svn_uri_get_file_url_from_dirent(const char **url,
const char *dirent,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
#ifdef __cplusplus
}
Modified: subversion/branches/file-handle-cache/subversion/include/svn_editor.h
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/include/svn_editor.h?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/include/svn_editor.h (original)
+++ subversion/branches/file-handle-cache/subversion/include/svn_editor.h Sun Dec 18 17:36:24 2011
@@ -123,6 +123,11 @@ extern "C" {
/** An abstract object that edits a target tree.
*
+ * @note The term "follow" means at any later time in the editor drive.
+ * Terms such as "must", "must not", "required", "shall", "shall not",
+ * "should", "should not", "recommended", "may", and "optional" in this
+ * document are to be interpreted as described in RFC 2119.
+ *
* \n
* <h3>Life-Cycle</h3>
*
@@ -236,8 +241,9 @@ extern "C" {
* destination of a copy (where these new, copied nodes are subject to
* the Once Rule).
*
- * - The ancestor of an added or modified node may not be deleted. The
- * ancestor may not be moved (instead: perform the move, *then* the edits).
+ * - The ancestor of an added, copied-here, moved-here or modified node may
+ * not be deleted. The ancestor may not be moved (instead: perform the
+ * move, *then* the edits).
*
* - svn_editor_delete() must not be used to replace a path -- i.e.
* svn_editor_delete() must not be followed by an svn_editor_add_*() on
@@ -336,11 +342,7 @@ extern "C" {
* context.
*
*
- * @todo ### TODO anything missing? -- allow text and prop change to follow
- * a move or copy. -- set_text() vs. apply_text_delta()? -- If a
- * set_props/set_text/set_target/copy/move/delete in a merge source is
- * applied to a different branch, which side will REVISION arguments reflect
- * and is there still a problem?
+ * @todo ### TODO anything missing?
*
* @since New in 1.8.
*/
@@ -699,17 +701,8 @@ svn_editor_setcb_many(svn_editor_t *edit
* Create a new directory at @a relpath. The immediate parent of @a relpath
* is expected to exist.
*
- * Set the properties of the new directory to @a props, which is an
- * apr_hash_t holding key-value pairs. Each key is a const char* of a
- * property name, each value is a const svn_string_t*. If no properties are
- * being set on the new directory, @a props must be NULL.
- *
- * If this add is expected to replace a previously existing file or
- * directory at @a relpath, the revision number of the node to be replaced
- * must be given in @a replaces_rev. Otherwise, @a replaces_rev must be
- * SVN_INVALID_REVNUM. Note: it is not allowed to call a "delete" followed
- * by an "add" on the same path. Instead, an "add" with @a replaces_rev set
- * accordingly MUST be used.
+ * For descriptions of @a props and @a replaces_rev, see
+ * svn_editor_add_file().
*
* A complete listing of the immediate children of @a relpath that will be
* added subsequently is given in @a children. @a children is an array of
@@ -737,7 +730,7 @@ svn_editor_add_directory(svn_editor_t *e
* property name, each value is a const svn_string_t*. If no properties are
* being set on the new file, @a props must be NULL.
*
- * If this add is expected to replace a previously existing file or
+ * If this add is expected to replace a previously existing file, symlink or
* directory at @a relpath, the revision number of the node to be replaced
* must be given in @a replaces_rev. Otherwise, @a replaces_rev must be
* SVN_INVALID_REVNUM. Note: it is not allowed to call a "delete" followed
@@ -778,6 +771,7 @@ svn_editor_add_symlink(svn_editor_t *edi
* Create an "absent" node of kind @a kind at @a relpath. The immediate
* parent of @a relpath is expected to exist.
* ### TODO @todo explain "absent".
+ * ### JAF: What are the allowed values of 'kind'?
*
* For a description of @a replaces_rev, see svn_editor_add_file().
*
@@ -800,6 +794,8 @@ svn_editor_add_absent(svn_editor_t *edit
* ### what about "entry props"? will these still be handled via
* ### the general prop function?
*
+ * For a description of @a props, see svn_editor_add_file().
+ *
* @a complete must be FALSE if and only if
* - @a relpath is a file and an svn_editor_set_text() call will follow on
* the same path, or
Modified: subversion/branches/file-handle-cache/subversion/include/svn_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/include/svn_fs.h?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/include/svn_fs.h (original)
+++ subversion/branches/file-handle-cache/subversion/include/svn_fs.h Sun Dec 18 17:36:24 2011
@@ -309,8 +309,31 @@ svn_fs_delete_fs(const char *path,
* means deleting copied, unused logfiles for a Berkeley DB source
* filesystem.
*
+ * If @a incremental is TRUE, make an effort to not re-copy information
+ * already present in the destination. If incremental hotcopy is not
+ * implemented, raise SVN_ERR_UNSUPPORTED_FEATURE.
+ *
+ * Use @a scratch_pool for temporary allocations.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_fs_hotcopy2(const char *src_path,
+ const char *dest_path,
+ svn_boolean_t clean,
+ svn_boolean_t incremental,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool);
+
+/**
+ * Like svn_fs_hotcopy2(), but without the @a incremental parameter
+ * and without cancellation support.
+ *
+ * @deprecated Provided for backward compatibility with the 1.7 API.
* @since New in 1.1.
*/
+SVN_DEPRECATED
svn_error_t *
svn_fs_hotcopy(const char *src_path,
const char *dest_path,
Modified: subversion/branches/file-handle-cache/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/include/svn_ra.h?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/include/svn_ra.h (original)
+++ subversion/branches/file-handle-cache/subversion/include/svn_ra.h Sun Dec 18 17:36:24 2011
@@ -1406,8 +1406,9 @@ svn_ra_do_diff(svn_ra_session_t *session
*
* If @a discover_changed_paths, then each call to @a receiver passes a
* <tt>const apr_hash_t *</tt> for the receiver's @a changed_paths argument;
- * the hash's keys are all the paths committed in that revision.
- * Otherwise, each call to receiver passes NULL for @a changed_paths.
+ * the hash's keys are all the paths committed in that revision, the hash's
+ * values are <tt>const svn_log_changed_path2_t *</tt> for each committed
+ * path. Otherwise, each call to receiver passes NULL for @a changed_paths.
*
* If @a strict_node_history is set, copy history will not be traversed
* (if any exists) when harvesting the revision logs for each path.
Modified: subversion/branches/file-handle-cache/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/include/svn_repos.h?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/include/svn_repos.h (original)
+++ subversion/branches/file-handle-cache/subversion/include/svn_repos.h Sun Dec 18 17:36:24 2011
@@ -516,7 +516,29 @@ svn_repos_fs(svn_repos_t *repos);
* source filesystem as part of the copy operation; currently, this
* means deleting copied, unused logfiles for a Berkeley DB source
* repository.
+ *
+ * If @a incremental is TRUE, make an effort to not re-copy information
+ * already present in the destination. If incremental hotcopy is not
+ * implemented by the filesystem backend, raise SVN_ERR_UNSUPPORTED_FEATURE.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_repos_hotcopy2(const char *src_path,
+ const char *dst_path,
+ svn_boolean_t clean_logs,
+ svn_boolean_t incremental,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *pool);
+
+/**
+ * Like svn_repos_hotcopy2(), but without the @a incremental parameter
+ * and without cancellation support.
+ *
+ * @deprecated Provided for backward compatibility with the 1.6 API.
*/
+SVN_DEPRECATED
svn_error_t *
svn_repos_hotcopy(const char *src_path,
const char *dst_path,
@@ -2991,6 +3013,9 @@ svn_repos_authz_read(svn_authz_t **authz
* to TRUE if at least one path is accessible with the @a
* required_access.
*
+ * For compatibility with 1.6, and earlier, @a repos_name can be NULL
+ * in which case it is equivalent to a @a repos_name of "".
+ *
* @since New in 1.3.
*/
svn_error_t *
Modified: subversion/branches/file-handle-cache/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/include/svn_wc.h?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/include/svn_wc.h (original)
+++ subversion/branches/file-handle-cache/subversion/include/svn_wc.h Sun Dec 18 17:36:24 2011
@@ -1354,7 +1354,9 @@ typedef struct svn_wc_notify_t {
* In all other cases, it is @c NULL. @since New in 1.5 */
const char *changelist_name;
- /** When @c action is #svn_wc_notify_merge_begin, and both the
+ /** When @c action is #svn_wc_notify_merge_begin or
+ * #svn_wc_notify_foreign_merge_begin or
+ * #svn_wc_notify_merge_record_info_begin, and both the
* left and right sides of the merge are from the same URL. In all
* other cases, it is @c NULL. @since New in 1.5 */
svn_merge_range_t *merge_range;
Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/add.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/add.c?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/add.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/add.c Sun Dec 18 17:36:24 2011
@@ -494,31 +494,27 @@ add_dir_recursive(const char *dir_abspat
}
-struct add_with_write_lock_baton {
- const char *local_abspath;
- svn_depth_t depth;
- svn_boolean_t force;
- svn_boolean_t no_ignore;
- svn_client_ctx_t *ctx;
-
- /* Absolute path to the first existing parent directory of local_abspath.
- * If not NULL, all missing parents of local_abspath must be created
- * before local_abspath can be added. */
- const char *existing_parent_abspath;
-};
-
-/* The main logic of the public svn_client_add4. */
+/* The main logic of the public svn_client_add4.
+ *
+ * EXISTING_PARENT_ABSPATH is the absolute path to the first existing
+ * parent directory of local_abspath. If not NULL, all missing parents
+ * of LOCAL_ABSPATH must be created before LOCAL_ABSPATH can be added. */
static svn_error_t *
-add(void *baton, apr_pool_t *result_pool, apr_pool_t *scratch_pool)
+add(const char *local_abspath,
+ svn_depth_t depth,
+ svn_boolean_t force,
+ svn_boolean_t no_ignore,
+ const char *existing_parent_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
{
svn_node_kind_t kind;
svn_error_t *err;
- struct add_with_write_lock_baton *b = baton;
svn_magic__cookie_t *magic_cookie;
svn_magic__init(&magic_cookie, scratch_pool);
- if (b->existing_parent_abspath)
+ if (existing_parent_abspath)
{
const char *parent_abspath;
const char *child_relpath;
@@ -526,9 +522,9 @@ add(void *baton, apr_pool_t *result_pool
int i;
apr_pool_t *iterpool;
- parent_abspath = b->existing_parent_abspath;
- child_relpath = svn_dirent_is_child(b->existing_parent_abspath,
- b->local_abspath, NULL);
+ parent_abspath = existing_parent_abspath;
+ child_relpath = svn_dirent_is_child(existing_parent_abspath,
+ local_abspath, NULL);
components = svn_path_decompose(child_relpath, scratch_pool);
iterpool = svn_pool_create(scratch_pool);
for (i = 0; i < components->nelts - 1; i++)
@@ -538,8 +534,8 @@ add(void *baton, apr_pool_t *result_pool
svn_pool_clear(iterpool);
- if (b->ctx->cancel_func)
- SVN_ERR(b->ctx->cancel_func(b->ctx->cancel_baton));
+ if (ctx->cancel_func)
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
component = APR_ARRAY_IDX(components, i, const char *);
parent_abspath = svn_dirent_join(parent_abspath, component,
@@ -548,29 +544,27 @@ add(void *baton, apr_pool_t *result_pool
if (disk_kind != svn_node_none && disk_kind != svn_node_dir)
return svn_error_createf(SVN_ERR_CLIENT_NO_VERSIONED_PARENT, NULL,
_("'%s' prevents creating parent of '%s'"),
- parent_abspath, b->local_abspath);
+ parent_abspath, local_abspath);
SVN_ERR(svn_io_make_dir_recursively(parent_abspath, scratch_pool));
- SVN_ERR(svn_wc_add_from_disk(b->ctx->wc_ctx, parent_abspath,
- b->ctx->notify_func2,
- b->ctx->notify_baton2,
+ SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, parent_abspath,
+ ctx->notify_func2, ctx->notify_baton2,
scratch_pool));
}
svn_pool_destroy(iterpool);
}
- SVN_ERR(svn_io_check_path(b->local_abspath, &kind, scratch_pool));
+ SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
if (kind == svn_node_dir)
{
/* We use add_dir_recursive for all directory targets
and pass depth along no matter what it is, so that the
target's depth will be set correctly. */
- err = add_dir_recursive(b->local_abspath, b->depth,
- b->force, b->no_ignore, magic_cookie, b->ctx,
- scratch_pool);
+ err = add_dir_recursive(local_abspath, depth, force, no_ignore,
+ magic_cookie, ctx, scratch_pool);
}
else if (kind == svn_node_file)
- err = add_file(b->local_abspath, magic_cookie, b->ctx, scratch_pool);
+ err = add_file(local_abspath, magic_cookie, ctx, scratch_pool);
else if (kind == svn_node_none)
{
svn_boolean_t tree_conflicted;
@@ -578,7 +572,7 @@ add(void *baton, apr_pool_t *result_pool
/* Provide a meaningful error message if the node does not exist
* on disk but is a tree conflict victim. */
err = svn_wc_conflicted_p3(NULL, NULL, &tree_conflicted,
- b->ctx->wc_ctx, b->local_abspath,
+ ctx->wc_ctx, local_abspath,
scratch_pool);
if (err)
svn_error_clear(err);
@@ -587,22 +581,22 @@ add(void *baton, apr_pool_t *result_pool
_("'%s' is an existing item in conflict; "
"please mark the conflict as resolved "
"before adding a new item here"),
- svn_dirent_local_style(b->local_abspath,
+ svn_dirent_local_style(local_abspath,
scratch_pool));
return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
_("'%s' not found"),
- svn_dirent_local_style(b->local_abspath,
+ svn_dirent_local_style(local_abspath,
scratch_pool));
}
else
return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
_("Unsupported node kind for path '%s'"),
- svn_dirent_local_style(b->local_abspath,
+ svn_dirent_local_style(local_abspath,
scratch_pool));
/* Ignore SVN_ERR_ENTRY_EXISTS when FORCE is set. */
- if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && b->force)
+ if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
{
svn_error_clear(err);
err = SVN_NO_ERROR;
@@ -675,7 +669,7 @@ svn_client_add4(const char *path,
{
const char *parent_abspath;
const char *local_abspath;
- struct add_with_write_lock_baton baton;
+ const char *existing_parent_abspath;
if (svn_path_is_url(path))
return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
@@ -695,30 +689,26 @@ svn_client_add4(const char *path,
else
parent_abspath = svn_dirent_dirname(local_abspath, pool);
- baton.existing_parent_abspath = NULL;
+ existing_parent_abspath = NULL;
if (add_parents)
{
apr_pool_t *subpool;
- const char *existing_parent_abspath;
+ const char *existing_parent_abspath2;
subpool = svn_pool_create(pool);
- SVN_ERR(find_existing_parent(&existing_parent_abspath, ctx,
+ SVN_ERR(find_existing_parent(&existing_parent_abspath2, ctx,
parent_abspath, pool, subpool));
- if (strcmp(existing_parent_abspath, parent_abspath) != 0)
- baton.existing_parent_abspath = existing_parent_abspath;
+ if (strcmp(existing_parent_abspath2, parent_abspath) != 0)
+ existing_parent_abspath = existing_parent_abspath2;
svn_pool_destroy(subpool);
}
- baton.local_abspath = local_abspath;
- baton.depth = depth;
- baton.force = force;
- baton.no_ignore = no_ignore;
- baton.ctx = ctx;
- SVN_ERR(svn_wc__call_with_write_lock(add, &baton, ctx->wc_ctx,
- baton.existing_parent_abspath
- ? baton.existing_parent_abspath
- : parent_abspath,
- FALSE, pool, pool));
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ add(local_abspath, depth, force, no_ignore, existing_parent_abspath,
+ ctx, pool),
+ ctx->wc_ctx,
+ existing_parent_abspath ? existing_parent_abspath : parent_abspath,
+ FALSE /* lock_anchor */, pool);
return SVN_NO_ERROR;
}
@@ -819,6 +809,11 @@ mkdir_urls(const apr_array_header_t *url
const char *bname;
svn_uri_split(&common, &bname, common, pool);
APR_ARRAY_PUSH(targets, const char *) = bname;
+
+ if (*bname == '\0')
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("There is no valid uri above '%s'"),
+ common);
}
else
{
@@ -841,6 +836,12 @@ mkdir_urls(const apr_array_header_t *url
const char *bname;
svn_uri_split(&common, &bname, common, pool);
+
+ if (*bname == '\0')
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("There is no valid uri above '%s'"),
+ common);
+
for (i = 0; i < targets->nelts; i++)
{
const char *path = APR_ARRAY_IDX(targets, i, const char *);
Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/cleanup.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/cleanup.c?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/cleanup.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/cleanup.c Sun Dec 18 17:36:24 2011
@@ -88,7 +88,7 @@ fetch_repos_info(const char **repos_root
svn_ra_session_t *ra_session;
/* The same info is likely to retrieved multiple times (e.g. externals) */
- if (ri->last_repos && svn_uri__is_child(ri->last_repos, url, scratch_pool))
+ if (ri->last_repos && svn_uri__is_ancestor(ri->last_repos, url))
{
*repos_root = apr_pstrdup(result_pool, ri->last_repos);
*repos_uuid = apr_pstrdup(result_pool, ri->last_uuid);
Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/client.h?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/client.h (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/client.h Sun Dec 18 17:36:24 2011
@@ -105,6 +105,7 @@ svn_error_t *svn_client__get_copy_source
specify the point(s) of interest (typically the revisions referred
to as the "operative range" for a given operation) along that history.
+ START_REVISION and/or END_REVISION may be NULL if not wanted.
END may be NULL or of kind svn_opt_revision_unspecified (in either case
END_URL and END_REVISION are not touched by the function);
START and REVISION may not.
@@ -131,9 +132,9 @@ svn_error_t *svn_client__get_copy_source
Use POOL for all allocations. */
svn_error_t *
svn_client__repos_locations(const char **start_url,
- svn_opt_revision_t **start_revision,
+ svn_revnum_t *start_revision,
const char **end_url,
- svn_opt_revision_t **end_revision,
+ svn_revnum_t *end_revision,
svn_ra_session_t *ra_session,
const char *path,
const svn_opt_revision_t *revision,
@@ -142,6 +143,22 @@ svn_client__repos_locations(const char *
svn_client_ctx_t *ctx,
apr_pool_t *pool);
+/* Trace a line of history of a particular versioned resource back to a
+ * specific revision.
+ *
+ * Set *OP_URL to the URL that the object PEG_URL@PEG_REVNUM had in
+ * revision OP_REVNUM.
+ * RA_SESSION is required. */
+svn_error_t *
+svn_client__repos_location(const char **start_url,
+ svn_ra_session_t *ra_session,
+ const char *peg_url,
+ svn_revnum_t peg_revnum,
+ svn_revnum_t op_revnum,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/* Set *SEGMENTS to an array of svn_location_segment_t * objects, each
representing a reposition location segment for the history of PATH
@@ -168,19 +185,30 @@ svn_client__repos_location_segments(apr_
apr_pool_t *pool);
-/* Set *ANCESTOR_PATH and *ANCESTOR_REVISION to the youngest common
- ancestor path (a path relative to the root of the repository) and
- revision, respectively, of the two locations identified as
- PATH_OR_URL1@REV1 and PATH_OR_URL2@REV1. Use the authentication
- baton cached in CTX to authenticate against the repository.
- This function assumes that PATH_OR_URL1@REV1 and PATH_OR_URL2@REV1
- both refer to the same repository. Use POOL for all allocations. */
+/* Find the common ancestor of two locations in a repository.
+ Ancestry is determined by the 'copy-from' relationship and the normal
+ successor relationship.
+
+ Set *ANCESTOR_RELPATH, *ANCESTOR_URL, and *ANCESTOR_REVISION to the
+ path (relative to the root of the repository, with no leading '/'),
+ URL, and revision, respectively, of the youngest common ancestor of
+ the two locations URL1@REV1 and URL2@REV2. Set *ANCESTOR_RELPATH and
+ *ANCESTOR_URL to NULL and *ANCESTOR_REVISION to SVN_INVALID_REVNUM if
+ they have no common ancestor. This function assumes that URL1@REV1
+ and URL2@REV2 both refer to the same repository.
+
+ Use the authentication baton cached in CTX to authenticate against
+ the repository. Use POOL for all allocations.
+
+ See also svn_client__youngest_common_ancestor().
+*/
svn_error_t *
-svn_client__get_youngest_common_ancestor(const char **ancestor_path,
+svn_client__get_youngest_common_ancestor(const char **ancestor_relpath,
+ const char **ancestor_url,
svn_revnum_t *ancestor_revision,
- const char *path_or_url1,
+ const char *url1,
svn_revnum_t rev1,
- const char *path_or_url2,
+ const char *url2,
svn_revnum_t rev2,
svn_client_ctx_t *ctx,
apr_pool_t *pool);
@@ -197,8 +225,9 @@ svn_client__get_youngest_common_ancestor
and should only be used if PATH_OR_URL is a url
### else NULL? what's it for?
- If PEG_REVISION's kind is svn_opt_revision_unspecified, it is
- interpreted as "head" for a URL or "working" for a working-copy path.
+ If PEG_REVISION->kind is 'unspecified', the peg revision is 'head'
+ for a URL or 'working' for a WC path. If REVISION->kind is
+ 'unspecified', the operative revision is the peg revision.
Store the resulting ra_session in *RA_SESSION_P. Store the actual
revision number of the object in *REV_P, and the final resulting
@@ -249,14 +278,12 @@ svn_client__ensure_ra_session_url(const
apr_pool_t *pool);
/* Return the path of ABSPATH_OR_URL relative to the repository root
- (REPOS_ROOT) in REL_PATH (URI-decoded), both allocated in RESULT_POOL.
+ in REL_PATH (URI-decoded), allocated in RESULT_POOL.
If INCLUDE_LEADING_SLASH is set, the returned result will have a leading
slash; otherwise, it will not.
- The remaining parameters are used to procure the repository root.
- Either REPOS_ROOT or RA_SESSION -- but not both -- may be NULL.
- REPOS_ROOT should be passed when available as an optimization (in
- that order of preference).
+ REPOS_ROOT and RA_SESSION may be NULL if ABSPATH_OR_URL is a WC path,
+ otherwise at least one of them must be non-null.
CAUTION: While having a leading slash on a so-called relative path
might work out well for functionality that interacts with
@@ -386,6 +413,19 @@ svn_error_t * svn_client__wc_delete(cons
svn_client_ctx_t *ctx,
apr_pool_t *pool);
+
+/* Like svn_client__wc_delete(), but deletes mulitple TARGETS efficiently. */
+svn_error_t *
+svn_client__wc_delete_many(const apr_array_header_t *targets,
+ svn_boolean_t force,
+ svn_boolean_t dry_run,
+ svn_boolean_t keep_local,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+
/* Make PATH and add it to the working copy, optionally making all the
intermediate parent directories if MAKE_PARENTS is TRUE. */
svn_error_t *
Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/commit.c?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/commit.c Sun Dec 18 17:36:24 2011
@@ -145,19 +145,22 @@ send_file_contents(const char *path,
if (svn_subst_translation_required(eol_style, eol, keywords,
FALSE, TRUE))
{
- svn_boolean_t repair = FALSE;
+ if (eol_style == svn_subst_eol_style_unknown)
+ return svn_error_createf(SVN_ERR_IO_UNKNOWN_EOL, NULL,
+ _("%s property on '%s' contains "
+ "unrecognized EOL-style '%s'"),
+ SVN_PROP_EOL_STYLE, path,
+ eol_style_val->data);
+ /* We're importing, so translate files with 'native' eol-style to
+ * repository-normal form, not to this platform's native EOL. */
if (eol_style == svn_subst_eol_style_native)
eol = SVN_SUBST_NATIVE_EOL_STR;
- else if (eol_style == svn_subst_eol_style_fixed)
- repair = TRUE;
- else if (eol_style != svn_subst_eol_style_none)
- return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL, NULL, NULL);
/* Wrap the working copy stream with a filter to detranslate it. */
contents = svn_subst_stream_translated(contents,
eol,
- repair,
+ TRUE /* repair */,
keywords,
FALSE /* expand */,
pool);
@@ -822,7 +825,7 @@ svn_client_import4(const char *path,
ignore_unknown_node_types, ctx, subpool)))
{
svn_error_clear(editor->abort_edit(edit_baton, subpool));
- return err;
+ return svn_error_trace(err);
}
svn_pool_destroy(subpool);
@@ -901,12 +904,11 @@ collect_lock_tokens(apr_hash_t **result,
{
const char *url = svn__apr_hash_index_key(hi);
const char *token = svn__apr_hash_index_val(hi);
+ const char *relpath = svn_uri_skip_ancestor(base_url, url, pool);
- if (svn_uri__is_ancestor(base_url, url))
+ if (relpath)
{
- url = svn_uri_skip_ancestor(base_url, url, pool);
-
- apr_hash_set(*result, url, APR_HASH_KEY_STRING, token);
+ apr_hash_set(*result, relpath, APR_HASH_KEY_STRING, token);
}
}
@@ -1168,12 +1170,113 @@ check_url_kind(void *baton,
kind, scratch_pool));
}
+/* Recurse into every target in REL_TARGETS, finding committable externals
+ * nested within. Append these to REL_TARGETS itself. The paths in REL_TARGETS
+ * are assumed to be / will be created relative to BASE_ABSPATH. The remaining
+ * arguments correspond to those of svn_client_commit6(). */
+static svn_error_t*
+append_externals_as_explicit_targets(apr_array_header_t *rel_targets,
+ const char *base_abspath,
+ svn_boolean_t include_file_externals,
+ svn_boolean_t include_dir_externals,
+ svn_depth_t depth,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ int rel_targets_nelts_fixed;
+ int i;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ /* Easy part of applying DEPTH to externals. */
+ if (depth == svn_depth_empty)
+ {
+ /* Don't recurse. */
+ return SVN_NO_ERROR;
+ }
+ else if (depth != svn_depth_infinity)
+ {
+ include_dir_externals = FALSE;
+ /* We slip in dir externals as explicit targets. When we do that,
+ * depth_immediates should become depth_empty for dir externals targets.
+ * But adding the dir external to the list of targets makes it get
+ * handled with depth_immediates itself, and thus will also include the
+ * immediate children of the dir external. So do dir externals only with
+ * depth_infinity or not at all.
+ * ### TODO: Maybe rework this (and svn_client_commit6()) into separate
+ * ### target lists, "duplicating" REL_TARGETS: one for the user's
+ * ### targets and one for the overlayed externals targets, and pass an
+ * ### appropriate depth for the externals targets in a separate call to
+ * ### svn_client__harvest_committables(). The only gain is correct
+ * ### handling of this very specific case: during 'svn commit
+ * ### --depth=immediates --include-externals', commit dir externals
+ * ### (only immediate children of a target) with depth_empty instead of
+ * ### not at all. No other effect. So not doing that for now. */
+ }
+
+ if (! (include_file_externals || include_dir_externals))
+ return SVN_NO_ERROR;
+
+ /* Iterate *and* grow REL_TARGETS at the same time. */
+ rel_targets_nelts_fixed = rel_targets->nelts;
+
+ for (i = 0; i < rel_targets_nelts_fixed; i++)
+ {
+ int j;
+ const char *target;
+ apr_array_header_t *externals = NULL;
+
+ svn_pool_clear(iterpool);
+
+ target = svn_dirent_join(base_abspath,
+ APR_ARRAY_IDX(rel_targets, i, const char *),
+ iterpool);
+
+ /* ### TODO: Possible optimization: No need to do this for file targets.
+ * ### But what's cheaper, stat'ing the file system or querying the db?
+ * ### --> future. */
+
+ SVN_ERR(svn_wc__committable_externals_below(&externals, ctx->wc_ctx,
+ target, depth,
+ iterpool, iterpool));
+
+ if (externals != NULL)
+ {
+ const char *rel_target;
+
+ for (j = 0; j < externals->nelts; j++)
+ {
+ svn_wc__committable_external_info_t *xinfo =
+ APR_ARRAY_IDX(externals, j,
+ svn_wc__committable_external_info_t *);
+
+ if ((xinfo->kind == svn_kind_file && ! include_file_externals)
+ || (xinfo->kind == svn_kind_dir && ! include_dir_externals))
+ continue;
+
+ rel_target = svn_dirent_skip_ancestor(base_abspath,
+ xinfo->local_abspath);
+
+ SVN_ERR_ASSERT(rel_target != NULL && *rel_target != '\0');
+
+ APR_ARRAY_PUSH(rel_targets, const char *) =
+ apr_pstrdup(result_pool, rel_target);
+ }
+ }
+ }
+
+ svn_pool_destroy(iterpool);
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
-svn_client_commit5(const apr_array_header_t *targets,
+svn_client_commit6(const apr_array_header_t *targets,
svn_depth_t depth,
svn_boolean_t keep_locks,
svn_boolean_t keep_changelists,
svn_boolean_t commit_as_operations,
+ svn_boolean_t include_file_externals,
+ svn_boolean_t include_dir_externals,
const apr_array_header_t *changelists,
const apr_hash_t *revprop_table,
svn_commit_callback2_t commit_callback,
@@ -1233,6 +1336,12 @@ svn_client_commit5(const apr_array_heade
if (rel_targets->nelts == 0)
APR_ARRAY_PUSH(rel_targets, const char *) = "";
+ SVN_ERR(append_externals_as_explicit_targets(rel_targets, base_abspath,
+ include_file_externals,
+ include_dir_externals,
+ depth, ctx,
+ pool, pool));
+
SVN_ERR(determine_lock_targets(&lock_targets, ctx->wc_ctx, base_abspath,
rel_targets, pool, iterpool));
@@ -1603,3 +1712,25 @@ svn_client_commit5(const apr_array_heade
return svn_error_trace(reconcile_errors(cmt_err, unlock_err, bump_err,
pool));
}
+
+svn_error_t *
+svn_client_commit5(const apr_array_header_t *targets,
+ svn_depth_t depth,
+ svn_boolean_t keep_locks,
+ svn_boolean_t keep_changelists,
+ svn_boolean_t commit_as_operations,
+ const apr_array_header_t *changelists,
+ const apr_hash_t *revprop_table,
+ svn_commit_callback2_t commit_callback,
+ void *commit_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ return svn_client_commit6(targets, depth, keep_locks, keep_changelists,
+ commit_as_operations,
+ TRUE, /* include_file_externals */
+ FALSE, /* include_dir_externals */
+ changelists, revprop_table, commit_callback,
+ commit_baton, ctx, pool);
+}
+
Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/commit_util.c?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/commit_util.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/commit_util.c Sun Dec 18 17:36:24 2011
@@ -410,6 +410,12 @@ bail_on_tree_conflicted_ancestor(svn_wc_
when harvesting committables; that is, don't add a path to
COMMITTABLES unless it's a member of one of those changelists.
+ IS_EXPLICIT_TARGET should always be passed as TRUE, except when
+ harvest_committables() calls itself in recursion. This provides a way to
+ tell whether LOCAL_ABSPATH was an original target or whether it was reached
+ by recursing deeper into a dir target. (This is used to skip all file
+ externals that aren't explicit commit targets.)
+
If CANCEL_FUNC is non-null, call it with CANCEL_BATON to see
if the user has cancelled the operation.
@@ -428,6 +434,7 @@ harvest_committables(svn_wc_context_t *w
apr_hash_t *changelists,
svn_boolean_t skip_files,
svn_boolean_t skip_dirs,
+ svn_boolean_t is_explicit_target,
svn_client__check_url_kind_t check_url_func,
void *check_url_baton,
svn_cancel_func_t cancel_func,
@@ -543,10 +550,24 @@ harvest_committables(svn_wc_context_t *w
svn_dirent_local_style(local_abspath, scratch_pool));
}
- /* ### in need of comment */
- if (copy_mode
- && is_update_root
- && db_kind == svn_node_file)
+ /* Handle file externals.
+ * (IS_UPDATE_ROOT is more generally defined, but at the moment this
+ * condition matches only file externals.)
+ *
+ * Don't copy files that svn:externals brought into the WC. So in copy_mode,
+ * even explicit targets are skipped.
+ *
+ * Exclude file externals from recursion. Hande file externals only when
+ * passed as explicit target. Note that svn_client_commit6() passes all
+ * committable externals in as explicit targets iff they count.
+ *
+ * Also note that dir externals will never be reached recursively by this
+ * function, since svn_wc__node_get_children_of_working_node() (used below
+ * to recurse) does not return switched subdirs. */
+ if (is_update_root
+ && db_kind == svn_node_file
+ && (copy_mode
+ || ! is_explicit_target))
{
return SVN_NO_ERROR;
}
@@ -841,6 +862,7 @@ harvest_committables(svn_wc_context_t *w
changelists,
(depth < svn_depth_files),
(depth < svn_depth_immediates),
+ FALSE, /* IS_EXPLICIT_TARGET */
check_url_func, check_url_baton,
cancel_func, cancel_baton,
notify_func, notify_baton,
@@ -1125,6 +1147,7 @@ svn_client__harvest_committables(svn_cli
FALSE /* COPY_MODE_ROOT */,
depth, just_locked, changelist_hash,
FALSE, FALSE,
+ TRUE /* IS_EXPLICIT_TARGET */,
check_url_func, check_url_baton,
ctx->cancel_func, ctx->cancel_baton,
ctx->notify_func2, ctx->notify_baton2,
@@ -1218,6 +1241,7 @@ harvest_copy_committables(void *baton, v
FALSE, /* JUST_LOCKED */
NULL,
FALSE, FALSE, /* skip files, dirs */
+ TRUE, /* IS_EXPLICIT_TARGET (don't care) */
btn->check_url_func,
btn->check_url_baton,
btn->ctx->cancel_func,
Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/copy.c?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/copy.c Sun Dec 18 17:36:24 2011
@@ -240,47 +240,41 @@ get_copy_pair_ancestors(const apr_array_
}
-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_with_write_lock(void *baton,
- apr_pool_t *result_pool,
+do_wc_to_wc_copies_with_write_lock(const apr_array_header_t *copy_pairs,
+ const char *dst_parent,
+ svn_client_ctx_t *ctx,
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(scratch_pool);
svn_error_t *err = SVN_NO_ERROR;
- for (i = 0; i < b->copy_pairs->nelts; i++)
+ for (i = 0; i < copy_pairs->nelts; i++)
{
const char *dst_abspath;
- svn_client__copy_pair_t *pair = APR_ARRAY_IDX(b->copy_pairs, i,
+ svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
svn_client__copy_pair_t *);
svn_pool_clear(iterpool);
/* Check for cancellation */
- if (b->ctx->cancel_func)
- SVN_ERR(b->ctx->cancel_func(b->ctx->cancel_baton));
+ if (ctx->cancel_func)
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
/* Perform the copy */
dst_abspath = svn_dirent_join(pair->dst_parent_abspath, pair->base_name,
iterpool);
- err = svn_wc_copy3(b->ctx->wc_ctx, pair->src_abspath_or_url, dst_abspath,
+ err = svn_wc_copy3(ctx->wc_ctx, pair->src_abspath_or_url, dst_abspath,
FALSE /* metadata_only */,
- b->ctx->cancel_func, b->ctx->cancel_baton,
- b->ctx->notify_func2, b->ctx->notify_baton2, iterpool);
+ ctx->cancel_func, ctx->cancel_baton,
+ ctx->notify_func2, ctx->notify_baton2, iterpool);
if (err)
break;
}
svn_pool_destroy(iterpool);
- svn_io_sleep_for_timestamps(b->dst_parent, scratch_pool);
+ svn_io_sleep_for_timestamps(dst_parent, scratch_pool);
SVN_ERR(err);
return SVN_NO_ERROR;
}
@@ -293,7 +287,6 @@ do_wc_to_wc_copies(const apr_array_heade
apr_pool_t *pool)
{
const char *dst_parent, *dst_parent_abspath;
- struct do_wc_to_wc_copies_with_write_lock_baton baton;
SVN_ERR(get_copy_pair_ancestors(copy_pairs, NULL, &dst_parent, NULL, pool));
if (copy_pairs->nelts == 1)
@@ -301,40 +294,31 @@ do_wc_to_wc_copies(const apr_array_heade
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,
- FALSE, pool, pool));
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ do_wc_to_wc_copies_with_write_lock(copy_pairs, dst_parent, ctx, pool),
+ ctx->wc_ctx, dst_parent_abspath, FALSE, 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,
+do_wc_to_wc_moves_with_locks2(svn_client__copy_pair_t *pair,
+ const char *dst_parent_abspath,
+ svn_boolean_t lock_src,
+ svn_boolean_t lock_dst,
+ svn_client_ctx_t *ctx,
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,
+ dst_abspath = svn_dirent_join(dst_parent_abspath, pair->base_name,
scratch_pool);
- SVN_ERR(svn_wc_move(b->ctx->wc_ctx, b->pair->src_abspath_or_url,
+ SVN_ERR(svn_wc_move(ctx->wc_ctx, pair->src_abspath_or_url,
dst_abspath, FALSE /* metadata_only */,
- b->ctx->cancel_func, b->ctx->cancel_baton,
- b->ctx->notify_func2, b->ctx->notify_baton2,
+ ctx->cancel_func, ctx->cancel_baton,
+ ctx->notify_func2, ctx->notify_baton2,
scratch_pool));
return SVN_NO_ERROR;
@@ -342,18 +326,21 @@ do_wc_to_wc_moves_with_locks2(void *bato
/* 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,
+do_wc_to_wc_moves_with_locks1(svn_client__copy_pair_t *pair,
+ const char *dst_parent_abspath,
+ svn_boolean_t lock_src,
+ svn_boolean_t lock_dst,
+ svn_client_ctx_t *ctx,
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,
- FALSE, result_pool, scratch_pool));
+ if (lock_dst)
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ do_wc_to_wc_moves_with_locks2(pair, dst_parent_abspath, lock_src,
+ lock_dst, ctx, scratch_pool),
+ ctx->wc_ctx, dst_parent_abspath, FALSE, scratch_pool);
else
- SVN_ERR(do_wc_to_wc_moves_with_locks2(b, result_pool, scratch_pool));
+ SVN_ERR(do_wc_to_wc_moves_with_locks2(pair, dst_parent_abspath, lock_src,
+ lock_dst, ctx, scratch_pool));
return SVN_NO_ERROR;
}
@@ -373,7 +360,7 @@ do_wc_to_wc_moves(const apr_array_header
for (i = 0; i < copy_pairs->nelts; i++)
{
const char *src_parent_abspath;
- struct do_wc_to_wc_moves_with_locks_baton baton;
+ svn_boolean_t lock_src, lock_dst;
svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
svn_client__copy_pair_t *);
@@ -397,32 +384,31 @@ do_wc_to_wc_moves(const apr_array_header
|| svn_dirent_is_child(src_parent_abspath, pair->dst_parent_abspath,
iterpool))
{
- baton.lock_src = TRUE;
- baton.lock_dst = FALSE;
+ lock_src = TRUE;
+ lock_dst = FALSE;
}
else if (svn_dirent_is_child(pair->dst_parent_abspath, src_parent_abspath,
iterpool))
{
- baton.lock_src = FALSE;
- baton.lock_dst = TRUE;
+ lock_src = FALSE;
+ lock_dst = TRUE;
}
else
{
- baton.lock_src = TRUE;
- baton.lock_dst = TRUE;
+ lock_src = TRUE;
+ lock_dst = TRUE;
}
/* Perform the copy and then the delete. */
- 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,
- FALSE, iterpool, iterpool));
+ if (lock_src)
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ do_wc_to_wc_moves_with_locks1(pair, pair->dst_parent_abspath,
+ lock_src, lock_dst, ctx, iterpool),
+ ctx->wc_ctx, src_parent_abspath,
+ FALSE, iterpool);
else
- SVN_ERR(do_wc_to_wc_moves_with_locks1(&baton, iterpool, iterpool));
+ SVN_ERR(do_wc_to_wc_moves_with_locks1(pair, pair->dst_parent_abspath,
+ lock_src, lock_dst, ctx, iterpool));
}
svn_pool_destroy(iterpool);
@@ -795,7 +781,6 @@ repos_to_repos_copy(const apr_array_head
svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
svn_client__copy_pair_t *);
apr_hash_t *mergeinfo;
- svn_opt_revision_t *src_rev;
/* Are the source and destination URLs at or under REPOS_ROOT? */
if (! (svn_uri__is_ancestor(repos_root, pair->src_abspath_or_url)
@@ -805,18 +790,11 @@ repos_to_repos_copy(const apr_array_head
_("Source and destination URLs appear not to point to the "
"same repository."));
- /* Resolve revision keywords and such into real revision number,
- passing NULL for the path (to ensure error if trying to get a
- revision based on the working copy). */
- SVN_ERR(svn_client__get_revision_number(&pair->src_revnum, &youngest,
- ctx->wc_ctx, NULL,
- ra_session,
- &pair->src_op_revision, pool));
-
- /* Run the history function to get the source's URL in the
+ /* Run the history function to get the source's URL and revnum in the
operational revision. */
SVN_ERR(svn_ra_reparent(ra_session, pair->src_abspath_or_url, pool));
- SVN_ERR(svn_client__repos_locations(&pair->src_abspath_or_url, &src_rev,
+ SVN_ERR(svn_client__repos_locations(&pair->src_abspath_or_url,
+ &pair->src_revnum,
NULL, NULL,
ra_session,
pair->src_abspath_or_url,
@@ -897,8 +875,6 @@ repos_to_repos_copy(const apr_array_head
directories of the destination that don't yet exist. */
if (make_parents)
{
- const char *dir;
-
new_dirs = apr_array_make(pool, 0, sizeof(const char *));
/* If this is a move, TOP_URL is at least the common ancestor of
@@ -921,17 +897,17 @@ repos_to_repos_copy(const apr_array_head
svn copy --parents URL/src URL/dst
- where src exists and dst does not. The svn_uri_dirname()
- call above will produce a string equivalent to TOP_URL,
- which means svn_uri_is_child() will return NULL. In this
- case, do not try to add dst to the NEW_DIRS list since it
+ where src exists and dst does not. If the dirname of the
+ destination path is equal to TOP_URL,
+ do not try to add dst to the NEW_DIRS list since it
will be added to the commit items array later in this
function. */
- dir = svn_uri__is_child(
- top_url,
- svn_uri_dirname(first_pair->dst_abspath_or_url, pool),
- pool);
- if (dir)
+ const char *dir = svn_uri_skip_ancestor(
+ top_url,
+ svn_uri_dirname(first_pair->dst_abspath_or_url,
+ pool),
+ pool);
+ if (dir && *dir)
SVN_ERR(find_absent_parents1(ra_session, dir, new_dirs, pool));
}
/* If, however, this is *not* a move, TOP_URL only points to the
@@ -950,8 +926,9 @@ repos_to_repos_copy(const apr_array_head
for (i = 0; i < new_urls->nelts; i++)
{
const char *new_url = APR_ARRAY_IDX(new_urls, i, const char *);
- dir = svn_uri__is_child(top_url, new_url, pool);
- APR_ARRAY_PUSH(new_dirs, const char *) = dir ? dir : "";
+ const char *dir = svn_uri_skip_ancestor(top_url, new_url, pool);
+
+ APR_ARRAY_PUSH(new_dirs, const char *) = dir;
}
}
}
@@ -967,10 +944,12 @@ repos_to_repos_copy(const apr_array_head
svn_client__copy_pair_t *);
path_driver_info_t *info = APR_ARRAY_IDX(path_infos, i,
path_driver_info_t *);
+ const char *relpath = svn_uri_skip_ancestor(pair->dst_abspath_or_url,
+ pair->src_abspath_or_url,
+ pool);
if ((strcmp(pair->dst_abspath_or_url, repos_root) != 0)
- && (svn_uri__is_child(pair->dst_abspath_or_url,
- pair->src_abspath_or_url, pool) != NULL))
+ && (relpath != NULL && *relpath != '\0'))
{
info->resurrection = TRUE;
top_url = svn_uri_dirname(top_url, pool);
@@ -1021,9 +1000,7 @@ repos_to_repos_copy(const apr_array_head
/* Figure out the basename that will result from this operation,
and ensure that we aren't trying to overwrite existing paths. */
- dst_rel = svn_uri__is_child(top_url, pair->dst_abspath_or_url, pool);
- if (! dst_rel)
- dst_rel = "";
+ dst_rel = svn_uri_skip_ancestor(top_url, pair->dst_abspath_or_url, pool);
SVN_ERR(svn_ra_check_path(ra_session, dst_rel, youngest,
&dst_kind, pool));
if (dst_kind != svn_node_none)
@@ -1277,9 +1254,8 @@ wc_to_repos_copy(const apr_array_header_
APR_ARRAY_IDX(copy_pairs, i, svn_client__copy_pair_t *);
svn_pool_clear(iterpool);
- dst_rel = svn_uri__is_child(top_dst_url,
- pair->dst_abspath_or_url,
- iterpool);
+ dst_rel = svn_uri_skip_ancestor(top_dst_url, pair->dst_abspath_or_url,
+ iterpool);
SVN_ERR(svn_ra_check_path(ra_session, dst_rel, SVN_INVALID_REVNUM,
&dst_kind, iterpool));
if (dst_kind != svn_node_none)
@@ -1783,29 +1759,6 @@ repos_to_wc_copy_locked(const apr_array_
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,
@@ -1817,7 +1770,6 @@ repos_to_wc_copy(const apr_array_header_
const char *top_src_url, *top_dst_path;
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. */
@@ -1826,11 +1778,10 @@ repos_to_wc_copy(const apr_array_header_
svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
svn_client__copy_pair_t *);
const char *src;
- svn_opt_revision_t *new_rev;
svn_pool_clear(iterpool);
- SVN_ERR(svn_client__repos_locations(&src, &new_rev, NULL, NULL,
+ SVN_ERR(svn_client__repos_locations(&src, &pair->src_revnum, NULL, NULL,
NULL,
pair->src_abspath_or_url,
&pair->src_peg_revision,
@@ -1857,18 +1808,6 @@ repos_to_wc_copy(const apr_array_header_
NULL, NULL, FALSE, TRUE,
ctx, pool));
- /* Pass null for the path, to ensure error if trying to get a
- revision based on the working copy. */
- 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 *);
-
- SVN_ERR(svn_client__get_revision_number(&pair->src_revnum, NULL,
- ctx->wc_ctx, NULL, ra_session,
- &pair->src_op_revision, pool));
- }
-
/* Get the correct src path for the peg revision used, and verify that we
aren't overwriting an existing path. */
for (i = 0; i < copy_pairs->nelts; i++)
@@ -1930,15 +1869,10 @@ repos_to_wc_copy(const apr_array_header_
}
svn_pool_destroy(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(svn_wc__call_with_write_lock(repos_to_wc_copy_cb, &baton,
- ctx->wc_ctx, lock_abspath,
- FALSE, pool, pool));
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ repos_to_wc_copy_locked(copy_pairs, top_dst_path, ignore_externals,
+ ra_session, ctx, pool),
+ ctx->wc_ctx, lock_abspath, FALSE, pool);
return SVN_NO_ERROR;
}
Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/delete.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/delete.c?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/delete.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/delete.c Sun Dec 18 17:36:24 2011
@@ -237,7 +237,7 @@ delete_urls_multi_repos(const apr_array_
for (hi = apr_hash_first(pool, sessions); hi; hi = apr_hash_next(hi))
{
repos_root = svn__apr_hash_index_key(hi);
- repos_relpath = svn_uri__is_child(repos_root, uri, pool);
+ repos_relpath = svn_uri_skip_ancestor(repos_root, uri, pool);
if (repos_relpath)
{
@@ -264,7 +264,7 @@ delete_urls_multi_repos(const apr_array_
SVN_ERR(svn_ra_reparent(ra_session, repos_root, pool));
apr_hash_set(sessions, repos_root, APR_HASH_KEY_STRING, ra_session);
- repos_relpath = svn_uri__is_child(repos_root, uri, pool);
+ repos_relpath = svn_uri_skip_ancestor(repos_root, uri, pool);
relpaths_list = apr_array_make(pool, 1, sizeof(const char *));
apr_hash_set(relpaths, repos_root, APR_HASH_KEY_STRING,
@@ -272,6 +272,12 @@ delete_urls_multi_repos(const apr_array_
APR_ARRAY_PUSH(relpaths_list, const char *) = repos_relpath;
}
+ /* Check we identified a non-root relpath. Return an RA error
+ code for 1.6 compatibility. */
+ if (!repos_relpath || !*repos_relpath)
+ return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+ "URL '%s' not within a repository", uri);
+
/* Now, test to see if the thing actually exists. */
SVN_ERR(svn_ra_check_path(ra_session, repos_relpath, SVN_INVALID_REVNUM,
&kind, pool));
@@ -329,29 +335,43 @@ 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)
+svn_error_t *
+svn_client__wc_delete_many(const apr_array_header_t *targets,
+ svn_boolean_t force,
+ svn_boolean_t dry_run,
+ svn_boolean_t keep_local,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
{
- struct delete_with_write_lock_baton *args = baton;
+ int i;
+ apr_array_header_t *abs_targets;
+
+ abs_targets = apr_array_make(pool, targets->nelts, sizeof(const char *));
+ for (i = 0; i < targets->nelts; i++)
+ {
+ const char *path = APR_ARRAY_IDX(targets, i, const char *);
+ const char *local_abspath;
+
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
+ APR_ARRAY_PUSH(abs_targets, const char *) = local_abspath;
+
+ if (!force && !keep_local)
+ /* Verify that there are no "awkward" files */
+ SVN_ERR(svn_client__can_delete(local_abspath, ctx, pool));
+ }
+
+ if (!dry_run)
+ /* Mark the entry for commit deletion and perform wc deletion */
+ return svn_error_trace(svn_wc__delete_many(ctx->wc_ctx, abs_targets,
+ keep_local, TRUE,
+ ctx->cancel_func,
+ ctx->cancel_baton,
+ notify_func, notify_baton,
+ pool));
- /* 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);
+ return SVN_NO_ERROR;
}
svn_error_t *
@@ -379,32 +399,75 @@ svn_client_delete4(const apr_array_heade
}
else
{
- apr_pool_t *subpool = svn_pool_create(pool);
+ const char *local_abspath;
+ apr_hash_t *wcroots;
+ apr_hash_index_t *hi;
int i;
-
+ int j;
+ apr_pool_t *iterpool;
+ svn_boolean_t is_new_target;
+
+ /* Build a map of wcroots and targets within them. */
+ wcroots = apr_hash_make(pool);
+ iterpool = svn_pool_create(pool);
for (i = 0; i < paths->nelts; i++)
{
- struct delete_with_write_lock_baton dwwlb;
- const char *path = APR_ARRAY_IDX(paths, i, const char *);
- const char *local_abspath;
+ const char *wcroot_abspath;
+ apr_array_header_t *targets;
- svn_pool_clear(subpool);
+ svn_pool_clear(iterpool);
/* See if the user wants us to stop. */
if (ctx->cancel_func)
SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
- 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, TRUE,
- pool, subpool));
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath,
+ APR_ARRAY_IDX(paths, i,
+ const char *),
+ pool));
+ SVN_ERR(svn_wc__get_wc_root(&wcroot_abspath, ctx->wc_ctx,
+ local_abspath, pool, iterpool));
+ targets = apr_hash_get(wcroots, wcroot_abspath,
+ APR_HASH_KEY_STRING);
+ if (targets == NULL)
+ {
+ targets = apr_array_make(pool, 1, sizeof(const char *));
+ apr_hash_set(wcroots, wcroot_abspath, APR_HASH_KEY_STRING,
+ targets);
+ }
+
+ /* Make sure targets are unique. */
+ is_new_target = TRUE;
+ for (j = 0; j < targets->nelts; j++)
+ {
+ if (strcmp(APR_ARRAY_IDX(targets, j, const char *),
+ local_abspath) == 0)
+ {
+ is_new_target = FALSE;
+ break;
+ }
+ }
+
+ if (is_new_target)
+ APR_ARRAY_PUSH(targets, const char *) = local_abspath;
+ }
+
+ /* Delete the targets from each working copy in turn. */
+ for (hi = apr_hash_first(pool, wcroots); hi; hi = apr_hash_next(hi))
+ {
+ const char *wcroot_abspath = svn__apr_hash_index_key(hi);
+ const apr_array_header_t *targets = svn__apr_hash_index_val(hi);
+
+ svn_pool_clear(iterpool);
+
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ svn_client__wc_delete_many(targets, force, FALSE, keep_local,
+ ctx->notify_func2, ctx->notify_baton2,
+ ctx, iterpool),
+ ctx->wc_ctx, wcroot_abspath, TRUE /* lock_anchor */,
+ iterpool);
}
- svn_pool_destroy(subpool);
+ svn_pool_destroy(iterpool);
}
return SVN_NO_ERROR;
Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/deprecated.c?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/deprecated.c Sun Dec 18 17:36:24 2011
@@ -44,6 +44,7 @@
#include "client.h"
#include "mergeinfo.h"
+#include "private/svn_opt_private.h"
#include "private/svn_wc_private.h"
#include "svn_private_config.h"
@@ -1362,16 +1363,11 @@ svn_client_log4(const apr_array_header_t
apr_pool_t *pool)
{
apr_array_header_t *revision_ranges;
- svn_opt_revision_range_t *range;
-
- range = apr_palloc(pool, sizeof(svn_opt_revision_range_t));
- range->start = *start;
- range->end = *end;
revision_ranges = apr_array_make(pool, 1,
sizeof(svn_opt_revision_range_t *));
-
- APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *) = range;
+ APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
+ = svn_opt__revision_range_create(start, end, pool);
return svn_client_log5(targets, peg_revision, revision_ranges, limit,
discover_changed_paths, strict_node_history,
@@ -1577,13 +1573,11 @@ svn_client_merge_peg2(const char *source
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- svn_opt_revision_range_t range;
apr_array_header_t *ranges_to_merge =
apr_array_make(pool, 1, sizeof(svn_opt_revision_range_t *));
- range.start = *revision1;
- range.end = *revision2;
- APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *) = ⦥
+ APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *)
+ = svn_opt__revision_range_create(revision1, revision2, pool);
return svn_client_merge_peg3(source, ranges_to_merge,
peg_revision,
target_wcpath,