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 2010/11/17 01:09:55 UTC
svn commit: r1035869 [2/19] - in /subversion/branches/performance: ./ build/
build/generator/ build/generator/templates/ build/win32/
subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/bindings/ja...
Modified: subversion/branches/performance/subversion/bindings/swig/ruby/svn/fs.rb
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/swig/ruby/svn/fs.rb?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/swig/ruby/svn/fs.rb (original)
+++ subversion/branches/performance/subversion/bindings/swig/ruby/svn/fs.rb Wed Nov 17 00:09:50 2010
@@ -602,8 +602,13 @@ module Svn
@tempfile1 = Tempfile.new("svn_fs")
@tempfile2 = Tempfile.new("svn_fs")
- dump_contents(@tempfile1, @root1, @path1)
- dump_contents(@tempfile2, @root2, @path2)
+ begin
+ dump_contents(@tempfile1, @root1, @path1)
+ dump_contents(@tempfile2, @root2, @path2)
+ ensure
+ @tempfile1.close
+ @tempfile2.close
+ end
[@tempfile1, @tempfile2]
end
@@ -623,15 +628,10 @@ module Svn
end
private
- def dump_contents(tempfile, root, path)
+ def dump_contents(open_tempfile, root, path)
if root and path
- begin
- tempfile.open
- root.file_contents(path) do |stream|
- tempfile.print(stream.read)
- end
- ensure
- tempfile.close
+ root.file_contents(path) do |stream|
+ open_tempfile.print(stream.read)
end
end
end
Modified: subversion/branches/performance/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/include/private/svn_wc_private.h?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/performance/subversion/include/private/svn_wc_private.h Wed Nov 17 00:09:50 2010
@@ -612,14 +612,14 @@ svn_wc__node_get_info_bits(apr_time_t *t
/**
- * Acquire a recursive write lock for @a local_abspath or if @a lock_anchor
+ * Acquire a recursive write lock for @a local_abspath. If @a lock_anchor
* is true, determine if @a local_abspath has an anchor that should be locked
- * instead. Store the obtained lock in @a wc_ctx.
+ * instead; otherwise, @a local_abspath must be a versioned directory.
+ * Store the obtained lock in @a wc_ctx.
*
* If @a lock_root_abspath is not NULL, store the root of the lock in
* @a *lock_root_abspath. If @a lock_root_abspath is NULL, then @a
- * local_abspath must be a versioned directory and @a lock_anchor must be
- * FALSE.
+ * lock_anchor must be FALSE.
*
* Returns @c SVN_ERR_WC_LOCKED if an existing lock is encountered, in
* which case any locks acquired will have been released.
Modified: subversion/branches/performance/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/include/svn_client.h?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/include/svn_client.h (original)
+++ subversion/branches/performance/subversion/include/svn_client.h Wed Nov 17 00:09:50 2010
@@ -1189,6 +1189,9 @@ svn_client_checkout(svn_revnum_t *result
* If @a allow_unver_obstructions is FALSE then the update will abort
* if there are any unversioned obstructing items.
*
+ * If @a make_parents is TRUE, create any non-existent parent
+ * directories also by checking them out at depth=empty.
+ *
* If @a ctx->notify_func2 is non-NULL, invoke @a ctx->notify_func2 with
* @a ctx->notify_baton2 for each item handled by the update, and also for
* files restored from text-base. If @a ctx->cancel_func is non-NULL, invoke
@@ -1207,8 +1210,28 @@ svn_client_checkout(svn_revnum_t *result
* implementation, and allows for the possibility that different
* targets may come from different repositories.
*
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_client_update4(apr_array_header_t **result_revs,
+ const apr_array_header_t *paths,
+ const svn_opt_revision_t *revision,
+ svn_depth_t depth,
+ svn_boolean_t depth_is_sticky,
+ svn_boolean_t ignore_externals,
+ svn_boolean_t allow_unver_obstructions,
+ svn_boolean_t make_parents,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+/**
+ * Similar to svn_client_update4() but with @a make_parents always set
+ * to FALSE.
+ *
+ * @deprecated Provided for backward compatibility with the 1.6 API.
* @since New in 1.5.
*/
+SVN_DEPRECATED
svn_error_t *
svn_client_update3(apr_array_header_t **result_revs,
const apr_array_header_t *paths,
@@ -2177,7 +2200,7 @@ svn_client_status5(svn_revnum_t *result_
/**
* Same as svn_client_status5(), but using #svn_wc_status_func3_t
- * instead of #svn_wc_status_func4_t and depth_as_sticky set to TRUE.
+ * instead of #svn_client_status_func_t and depth_as_sticky set to TRUE.
*
* @since New in 1.6.
* @deprecated Provided for backward compatibility with the 1.6 API.
Modified: subversion/branches/performance/subversion/include/svn_error_codes.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/include/svn_error_codes.h?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/include/svn_error_codes.h (original)
+++ subversion/branches/performance/subversion/include/svn_error_codes.h Wed Nov 17 00:09:50 2010
@@ -219,6 +219,11 @@ SVN_ERROR_START
SVN_ERR_BAD_CATEGORY_START + 13,
"Unknown string value of token")
+ /** @since New in 1.7. */
+ SVN_ERRDEF(SVN_ERR_BAD_CHANGELIST_NAME,
+ SVN_ERR_BAD_CATEGORY_START + 14,
+ "Invalid changelist name")
+
/* xml errors */
SVN_ERRDEF(SVN_ERR_XML_ATTRIB_NOT_FOUND,
@@ -1391,6 +1396,10 @@ SVN_ERROR_START
SVN_ERR_CL_CATEGORY_START + 10,
"No external merge tool available")
+ SVN_ERRDEF(SVN_ERR_CL_ERROR_PROCESSING_EXTERNALS,
+ SVN_ERR_CL_CATEGORY_START + 11,
+ "Failed processing one or more externals definitions")
+
/* malfunctions such as assertion failures */
SVN_ERRDEF(SVN_ERR_ASSERTION_FAIL,
Modified: subversion/branches/performance/subversion/include/svn_path.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/include/svn_path.h?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/include/svn_path.h (original)
+++ subversion/branches/performance/subversion/include/svn_path.h Wed Nov 17 00:09:50 2010
@@ -64,6 +64,10 @@ extern "C" {
/** Convert @a path from the local style to the canonical internal style.
+ *
+ * New code should use either svn_dirent_internal_style() (for local paths) or
+ * svn_relpath_internal_style() (for relative paths).
+ *
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
SVN_DEPRECATED
@@ -71,6 +75,10 @@ const char *
svn_path_internal_style(const char *path, apr_pool_t *pool);
/** Convert @a path from the canonical internal style to the local style.
+ *
+ * New code should use either svn_dirent_local_style() (for local paths) or
+ * svn_relpath_local_style() (for relative paths).
+ *
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
SVN_DEPRECATED
@@ -101,6 +109,9 @@ svn_path_local_style(const char *path, a
* @a component won't be detected. An absolute URI can only be used
* for the base.
*
+ * New code should use either svn_dirent_join() (for local paths) or
+ * svn_uri_join() (for urls) or svn_relpath_join() (for relative paths).
+ *
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
SVN_DEPRECATED
@@ -118,7 +129,9 @@ svn_path_join(const char *base, const ch
* This function does not support URLs.
*
* See svn_path_join() for further notes about joining paths.
- *
+ *
+ * New code should use svn_dirent_join_many() instead.
+ *
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
SVN_DEPRECATED
@@ -139,7 +152,7 @@ svn_path_join_many(apr_pool_t *pool, con
* @note If an empty string is passed, then an empty string will be returned.
*
* New code should use either svn_dirent_basename() (for local paths) or
- * svn_uri_basename() (for urls and repository paths).
+ * svn_uri_basename() (for urls) or svn_relpath_basename (for relative paths).
*
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
@@ -154,7 +167,7 @@ svn_path_basename(const char *path, apr_
* The returned dirname will be allocated in @a pool.
*
* New code should use either svn_dirent_dirname() (for local paths) or
- * svn_uri_dirname() (for urls and repository paths).
+ * svn_uri_dirname() (for urls) or svn_relpath_dirname() (for relative paths).
*
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
@@ -227,7 +240,7 @@ svn_path_remove_components(svn_stringbuf
* - <pre>"" ==> "" and ""</pre>
*
* New code should use either svn_dirent_split() (for local paths) or
- * svn_uri_split() (for urls and repository paths).
+ * svn_uri_split() (for urls) or svn_relpath_split() (for relative paths).
*
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
@@ -266,6 +279,10 @@ svn_dirent_is_root(const char *dirent, a
* The returned path may be statically allocated, equal to @a path, or
* allocated from @a pool.
*
+ * New code should use either svn_dirent_canonicalize() (for local paths) or
+ * svn_uri_canonicalize() (for urls) or svn_relpath_canonicalize() (for
+ * relative paths).
+ *
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
SVN_DEPRECATED
@@ -275,6 +292,10 @@ svn_path_canonicalize(const char *path,
/** Return @c TRUE iff path is canonical. Use @a pool for temporary
* allocations.
*
+ * New code should use either svn_dirent_is_canonical() (for local paths) or
+ * svn_uri_is_canonical() (for urls) or svn_relpath_is_canonical() (for
+ * relative paths).
+ *
* @since New in 1.5.
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
@@ -300,6 +321,10 @@ svn_path_compare_paths(const char *path1
* different resources), and (b) share a common ancestor in their path
* component, i.e. 'protocol://' is not a sufficient ancestor.
*
+ * New code should use either svn_dirent_get_longest_ancestor()
+ * (for local paths) or svn_uri_get_longest_ancestor() (for urls)
+ * or svn_relpath_get_longest_ancestor() (for relative paths).
+ *
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
SVN_DEPRECATED
@@ -314,6 +339,8 @@ svn_path_get_longest_ancestor(const char
* @a relative may be a URL, in which case no attempt is made to convert it,
* and a copy of the URL is returned.
*
+ * New code should use svn_dirent_get_absolute() instead.
+ *
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
SVN_DEPRECATED
@@ -365,6 +392,9 @@ svn_path_split_if_file(const char *path,
* If there are no items in @a targets, set @a *pcommon and (if
* applicable) @a *pcondensed_targets to @c NULL.
*
+ * New code should use either svn_dirent_condense_targets() (for local paths)
+ * or svn_uri_condense_targets() (for urls).
+ *
* @note There is no guarantee that @a *pcommon is within a working
* copy.
*
@@ -489,6 +519,10 @@ svn_path_is_dotpath_present(const char *
* in which case a pointer into @a path2 will be returned to
* identify the remainder path.
*
+ * New code should use either svn_dirent_is_child() (for local paths) or
+ * svn_uri_is_child() (for urls) or svn_relpath_is_child()
+ * (for relative paths).
+ *
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
SVN_DEPRECATED
@@ -499,6 +533,11 @@ svn_path_is_child(const char *path1, con
* and FALSE otherwise.
*
* @since New in 1.3.
+ *
+ * New code should use either svn_dirent_is_ancestor() (for local paths) or
+ * svn_uri_is_ancestor() (for urls) or svn_relpath_is_ancestor() (for relative
+ * paths).
+ *
* @deprecated Provided for backward compatibility with the 1.6 API.
*/
SVN_DEPRECATED
@@ -584,7 +623,7 @@ svn_path_url_add_component2(const char *
const char *component,
apr_pool_t *pool);
-/** Like svn_path_url_add_component2, but allows path components that
+/** Like svn_path_url_add_component2(), but allows path components that
* end with a trailing '/'
*
* @deprecated Provided for backward compatibility with the 1.5 API.
Modified: subversion/branches/performance/subversion/include/svn_types.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/include/svn_types.h?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/include/svn_types.h (original)
+++ subversion/branches/performance/subversion/include/svn_types.h Wed Nov 17 00:09:50 2010
@@ -183,13 +183,13 @@ svn_node_kind_from_word(const char *word
/** Generic three-state property to represent an unknown value for values
* that are just like booleans. The values have been set deliberately to
- * make tristates mainly compatible with #svn_boolean_t.
+ * make tristates disjoint from #svn_boolean_t.
*
* @since New in 1.7. */
typedef enum
{
- svn_tristate_false = FALSE,
- svn_tristate_true = TRUE,
+ svn_tristate_false = 2,
+ svn_tristate_true,
svn_tristate_unknown
} svn_tristate_t;
Modified: subversion/branches/performance/subversion/libsvn_client/changelist.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/changelist.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/changelist.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/changelist.c Wed Nov 17 00:09:50 2010
@@ -107,6 +107,10 @@ svn_client_add_to_changelist(const apr_a
apr_hash_t *changelist_hash = NULL;
int i;
+ if (changelist[0] == '\0')
+ return svn_error_create(SVN_ERR_BAD_CHANGELIST_NAME, NULL,
+ _("Target changelist name must not be empty"));
+
for (i = 0; i < paths->nelts; i++)
{
const char *path = APR_ARRAY_IDX(paths, i, const char *);
Modified: subversion/branches/performance/subversion/libsvn_client/checkout.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/checkout.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/checkout.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/checkout.c Wed Nov 17 00:09:50 2010
@@ -218,7 +218,7 @@ svn_client__checkout_internal(svn_revnum
revision, depth, TRUE,
ignore_externals,
allow_unver_obstructions,
- use_sleep, innercheckout,
+ use_sleep, innercheckout, FALSE,
ctx, pool);
if (err)
Modified: subversion/branches/performance/subversion/libsvn_client/cleanup.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/cleanup.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/cleanup.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/cleanup.c Wed Nov 17 00:09:50 2010
@@ -163,11 +163,9 @@ svn_client_upgrade(const char *path,
externals_p = apr_array_make(iterpool, 1,
sizeof(svn_wc_external_item2_t*));
- SVN_ERR(svn_wc_parse_externals_description3(&externals_p,
- svn_dirent_dirname(path,
- iterpool),
- external_desc->data, TRUE,
- iterpool));
+ SVN_ERR(svn_wc_parse_externals_description3(
+ &externals_p, svn_dirent_dirname(path, iterpool),
+ external_desc->data, TRUE, iterpool));
for (i = 0; i < externals_p->nelts; i++)
{
svn_wc_external_item2_t *item;
Modified: subversion/branches/performance/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/client.h?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/client.h (original)
+++ subversion/branches/performance/subversion/libsvn_client/client.h Wed Nov 17 00:09:50 2010
@@ -39,34 +39,16 @@
extern "C" {
#endif /* __cplusplus */
-struct svn_cl__externals_store
-{
- apr_pool_t *pool;
- apr_hash_t *externals_old;
- apr_hash_t *externals_new;
- apr_hash_t *depths;
-};
-
-/* svn_wc_external_update_t handler, storing the received data in a
- * svn_cl__externals_store instance, which must be passed as baton.
- * When one of the hashes is NULL, these values are not stored */
-svn_error_t *
-svn_cl__store_externals(void *baton,
- const char *local_abspath,
- const svn_string_t *old_value,
- const svn_string_t *new_value,
- svn_depth_t depth,
- apr_pool_t *scratch_pool);
-
-
-/* Set *URL, allocated in RESULT_POOL, and *PEG_REVNUM (the latter is
- ignored if NULL) to the repository URL of ABSPATH_OR_URL. If
+/* Set *URL and *PEG_REVNUM (the latter is ignored if NULL) to the
+ repository URL of ABSPATH_OR_URL as found in revision PEG_REVISION.
+ If PEG_REVISION->kind is svn_opt_revision_unspecified, use the head
+ revision for a URL or the working revision for a local path. If
ABSPATH_OR_URL is an absolute WC path and PEG_REVISION->kind is
svn_opt_revision_working, use the corresponding entry's copyfrom info.
RA_SESSION may be NULL regardless of whether ABSPATH_OR_URL is a URL.
- Use CTX for cancellation (ignored if NULL), and SCRATCH_POOL for all
- temporary allocations. */
+ Use CTX for authentication and for a working copy context. Allocate
+ *URL in RESULT_POOL. Use SCRATCH_POOL for temporary allocations. */
svn_error_t *
svn_client__derive_location(const char **url,
svn_revnum_t *peg_revnum,
@@ -91,7 +73,8 @@ svn_client__derive_location(const char *
If PEG_REV_NUM is svn_opt_revision_unspecified, svn_opt_revision_number,
svn_opt_revision_base, or svn_opt_revision_working then set *REVNUM
- to the base revision. */
+ to the base revision.
+ ### What's up with this last paragraph? Sounds all wrong. */
svn_error_t *
svn_client__entry_location(const char **url,
svn_revnum_t *revnum,
@@ -491,6 +474,12 @@ svn_client__make_local_parents(const cha
these obstructions cause the update to fail.
If INNERUPDATE is true, no anchor check is performed on the update target.
+
+ If MAKE_PARENTS is true, allow the update to calculate and checkout
+ (with depth=empty) any parent directories of the requested update
+ target which are missing from the working copy.
+
+ NOTE: You may not specify both INNERUPDATE and MAKE_PARENTS as true.
*/
svn_error_t *
svn_client__update_internal(svn_revnum_t *result_rev,
@@ -502,6 +491,7 @@ svn_client__update_internal(svn_revnum_t
svn_boolean_t allow_unver_obstructions,
svn_boolean_t *timestamp_sleep,
svn_boolean_t innerupdate,
+ svn_boolean_t make_parents,
svn_client_ctx_t *ctx,
apr_pool_t *pool);
@@ -912,7 +902,6 @@ svn_client__do_commit(const char *base_u
/*** Externals (Modules) ***/
/* Handle changes to the svn:externals property described by EXTERNALS_OLD,
-
EXTERNALS_NEW, and AMBIENT_DEPTHS. The tree's top level directory
is at TO_ABSPATH and corresponds to FROM_URL URL in the repository,
which has a root URL of REPOS_ROOT_URL. A write lock should be
@@ -1004,6 +993,44 @@ svn_client__do_external_status(svn_clien
void *status_baton,
apr_pool_t *pool);
+/* Set *EXTERNALS_P to a hash mapping const char * local absolute
+ paths to const svn_string_t * svn:externals property values, those
+ found by crawling LOCAL_ABSPATH to DEPTH. */
+svn_error_t *
+svn_client__crawl_for_externals(apr_hash_t **externals_p,
+ const char *local_abspath,
+ svn_depth_t depth,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool,
+ apr_pool_t *result_pool);
+
+/* Baton type for svn_wc__external_info_gatherer(). */
+typedef struct svn_client__external_func_baton_t
+{
+ apr_hash_t *externals_old; /* Hash of old externals property values,
+ or NULL if the caller doesn't care. */
+ apr_hash_t *externals_new; /* Hash of new externals property values,
+ or NULL if the caller doesn't care. */
+ apr_hash_t *ambient_depths; /* Hash of ambient depth values, or NULL
+ if the caller doesn't care. */
+ apr_pool_t *result_pool; /* Pool to use for all stored values. */
+
+} svn_client__external_func_baton_t;
+
+
+/* This function gets invoked whenever external changes are encountered.
+ This implements the `svn_wc_external_update_t' interface, and can
+ be used with an svn_client__external_func_baton_t BATON to gather
+ information about changes to externals definitions. */
+svn_error_t *
+svn_client__external_info_gatherer(void *baton,
+ const char *local_abspath,
+ const svn_string_t *old_val,
+ const svn_string_t *new_val,
+ svn_depth_t depth,
+ apr_pool_t *scratch_pool);
+
+
/* Retrieve log messages using the first provided (non-NULL) callback
@@ -1081,30 +1108,6 @@ svn_cl__rev_default_to_peg(const svn_opt
const svn_opt_revision_t *peg_revision);
-/* Some external traversal helpers.
- */
-/* This function gets invoked whenever external changes are encountered.
- This implements svn_wc_external_update_t */
-svn_error_t *
-svn_client__external_info_gatherer(void *baton,
- const char *local_abspath,
- const svn_string_t *old_val,
- const svn_string_t *new_val,
- svn_depth_t depth,
- apr_pool_t *scratch_pool);
-
-/* Baton type for svn_wc__external_info_gatherer(). All fields must be
- populated before use. */
-typedef struct svn_client__external_func_baton_t
-{
- apr_hash_t *externals_old;
- apr_hash_t *externals_new;
- apr_hash_t *ambient_depths;
-
- apr_pool_t *result_pool;
-} svn_client__external_func_baton_t;
-
-
#ifdef __cplusplus
Modified: subversion/branches/performance/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/deprecated.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/deprecated.c Wed Nov 17 00:09:50 2010
@@ -1796,6 +1796,22 @@ svn_client_status(svn_revnum_t *result_r
/*** From update.c ***/
svn_error_t *
+svn_client_update3(apr_array_header_t **result_revs,
+ const apr_array_header_t *paths,
+ const svn_opt_revision_t *revision,
+ svn_depth_t depth,
+ svn_boolean_t depth_is_sticky,
+ svn_boolean_t ignore_externals,
+ svn_boolean_t allow_unver_obstructions,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ return svn_client_update4(result_revs, paths, revision,
+ depth, depth_is_sticky, ignore_externals,
+ allow_unver_obstructions, FALSE, ctx, pool);
+}
+
+svn_error_t *
svn_client_update2(apr_array_header_t **result_revs,
const apr_array_header_t *paths,
const svn_opt_revision_t *revision,
Modified: subversion/branches/performance/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/externals.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/externals.c Wed Nov 17 00:09:50 2010
@@ -204,7 +204,7 @@ switch_dir_external(const char *path,
SVN_ERR(svn_client__update_internal(NULL, local_abspath,
revision, svn_depth_unknown,
FALSE, FALSE, FALSE,
- timestamp_sleep, TRUE,
+ timestamp_sleep, TRUE, FALSE,
ctx, subpool));
svn_pool_destroy(subpool);
return SVN_NO_ERROR;
@@ -1392,70 +1392,86 @@ svn_client__do_external_status(svn_clien
return SVN_NO_ERROR;
}
-/* Implements svn_wc_externals_update_t */
+
+/* Implements the `svn_wc_externals_update_t' interface. */
svn_error_t *
-svn_cl__store_externals(void *baton,
- const char *local_abspath,
- const svn_string_t *old_value,
- const svn_string_t *new_value,
- svn_depth_t depth,
- apr_pool_t *scratch_pool)
+svn_client__external_info_gatherer(void *baton,
+ const char *local_abspath,
+ const svn_string_t *old_value,
+ const svn_string_t *new_value,
+ svn_depth_t depth,
+ apr_pool_t *scratch_pool)
{
- struct svn_cl__externals_store *eb = baton;
- apr_pool_t *dup_pool = eb->pool;
+ svn_client__external_func_baton_t *efb = baton;
+
+ local_abspath = apr_pstrdup(efb->result_pool, local_abspath);
- local_abspath = apr_pstrdup(dup_pool, local_abspath);
+ if (efb->externals_old != NULL && old_value != NULL)
+ apr_hash_set(efb->externals_old, local_abspath, APR_HASH_KEY_STRING,
+ apr_pstrndup(efb->result_pool,
+ old_value->data, old_value->len));
+
+ if (efb->externals_new != NULL && new_value != NULL)
+ apr_hash_set(efb->externals_new, local_abspath, APR_HASH_KEY_STRING,
+ apr_pstrndup(efb->result_pool,
+ new_value->data, new_value->len));
- if (eb->externals_old != NULL && old_value != NULL)
- apr_hash_set(eb->externals_new,
- local_abspath, APR_HASH_KEY_STRING,
- apr_pstrndup(dup_pool, old_value->data, old_value->len));
-
- if (eb->externals_new != NULL && new_value != NULL)
- apr_hash_set(eb->externals_new,
- local_abspath, APR_HASH_KEY_STRING,
- apr_pstrndup(dup_pool, new_value->data, new_value->len));
-
- if (eb->depths != NULL)
- apr_hash_set(eb->depths,
- local_abspath, APR_HASH_KEY_STRING,
+ if (efb->ambient_depths != NULL)
+ apr_hash_set(efb->ambient_depths, local_abspath, APR_HASH_KEY_STRING,
svn_depth_to_word(depth));
return SVN_NO_ERROR;
}
-
-svn_error_t *
-svn_client__external_info_gatherer(void *baton,
- const char *local_abspath,
- const svn_string_t *old_val,
- const svn_string_t *new_val,
- svn_depth_t depth,
- apr_pool_t *scratch_pool)
+/* Callback of type svn_wc_external_update_t. Just squirrels away an
+ svn:externals property value into BATON (which is an apr_hash_t *
+ keyed on local absolute path). */
+static svn_error_t *
+externals_update_func(void *baton,
+ const char *local_abspath,
+ const svn_string_t *old_val,
+ const svn_string_t *new_val,
+ svn_depth_t depth,
+ apr_pool_t *scratch_pool)
{
- svn_client__external_func_baton_t *efb = baton;
- const char *dup_val = NULL;
- const char *dup_path = apr_pstrdup(efb->result_pool, local_abspath);
+ apr_hash_t *externals_hash = baton;
+ apr_pool_t *hash_pool = apr_hash_pool_get(externals_hash);
- if (old_val)
- {
- dup_val = apr_pstrmemdup(efb->result_pool, old_val->data, old_val->len);
+ apr_hash_set(externals_hash, apr_pstrdup(hash_pool, local_abspath),
+ APR_HASH_KEY_STRING, svn_string_dup(new_val, hash_pool));
+ return SVN_NO_ERROR;
+}
- apr_hash_set(efb->externals_old, dup_path, APR_HASH_KEY_STRING, dup_val);
- }
- if (new_val)
- {
- /* In most cases the value is identical */
- if (old_val != new_val)
- dup_val = apr_pstrmemdup(efb->result_pool, new_val->data, new_val->len);
+/* Callback of type svn_wc_status_func4_t. Does nothing. */
+static svn_error_t *
+status_noop_func(void *baton,
+ const char *local_abspath,
+ const svn_wc_status3_t *status,
+ apr_pool_t *scratch_pool)
+{
+ return SVN_NO_ERROR;
+}
- apr_hash_set(efb->externals_new, dup_path, APR_HASH_KEY_STRING, dup_val);
- }
- apr_hash_set(efb->ambient_depths, dup_path, APR_HASH_KEY_STRING,
- svn_depth_to_word(depth));
+svn_error_t *
+svn_client__crawl_for_externals(apr_hash_t **externals_p,
+ const char *local_abspath,
+ svn_depth_t depth,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool,
+ apr_pool_t *result_pool)
+{
+ apr_hash_t *externals_hash = apr_hash_make(result_pool);
+
+ /* Do a status run just to harvest externals definitions. */
+ SVN_ERR(svn_wc_walk_status(ctx->wc_ctx, local_abspath, depth,
+ FALSE, FALSE, NULL, status_noop_func, NULL,
+ externals_update_func, externals_hash,
+ ctx->cancel_func, ctx->cancel_baton,
+ scratch_pool));
+ *externals_p = externals_hash;
return SVN_NO_ERROR;
}
Modified: subversion/branches/performance/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/patch.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/patch.c Wed Nov 17 00:09:50 2010
@@ -203,6 +203,9 @@ typedef struct patch_target_t {
/* True if the patch changed any of the properties of the target. */
svn_boolean_t has_prop_changes;
+ /* True if the patch contained a svn:special property. */
+ svn_boolean_t is_special;
+
/* All the information that is specific to the content of the target. */
target_content_info_t *content_info;
@@ -235,7 +238,7 @@ strip_path(const char **result, const ch
apr_array_header_t *stripped;
components = svn_path_decompose(path, scratch_pool);
- if (strip_count >= components->nelts)
+ if (strip_count > components->nelts)
return svn_error_createf(SVN_ERR_CLIENT_PATCH_BAD_STRIP_COUNT, NULL,
_("Cannot strip %u components from '%s'"),
strip_count,
@@ -1609,44 +1612,6 @@ send_patch_notification(const patch_targ
return SVN_NO_ERROR;
}
-/* Close the streams of the TARGET so that their content is flushed
- * to disk. This will also close underlying streams and files. Use POOL for
- * temporary allocations. */
-static svn_error_t *
-close_target_streams(const patch_target_t *target,
- apr_pool_t *pool)
-{
- apr_hash_index_t *hi;
- target_content_info_t *prop_content_info;
-
- /* First the streams belonging to properties .. */
- for (hi = apr_hash_first(pool, target->prop_targets);
- hi;
- hi = apr_hash_next(hi))
- {
- prop_patch_target_t *prop_target;
- prop_target = svn__apr_hash_index_val(hi);
- prop_content_info = prop_target->content_info;
-
- /* ### If the prop did not exist pre-patching we'll not have a
- * ### stream to read from. Find a better way to store info on
- * ### the existence of the target prop. */
- if (prop_content_info->stream)
- SVN_ERR(svn_stream_close(prop_content_info->stream));
-
- SVN_ERR(svn_stream_close(prop_content_info->patched));
- }
-
- /* .. and then streams associated with the file.
- * ### We're not closing the reject stream -- it still needed and
- * ### will be closed later in write_out_rejected_hunks(). */
- if (target->kind_on_disk == svn_node_file)
- SVN_ERR(svn_stream_close(target->content_info->stream));
- SVN_ERR(svn_stream_close(target->content_info->patched));
-
- return SVN_NO_ERROR;
-}
-
/* Apply a PATCH to a working copy at ABS_WC_PATH and put the result
* into temporary files, to be installed in the working copy later.
* Return information about the patch target in *PATCH_TARGET, allocated
@@ -1675,6 +1640,7 @@ apply_one_patch(patch_target_t **patch_t
int i;
static const int MAX_FUZZ = 2;
apr_hash_index_t *hash_index;
+ target_content_info_t *prop_content_info;
SVN_ERR(init_patch_target(&target, patch, abs_wc_path, wc_ctx, strip_count,
remove_tempfiles, result_pool, scratch_pool));
@@ -1773,6 +1739,9 @@ apply_one_patch(patch_target_t **patch_t
prop_name = svn__apr_hash_index_key(hash_index);
prop_patch = svn__apr_hash_index_val(hash_index);
+ if (! strcmp(prop_name, SVN_PROP_SPECIAL))
+ target->is_special = TRUE;
+
/* We'll store matched hunks in prop_content_info. */
prop_target = apr_hash_get(target->prop_targets, prop_name,
APR_HASH_KEY_STRING);
@@ -1855,7 +1824,31 @@ apply_one_patch(patch_target_t **patch_t
svn_pool_destroy(iterpool);
- SVN_ERR(close_target_streams(target, scratch_pool));
+ /* Now close some streams that we don't need any longer to get
+ * file buffers flushed to disk. First, close the props streams... */
+ for (hash_index = apr_hash_first(scratch_pool, target->prop_targets);
+ hash_index;
+ hash_index = apr_hash_next(hash_index))
+ {
+ prop_patch_target_t *prop_target;
+ prop_target = svn__apr_hash_index_val(hash_index);
+ prop_content_info = prop_target->content_info;
+
+ /* ### If the prop did not exist pre-patching we'll not have a
+ * ### stream to read from. Find a better way to store info on
+ * ### the existence of the target prop. */
+ if (prop_content_info->stream)
+ SVN_ERR(svn_stream_close(prop_content_info->stream));
+
+ SVN_ERR(svn_stream_close(prop_content_info->patched));
+ }
+
+ /* .. and then streams associated with the file.
+ * But we're not closing the reject stream -- it still needed and
+ * will be closed later in write_out_rejected_hunks(). */
+ if (target->kind_on_disk == svn_node_file)
+ SVN_ERR(svn_stream_close(target->content_info->stream));
+ SVN_ERR(svn_stream_close(target->content_info->patched));
if (! target->skipped)
{
@@ -2118,9 +2111,33 @@ install_patched_target(patch_target_t *t
if (! dry_run && ! target->skipped)
{
- /* Copy the patched file on top of the target file. */
- SVN_ERR(svn_io_copy_file(target->patched_path,
- target->local_abspath, FALSE, pool));
+ if (target->is_special)
+ {
+ svn_stream_t *stream;
+ svn_stream_t *patched_stream;
+ apr_file_t *file;
+
+ SVN_ERR(svn_io_file_open(&file, target->patched_path,
+ APR_READ | APR_BINARY, APR_OS_DEFAULT,
+ pool));
+
+ patched_stream = svn_stream_from_aprfile2(file, FALSE /* disown */,
+ pool);
+ SVN_ERR(svn_subst_create_specialfile(&stream,
+ target->local_abspath,
+ pool, pool));
+ SVN_ERR(svn_stream_copy3(patched_stream, stream,
+ NULL, /* cancel_func */
+ NULL, /* cancel_baton */
+ pool));
+ }
+ else
+ {
+ /* Copy the patched file on top of the target file. */
+ SVN_ERR(svn_io_copy_file(target->patched_path,
+ target->local_abspath, FALSE, pool));
+ }
+
if (target->added || target->replaced)
{
/* The target file didn't exist previously,
@@ -2736,6 +2753,12 @@ svn_client_patch(const char *patch_abspa
return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
_("strip count must be positive"));
+ if (svn_path_is_url(local_abspath))
+ return svn_error_return(svn_error_createf(SVN_ERR_ILLEGAL_TARGET,
+ NULL,
+ _("'%s' is not a local path"),
+ local_abspath));
+
baton.patch_abspath = patch_abspath;
baton.abs_wc_path = local_abspath;
baton.dry_run = dry_run;
Modified: subversion/branches/performance/subversion/libsvn_client/relocate.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/relocate.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/relocate.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/relocate.c Wed Nov 17 00:09:50 2010
@@ -126,37 +126,6 @@ validator_func(void *baton,
}
-/* Callback of type svn_wc_external_update_t. Just squirrels away an
- svn:externals property value into BATON (which is an apr_hash_t *
- keyed on local absolute path). */
-static svn_error_t *
-externals_update_func(void *baton,
- const char *local_abspath,
- const svn_string_t *old_val,
- const svn_string_t *new_val,
- svn_depth_t depth,
- apr_pool_t *scratch_pool)
-{
- apr_hash_t *externals_hash = baton;
- apr_pool_t *hash_pool = apr_hash_pool_get(externals_hash);
-
- apr_hash_set(externals_hash, apr_pstrdup(hash_pool, local_abspath),
- APR_HASH_KEY_STRING, svn_string_dup(new_val, hash_pool));
- return SVN_NO_ERROR;
-}
-
-
-/* Callback of type svn_wc_status_func4_t. Does nothing. */
-static svn_error_t *
-status_noop_func(void *baton,
- const char *local_abspath,
- const svn_wc_status3_t *status,
- apr_pool_t *scratch_pool)
-{
- return SVN_NO_ERROR;
-}
-
-
/* Examing the array of svn_wc_external_item2_t's EXT_DESC (parsed
from the svn:externals property set on LOCAL_ABSPATH) and determine
if the external working copies described by such should be
@@ -270,16 +239,10 @@ svn_client_relocate2(const char *wcroot_
SVN_ERR(svn_client_root_url_from_path(&new_repos_root_url, local_abspath,
ctx, pool));
- externals_hash = apr_hash_make(pool);
-
- /* Do a status run just to harvest externals definitions. */
- SVN_ERR(svn_wc_walk_status(ctx->wc_ctx, local_abspath,
- svn_depth_infinity, FALSE, FALSE, NULL,
- status_noop_func, NULL,
- externals_update_func, externals_hash,
- ctx->cancel_func, ctx->cancel_baton, pool));
- /* No externals? No problem. We're done here. */
+ /* Relocate externals, too (if any). */
+ SVN_ERR(svn_client__crawl_for_externals(&externals_hash, local_abspath,
+ svn_depth_infinity, ctx, pool, pool));
if (! apr_hash_count(externals_hash))
return SVN_NO_ERROR;
Modified: subversion/branches/performance/subversion/libsvn_client/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/status.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/status.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/status.c Wed Nov 17 00:09:50 2010
@@ -267,7 +267,7 @@ svn_client_status5(svn_revnum_t *result_
apr_array_header_t *ignores;
svn_error_t *err;
apr_hash_t *changelist_hash = NULL;
- struct svn_cl__externals_store externals_store = { NULL };
+ struct svn_client__external_func_baton_t externals_store = { NULL };
if (svn_path_is_url(path))
return svn_error_return(svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
@@ -357,7 +357,7 @@ svn_client_status5(svn_revnum_t *result_
if (!ignore_externals)
{
- externals_store.pool = pool;
+ externals_store.result_pool = pool;
externals_store.externals_new = apr_hash_make(pool);
}
@@ -393,10 +393,10 @@ svn_client_status5(svn_revnum_t *result_
dir_abspath, target_basename,
depth, get_all,
no_ignore, ignores, tweak_status, &sb,
- ignore_externals ? NULL
- : svn_cl__store_externals,
- ignore_externals ? NULL
- : &externals_store,
+ ignore_externals
+ ? NULL
+ : svn_client__external_info_gatherer,
+ ignore_externals ? NULL : &externals_store,
ctx->cancel_func, ctx->cancel_baton,
pool, pool));
@@ -517,10 +517,10 @@ svn_client_status5(svn_revnum_t *result_
err = svn_wc_walk_status(ctx->wc_ctx, target_abspath,
depth, get_all, no_ignore, ignores,
tweak_status, &sb,
- ignore_externals ? NULL
- : svn_cl__store_externals,
- ignore_externals ? NULL
- : &externals_store,
+ ignore_externals
+ ? NULL
+ : svn_client__external_info_gatherer,
+ ignore_externals ? NULL : &externals_store,
ctx->cancel_func, ctx->cancel_baton,
pool);
Modified: subversion/branches/performance/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/update.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/update.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/update.c Wed Nov 17 00:09:50 2010
@@ -44,7 +44,18 @@
/*** Code. ***/
-
+/* This is a helper for svn_client__update_internal(), which see for
+ an explanation of most of these parameters. Some stuff that's
+ unique is as follows:
+
+ ANCHOR_ABSPATH is the local absolute path of the update anchor.
+ This is typically either the same as LOCAL_ABSPATH, or the
+ immediate parent of LOCAL_ABSPATH.
+
+ If NOTIFY_SUMMARY is set (and there's a notification hander in
+ CTX), transmit the final update summary upon successful
+ completion of the update.
+*/
static svn_error_t *
update_internal(svn_revnum_t *result_rev,
const char *local_abspath,
@@ -56,6 +67,7 @@ update_internal(svn_revnum_t *result_rev
svn_boolean_t allow_unver_obstructions,
svn_boolean_t *timestamp_sleep,
svn_boolean_t innerupdate,
+ svn_boolean_t notify_summary,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
@@ -235,8 +247,8 @@ update_internal(svn_revnum_t *result_rev
if (sleep_here)
svn_io_sleep_for_timestamps(local_abspath, pool);
- /* Let everyone know we're finished here. */
- if (ctx->notify_func2)
+ /* Let everyone know we're finished here (unless we're asked not to). */
+ if (ctx->notify_func2 && notify_summary)
{
svn_wc_notify_t *notify
= svn_wc_create_notify(local_abspath, svn_wc_notify_update_completed,
@@ -266,44 +278,99 @@ svn_client__update_internal(svn_revnum_t
svn_boolean_t allow_unver_obstructions,
svn_boolean_t *timestamp_sleep,
svn_boolean_t innerupdate,
+ svn_boolean_t make_parents,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- const char *anchor_abspath;
+ const char *anchor_abspath, *lockroot_abspath;
svn_error_t *err;
+ svn_opt_revision_t peg_revision = *((svn_opt_revision_t *)revision);
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+ SVN_ERR_ASSERT(! (innerupdate && make_parents));
+
+ if (make_parents)
+ {
+ int i;
+ const char *parent_abspath = local_abspath;
+ apr_array_header_t *missing_parents =
+ apr_array_make(pool, 4, sizeof(const char *));
+
+ while (1)
+ {
+ /* Try to lock. If we can't lock because our target (or its
+ parent) isn't a working copy, we'll try to walk up the
+ tree to find a working copy, remembering this path's
+ parent as one we need to flesh out. */
+ err = svn_wc__acquire_write_lock(&lockroot_abspath, ctx->wc_ctx,
+ parent_abspath, !innerupdate,
+ pool, pool);
+ if (!err)
+ break;
+ if ((err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
+ || svn_dirent_is_root(parent_abspath, strlen(parent_abspath)))
+ return err;
+ svn_error_clear(err);
+
+ /* Remember the parent of our update target as a missing
+ parent. */
+ parent_abspath = svn_dirent_dirname(parent_abspath, pool);
+ APR_ARRAY_PUSH(missing_parents, const char *) = parent_abspath;
+ }
+
+ /* Run 'svn up --depth=empty' (effectively) on the missing
+ parents, if any. */
+ anchor_abspath = lockroot_abspath;
+ for (i = missing_parents->nelts - 1; i >= 0; i--)
+ {
+ const char *missing_parent =
+ APR_ARRAY_IDX(missing_parents, i, const char *);
+ err = update_internal(result_rev, missing_parent, anchor_abspath,
+ &peg_revision, svn_depth_empty, FALSE,
+ ignore_externals, allow_unver_obstructions,
+ timestamp_sleep, innerupdate, FALSE,
+ ctx, pool);
+ if (err)
+ goto cleanup;
+ anchor_abspath = missing_parent;
- if (!innerupdate)
- SVN_ERR(svn_wc__acquire_write_lock(&anchor_abspath,
- ctx->wc_ctx, local_abspath, TRUE,
- pool, pool));
+ /* If we successfully updated a missing parent, let's re-use
+ the returned revision number for future updates for the
+ sake of consistency. */
+ peg_revision.kind = svn_opt_revision_number;
+ peg_revision.value.number = *result_rev;
+ }
+ }
else
- SVN_ERR(svn_wc__acquire_write_lock(&anchor_abspath,
- ctx->wc_ctx, local_abspath, FALSE,
- pool, pool));
+ {
+ SVN_ERR(svn_wc__acquire_write_lock(&lockroot_abspath, ctx->wc_ctx,
+ local_abspath, !innerupdate,
+ pool, pool));
+ anchor_abspath = lockroot_abspath;
+ }
err = update_internal(result_rev, local_abspath, anchor_abspath,
- revision, depth, depth_is_sticky,
- ignore_externals, allow_unver_obstructions,
- timestamp_sleep, innerupdate, ctx, pool);
-
+ &peg_revision, depth, depth_is_sticky,
+ ignore_externals, allow_unver_obstructions,
+ timestamp_sleep, innerupdate, TRUE, ctx, pool);
+ cleanup:
err = svn_error_compose_create(
err,
- svn_wc__release_write_lock(ctx->wc_ctx, anchor_abspath, pool));
+ svn_wc__release_write_lock(ctx->wc_ctx, lockroot_abspath, pool));
return svn_error_return(err);
}
svn_error_t *
-svn_client_update3(apr_array_header_t **result_revs,
+svn_client_update4(apr_array_header_t **result_revs,
const apr_array_header_t *paths,
const svn_opt_revision_t *revision,
svn_depth_t depth,
svn_boolean_t depth_is_sticky,
svn_boolean_t ignore_externals,
svn_boolean_t allow_unver_obstructions,
+ svn_boolean_t make_parents,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
@@ -340,7 +407,8 @@ svn_client_update3(apr_array_header_t **
revision, depth, depth_is_sticky,
ignore_externals,
allow_unver_obstructions,
- &sleep, FALSE, ctx, subpool);
+ &sleep, FALSE, make_parents,
+ ctx, subpool);
if (err && err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
{
Modified: subversion/branches/performance/subversion/libsvn_diff/diff_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_diff/diff_file.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/branches/performance/subversion/libsvn_diff/diff_file.c Wed Nov 17 00:09:50 2010
@@ -563,12 +563,42 @@ svn_diff_file_options_create(apr_pool_t
return apr_pcalloc(pool, sizeof(svn_diff_file_options_t));
}
+/* A baton for use with opt_parsing_error_func(). */
+struct opt_parsing_error_baton_t
+{
+ svn_error_t *err;
+ apr_pool_t *pool;
+};
+
+/* Store an error message from apr_getopt_long(). Set BATON->err to a new
+ * error with a message generated from FMT and the remaining arguments.
+ * Implements apr_getopt_err_fn_t. */
+static void
+opt_parsing_error_func(void *baton,
+ const char *fmt, ...)
+{
+ struct opt_parsing_error_baton_t *b = baton;
+ const char *message;
+ va_list ap;
+
+ va_start(ap, fmt);
+ message = apr_pvsprintf(b->pool, fmt, ap);
+ va_end(ap);
+
+ /* Skip leading ": " (if present, which it always is in known cases). */
+ if (strncmp(message, ": ", 2) == 0)
+ message += 2;
+
+ b->err = svn_error_create(SVN_ERR_INVALID_DIFF_OPTION, NULL, message);
+}
+
svn_error_t *
svn_diff_file_options_parse(svn_diff_file_options_t *options,
const apr_array_header_t *args,
apr_pool_t *pool)
{
apr_getopt_t *os;
+ struct opt_parsing_error_baton_t opt_parsing_error_baton = { NULL, pool };
/* Make room for each option (starting at index 1) plus trailing NULL. */
const char **argv = apr_palloc(pool, sizeof(char*) * (args->nelts + 2));
@@ -577,8 +607,12 @@ svn_diff_file_options_parse(svn_diff_fil
argv[args->nelts + 1] = NULL;
apr_getopt_init(&os, pool, args->nelts + 1, argv);
- /* No printing of error messages, please! */
- os->errfn = NULL;
+
+ /* Capture any error message from apr_getopt_long(). This will typically
+ * say which option is wrong, which we would not otherwise know. */
+ os->errfn = opt_parsing_error_func;
+ os->errarg = &opt_parsing_error_baton;
+
while (1)
{
const char *opt_arg;
@@ -588,7 +622,13 @@ svn_diff_file_options_parse(svn_diff_fil
if (APR_STATUS_IS_EOF(err))
break;
if (err)
- return svn_error_wrap_apr(err, _("Error parsing diff options"));
+ /* Wrap apr_getopt_long()'s error message. Its doc string implies
+ * it always will produce one, but never mind if it doesn't. Avoid
+ * using the message associated with the return code ERR, because
+ * it refers to the "command line" which may be misleading here. */
+ return svn_error_create(SVN_ERR_INVALID_DIFF_OPTION,
+ opt_parsing_error_baton.err,
+ _("Error in options to internal diff"));
switch (opt_id)
{
Modified: subversion/branches/performance/subversion/libsvn_fs_fs/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/dag.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/dag.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/dag.c Wed Nov 17 00:09:50 2010
@@ -29,7 +29,6 @@
#include "svn_pools.h"
#include "dag.h"
-#include "err.h"
#include "fs.h"
#include "key-gen.h"
#include "fs_fs.h"
Modified: subversion/branches/performance/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/fs.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/fs.c Wed Nov 17 00:09:50 2010
@@ -34,7 +34,6 @@
#include "svn_version.h"
#include "svn_pools.h"
#include "fs.h"
-#include "err.h"
#include "fs_fs.h"
#include "tree.h"
#include "lock.h"
Modified: subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c Wed Nov 17 00:09:50 2010
@@ -51,7 +51,6 @@
#include "svn_ctype.h"
#include "fs.h"
-#include "err.h"
#include "tree.h"
#include "lock.h"
#include "key-gen.h"
@@ -2225,6 +2224,16 @@ read_rep_offsets(representation_t **rep_
return SVN_NO_ERROR;
}
+static svn_error_t *
+err_dangling_id(svn_fs_t *fs, const svn_fs_id_t *id)
+{
+ svn_string_t *id_str = svn_fs_fs__id_unparse(id, fs->pool);
+ return svn_error_createf
+ (SVN_ERR_FS_ID_NOT_FOUND, 0,
+ _("Reference to non-existent node '%s' in filesystem '%s'"),
+ id_str->data, fs->path);
+}
+
/* Combine the revision and offset of the ID to a string that will
* be used as a cache key. Allocations will be made from POOL.
*/
@@ -2332,7 +2341,7 @@ get_node_revision_body(node_revision_t *
if (APR_STATUS_IS_ENOENT(err->apr_err))
{
svn_error_clear(err);
- return svn_fs_fs__err_dangling_id(fs, id);
+ return svn_error_return(err_dangling_id(fs, id));
}
return svn_error_return(err);
@@ -7300,15 +7309,41 @@ recover_body(void *baton, apr_pool_t *po
SVN_ERR(svn_io_check_path(path_revprops(fs, max_rev, pool),
&youngest_revprops_kind, pool));
if (youngest_revprops_kind == svn_node_none)
- return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
- _("Revision %ld has a revs file but no "
- "revprops file"),
- max_rev);
+ {
+ svn_boolean_t uhohs = TRUE;
+
+ /* No file? Hrm... maybe that's because this repository is
+ packed and the youngest revision is in the revprops.db
+ file? We can at least see if that's a possibility.
+
+ ### TODO: Could we check for revprops in the revprops.db?
+ ### What if rNNN legitimately has no revprops? */
+ if (ffd->format >= SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
+ {
+ svn_revnum_t min_unpacked_revprop;
+ const char *min_unpacked_revprop_path =
+ svn_dirent_join(fs->path, PATH_MIN_UNPACKED_REVPROP, pool);
+
+ SVN_ERR(read_min_unpacked_rev(&min_unpacked_revprop,
+ min_unpacked_revprop_path, pool));
+ if (min_unpacked_revprop == (max_rev + 1))
+ uhohs = FALSE;
+ }
+ if (uhohs)
+ {
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ _("Revision %ld has a revs file but no "
+ "revprops file"),
+ max_rev);
+ }
+ }
else if (youngest_revprops_kind != svn_node_file)
- return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
- _("Revision %ld has a non-file where its "
- "revprops file should be"),
- max_rev);
+ {
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ _("Revision %ld has a non-file where its "
+ "revprops file should be"),
+ max_rev);
+ }
/* Now store the discovered youngest revision, and the next IDs if
relevant, in a new 'current' file. */
@@ -7385,7 +7420,7 @@ svn_fs_fs__set_uuid(svn_fs_t *fs,
permissions as FS->path.*/
svn_error_t *
svn_fs_fs__ensure_dir_exists(const char *path,
- svn_fs_t *fs,
+ const char *fs_path,
apr_pool_t *pool)
{
svn_error_t *err = svn_io_dir_make(path, APR_OS_DEFAULT, pool);
@@ -7398,7 +7433,7 @@ svn_fs_fs__ensure_dir_exists(const char
/* We successfully created a new directory. Dup the permissions
from FS->path. */
- return svn_io_copy_perms(path, fs->path, pool);
+ return svn_io_copy_perms(path, fs_path, pool);
}
/* Set *NODE_ORIGINS to a hash mapping 'const char *' node IDs to
@@ -7470,7 +7505,7 @@ set_node_origins_for_file(svn_fs_t *fs,
SVN_ERR(svn_fs_fs__ensure_dir_exists(svn_dirent_join(fs->path,
PATH_NODE_ORIGINS_DIR,
pool),
- fs, pool));
+ fs->path, pool));
/* Read the previously existing origins (if any), and merge our
update with it. */
Modified: subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.h?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.h Wed Nov 17 00:09:50 2010
@@ -490,9 +490,9 @@ svn_error_t *svn_fs_fs__txn_prop(svn_str
const char *propname, apr_pool_t *pool);
/* If directory PATH does not exist, create it and give it the same
- permissions as FS->path.*/
+ permissions as FS_PATH.*/
svn_error_t *svn_fs_fs__ensure_dir_exists(const char *path,
- svn_fs_t *fs,
+ const char *fs_path,
apr_pool_t *pool);
/* Update the node origin index for FS, recording the mapping from
Modified: subversion/branches/performance/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/lock.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/lock.c Wed Nov 17 00:09:50 2010
@@ -36,7 +36,6 @@
#include "lock.h"
#include "tree.h"
-#include "err.h"
#include "fs_fs.h"
#include "../libsvn_fs/fs-loader.h"
@@ -108,17 +107,28 @@ hash_fetch(apr_hash_t *hash,
}
+/* SVN_ERR_FS_CORRUPT: the lockfile for PATH in FS is corrupt. */
+static svn_error_t *
+err_corrupt_lockfile(const char *fs_path, const char *path)
+{
+ return
+ svn_error_createf(
+ SVN_ERR_FS_CORRUPT, 0,
+ _("Corrupt lockfile for path '%s' in filesystem '%s'"),
+ path, fs_path);
+}
+
/*** Digest file handling functions. ***/
/* Return the path of the lock/entries file for which DIGEST is the
hashed repository relative path. */
static const char *
-digest_path_from_digest(svn_fs_t *fs,
+digest_path_from_digest(const char *fs_path,
const char *digest,
apr_pool_t *pool)
{
- return svn_dirent_join_many(pool, fs->path, PATH_LOCKS_DIR,
+ return svn_dirent_join_many(pool, fs_path, PATH_LOCKS_DIR,
apr_pstrmemdup(pool, digest, DIGEST_SUBDIR_LEN),
digest, NULL);
}
@@ -128,12 +138,12 @@ digest_path_from_digest(svn_fs_t *fs,
PATH, where PATH is the path to the lock file or lock entries file
in FS. */
static const char *
-digest_path_from_path(svn_fs_t *fs,
+digest_path_from_path(const char *fs_path,
const char *path,
apr_pool_t *pool)
{
const char *digest = make_digest(path, pool);
- return svn_dirent_join_many(pool, fs->path, PATH_LOCKS_DIR,
+ return svn_dirent_join_many(pool, fs_path, PATH_LOCKS_DIR,
apr_pstrmemdup(pool, digest, DIGEST_SUBDIR_LEN),
digest, NULL);
}
@@ -142,12 +152,15 @@ digest_path_from_path(svn_fs_t *fs,
/* Write to DIGEST_PATH a representation of CHILDREN (which may be
empty, if the versioned path in FS represented by DIGEST_PATH has
no children) and LOCK (which may be NULL if that versioned path is
- lock itself locked). Use POOL for all allocations. */
+ lock itself locked). Set the permissions of DIGEST_PATH to those of
+ PERMS_REFERENCE. Use POOL for all allocations.
+ */
static svn_error_t *
write_digest_file(apr_hash_t *children,
svn_lock_t *lock,
- svn_fs_t *fs,
+ const char *fs_path,
const char *digest_path,
+ const char *perms_reference,
apr_pool_t *pool)
{
svn_error_t *err = SVN_NO_ERROR;
@@ -155,12 +168,11 @@ write_digest_file(apr_hash_t *children,
apr_hash_index_t *hi;
apr_hash_t *hash = apr_hash_make(pool);
const char *tmp_path;
- const char *rev_0_path;
- SVN_ERR(svn_fs_fs__ensure_dir_exists(svn_dirent_join(fs->path, PATH_LOCKS_DIR,
- pool), fs, pool));
+ SVN_ERR(svn_fs_fs__ensure_dir_exists(svn_dirent_join(fs_path, PATH_LOCKS_DIR,
+ pool), fs_path, pool));
SVN_ERR(svn_fs_fs__ensure_dir_exists(svn_dirent_dirname(digest_path, pool),
- fs, pool));
+ fs_path, pool));
if (lock)
{
@@ -212,8 +224,8 @@ write_digest_file(apr_hash_t *children,
SVN_ERR(svn_stream_close(stream));
SVN_ERR(svn_io_file_rename(tmp_path, digest_path, pool));
- SVN_ERR(svn_fs_fs__path_rev_absolute(&rev_0_path, fs, 0, pool));
- return svn_io_copy_perms(rev_0_path, digest_path, pool);
+ SVN_ERR(svn_io_copy_perms(perms_reference, digest_path, pool));
+ return SVN_NO_ERROR;
}
@@ -224,7 +236,7 @@ write_digest_file(apr_hash_t *children,
static svn_error_t *
read_digest_file(apr_hash_t **children_p,
svn_lock_t **lock_p,
- svn_fs_t *fs,
+ const char *fs_path,
const char *digest_path,
apr_pool_t *pool)
{
@@ -275,17 +287,17 @@ read_digest_file(apr_hash_t **children_p
lock->path = path;
if (! ((lock->token = hash_fetch(hash, TOKEN_KEY, pool))))
- return svn_fs_fs__err_corrupt_lockfile(fs, path);
+ return svn_error_return(err_corrupt_lockfile(fs_path, path));
if (! ((lock->owner = hash_fetch(hash, OWNER_KEY, pool))))
- return svn_fs_fs__err_corrupt_lockfile(fs, path);
+ return svn_error_return(err_corrupt_lockfile(fs_path, path));
if (! ((val = hash_fetch(hash, IS_DAV_COMMENT_KEY, pool))))
- return svn_fs_fs__err_corrupt_lockfile(fs, path);
+ return svn_error_return(err_corrupt_lockfile(fs_path, path));
lock->is_dav_comment = (val[0] == '1');
if (! ((val = hash_fetch(hash, CREATION_DATE_KEY, pool))))
- return svn_fs_fs__err_corrupt_lockfile(fs, path);
+ return svn_error_return(err_corrupt_lockfile(fs_path, path));
SVN_ERR(svn_time_from_cstring(&(lock->creation_date), val, pool));
if ((val = hash_fetch(hash, EXPIRATION_DATE_KEY, pool)))
@@ -318,10 +330,16 @@ read_digest_file(apr_hash_t **children_p
schema-supporting paths) ***/
-/* Write LOCK in FS to the actual OS filesystem. */
+/* Write LOCK in FS to the actual OS filesystem.
+
+ Use PERMS_REFERENCE for the permissions of any digest files.
+
+ Note: this takes an FS_PATH because it's called from the hotcopy logic.
+ */
static svn_error_t *
-set_lock(svn_fs_t *fs,
+set_lock(const char *fs_path,
svn_lock_t *lock,
+ const char *perms_reference,
apr_pool_t *pool)
{
svn_stringbuf_t *this_path = svn_stringbuf_create(lock->path, pool);
@@ -344,10 +362,10 @@ set_lock(svn_fs_t *fs,
/* Calculate the DIGEST_PATH for the currently FS path, and then
get its DIGEST_FILE basename. */
- digest_path = digest_path_from_path(fs, this_path->data, subpool);
+ digest_path = digest_path_from_path(fs_path, this_path->data, subpool);
digest_file = svn_dirent_basename(digest_path, subpool);
- SVN_ERR(read_digest_file(&this_children, &this_lock, fs,
+ SVN_ERR(read_digest_file(&this_children, &this_lock, fs_path,
digest_path, subpool));
/* We're either writing a new lock (first time through only) or
@@ -367,8 +385,8 @@ set_lock(svn_fs_t *fs,
apr_hash_set(this_children, lock_digest_path,
APR_HASH_KEY_STRING, (void *)1);
}
- SVN_ERR(write_digest_file(this_children, this_lock, fs,
- digest_path, subpool));
+ SVN_ERR(write_digest_file(this_children, this_lock, fs_path,
+ digest_path, perms_reference, subpool));
/* Prep for next iteration, or bail if we're done. */
if (svn_dirent_is_root(this_path->data, this_path->len))
@@ -406,10 +424,10 @@ delete_lock(svn_fs_t *fs,
/* Calculate the DIGEST_PATH for the currently FS path, and then
get its DIGEST_FILE basename. */
- digest_path = digest_path_from_path(fs, this_path->data, subpool);
+ digest_path = digest_path_from_path(fs->path, this_path->data, subpool);
digest_file = svn_dirent_basename(digest_path, subpool);
- SVN_ERR(read_digest_file(&this_children, &this_lock, fs,
+ SVN_ERR(read_digest_file(&this_children, &this_lock, fs->path,
digest_path, subpool));
/* Delete the lock (first time through only). */
@@ -431,8 +449,10 @@ delete_lock(svn_fs_t *fs,
}
else
{
- SVN_ERR(write_digest_file(this_children, this_lock, fs,
- digest_path, subpool));
+ const char *rev_0_path;
+ SVN_ERR(svn_fs_fs__path_rev_absolute(&rev_0_path, fs, 0, pool));
+ SVN_ERR(write_digest_file(this_children, this_lock, fs->path,
+ digest_path, rev_0_path, subpool));
}
/* Prep for next iteration, or bail if we're done. */
@@ -458,9 +478,9 @@ get_lock(svn_lock_t **lock_p,
apr_pool_t *pool)
{
svn_lock_t *lock;
- const char *digest_path = digest_path_from_path(fs, path, pool);
+ const char *digest_path = digest_path_from_path(fs->path, path, pool);
- SVN_ERR(read_digest_file(NULL, &lock, fs, digest_path, pool));
+ SVN_ERR(read_digest_file(NULL, &lock, fs->path, digest_path, pool));
if (! lock)
return SVN_FS__ERR_NO_SUCH_LOCK(fs, path, pool);
@@ -513,43 +533,82 @@ get_lock_helper(svn_fs_t *fs,
}
-/* A recursive function that calls GET_LOCKS_FUNC/GET_LOCKS_BATON for
- all locks in and under PATH in FS.
- HAVE_WRITE_LOCK should be true if the caller (directly or indirectly)
- has the FS write lock. */
+/* Baton for locks_walker(). */
+struct walk_locks_baton {
+ svn_fs_get_locks_callback_t get_locks_func;
+ void *get_locks_baton;
+ svn_fs_t *fs;
+};
+
+/* Implements walk_digests_callback_t. */
static svn_error_t *
-walk_digest_files(svn_fs_t *fs,
- const char *digest_path,
- svn_fs_get_locks_callback_t get_locks_func,
- void *get_locks_baton,
- svn_boolean_t have_write_lock,
- apr_pool_t *pool)
+locks_walker(void *baton,
+ const char *fs_path,
+ const char *digest_path,
+ apr_hash_t *children,
+ svn_lock_t *lock,
+ svn_boolean_t have_write_lock,
+ apr_pool_t *pool)
{
- apr_hash_t *children;
- svn_lock_t *lock;
- apr_hash_index_t *hi;
- apr_pool_t *subpool;
+ struct walk_locks_baton *wlb = baton;
- /* First, send up any locks in the current digest file. */
- SVN_ERR(read_digest_file(&children, &lock, fs, digest_path, pool));
if (lock)
{
/* Don't report an expired lock. */
if (lock->expiration_date == 0
|| (apr_time_now() <= lock->expiration_date))
{
- if (get_locks_func)
- SVN_ERR(get_locks_func(get_locks_baton, lock, pool));
+ if (wlb->get_locks_func)
+ SVN_ERR(wlb->get_locks_func(wlb->get_locks_baton, lock, pool));
}
else
{
/* Only remove the lock if we have the write lock.
Read operations shouldn't change the filesystem. */
if (have_write_lock)
- SVN_ERR(delete_lock(fs, lock, pool));
+ SVN_ERR(delete_lock(wlb->fs, lock, pool));
}
}
+ return SVN_NO_ERROR;
+}
+
+/* Callback type for walk_digest_files().
+ *
+ * CHILDREN and LOCK come from a read_digest_file(digest_path) call.
+ */
+typedef svn_error_t *(*walk_digests_callback_t)(void *baton,
+ const char *fs_path,
+ const char *digest_path,
+ apr_hash_t *children,
+ svn_lock_t *lock,
+ svn_boolean_t have_write_lock,
+ apr_pool_t *pool);
+
+/* A recursive function that calls WALK_DIGESTS_FUNC/WALK_DIGESTS_BATON for
+ all lock digest files in and under PATH in FS.
+ HAVE_WRITE_LOCK should be true if the caller (directly or indirectly)
+ has the FS write lock. */
+static svn_error_t *
+walk_digest_files(const char *fs_path,
+ const char *digest_path,
+ walk_digests_callback_t walk_digests_func,
+ void *walk_digests_baton,
+ svn_boolean_t have_write_lock,
+ apr_pool_t *pool)
+{
+ apr_hash_index_t *hi;
+ apr_hash_t *children;
+ apr_pool_t *subpool;
+ svn_lock_t *lock;
+
+ /* First, send up any locks in the current digest file. */
+ SVN_ERR(read_digest_file(&children, &lock, fs_path, digest_path, pool));
+
+ SVN_ERR(walk_digests_func(walk_digests_baton, fs_path, digest_path,
+ children, lock,
+ have_write_lock, pool));
+
/* Now, recurse on this thing's child entries (if any; bail otherwise). */
if (! apr_hash_count(children))
return SVN_NO_ERROR;
@@ -559,13 +618,31 @@ walk_digest_files(svn_fs_t *fs,
const char *digest = svn__apr_hash_index_key(hi);
svn_pool_clear(subpool);
SVN_ERR(walk_digest_files
- (fs, digest_path_from_digest(fs, digest, subpool),
- get_locks_func, get_locks_baton, have_write_lock, subpool));
+ (fs_path, digest_path_from_digest(fs_path, digest, subpool),
+ walk_digests_func, walk_digests_baton, have_write_lock, subpool));
}
svn_pool_destroy(subpool);
return SVN_NO_ERROR;
}
+/* A recursive function that calls GET_LOCKS_FUNC/GET_LOCKS_BATON for
+ all locks in and under PATH in FS.
+ HAVE_WRITE_LOCK should be true if the caller (directly or indirectly)
+ has the FS write lock. */
+static svn_error_t *
+walk_locks(svn_fs_t *fs,
+ const char *digest_path,
+ svn_fs_get_locks_callback_t get_locks_func,
+ void *get_locks_baton,
+ svn_boolean_t have_write_lock,
+ apr_pool_t *pool)
+{
+ struct walk_locks_baton wlb = { get_locks_func, get_locks_baton, fs };
+ SVN_ERR(walk_digest_files(fs->path, digest_path, locks_walker, &wlb,
+ have_write_lock, pool));
+ return SVN_NO_ERROR;
+}
+
/* Utility function: verify that a lock can be used. Interesting
errors returned from this function:
@@ -625,9 +702,9 @@ svn_fs_fs__allow_locked_operation(const
if (recurse)
{
/* Discover all locks at or below the path. */
- const char *digest_path = digest_path_from_path(fs, path, pool);
- SVN_ERR(walk_digest_files(fs, digest_path, get_locks_callback,
- fs, have_write_lock, pool));
+ const char *digest_path = digest_path_from_path(fs->path, path, pool);
+ SVN_ERR(walk_locks(fs, digest_path, get_locks_callback,
+ fs, have_write_lock, pool));
}
else
{
@@ -667,6 +744,7 @@ lock_body(void *baton, apr_pool_t *pool)
svn_lock_t *lock;
svn_fs_root_t *root;
svn_revnum_t youngest;
+ const char *rev_0_path;
/* Until we implement directory locks someday, we only allow locks
on files or non-existent paths. */
@@ -766,7 +844,8 @@ lock_body(void *baton, apr_pool_t *pool)
lock->is_dav_comment = lb->is_dav_comment;
lock->creation_date = apr_time_now();
lock->expiration_date = lb->expiration_date;
- SVN_ERR(set_lock(lb->fs, lock, pool));
+ SVN_ERR(svn_fs_fs__path_rev_absolute(&rev_0_path, lb->fs, 0, pool));
+ SVN_ERR(set_lock(lb->fs->path, lock, rev_0_path, pool));
*lb->lock_p = lock;
return SVN_NO_ERROR;
@@ -973,7 +1052,8 @@ svn_fs_fs__get_locks(svn_fs_t *fs,
glfb.get_locks_baton = get_locks_baton;
/* Get the top digest path in our tree of interest, and then walk it. */
- digest_path = digest_path_from_path(fs, path, pool);
- return walk_digest_files(fs, digest_path, get_locks_filter_func, &glfb,
- FALSE, pool);
+ digest_path = digest_path_from_path(fs->path, path, pool);
+ SVN_ERR(walk_locks(fs, digest_path, get_locks_filter_func, &glfb,
+ FALSE, pool));
+ return SVN_NO_ERROR;
}
Modified: subversion/branches/performance/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/tree.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/tree.c Wed Nov 17 00:09:50 2010
@@ -51,7 +51,6 @@
#include "svn_props.h"
#include "fs.h"
-#include "err.h"
#include "key-gen.h"
#include "dag.h"
#include "lock.h"
Modified: subversion/branches/performance/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/load-fs-vtable.c?rev=1035869&r1=1035868&r2=1035869&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/load-fs-vtable.c Wed Nov 17 00:09:50 2010
@@ -626,7 +626,10 @@ set_node_property(void *baton,
if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
{
- svn_string_t *renumbered_mergeinfo, *prop_val = (svn_string_t *)value;
+ svn_string_t *renumbered_mergeinfo;
+ /* ### Need to cast away const. We cannot change the declaration of
+ * ### this function since it is part of svn_repos_parse_fns2_t. */
+ svn_string_t *prop_val = (svn_string_t *)value;
/* Tolerate mergeinfo with "\r\n" line endings because some
dumpstream sources might contain as much. If so normalize