This appears to break a couple merge tests. I'll get that fixed up shortly...
On Sat, Apr 18, 2009 at 22:12, Greg Stein <gstein_at_gmail.com> wrote:
> Author: gstein
> Date: Sat Apr 18 13:12:27 2009
> New Revision: 37355
>
> Log:
> Revamp a lot of internal props code to not worry about access batons.
>
> * subversion/libsvn_wc/props.h:
> (svn_wc__wcprop_list): revamp the parameter set
> (svn_wc__load_props): take an ENTRY instead of an access baton. switch
> to dual-pool rather than single.
>
> * subversion/libsvn_wc/props.c:
> (svn_wc__load_props): take an ENTRY as a param, which means we don't
> need the logic to test for a missing/unversioned node. switch to
> dual-pool usage.
> (read_wcprops): take a DB and a directory abspath, rather than an access
> baton. get the wc_format from the DB rather than access baton.
> (delete_wcprops): update params to read_wcprops().
> (svn_wc__merge_props): update params to svn_wc__load_props(), which also
> entails fetching an entry.
> (svn_wc__wcprop_list): revamp params, and update call to read_wcprops.
> (wcprop_get): removed. inlined into svn_wc_prop_get() since all that was
> really needed is the call to svn_wc__wcprop_list().
> (svn_wc__wcprop_set): update call to read_wcprops()
> (svn_wc_prop_list): use svn_wc__get_entry() instead of svn_wc_entry.
> trim out a bunch of crap and update call to svn_wc__load_props.
> (svn_wc_prop_get): early-out for incorrect property kinds. use
> svn_wc__get_entry, but be wary that callers give us a lot of bogus
> queries, so ignore potential errors. rather than wcprop_get, use
> svn_wc__wcprop_list to get the prophash. rather than svn_wc_prop_list,
> use svn_wc__load_props directly.
> (svn_wc_prop_set3, svn_wc_get_prop_diffs): update call to svn_wc__load_props
>
> * subversion/libsvn_wc/entries.h:
> (svn_wc__get_entry): add ALLOW_UNVERSIONED param. update docstring.
>
> * subversion/libsvn_wc/entries.c:
> (svn_wc__get_entry): adjust logic for missing items when
> ALLOW_UNVERSIONED is true.
>
> * subversion/libsvn_wc/adm_ops.c:
> (revert_admin_things): update call to svn_wc__load_props()
>
> * subversion/libsvn_wc/lock.c:
> (convert_wcprops): update call to svn_wc__wcprop_list. construct
> full_path in the subpool.
>
> * subversion/libsvn_wc/update_editor.c:
> (struct edit_baton): add a DB handle
> (close_directory): update call to svn_wc__load_props(), which also
> requires fetching the entry.
> (add_file_with_history): pass the source entry to svn_wc__load_props.
> (make_editor): store the DB into the edit baton
> (check_wc_root): allow the entry to be unversioned and test for a NULL
> entry, rather than detecting the not-found error. update all calls to
> get_entry()
>
> * subversion/libsvn_wc/copy.c:
> (copy_file_administratively): update call to svn_wc__load_props
>
> * subversion/libsvn_wc/wc_db.c:
> (svn_wc__db_temp_get_format): if this is called for an unversioned
> subdir, then we walk up the filesystem until we find a versioned
> directory, and create a wcroot for that. this works the first time
> through when parse_local_abspath is called. the second time would fail
> the assertion. instead, recognize the problem and return failure.
>
> Modified:
> trunk/subversion/libsvn_wc/adm_ops.c
> trunk/subversion/libsvn_wc/copy.c
> trunk/subversion/libsvn_wc/entries.c
> trunk/subversion/libsvn_wc/entries.h
> trunk/subversion/libsvn_wc/lock.c
> trunk/subversion/libsvn_wc/props.c
> trunk/subversion/libsvn_wc/props.h
> trunk/subversion/libsvn_wc/update_editor.c
> trunk/subversion/libsvn_wc/wc_db.c
>
> Modified: trunk/subversion/libsvn_wc/adm_ops.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/adm_ops.c?pathrev=37355&r1=37354&r2=37355
> ==============================================================================
> --- trunk/subversion/libsvn_wc/adm_ops.c Sat Apr 18 10:11:47 2009 (r37354)
> +++ trunk/subversion/libsvn_wc/adm_ops.c Sat Apr 18 13:12:27 2009 (r37355)
> @@ -1703,9 +1703,8 @@ revert_admin_things(svn_wc_adm_access_t
>
> /* Use the revertpath as the new propsbase if it exists. */
>
> - baseprops = apr_hash_make(pool);
> - SVN_ERR(svn_wc__load_props(NULL, NULL, &baseprops,
> - adm_access, fullpath, pool));
> + SVN_ERR(svn_wc__load_props(NULL, NULL, &baseprops, entry, fullpath,
> + pool, pool));
>
> /* Ensure the revert propfile gets removed. */
> SVN_ERR(svn_wc__loggy_props_delete(&log_accum,
>
> Modified: trunk/subversion/libsvn_wc/copy.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/copy.c?pathrev=37355&r1=37354&r2=37355
> ==============================================================================
> --- trunk/subversion/libsvn_wc/copy.c Sat Apr 18 10:11:47 2009 (r37354)
> +++ trunk/subversion/libsvn_wc/copy.c Sat Apr 18 13:12:27 2009 (r37355)
> @@ -33,6 +33,7 @@
> #include "entries.h"
> #include "props.h"
> #include "translate.h"
> +#include "lock.h"
>
> #include "svn_private_config.h"
> #include "private/svn_wc_private.h"
> @@ -528,8 +529,8 @@ copy_file_administratively(const char *s
> }
>
> /* Load source base and working props. */
> - SVN_ERR(svn_wc__load_props(&base_props, &props, NULL, src_access,
> - src_path, pool));
> + SVN_ERR(svn_wc__load_props(&base_props, &props, NULL, src_entry, src_path,
> + pool, pool));
>
> /* Copy working copy file to temporary location */
> {
>
> Modified: trunk/subversion/libsvn_wc/entries.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/entries.c?pathrev=37355&r1=37354&r2=37355
> ==============================================================================
> --- trunk/subversion/libsvn_wc/entries.c Sat Apr 18 10:11:47 2009 (r37354)
> +++ trunk/subversion/libsvn_wc/entries.c Sat Apr 18 13:12:27 2009 (r37355)
> @@ -42,6 +42,7 @@
> #include "private/svn_wc_private.h"
> #include "private/svn_sqlite.h"
> #include "private/svn_skel.h"
> +#include "private/svn_debug.h"
>
> #include "wc-metadata.h"
> #include "wc-checks.h"
> @@ -1568,6 +1569,7 @@ svn_error_t *
> svn_wc__get_entry(const svn_wc_entry_t **entry,
> svn_wc__db_t *db,
> const char *local_abspath,
> + svn_boolean_t allow_unversioned,
> svn_node_kind_t kind,
> svn_boolean_t need_parent_stub,
> apr_pool_t *result_pool,
> @@ -1687,10 +1689,14 @@ svn_wc__get_entry(const svn_wc_entry_t *
>
> *entry = apr_hash_get(entries, entry_name, APR_HASH_KEY_STRING);
> if (*entry == NULL)
> - return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
> - _("'%s' is not under version control"),
> - svn_path_local_style(local_abspath,
> - scratch_pool));
> + {
> + if (allow_unversioned)
> + return SVN_NO_ERROR;
> + return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
> + _("'%s' is not under version control"),
> + svn_path_local_style(local_abspath,
> + scratch_pool));
> + }
>
> /* Give the caller a valid entry. */
> *entry = svn_wc_entry_dup(*entry, result_pool);
>
> Modified: trunk/subversion/libsvn_wc/entries.h
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/entries.h?pathrev=37355&r1=37354&r2=37355
> ==============================================================================
> --- trunk/subversion/libsvn_wc/entries.h Sat Apr 18 10:11:47 2009 (r37354)
> +++ trunk/subversion/libsvn_wc/entries.h Sat Apr 18 13:12:27 2009 (r37355)
> @@ -249,7 +249,11 @@ svn_wc__tweak_entry(svn_wc_adm_access_t
> /** Get an ENTRY for the given LOCAL_ABSPATH.
> *
> * This API does not require an access baton, just a wc_db handle (DB).
> - * The requested entry MUST be present and version-controlled.
> + * The requested entry MUST be present and version-controlled when
> + * ALLOW_UNVERSIONED is FALSE; otherwise, SVN_ERR_WC_PATH_NOT_FOUND is
> + * returned. When ALLOW_UNVERSIONED is TRUE, and the node is not under
> + * version control, *ENTRY will be set to NULL (this is easier for callers
> + * to handle, than detecting the error and clearing it).
> *
> * If you know the entry is a FILE or DIR, then specify that in KIND. If you
> * are unsure, then specific 'svn_node_unknown' for KIND. This value will be
> @@ -284,6 +288,7 @@ svn_error_t *
> svn_wc__get_entry(const svn_wc_entry_t **entry,
> svn_wc__db_t *db,
> const char *local_abspath,
> + svn_boolean_t allow_unversioned,
> svn_node_kind_t kind,
> svn_boolean_t need_parent_stub,
> apr_pool_t *result_pool,
>
> Modified: trunk/subversion/libsvn_wc/lock.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/lock.c?pathrev=37355&r1=37354&r2=37355
> ==============================================================================
> --- trunk/subversion/libsvn_wc/lock.c Sat Apr 18 10:11:47 2009 (r37354)
> +++ trunk/subversion/libsvn_wc/lock.c Sat Apr 18 13:12:27 2009 (r37355)
> @@ -120,10 +120,12 @@ convert_wcprops(svn_stringbuf_t *log_acc
> svn_wc_adm_access_t *adm_access,
> apr_pool_t *pool)
> {
> + const char *dir_abspath;
> apr_hash_t *entries;
> apr_hash_index_t *hi;
> apr_pool_t *subpool = svn_pool_create(pool);
>
> + SVN_ERR(svn_dirent_get_absolute(&dir_abspath, adm_access->path, pool));
> SVN_ERR(svn_wc_entries_read(&entries, adm_access, FALSE, pool));
>
> /* Walk over the entries, adding a modify-wcprop command for each wcprop.
> @@ -137,19 +139,22 @@ convert_wcprops(svn_stringbuf_t *log_acc
> apr_hash_t *wcprops;
> apr_hash_index_t *hj;
> const char *full_path;
> + const char *local_abspath;
>
> apr_hash_this(hi, NULL, NULL, &val);
> entry = val;
>
> - full_path = svn_dirent_join(adm_access->path, entry->name, pool);
> -
> if (entry->kind != svn_node_file
> && strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR) != 0)
> continue;
>
> svn_pool_clear(subpool);
>
> - SVN_ERR(svn_wc__wcprop_list(&wcprops, entry->name, adm_access, subpool));
> + full_path = svn_dirent_join(adm_access->path, entry->name, subpool);
> + local_abspath = svn_dirent_join(dir_abspath, entry->name, subpool);
> +
> + SVN_ERR(svn_wc__wcprop_list(&wcprops, adm_access->db, local_abspath,
> + entry->kind, subpool, subpool));
>
> /* Create a subsubpool for the inner loop...
> No, just kidding. There are typically just one or two wcprops
>
> Modified: trunk/subversion/libsvn_wc/props.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/props.c?pathrev=37355&r1=37354&r2=37355
> ==============================================================================
> --- trunk/subversion/libsvn_wc/props.c Sat Apr 18 10:11:47 2009 (r37354)
> +++ trunk/subversion/libsvn_wc/props.c Sat Apr 18 13:12:27 2009 (r37355)
> @@ -20,12 +20,14 @@
>
> #include <stdlib.h>
> #include <string.h>
> +
> #include <apr_pools.h>
> #include <apr_hash.h>
> #include <apr_tables.h>
> #include <apr_file_io.h>
> #include <apr_strings.h>
> #include <apr_general.h>
> +
> #include "svn_types.h"
> #include "svn_string.h"
> #include "svn_pools.h"
> @@ -54,13 +56,9 @@
> #include "lock.h"
>
> #include "svn_private_config.h"
> +#include "private/svn_debug.h"
>
> -/*---------------------------------------------------------------------*/
> -
> -/*** Deducing local changes to properties ***/
>
> -/*---------------------------------------------------------------------*/
> -
> /*** Reading/writing property hashes from disk ***/
>
> /* ### HKW/WC-NG: This is a summary of the my efforts to localize accesses to
> @@ -246,27 +244,15 @@ svn_error_t *
> svn_wc__load_props(apr_hash_t **base_props_p,
> apr_hash_t **props_p,
> apr_hash_t **revert_props_p,
> - svn_wc_adm_access_t *adm_access,
> + const svn_wc_entry_t *entry,
> const char *path,
> - apr_pool_t *pool)
> + apr_pool_t *result_pool,
> + apr_pool_t *scratch_pool)
> {
> svn_node_kind_t kind;
> - const svn_wc_entry_t *entry;
> apr_hash_t *base_props = NULL; /* Silence uninitialized warning. */
>
> - SVN_ERR(svn_wc_entry(&entry, path, adm_access, FALSE, pool));
> - /* If there is no entry, we just return empty hashes, since the
> - property merging can use this function when there is no entry. */
> - if (! entry)
> - {
> - if (base_props_p)
> - *base_props_p = apr_hash_make(pool);
> - if (props_p)
> - *props_p = apr_hash_make(pool);
> - if (revert_props_p)
> - *revert_props_p = apr_hash_make(pool);
> - return SVN_NO_ERROR;
> - }
> + SVN_ERR_ASSERT(entry != NULL);
>
> kind = entry->kind;
>
> @@ -274,7 +260,8 @@ svn_wc__load_props(apr_hash_t **base_pro
> them if no (working) prop mods have occurred. */
> if (base_props_p != NULL || props_p != NULL)
> {
> - SVN_ERR(load_props(&base_props, path, kind, svn_wc__props_base, pool));
> + SVN_ERR(load_props(&base_props, path, kind, svn_wc__props_base,
> + result_pool));
>
> if (base_props_p)
> *base_props_p = base_props;
> @@ -282,7 +269,8 @@ svn_wc__load_props(apr_hash_t **base_pro
>
> if (props_p)
> {
> - SVN_ERR(load_props(props_p, path, kind, svn_wc__props_working, pool));
> + SVN_ERR(load_props(props_p, path, kind, svn_wc__props_working,
> + result_pool));
>
> /* If the WORKING props are not present, then no modifications have
> occurred. Simply return a copy of the BASE props.
> @@ -290,17 +278,16 @@ svn_wc__load_props(apr_hash_t **base_pro
> Note that the WORKING props might be present, but simply empty,
> signifying that all BASE props have been deleted. */
> if (*props_p == NULL)
> - *props_p = apr_hash_copy(pool, base_props);
> + *props_p = apr_hash_copy(result_pool, base_props);
> }
>
> if (revert_props_p)
> {
> if (entry->schedule == svn_wc_schedule_replace)
> SVN_ERR(load_props(revert_props_p, path, kind, svn_wc__props_revert,
> - pool));
> + result_pool));
> else
> - *revert_props_p = apr_hash_make(pool);
> -
> + *revert_props_p = apr_hash_make(result_pool);
> }
>
> return SVN_NO_ERROR;
> @@ -463,7 +450,8 @@ remove_file_if_present(const char *file,
> SCRATCH_POOL for temporary allocations. */
> static svn_error_t *
> read_wcprops(apr_hash_t **all_wcprops,
> - svn_wc_adm_access_t *adm_access,
> + svn_wc__db_t *db,
> + const char *dir_abspath,
> apr_pool_t *result_pool,
> apr_pool_t *scratch_pool)
> {
> @@ -472,7 +460,8 @@ read_wcprops(apr_hash_t **all_wcprops,
> svn_stream_t *stream;
> svn_error_t *err;
>
> - SVN_ERR(svn_wc__adm_wc_format(&wc_format, adm_access, scratch_pool));
> + SVN_ERR(svn_wc__db_temp_get_format(&wc_format, db, dir_abspath,
> + scratch_pool));
>
> /* If the WC format is too old, there is no 'all_wcprops' file. */
> if (wc_format <= SVN_WC__WCPROPS_MANY_FILES_VERSION)
> @@ -483,7 +472,7 @@ read_wcprops(apr_hash_t **all_wcprops,
>
> *all_wcprops = apr_hash_make(result_pool);
>
> - err = svn_wc__open_adm_stream(&stream, svn_wc_adm_access_path(adm_access),
> + err = svn_wc__open_adm_stream(&stream, dir_abspath,
> SVN_WC__ADM_ALL_WCPROPS,
> scratch_pool, scratch_pool);
>
> @@ -514,8 +503,7 @@ read_wcprops(apr_hash_t **all_wcprops,
> return svn_error_createf
> (SVN_ERR_WC_CORRUPT, NULL,
> _("Missing end of line in wcprops file for '%s'"),
> - svn_path_local_style(svn_wc_adm_access_path(adm_access),
> - scratch_pool));
> + svn_path_local_style(dir_abspath, scratch_pool));
> break;
> }
> proplist = apr_hash_make(result_pool);
> @@ -663,14 +651,19 @@ delete_wcprops(const char *path,
> /* We use 1 file for all wcprops in a directory,
> use a helper to remove them from that file */
>
> + svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
> svn_wc_adm_access_t *path_access;
> + const char *dir_abspath;
> const char *filename;
> apr_hash_t *all_wcprops;
>
> SVN_ERR(svn_wc_adm_probe_retrieve(&path_access, adm_access, path, pool));
> SVN_ERR(wcprops_modify_allowed(path_access, pool));
>
> - SVN_ERR(read_wcprops(&all_wcprops, path_access, pool, pool));
> + SVN_ERR(svn_dirent_get_absolute(&dir_abspath,
> + svn_wc_adm_access_path(path_access),
> + pool));
> + SVN_ERR(read_wcprops(&all_wcprops, db, dir_abspath, pool, pool));
>
> /* If PATH is a directory, then FILENAME will be NULL.
> If PATH is a file, then FILENAME will be the BASE_NAME of PATH. */
> @@ -1697,9 +1690,9 @@ svn_wc__merge_props(svn_wc_notify_state_
> apr_pool_t *pool,
> svn_stringbuf_t **entry_accum)
> {
> + svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
> int i;
> svn_boolean_t is_dir;
> -
> const char *reject_path = NULL;
> svn_stream_t *reject_tmp_stream = NULL; /* the temporary conflicts stream */
> const char *reject_tmp_path = NULL;
> @@ -1711,9 +1704,28 @@ svn_wc__merge_props(svn_wc_notify_state_
>
> /* If not provided, load the base & working property files into hashes */
> if (! base_props || ! working_props)
> - SVN_ERR(svn_wc__load_props(base_props ? NULL : &base_props,
> - working_props ? NULL : &working_props,
> - NULL, adm_access, path, pool));
> + {
> + const char *local_abspath;
> + const svn_wc_entry_t *entry;
> +
> + SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
> + SVN_ERR(svn_wc__get_entry(&entry, db, local_abspath, TRUE,
> + svn_node_unknown, FALSE, pool, pool));
> + if (entry == NULL)
> + {
> + /* No entry... no props. */
> + if (base_props == NULL)
> + base_props = apr_hash_make(pool);
> + if (working_props == NULL)
> + working_props = apr_hash_make(pool);
> + }
> + else
> + {
> + SVN_ERR(svn_wc__load_props(base_props ? NULL : &base_props,
> + working_props ? NULL : &working_props,
> + NULL, entry, path, pool, pool));
> + }
> + }
> if (!server_baseprops)
> server_baseprops = base_props;
>
> @@ -1905,14 +1917,15 @@ svn_wc_merge_prop_diffs(svn_wc_notify_st
>
> svn_error_t *
> svn_wc__wcprop_list(apr_hash_t **wcprops,
> - const char *entryname,
> - svn_wc_adm_access_t *adm_access,
> - apr_pool_t *pool)
> + svn_wc__db_t *db,
> + const char *local_abspath,
> + svn_node_kind_t kind,
> + apr_pool_t *result_pool,
> + apr_pool_t *scratch_pool)
> {
> - const svn_wc_entry_t *entry;
> + const char *dir_abspath;
> + const char *entryname;
> apr_hash_t *all_wcprops;
> - const char *path = svn_dirent_join(svn_wc_adm_access_path(adm_access),
> - entryname, pool);
>
> /* ### note: it is allowed to return a hash table allocated from POOL.
> ### it does not have to be part of ACCESS_POOL.
> @@ -1920,60 +1933,32 @@ svn_wc__wcprop_list(apr_hash_t **wcprops
> ### if there is no cache, then we load individual files into POOL.
> ### therefore, we can return values from POOL, too. */
>
> - SVN_ERR(svn_wc_entry(&entry, path, adm_access, FALSE, pool));
> - if (! entry)
> + if (kind == svn_node_dir)
> {
> - /* No entry exists, therefore no wcprop-file can exist */
> - *wcprops = apr_hash_make(pool);
> - return SVN_NO_ERROR;
> + dir_abspath = local_abspath;
> + entryname = "";
> + }
> + else
> + {
> + svn_dirent_split(local_abspath, &dir_abspath, &entryname, scratch_pool);
> }
>
> - SVN_ERR(read_wcprops(&all_wcprops, adm_access, pool, pool));
> + SVN_ERR(read_wcprops(&all_wcprops, db, dir_abspath,
> + result_pool, scratch_pool));
> if (all_wcprops)
> {
> *wcprops = apr_hash_get(all_wcprops, entryname, APR_HASH_KEY_STRING);
>
> /* Create an empty proplist if one hasn't been stored. */
> if (! *wcprops)
> - *wcprops = apr_hash_make(pool);
> + *wcprops = apr_hash_make(result_pool);
>
> return SVN_NO_ERROR;
> }
>
> /* Fall back on individual files for backwards compatibility. */
> - return load_props(wcprops, path, entry->kind, svn_wc__props_wcprop, pool);
> -}
> -
> -
> -/* Get a single 'wcprop' NAME for versioned object PATH, return in
> - *VALUE. ADM_ACCESS is an access baton set that contains PATH. */
> -static svn_error_t *
> -wcprop_get(const svn_string_t **value,
> - const char *name,
> - const char *path,
> - svn_wc_adm_access_t *adm_access,
> - apr_pool_t *pool)
> -{
> - apr_hash_t *prophash;
> - const svn_wc_entry_t *entry;
> -
> - SVN_ERR(svn_wc_entry(&entry, path, adm_access, FALSE, pool));
> - if (! entry)
> - {
> - *value = NULL;
> - return SVN_NO_ERROR;
> - }
> - if (entry->kind == svn_node_dir)
> - SVN_ERR(svn_wc_adm_retrieve(&adm_access, adm_access, path, pool));
> - else
> - SVN_ERR(svn_wc_adm_retrieve(&adm_access, adm_access,
> - svn_dirent_dirname(path, pool), pool));
> -
> - SVN_ERR_W(svn_wc__wcprop_list(&prophash, entry->name, adm_access, pool),
> - _("Failed to load properties from disk"));
> -
> - *value = apr_hash_get(prophash, name, APR_HASH_KEY_STRING);
> - return SVN_NO_ERROR;
> + return load_props(wcprops, local_abspath, kind, svn_wc__props_wcprop,
> + result_pool);
> }
>
>
> @@ -1984,9 +1969,11 @@ svn_wc__wcprop_set(const char *name,
> svn_wc_adm_access_t *adm_access,
> apr_pool_t *pool)
> {
> + svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
> + const svn_wc_entry_t *entry;
> + const char *dir_abspath;
> apr_hash_t *all_wcprops;
> apr_hash_t *prophash;
> - const svn_wc_entry_t *entry;
>
> SVN_ERR(svn_wc__entry_versioned(&entry, path, adm_access, FALSE, pool));
>
> @@ -1998,7 +1985,10 @@ svn_wc__wcprop_set(const char *name,
>
> SVN_ERR(wcprops_modify_allowed(adm_access, pool));
>
> - SVN_ERR(read_wcprops(&all_wcprops, adm_access, pool, pool));
> + SVN_ERR(svn_dirent_get_absolute(&dir_abspath,
> + svn_wc_adm_access_path(adm_access),
> + pool));
> + SVN_ERR(read_wcprops(&all_wcprops, db, dir_abspath, pool, pool));
> if (all_wcprops == NULL)
> {
> /* Nothing is on disk. Start an empty hash-of-hashes. */
> @@ -2037,25 +2027,22 @@ svn_wc_prop_list(apr_hash_t **props,
> svn_wc_adm_access_t *adm_access,
> apr_pool_t *pool)
> {
> + svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
> + const char *local_abspath;
> const svn_wc_entry_t *entry;
>
> - SVN_ERR(svn_wc_entry(&entry, path, adm_access, FALSE, pool));
> -
> /* if there is no entry, 'path' is not under version control and
> therefore has no props. */
> - if (! entry)
> + SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
> + SVN_ERR(svn_wc__get_entry(&entry, db, local_abspath, TRUE, svn_node_unknown,
> + FALSE, pool, pool));
> + if (entry == NULL)
> {
> *props = apr_hash_make(pool);
> return SVN_NO_ERROR;
> }
>
> - if (entry->kind == svn_node_dir)
> - SVN_ERR(svn_wc_adm_retrieve(&adm_access, adm_access, path, pool));
> - else
> - SVN_ERR(svn_wc_adm_retrieve(&adm_access, adm_access,
> - svn_dirent_dirname(path, pool), pool));
> -
> - return svn_wc__load_props(NULL, props, NULL, adm_access, path, pool);
> + return svn_wc__load_props(NULL, props, NULL, entry, path, pool, pool);
> }
>
> svn_error_t *
> @@ -2065,37 +2052,57 @@ svn_wc_prop_get(const svn_string_t **val
> svn_wc_adm_access_t *adm_access,
> apr_pool_t *pool)
> {
> + svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
> + const char *local_abspath;
> + svn_error_t *err;
> apr_hash_t *prophash;
> enum svn_prop_kind kind = svn_property_kind(NULL, name);
> const svn_wc_entry_t *entry;
>
> - SVN_ERR(svn_wc_entry(&entry, path, adm_access, FALSE, pool));
> + if (kind == svn_prop_entry_kind)
> + {
> + /* we don't do entry properties here */
> + return svn_error_createf(SVN_ERR_BAD_PROP_KIND, NULL,
> + _("Property '%s' is an entry property"), name);
> + }
>
> - if (entry == NULL)
> + SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
> + err = svn_wc__get_entry(&entry, db, local_abspath, TRUE, svn_node_unknown,
> + FALSE, pool, pool);
> + if (err)
> {
> + /* ### holy crap. people pass some really weird shit into this
> + ### function. generally, we get pointed at directories that
> + ### are not working copies. rather than throwing an error,
> + ### we'll ignore it, and pretend an entry was not returned. */
> + svn_error_clear(err);
> + entry = NULL;
> + }
> + if (entry == NULL || svn_wc__entry_is_hidden(entry))
> + {
> + /* The node is not present, or not really "here". Therefore, the
> + property is not present. */
> *value = NULL;
> return SVN_NO_ERROR;
> }
>
> if (kind == svn_prop_wc_kind)
> {
> - return wcprop_get(value, name, path, adm_access, pool);
> - }
> - if (kind == svn_prop_entry_kind)
> - {
> - return svn_error_createf /* we don't do entry properties here */
> - (SVN_ERR_BAD_PROP_KIND, NULL,
> - _("Property '%s' is an entry property"), name);
> + SVN_ERR_W(svn_wc__wcprop_list(&prophash, db, local_abspath, entry->kind,
> + pool, pool),
> + _("Failed to load properties from disk"));
> }
> - else /* regular prop */
> + else
> {
> - SVN_ERR_W(svn_wc_prop_list(&prophash, path, adm_access, pool),
> + /* regular prop */
> + SVN_ERR_W(svn_wc__load_props(NULL, &prophash, NULL, entry, path,
> + pool, pool),
> _("Failed to load properties from disk"));
> + }
>
> - *value = apr_hash_get(prophash, name, APR_HASH_KEY_STRING);
> + *value = apr_hash_get(prophash, name, APR_HASH_KEY_STRING);
>
> - return SVN_NO_ERROR;
> - }
> + return SVN_NO_ERROR;
> }
>
>
> @@ -2308,8 +2315,8 @@ svn_wc_prop_set3(const char *name,
> /* If not, we'll set the file to read-only at commit time. */
> }
>
> - SVN_ERR_W(svn_wc__load_props(&base_prophash, &prophash, NULL,
> - adm_access, path, pool),
> + SVN_ERR_W(svn_wc__load_props(&base_prophash, &prophash, NULL, entry, path,
> + pool, pool),
> _("Failed to load properties from disk"));
>
> /* If we're changing this file's list of expanded keywords, then
> @@ -2699,7 +2706,7 @@ svn_wc_get_prop_diffs(apr_array_header_t
> }
>
> SVN_ERR(svn_wc__load_props(&baseprops, propchanges ? &props : NULL, NULL,
> - adm_access, path, pool));
> + entry, path, pool, pool));
>
> if (original_props != NULL)
> *original_props = baseprops;
>
> Modified: trunk/subversion/libsvn_wc/props.h
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/props.h?pathrev=37355&r1=37354&r2=37355
> ==============================================================================
> --- trunk/subversion/libsvn_wc/props.h Sat Apr 18 10:11:47 2009 (r37354)
> +++ trunk/subversion/libsvn_wc/props.h Sat Apr 18 13:12:27 2009 (r37355)
> @@ -21,10 +21,12 @@
> #define SVN_LIBSVN_WC_PROPS_H
>
> #include <apr_pools.h>
> +
> #include "svn_types.h"
> #include "svn_string.h"
> #include "svn_props.h"
>
> +#include "wc_db.h"
>
> #ifdef __cplusplus
> extern "C" {
> @@ -82,16 +84,17 @@ svn_error_t *svn_wc__merge_props(svn_wc_
> svn_stringbuf_t **entry_accum);
>
>
> -/* Return a list of wc props for ENTRYNAME in ADM_ACCESS.
> - ENTRYNAME must be the name of a file or SVN_WC_ENTRY_THIS_DIR.
> +/* Return a list of wc props for the node at LOCAL_ABSPATH, which is KIND.
>
> - The returned WCPROPS may be allocated in POOL, or may be the props
> - cached in ADM_ACCESS. */
> + The returned WCPROPS will be allocated in RESULT_POOL, and any temporary
> + allocations will be made in SCRATCH_POOL. */
> svn_error_t *
> svn_wc__wcprop_list(apr_hash_t **wcprops,
> - const char *entryname,
> - svn_wc_adm_access_t *adm_access,
> - apr_pool_t *pool);
> + svn_wc__db_t *db,
> + const char *local_abspath,
> + svn_node_kind_t kind,
> + apr_pool_t *result_pool,
> + apr_pool_t *scratch_pool);
>
> /* Set a single 'wcprop' NAME to VALUE for versioned object PATH.
> If VALUE is null, remove property NAME. ADM_ACCESS is an access
> @@ -175,17 +178,19 @@ svn_wc__working_props_committed(const ch
> svn_boolean_t sync_entries,
> apr_pool_t *pool);
>
> -/* Load the base, working and revert props for PATH in ADM_ACCESS returning
> +/* Load the base, working and revert props for ENTRY at PATH returning
> them in *BASE_PROPS_P, *PROPS_P and *REVERT_PROPS_P respectively.
> - Any of BASE_PROPS, PROPS and REVERT_PROPS may be null.
> - Do all allocations in POOL. */
> + Any of BASE_PROPS, PROPS and REVERT_PROPS may be NULL.
> + Returned hashes/values are allocated in RESULT_POOL. All temporary
> + allocations are made in SCRATCH_POOL. */
> svn_error_t *
> svn_wc__load_props(apr_hash_t **base_props_p,
> apr_hash_t **props_p,
> apr_hash_t **revert_props_p,
> - svn_wc_adm_access_t *adm_access,
> + const svn_wc_entry_t *entry,
> const char *path,
> - apr_pool_t *pool);
> + apr_pool_t *result_pool,
> + apr_pool_t *scratch_pool);
>
> #ifdef __cplusplus
> }
>
> Modified: trunk/subversion/libsvn_wc/update_editor.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/update_editor.c?pathrev=37355&r1=37354&r2=37355
> ==============================================================================
> --- trunk/subversion/libsvn_wc/update_editor.c Sat Apr 18 10:11:47 2009 (r37354)
> +++ trunk/subversion/libsvn_wc/update_editor.c Sat Apr 18 13:12:27 2009 (r37355)
> @@ -152,6 +152,9 @@ struct edit_baton
> const char *anchor;
> const char *target;
>
> + /* The DB handle for managing the working copy state. */
> + svn_wc__db_t *db;
> +
> /* ADM_ACCESS is an access baton that includes the ANCHOR directory */
> svn_wc_adm_access_t *adm_access;
>
> @@ -2805,11 +2808,24 @@ close_directory(void *dir_baton,
> deleted (issue #1672). */
> if (db->was_incomplete)
> {
> + const char *local_abspath;
> + const svn_wc_entry_t *entry;
> int i;
> apr_hash_t *props_to_delete;
>
> - SVN_ERR(svn_wc__load_props(&base_props, &working_props, NULL,
> - adm_access, db->path, pool));
> + SVN_ERR(svn_dirent_get_absolute(&local_abspath, db->path, pool));
> + SVN_ERR(svn_wc__get_entry(&entry, db->edit_baton->db, local_abspath,
> + TRUE, svn_node_unknown, FALSE, pool, pool));
> + if (entry == NULL)
> + {
> + base_props = apr_hash_make(pool);
> + working_props = apr_hash_make(pool);
> + }
> + else
> + {
> + SVN_ERR(svn_wc__load_props(&base_props, &working_props, NULL,
> + entry, db->path, pool, pool));
> + }
>
> /* Calculate which base props weren't also in the incoming
> propchanges. */
> @@ -3322,7 +3338,7 @@ add_file_with_history(const char *path,
> SVN_ERR(svn_wc__get_revert_contents(&source_text_base, src_path,
> subpool, subpool));
> SVN_ERR(svn_wc__load_props(NULL, NULL, &base_props,
> - src_access, src_path, pool));
> + src_entry, src_path, pool, subpool));
> /* The old working props are lost, just like the old
> working file text is. Just use the base props. */
> working_props = base_props;
> @@ -3332,7 +3348,7 @@ add_file_with_history(const char *path,
> SVN_ERR(svn_wc_get_pristine_contents(&source_text_base, src_path,
> subpool, subpool));
> SVN_ERR(svn_wc__load_props(&base_props, &working_props, NULL,
> - src_access, src_path, pool));
> + src_entry, src_path, pool, subpool));
> }
>
> SVN_ERR(svn_stream_copy3(source_text_base, copied_stream,
> @@ -4716,6 +4732,7 @@ make_editor(svn_revnum_t *target_revisio
> eb->switch_url = switch_url;
> eb->repos = entry ? entry->repos : NULL;
> eb->uuid = entry ? entry->uuid : NULL;
> + eb->db = svn_wc__adm_get_db(adm_access);
> eb->adm_access = adm_access;
> eb->anchor = anchor;
> eb->target = target;
> @@ -5134,9 +5151,10 @@ check_wc_root(svn_boolean_t *wc_root,
> otherwise hidden), treat it as if it were a file so that the anchor
> will be the parent directory. If the node is a FILE, then it is
> definitely not a root. */
> - err = svn_wc__get_entry(&entry, db, abspath, svn_node_unknown, FALSE,
> + err = svn_wc__get_entry(&entry, db, abspath, TRUE, svn_node_unknown, FALSE,
> pool, pool);
> - if (err || entry->kind == svn_node_file || svn_wc__entry_is_hidden(entry))
> + if (err || entry == NULL || entry->kind == svn_node_file
> + || svn_wc__entry_is_hidden(entry))
> {
> if (err)
> {
> @@ -5148,7 +5166,7 @@ check_wc_root(svn_boolean_t *wc_root,
> instead. We can pretend this is a file so the parent will
> be the anchor. */
> }
> - else if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
> + else
> return err;
> svn_error_clear(err);
> }
> @@ -5177,7 +5195,7 @@ check_wc_root(svn_boolean_t *wc_root,
> svn_dirent_split(abspath, &parent, &base_name, pool);
>
> /* If we cannot get an entry for PATH's parent, PATH is a WC root. */
> - err = svn_wc__get_entry(&p_entry, db, parent, svn_node_dir, FALSE,
> + err = svn_wc__get_entry(&p_entry, db, parent, FALSE, svn_node_dir, FALSE,
> pool, pool);
> if (err)
> {
> @@ -5203,7 +5221,7 @@ check_wc_root(svn_boolean_t *wc_root,
>
> /* If PATH's parent in the repository is not its parent in the WC,
> PATH is a WC root. */
> - err = svn_wc__get_entry(&p_entry, db, abspath, svn_node_dir, TRUE,
> + err = svn_wc__get_entry(&p_entry, db, abspath, FALSE, svn_node_dir, TRUE,
> pool, pool);
> if (err || svn_wc__entry_is_hidden(p_entry))
> {
>
> Modified: trunk/subversion/libsvn_wc/wc_db.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/wc_db.c?pathrev=37355&r1=37354&r2=37355
> ==============================================================================
> --- trunk/subversion/libsvn_wc/wc_db.c Sat Apr 18 10:11:47 2009 (r37354)
> +++ trunk/subversion/libsvn_wc/wc_db.c Sat Apr 18 13:12:27 2009 (r37355)
> @@ -3461,8 +3461,11 @@ svn_wc__db_temp_get_format(int *format,
> svn_sqlite__mode_readonly,
> scratch_pool, scratch_pool);
>
> - /* If we hit an error examining this directory, or if the information
> - returned is not for THIS directory, then bail out. */
> + /* If we hit an error examining this directory, then declare this
> + directory to not be a working copy. */
> + /* ### for per-dir layouts, the wcroot should be this directory,
> + ### so bail if the PDH is a parent (and, thus, local_relpath is
> + ### something besides ""). */
> if (err || *local_relpath != '\0')
> {
> if (err && err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
> @@ -3479,7 +3482,17 @@ svn_wc__db_temp_get_format(int *format,
>
> SVN_ERR_ASSERT(pdh->wcroot != NULL);
> }
> - SVN_ERR_ASSERT(strcmp(local_dir_abspath, pdh->wcroot->abspath) == 0);
> +
> + /* ### for per-dir layouts, the wcroot should be this directory. */
> + if (strcmp(local_dir_abspath, pdh->wcroot->abspath) != 0)
> + {
> + *format = 0;
> + return svn_error_createf(SVN_ERR_WC_MISSING, NULL,
> + _("'%s' is not a working copy"),
> + svn_dirent_local_style(local_dir_abspath,
> + scratch_pool));
> + }
> +
> SVN_ERR_ASSERT(pdh->wcroot->format >= 1);
>
> *format = pdh->wcroot->format;
>
> ------------------------------------------------------
> http://subversion.tigris.org/ds/viewMessage.do?dsForumId=495&dsMessageId=1795382
>
------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=462&dsMessageId=1795419
Received on 2009-04-18 22:17:26 CEST