You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gs...@apache.org on 2010/03/11 07:37:44 UTC
svn commit: r921703 - /subversion/trunk/subversion/libsvn_wc/upgrade.c
Author: gstein
Date: Thu Mar 11 06:37:44 2010
New Revision: 921703
URL: http://svn.apache.org/viewvc?rev=921703&view=rev
Log:
Revamp the property reading within the upgrade code. A simple utility to
read a property has, given a filename is the key change here.
* subversion/libsvn_wc/upgrade.c:
(read_propfile): new function to read props from a given file
(read_many_wcprops): don't worry about streams and use read_propfile
instead of read_one_proplist (which is really designed to read a
series of wcprops from one mother file).
(migrate_props): switch over to read_propfile, and be wary for missing
"working_props" files. simplify using apr_pstrcat rather than a full
apr_sprintf. simplify tmp area removal.
Modified:
subversion/trunk/subversion/libsvn_wc/upgrade.c
Modified: subversion/trunk/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/upgrade.c?rev=921703&r1=921702&r2=921703&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_wc/upgrade.c Thu Mar 11 06:37:44 2010
@@ -60,6 +60,45 @@
#define ADM_EMPTY_FILE "empty-file"
+/* Read the properties from the file at PROPFILE_ABSPATH, returning them
+ as a hash in *PROPS. If the propfile is NOT present, then NULL will
+ be returned in *PROPS. */
+static svn_error_t *
+read_propfile(apr_hash_t **props,
+ const char *propfile_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_error_t *err;
+ svn_stream_t *stream;
+
+ err = svn_stream_open_readonly(&stream, propfile_abspath,
+ scratch_pool, scratch_pool);
+ if (err)
+ {
+ if (!APR_STATUS_IS_ENOENT(err->apr_err))
+ return svn_error_return(err);
+
+ /* The propfile was not there. Signal with a NULL. */
+ *props = NULL;
+ return SVN_NO_ERROR;
+ }
+
+ /* ### does this function need to be smarter? will we see zero-length
+ ### files? see props.c::load_props(). there may be more work here.
+ ### need a historic analysis of 1.x property storage. what will we
+ ### actually run into? */
+
+ /* ### should we be forgiving in here? I say "no". if we can't be sure,
+ ### then we could effectively corrupt the local working copy. */
+
+ *props = apr_hash_make(result_pool);
+ SVN_ERR(svn_hash_read2(*props, stream, SVN_HASH_TERMINATOR, result_pool));
+
+ return svn_error_return(svn_stream_close(stream));
+}
+
+
/* Read one proplist (allocated from RESULT_POOL) from STREAM, and place it
into ALL_WCPROPS at NAME. */
static svn_error_t *
@@ -88,9 +127,9 @@ read_many_wcprops(apr_hash_t **all_wcpro
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_stream_t *stream;
+ const char *propfile_abspath;
+ apr_hash_t *wcprops;
apr_hash_t *dirents;
- svn_error_t *err;
const char *props_dir_abspath;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
apr_hash_index_t *hi;
@@ -98,22 +137,12 @@ read_many_wcprops(apr_hash_t **all_wcpro
*all_wcprops = apr_hash_make(result_pool);
/* First, look at dir-wcprops. */
- err = svn_wc__open_adm_stream(&stream, dir_abspath, WCPROPS_FNAME_FOR_DIR,
- iterpool, iterpool);
- if (err)
- {
- /* If the file doesn't exist, it means no wcprops. */
- if (APR_STATUS_IS_ENOENT(err->apr_err))
- svn_error_clear(err);
- else
- return svn_error_return(err);
- }
- else
- {
- SVN_ERR(read_one_proplist(*all_wcprops, SVN_WC_ENTRY_THIS_DIR, stream,
- result_pool, iterpool));
- SVN_ERR(svn_stream_close(stream));
- }
+ propfile_abspath = svn_wc__adm_child(dir_abspath, WCPROPS_FNAME_FOR_DIR,
+ scratch_pool);
+ SVN_ERR(read_propfile(&wcprops, propfile_abspath, result_pool, iterpool));
+ if (wcprops != NULL)
+ apr_hash_set(*all_wcprops, SVN_WC_ENTRY_THIS_DIR, APR_HASH_KEY_STRING,
+ wcprops);
props_dir_abspath = svn_wc__adm_child(dir_abspath, WCPROPS_SUBDIR_FOR_FILES,
scratch_pool);
@@ -126,17 +155,17 @@ read_many_wcprops(apr_hash_t **all_wcpro
hi = apr_hash_next(hi))
{
const char *name = svn_apr_hash_index_key(hi);
- const char *prop_path;
svn_pool_clear(iterpool);
- prop_path = svn_dirent_join(props_dir_abspath, name, iterpool);
+ propfile_abspath = svn_dirent_join(props_dir_abspath, name, iterpool);
- SVN_ERR(svn_stream_open_readonly(&stream, prop_path,
- iterpool, iterpool));
- SVN_ERR(read_one_proplist(*all_wcprops, name, stream,
- result_pool, iterpool));
- SVN_ERR(svn_stream_close(stream));
+ SVN_ERR(read_propfile(&wcprops, propfile_abspath,
+ result_pool, iterpool));
+ SVN_ERR_ASSERT(wcprops != NULL);
+ apr_hash_set(*all_wcprops,
+ apr_pstrdup(result_pool, name), APR_HASH_KEY_STRING,
+ wcprops);
}
svn_pool_destroy(iterpool);
@@ -872,14 +901,17 @@ migrate_props(const char *wcroot_abspath
if (node is replaced):
revert -> BASE
- working -> ACTUAL
base -> WORKING
+ working -> ACTUAL
else if (prop pristine is working [as defined in props.c] ):
base -> WORKING
working -> ACTUAL
else:
base -> BASE
working -> ACTUAL
+
+ Note that it is legal for "working" props to be missing. That implies
+ no local changes to the properties.
*/
const apr_array_header_t *children;
apr_pool_t *iterpool;
@@ -888,6 +920,8 @@ migrate_props(const char *wcroot_abspath
svn_wc__db_t *db;
int i;
+ /* ### the use of DB within this function must go away. */
+
/* *sigh* We actually want to use wc_db APIs to read data, but we aren't
provided a wc_db, so open one. */
SVN_ERR(svn_wc__db_open(&db, svn_wc__db_openmode_default, NULL, FALSE, TRUE,
@@ -913,42 +947,43 @@ migrate_props(const char *wcroot_abspath
svn_boolean_t replaced;
apr_hash_t *working_props;
apr_hash_t *base_props;
- svn_stream_t *stream;
svn_pool_clear(iterpool);
/* Several useful paths. */
child_abspath = svn_dirent_join(wcroot_abspath, child_relpath, iterpool);
prop_base_path = svn_dirent_join(props_base_dirpath,
- apr_psprintf(iterpool, "%s" SVN_WC__BASE_EXT,
- child_relpath),
- iterpool);
+ apr_pstrcat(iterpool,
+ child_relpath,
+ SVN_WC__BASE_EXT,
+ NULL),
+ iterpool);
prop_working_path = svn_dirent_join(props_dirpath,
- apr_psprintf(iterpool, "%s" SVN_WC__WORK_EXT,
- child_relpath),
- iterpool);
+ apr_pstrcat(iterpool,
+ child_relpath,
+ SVN_WC__WORK_EXT,
+ NULL),
+ iterpool);
prop_revert_path = svn_dirent_join(props_base_dirpath,
- apr_psprintf(iterpool, "%s" SVN_WC__REVERT_EXT,
- child_relpath),
- iterpool);
-
- base_props = apr_hash_make(iterpool);
- SVN_ERR(svn_stream_open_readonly(&stream, prop_base_path, iterpool,
- iterpool));
- SVN_ERR(svn_hash_read2(base_props, stream, SVN_HASH_TERMINATOR,
- iterpool));
+ apr_pstrcat(iterpool,
+ child_relpath,
+ SVN_WC__REVERT_EXT,
+ NULL),
+ iterpool);
+
+ SVN_ERR(read_propfile(&base_props, prop_base_path, iterpool, iterpool));
+ SVN_ERR_ASSERT(base_props != NULL);
/* if node is replaced ... */
SVN_ERR(svn_wc__internal_is_replaced(&replaced, db, child_abspath,
iterpool));
if (replaced)
{
- apr_hash_t *revert_props = apr_hash_make(iterpool);
+ apr_hash_t *revert_props;
- SVN_ERR(svn_stream_open_readonly(&stream, prop_revert_path, iterpool,
- iterpool));
- SVN_ERR(svn_hash_read2(revert_props, stream, SVN_HASH_TERMINATOR,
- iterpool));
+ SVN_ERR(read_propfile(&revert_props, prop_revert_path,
+ iterpool, iterpool));
+ SVN_ERR_ASSERT(revert_props != NULL);
SVN_ERR(svn_wc__db_temp_op_set_pristine_props(db, child_abspath,
revert_props, FALSE,
@@ -967,28 +1002,26 @@ migrate_props(const char *wcroot_abspath
iterpool));
}
- working_props = apr_hash_make(iterpool);
- SVN_ERR(svn_stream_open_readonly(&stream, prop_working_path, iterpool,
- iterpool));
- SVN_ERR(svn_hash_read2(working_props, stream, SVN_HASH_TERMINATOR,
- iterpool));
-
- SVN_ERR(svn_wc__db_op_set_props(db, child_abspath, working_props,
- iterpool));
+ /* If the properties file does not exist, then that simply means
+ there were no changes made. Avoid setting new props in that case. */
+ SVN_ERR(read_propfile(&working_props, prop_working_path,
+ iterpool, iterpool));
+ if (working_props != NULL)
+ {
+ SVN_ERR(svn_wc__db_op_set_props(db, child_abspath, working_props,
+ iterpool));
+ }
}
/* Now delete the old directories. */
SVN_ERR(svn_io_remove_dir2(props_dirpath, TRUE, NULL, NULL, iterpool));
SVN_ERR(svn_io_remove_dir2(props_base_dirpath, TRUE, NULL, NULL,
iterpool));
- SVN_ERR(svn_io_remove_dir2(svn_dirent_join(wcroot_abspath,
- ".svn/" TEMP_DIR "/" PROPS_SUBDIR,
- iterpool),
- TRUE, NULL, NULL, iterpool));
- SVN_ERR(svn_io_remove_dir2(svn_dirent_join(wcroot_abspath,
- ".svn/" TEMP_DIR "/" PROP_BASE_SUBDIR,
- iterpool),
- TRUE, NULL, NULL, iterpool));
+
+#if 0
+ /* ### we are not (yet) taking out a write lock */
+ SVN_ERR(svn_wc__adm_cleanup_tmp_area(db, wcroot_abspath, iterpool));
+#endif
SVN_ERR(svn_wc__db_close(db));
svn_pool_destroy(iterpool);