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

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

From: Kamesh Jayachandran <kamesh_at_collab.net>
Date: 2007-09-07 11:56:57 CEST

Hi,

Since r26476 I observed SIGABRT over ra_dav due to uncleared
error(--enable-maintainer-mode build), This commit seems to fix it.
Though I could not understand the fix or no mention of the same.

Refer merge_tests.py's
'avoid_repeated_merge_using_inherited_merge_info'. Commit of r5 was
causing this SIGABRT.

I could see the 'uncleared error to be' "File not found: transaction
'4-4', path '/A/B/E/alpha'".

In r26489 and pre-26476 this error does not happen.

Dav http request level difference between r26476 and r26489 is 'CHECKOUT
/svn-test-work/repositories/merge_tests-1/!svn/ver/1/A/B/E/alpha'

r26476 makes this 'CHECKOUT' req and gets the error which is not handled
and left uncleared.

Pre r26476 and r26489 does not make this extra CHECKOUT request and
hence no SIGABRT.

I could see in general this commit to be 're-org' type of commit except
few functional bits like 'remove_wcprops', though I could not connect
this changes to 'removal of one extra CHECKOUT'.

Can someone explain here?

With regards
Kamesh Jayachandran
dionisos@tigris.org wrote:
> Author: dionisos
> Date: Thu Sep 6 14:31:47 2007
> New Revision: 26489
>
> Log:
> Generalize wcprops access interfaces.
>
> * subversion/libsvn_wc/props.h
> * subversion/libsvn_wc/props.c
> (svn_wc__wcprop_write): Rename to write_wcprops().
> Assimilate external interface into ...
> (svn_wc__props_flush): ... here.
> (remove_wcprops): Reinstate from r26476 removed svn_wc__remove_wcprops().
> (svn_wc__props_delete): Use remove_wcprops() to remove remove .. wcprops.
> (svn_wc__loggy_props_delete): Write specific log commands to do removal.
>
> * subversion/libsvn_wc/log.c
> Adjust caller.
>
>
>
> Modified:
> trunk/subversion/libsvn_wc/log.c
> trunk/subversion/libsvn_wc/props.c
> trunk/subversion/libsvn_wc/props.h
>
> Modified: trunk/subversion/libsvn_wc/log.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/log.c?pathrev=26489&r1=26488&r2=26489
> ==============================================================================
> --- trunk/subversion/libsvn_wc/log.c (original)
> +++ trunk/subversion/libsvn_wc/log.c Thu Sep 6 14:31:47 2007
> @@ -1816,7 +1816,8 @@
> SVN_ERR(svn_wc__entries_write(entries, loggy->adm_access, pool));
> }
> if (loggy->wcprops_modified)
> - SVN_ERR(svn_wc__wcprops_write(loggy->adm_access, pool));
> + SVN_ERR(svn_wc__props_flush(svn_wc_adm_access_path(adm_access),
> + svn_wc__props_wcprop, loggy->adm_access, pool));
>
> /* Check for a 'killme' file in the administrative area. */
> SVN_ERR(svn_wc__check_killme(adm_access, &killme, &kill_adm_only, pool));
>
> Modified: trunk/subversion/libsvn_wc/props.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/props.c?pathrev=26489&r1=26488&r2=26489
> ==============================================================================
> --- trunk/subversion/libsvn_wc/props.c (original)
> +++ trunk/subversion/libsvn_wc/props.c Thu Sep 6 14:31:47 2007
> @@ -527,6 +527,225 @@
> return err;
> }
>
> +
> +/* If wcprops are stored in a single file in this working copy, read that file
> + and store it in the cache of ADM_ACCESS. Use POOL for temporary
> + allocations. */
> +static svn_error_t *
> +read_wcprops(svn_wc_adm_access_t *adm_access, apr_pool_t *pool)
> +{
> + apr_file_t *file;
> + apr_pool_t *cache_pool = svn_wc_adm_access_pool(adm_access);
> + apr_hash_t *all_wcprops;
> + apr_hash_t *proplist;
> + svn_stream_t *stream;
> + svn_error_t *err;
> +
> + /* If the WC format is too old, there is nothing to cache. */
> + if (svn_wc__adm_wc_format(adm_access) <= SVN_WC__WCPROPS_MANY_FILES_VERSION)
> + return SVN_NO_ERROR;
> +
> + all_wcprops = apr_hash_make(cache_pool);
> +
> + err = svn_wc__open_adm_file(&file, svn_wc_adm_access_path(adm_access),
> + SVN_WC__ADM_ALL_WCPROPS,
> + APR_READ | APR_BUFFERED, pool);
> +
> + /* A non-existent file means there are no props. */
> + if (err && APR_STATUS_IS_ENOENT(err->apr_err))
> + {
> + svn_error_clear(err);
> + svn_wc__adm_access_set_wcprops(adm_access, all_wcprops);
> + return SVN_NO_ERROR;
> + }
> + SVN_ERR(err);
> +
> + stream = svn_stream_from_aprfile2(file, TRUE, pool);
> +
> + /* Read the proplist for THIS_DIR. */
> + proplist = apr_hash_make(cache_pool);
> + SVN_ERR(svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR, cache_pool));
> + apr_hash_set(all_wcprops, SVN_WC_ENTRY_THIS_DIR, APR_HASH_KEY_STRING,
> + proplist);
> +
> + /* And now, the children. */
> + while (1729)
> + {
> + svn_stringbuf_t *line;
> + svn_boolean_t eof;
> + SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, cache_pool));
> + if (eof)
> + {
> + if (line->len > 0)
> + 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), pool));
> + break;
> + }
> + proplist = apr_hash_make(cache_pool);
> + SVN_ERR(svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR,
> + cache_pool));
> + apr_hash_set(all_wcprops, line->data, APR_HASH_KEY_STRING, proplist);
> + }
> +
> + svn_wc__adm_access_set_wcprops(adm_access, all_wcprops);
> +
> + SVN_ERR(svn_wc__close_adm_file(file, svn_wc_adm_access_path(adm_access),
> + SVN_WC__ADM_ALL_WCPROPS, FALSE, pool));
> +
> + return SVN_NO_ERROR;
> +}
> +
> +static svn_error_t *
> +write_wcprops(svn_wc_adm_access_t *adm_access, apr_pool_t *pool)
> +{
> + apr_hash_t *wcprops = svn_wc__adm_access_wcprops(adm_access);
> + apr_file_t *file;
> + svn_stream_t *stream;
> + apr_hash_t *proplist;
> + apr_hash_index_t *hi;
> + apr_pool_t *subpool = svn_pool_create(pool);
> + svn_boolean_t any_props = FALSE;
> +
> + /* If there are no cached wcprops, there is nothing to do. */
> + if (! wcprops)
> + return SVN_NO_ERROR;
> +
> + /* Check if there are any properties at all. */
> + for (hi = apr_hash_first(pool, wcprops); hi && ! any_props;
> + hi = apr_hash_next(hi))
> + {
> + void *val;
> +
> + apr_hash_this(hi, NULL, NULL, &val);
> + proplist = val;
> + if (apr_hash_count(proplist) > 0)
> + any_props = TRUE;
> + }
> +
> + /* If there are no props, remove the file. */
> + if (! any_props)
> + {
> + svn_error_t *err;
> +
> + err = svn_wc__remove_adm_file(svn_wc_adm_access_path(adm_access), pool,
> + SVN_WC__ADM_ALL_WCPROPS, NULL);
> + if (err && APR_STATUS_IS_ENOENT(err->apr_err))
> + {
> + svn_error_clear(err);
> + return SVN_NO_ERROR;
> + }
> + else
> + return err;
> + }
> +
> + SVN_ERR(svn_wc__open_adm_file(&file, svn_wc_adm_access_path(adm_access),
> + SVN_WC__ADM_ALL_WCPROPS,
> + APR_WRITE | APR_BUFFERED, pool));
> + stream = svn_stream_from_aprfile2(file, TRUE, pool);
> +
> + /* First, the props for this_dir. */
> + proplist = apr_hash_get(wcprops, SVN_WC_ENTRY_THIS_DIR, APR_HASH_KEY_STRING);
> + if (! proplist)
> + proplist = apr_hash_make(subpool);
> + SVN_ERR(svn_hash_write2(proplist, stream, SVN_HASH_TERMINATOR, subpool));
> +
> + /* Write children. */
> + for (hi = apr_hash_first(pool, wcprops); hi; hi = apr_hash_next(hi))
> + {
> + const void *key;
> + void *val;
> + const char *name;
> +
> + apr_hash_this(hi, &key, NULL, &val);
> + name = key;
> + proplist = val;
> +
> + /* We already wrote this_dir, and writing empty hashes makes me
> + feel silly... */
> + if (strcmp(SVN_WC_ENTRY_THIS_DIR, name) == 0
> + || apr_hash_count(proplist) == 0)
> + continue;
> +
> + svn_pool_clear(subpool);
> +
> + SVN_ERR(svn_stream_printf(stream, subpool, "%s\n", name));
> + SVN_ERR(svn_hash_write2(proplist, stream, SVN_HASH_TERMINATOR, subpool));
> + }
> +
> + SVN_ERR(svn_wc__close_adm_file(file, svn_wc_adm_access_path(adm_access),
> + SVN_WC__ADM_ALL_WCPROPS, TRUE, pool));
> +
> + return SVN_NO_ERROR;
> +}
> +
> +
> +svn_error_t *
> +svn_wc__props_flush(const char *path,
> + svn_wc__props_kind_t props_kind,
> + svn_wc_adm_access_t *adm_access,
> + apr_pool_t *pool)
> +{
> + if (props_kind != svn_wc__props_wcprop)
> + return SVN_NO_ERROR;
> + else
> + {
> + svn_wc_adm_access_t *prop_access;
> +
> + SVN_ERR(svn_wc_adm_probe_retrieve(&prop_access, adm_access,
> + path, pool));;
> + SVN_ERR(write_wcprops(prop_access, pool));
> + }
> +
> + return SVN_NO_ERROR;
> +}
> +
> +
> +static svn_error_t *
> +remove_wcprops(svn_wc_adm_access_t *adm_access,
> + const char *name,
> + apr_pool_t *pool)
> +{
> + apr_hash_t *all_wcprops = svn_wc__adm_access_wcprops(adm_access);
> + svn_boolean_t write_needed = FALSE;
> +
> + if (! name)
> + {
> + /* There is no point in reading the props just to determine if we
> + need to rewrite them:-), so assume a write is needed if the props
> + aren't already cached. */
> + if (! all_wcprops || apr_hash_count(all_wcprops) > 0)
> + {
> + svn_wc__adm_access_set_wcprops
> + (adm_access, apr_hash_make(svn_wc_adm_access_pool(adm_access)));
> + write_needed = TRUE;
> + }
> + }
> + else
> + {
> + apr_hash_t *wcprops;
> + if (! all_wcprops)
> + {
> + SVN_ERR(read_wcprops(adm_access, pool));
> + all_wcprops = svn_wc__adm_access_wcprops(adm_access);
> + }
> + if (all_wcprops)
> + wcprops = apr_hash_get(all_wcprops, name, APR_HASH_KEY_STRING);
> + else
> + wcprops = NULL;
> + if (wcprops && apr_hash_count(wcprops) > 0)
> + {
> + apr_hash_set(all_wcprops, name, APR_HASH_KEY_STRING, NULL);
> + write_needed = TRUE;
> + }
> + }
> + if (write_needed)
> + SVN_ERR(write_wcprops(adm_access, pool));
> +
> + return SVN_NO_ERROR;
> +}
> +
> svn_error_t *
> svn_wc__loggy_props_delete(svn_stringbuf_t **log_accum,
> const char *path,
> @@ -536,8 +755,40 @@
> {
> const char *props_file;
>
> - SVN_ERR(get_prop_path(&props_file, path, props_kind, adm_access, pool));
> - SVN_ERR(svn_wc__loggy_remove(log_accum, adm_access, props_file, pool));
> + if (props_kind == svn_wc__props_wcprop)
> + {
> + /* We use 1 file for all wcprops in a directory,
> + use a helper to remove them from that file */
> + apr_hash_t *props;
> + apr_pool_t *iterpool = svn_pool_create(pool);
> + apr_hash_index_t *hi;
> +
> + SVN_ERR(svn_wc__wcprop_list(&props, path, adm_access, pool));
> + /* ### TODO: There's no log command to delete all wcprops
> + from a file at once. Removing all props should do it though. */
> +
> + for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
> + {
> + const void *key;
> + const char *name;
> +
> + svn_pool_clear(iterpool);
> +
> + apr_hash_this(hi, &key, NULL, NULL);
> + name = key;
> +
> + SVN_ERR(svn_wc__loggy_modify_wcprop(log_accum,
> + adm_access, path,
> + name, NULL, iterpool));
> + }
> +
> + svn_pool_destroy(iterpool);
> + }
> + else
> + {
> + SVN_ERR(get_prop_path(&props_file, path, props_kind, adm_access, pool));
> + SVN_ERR(svn_wc__loggy_remove(log_accum, adm_access, props_file, pool));
> + }
>
> return SVN_NO_ERROR;
> }
> @@ -551,8 +802,25 @@
> {
> const char *props_file;
>
> - SVN_ERR(get_prop_path(&props_file, path, props_kind, adm_access, pool));
> - SVN_ERR(remove_file_if_present(props_file, pool));
> + if (props_kind == svn_wc__props_wcprop)
> + {
> + /* We use 1 file for all wcprops in a directory,
> + use a helper to remove them from that file */
> +
> + svn_wc_adm_access_t *path_access;
> +
> + SVN_ERR(svn_wc_adm_probe_retrieve(&path_access, adm_access,
> + path, pool));
> + SVN_ERR(remove_wcprops
> + (path_access,
> + svn_path_is_child(svn_wc_adm_access_path(path_access),
> + path, NULL), pool));
> + }
> + else
> + {
> + SVN_ERR(get_prop_path(&props_file, path, props_kind, adm_access, pool));
> + SVN_ERR(remove_file_if_present(props_file, pool));
> + }
>
> return SVN_NO_ERROR;
> }
> @@ -1387,157 +1655,6 @@
>
> /*** Private 'wc prop' functions ***/
>
> -/* If wcprops are stored in a single file in this working copy, read that file
> - and store it in the cache of ADM_ACCESS. Use POOL for temporary
> - allocations. */
> -static svn_error_t *
> -read_wcprops(svn_wc_adm_access_t *adm_access, apr_pool_t *pool)
> -{
> - apr_file_t *file;
> - apr_pool_t *cache_pool = svn_wc_adm_access_pool(adm_access);
> - apr_hash_t *all_wcprops;
> - apr_hash_t *proplist;
> - svn_stream_t *stream;
> - svn_error_t *err;
> -
> - /* If the WC format is too old, there is nothing to cache. */
> - if (svn_wc__adm_wc_format(adm_access) <= SVN_WC__WCPROPS_MANY_FILES_VERSION)
> - return SVN_NO_ERROR;
> -
> - all_wcprops = apr_hash_make(cache_pool);
> -
> - err = svn_wc__open_adm_file(&file, svn_wc_adm_access_path(adm_access),
> - SVN_WC__ADM_ALL_WCPROPS,
> - APR_READ | APR_BUFFERED, pool);
> -
> - /* A non-existent file means there are no props. */
> - if (err && APR_STATUS_IS_ENOENT(err->apr_err))
> - {
> - svn_error_clear(err);
> - svn_wc__adm_access_set_wcprops(adm_access, all_wcprops);
> - return SVN_NO_ERROR;
> - }
> - SVN_ERR(err);
> -
> - stream = svn_stream_from_aprfile2(file, TRUE, pool);
> -
> - /* Read the proplist for THIS_DIR. */
> - proplist = apr_hash_make(cache_pool);
> - SVN_ERR(svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR, cache_pool));
> - apr_hash_set(all_wcprops, SVN_WC_ENTRY_THIS_DIR, APR_HASH_KEY_STRING,
> - proplist);
> -
> - /* And now, the children. */
> - while (1729)
> - {
> - svn_stringbuf_t *line;
> - svn_boolean_t eof;
> - SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, cache_pool));
> - if (eof)
> - {
> - if (line->len > 0)
> - 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), pool));
> - break;
> - }
> - proplist = apr_hash_make(cache_pool);
> - SVN_ERR(svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR,
> - cache_pool));
> - apr_hash_set(all_wcprops, line->data, APR_HASH_KEY_STRING, proplist);
> - }
> -
> - svn_wc__adm_access_set_wcprops(adm_access, all_wcprops);
> -
> - SVN_ERR(svn_wc__close_adm_file(file, svn_wc_adm_access_path(adm_access),
> - SVN_WC__ADM_ALL_WCPROPS, FALSE, pool));
> -
> - return SVN_NO_ERROR;
> -}
> -
> -svn_error_t *
> -svn_wc__wcprops_write(svn_wc_adm_access_t *adm_access, apr_pool_t *pool)
> -{
> - apr_hash_t *wcprops = svn_wc__adm_access_wcprops(adm_access);
> - apr_file_t *file;
> - svn_stream_t *stream;
> - apr_hash_t *proplist;
> - apr_hash_index_t *hi;
> - apr_pool_t *subpool = svn_pool_create(pool);
> - svn_boolean_t any_props = FALSE;
> -
> - /* If there are no cached wcprops, there is nothing to do. */
> - if (! wcprops)
> - return SVN_NO_ERROR;
> -
> - /* Check if there are any properties at all. */
> - for (hi = apr_hash_first(pool, wcprops); hi && ! any_props;
> - hi = apr_hash_next(hi))
> - {
> - void *val;
> -
> - apr_hash_this(hi, NULL, NULL, &val);
> - proplist = val;
> - if (apr_hash_count(proplist) > 0)
> - any_props = TRUE;
> - }
> -
> - /* If there are no props, remove the file. */
> - if (! any_props)
> - {
> - svn_error_t *err;
> -
> - err = svn_wc__remove_adm_file(svn_wc_adm_access_path(adm_access), pool,
> - SVN_WC__ADM_ALL_WCPROPS, NULL);
> - if (err && APR_STATUS_IS_ENOENT(err->apr_err))
> - {
> - svn_error_clear(err);
> - return SVN_NO_ERROR;
> - }
> - else
> - return err;
> - }
> -
> - SVN_ERR(svn_wc__open_adm_file(&file, svn_wc_adm_access_path(adm_access),
> - SVN_WC__ADM_ALL_WCPROPS,
> - APR_WRITE | APR_BUFFERED, pool));
> - stream = svn_stream_from_aprfile2(file, TRUE, pool);
> -
> - /* First, the props for this_dir. */
> - proplist = apr_hash_get(wcprops, SVN_WC_ENTRY_THIS_DIR, APR_HASH_KEY_STRING);
> - if (! proplist)
> - proplist = apr_hash_make(subpool);
> - SVN_ERR(svn_hash_write2(proplist, stream, SVN_HASH_TERMINATOR, subpool));
> -
> - /* Write children. */
> - for (hi = apr_hash_first(pool, wcprops); hi; hi = apr_hash_next(hi))
> - {
> - const void *key;
> - void *val;
> - const char *name;
> -
> - apr_hash_this(hi, &key, NULL, &val);
> - name = key;
> - proplist = val;
> -
> - /* We already wrote this_dir, and writing empty hashes makes me
> - feel silly... */
> - if (strcmp(SVN_WC_ENTRY_THIS_DIR, name) == 0
> - || apr_hash_count(proplist) == 0)
> - continue;
> -
> - svn_pool_clear(subpool);
> -
> - SVN_ERR(svn_stream_printf(stream, subpool, "%s\n", name));
> - SVN_ERR(svn_hash_write2(proplist, stream, SVN_HASH_TERMINATOR, subpool));
> - }
> -
> - SVN_ERR(svn_wc__close_adm_file(file, svn_wc_adm_access_path(adm_access),
> - SVN_WC__ADM_ALL_WCPROPS, TRUE, pool));
> -
> - return SVN_NO_ERROR;
> -}
>
> svn_error_t *
> svn_wc__wcprop_list(apr_hash_t **wcprops,
> @@ -1658,7 +1775,7 @@
> if (svn_wc__adm_wc_format(adm_access) > SVN_WC__WCPROPS_MANY_FILES_VERSION)
> {
> if (force_write)
> - SVN_ERR(svn_wc__wcprops_write(adm_access, pool));
> + SVN_ERR(write_wcprops(adm_access, pool));
> }
> else
> {
>
> Modified: trunk/subversion/libsvn_wc/props.h
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/props.h?pathrev=26489&r1=26488&r2=26489
> ==============================================================================
> --- trunk/subversion/libsvn_wc/props.h (original)
> +++ trunk/subversion/libsvn_wc/props.h Thu Sep 6 14:31:47 2007
> @@ -101,12 +101,6 @@
> svn_boolean_t force_write,
> apr_pool_t *pool);
>
> -/* Write the wcprops cached in ADM_ACCESS, if any, to disk using POOL for
> - temporary allocations. */
> -svn_error_t *
> -svn_wc__wcprops_write(svn_wc_adm_access_t *adm_access, apr_pool_t *pool);
> -
> -
> /* Returns TRUE if PROPS contains the svn:special property */
> svn_boolean_t svn_wc__has_special_property(apr_hash_t *props);
>
> @@ -163,6 +157,14 @@
> apr_pool_t *pool);
>
>
> +/* Flushes props for PATH of PROPS_KIND cached in ADM_ACCESS to disk
> + using POOL for temporary allocations. */
> +svn_error_t *
> +svn_wc__props_flush(const char *path,
> + svn_wc__props_kind_t props_kind,
> + svn_wc_adm_access_t *adm_access,
> + apr_pool_t *pool);
> +
> /* Install PATHs working props as base props, clearing the
> has_prop_mods cache value in the entries file.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: svn-unsubscribe@subversion.tigris.org
> For additional commands, e-mail: svn-help@subversion.tigris.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Sep 7 11:52:05 2007

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