[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: svn commit: r37355 - trunk/subversion/libsvn_wc

From: Greg Stein <gstein_at_gmail.com>
Date: Sat, 18 Apr 2009 22:17:05 +0200

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

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.