Modified: subversion/branches/ev2-export/subversion/libsvn_wc/deprecated.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/deprecated.c?rev=1400556&r1=1400555&r2=1400556&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/libsvn_wc/deprecated.c (original) +++ subversion/branches/ev2-export/subversion/libsvn_wc/deprecated.c Sun Oct 21 02:00:31 2012 @@ -3269,7 +3269,7 @@ svn_wc_get_update_editor4(const svn_delt target_revision, wc_ctx, anchor_abspath, - target_basename, + target_basename, NULL, use_commit_times, depth, depth_is_sticky, allow_unver_obstructions, @@ -3455,7 +3455,7 @@ svn_wc_get_switch_editor4(const svn_delt target_revision, wc_ctx, anchor_abspath, target_basename, - switch_url, + switch_url, NULL, use_commit_times, depth, depth_is_sticky, allow_unver_obstructions, @@ -4463,3 +4463,22 @@ svn_wc_crop_tree(svn_wc_adm_access_t *an return svn_error_trace(svn_wc_context_destroy(wc_ctx)); } + +svn_error_t * +svn_wc_move(svn_wc_context_t *wc_ctx, + const char *src_abspath, + const char *dst_abspath, + svn_boolean_t metadata_only, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool) +{ + return svn_error_trace(svn_wc__move2(wc_ctx, src_abspath, dst_abspath, + metadata_only, + TRUE, /* allow_mixed_revisions */ + cancel_func, cancel_baton, + notify_func, notify_baton, + scratch_pool)); +}
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/entries.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/entries.c?rev=1400556&r1=1400555&r2=1400556&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/libsvn_wc/entries.c (original) +++ subversion/branches/ev2-export/subversion/libsvn_wc/entries.c Sun Oct 21 02:00:31 2012 @@ -455,6 +455,7 @@ read_one_entry(const svn_wc_entry_t **ne SVN_ERR(svn_wc__read_conflicts(&child_conflicts, db, child_abspath, + FALSE /* create tempfiles */, scratch_pool, scratch_pool)); for (j = 0; j < child_conflicts->nelts; j++) @@ -874,37 +875,53 @@ read_one_entry(const svn_wc_entry_t **ne if (conflicted) { - const apr_array_header_t *conflicts; - int j; - SVN_ERR(svn_wc__read_conflicts(&conflicts, db, entry_abspath, - scratch_pool, scratch_pool)); - - for (j = 0; j < conflicts->nelts; j++) - { - const svn_wc_conflict_description2_t *cd; - cd = APR_ARRAY_IDX(conflicts, j, - const svn_wc_conflict_description2_t *); + svn_skel_t *conflict; + svn_boolean_t text_conflicted; + svn_boolean_t prop_conflicted; + SVN_ERR(svn_wc__db_read_conflict(&conflict, db, entry_abspath, + scratch_pool, scratch_pool)); - switch (cd->kind) - { - case svn_wc_conflict_kind_text: - if (cd->base_abspath) - entry->conflict_old = svn_dirent_basename(cd->base_abspath, - result_pool); - if (cd->their_abspath) - entry->conflict_new = svn_dirent_basename(cd->their_abspath, - result_pool); - if (cd->my_abspath) - entry->conflict_wrk = svn_dirent_basename(cd->my_abspath, - result_pool); - break; - case svn_wc_conflict_kind_property: - entry->prejfile = svn_dirent_basename(cd->their_abspath, - result_pool); - break; - case svn_wc_conflict_kind_tree: - break; - } + SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, &text_conflicted, + &prop_conflicted, NULL, + db, dir_abspath, conflict, + scratch_pool, scratch_pool)); + + if (text_conflicted) + { + const char *my_abspath; + const char *their_old_abspath; + const char *their_abspath; + SVN_ERR(svn_wc__conflict_read_text_conflict(&my_abspath, + &their_old_abspath, + &their_abspath, + db, dir_abspath, + conflict, scratch_pool, + scratch_pool)); + + if (my_abspath) + entry->conflict_wrk = svn_dirent_basename(my_abspath, result_pool); + + if (their_old_abspath) + entry->conflict_old = svn_dirent_basename(their_old_abspath, + result_pool); + + if (their_abspath) + entry->conflict_new = svn_dirent_basename(their_abspath, + result_pool); + } + + if (prop_conflicted) + { + const char *prej_abspath; + + SVN_ERR(svn_wc__conflict_read_prop_conflict(&prej_abspath, NULL, + NULL, NULL, NULL, + db, dir_abspath, + conflict, scratch_pool, + scratch_pool)); + + if (prej_abspath) + entry->prejfile = svn_dirent_basename(prej_abspath, result_pool); } } @@ -1459,7 +1476,7 @@ insert_node(svn_sqlite__db_t *sdb, else if (node->presence == svn_wc__db_status_excluded) SVN_ERR(svn_sqlite__bind_text(stmt, 8, "excluded")); else if (node->presence == svn_wc__db_status_server_excluded) - SVN_ERR(svn_sqlite__bind_text(stmt, 8, "absent")); + SVN_ERR(svn_sqlite__bind_text(stmt, 8, "server-excluded")); if (node->kind == svn_node_none) SVN_ERR(svn_sqlite__bind_text(stmt, 10, "unknown")); @@ -1508,9 +1525,7 @@ insert_actual_node(svn_sqlite__db_t *sdb apr_pool_t *scratch_pool) { svn_sqlite__stmt_t *stmt; -#if SVN_WC__VERSION >= SVN_WC__USES_CONFLICT_SKELS svn_skel_t *conflict_data = NULL; -#endif SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_ACTUAL_NODE)); @@ -1525,22 +1540,6 @@ insert_actual_node(svn_sqlite__db_t *sdb if (actual_node->changelist) SVN_ERR(svn_sqlite__bind_text(stmt, 5, actual_node->changelist)); -#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS - if (actual_node->conflict_old - || actual_node->conflict_new - || actual_node->conflict_working) - { - SVN_ERR(svn_sqlite__bind_text(stmt, 7, actual_node->conflict_old)); - SVN_ERR(svn_sqlite__bind_text(stmt, 8, actual_node->conflict_new)); - SVN_ERR(svn_sqlite__bind_text(stmt, 9, actual_node->conflict_working)); - } - - if (actual_node->prop_reject) - SVN_ERR(svn_sqlite__bind_text(stmt, 10, actual_node->prop_reject)); - - if (actual_node->tree_conflict_data) - SVN_ERR(svn_sqlite__bind_text(stmt, 11, actual_node->tree_conflict_data)); -#else SVN_ERR(svn_wc__upgrade_conflict_skel_from_raw( &conflict_data, db, wri_abspath, @@ -1559,7 +1558,6 @@ insert_actual_node(svn_sqlite__db_t *sdb SVN_ERR(svn_sqlite__bind_blob(stmt, 6, data->data, data->len)); } -#endif /* Execute and reset the insert clause. */ return svn_error_trace(svn_sqlite__insert(NULL, stmt)); Modified: subversion/branches/ev2-export/subversion/libsvn_wc/externals.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/externals.c?rev=1400556&r1=1400555&r2=1400556&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/libsvn_wc/externals.c (original) +++ subversion/branches/ev2-export/subversion/libsvn_wc/externals.c Sun Oct 21 02:00:31 2012 @@ -381,6 +381,10 @@ struct edit_baton /* List of incoming propchanges */ apr_array_header_t *propchanges; + /* Array of svn_prop_inherited_item_t * structures representing the + properties inherited by the base node at LOCAL_ABSPATH. */ + apr_array_header_t *iprops; + /* The last change information */ svn_revnum_t changed_rev; apr_time_t changed_date; @@ -810,6 +814,7 @@ close_file(void *file_baton, eb->repos_uuid, *eb->target_revision, new_pristine_props, + eb->iprops, eb->changed_rev, eb->changed_date, eb->changed_author, @@ -825,6 +830,12 @@ close_file(void *file_baton, all_work_items, pool)); + /* close_edit may also update iprops for switched files, catching + those for which close_file is never called (e.g. an update of a + file external with no changes). So as a minor optimization we + clear the iprops so as not to set them again in close_edit. */ + eb->iprops = NULL; + SVN_ERR(svn_wc__wq_run(eb->db, eb->wri_abspath, eb->cancel_func, eb->cancel_baton, pool)); } @@ -864,8 +875,18 @@ close_edit(void *edit_baton, { struct edit_baton *eb = edit_baton; - if (!eb->file_closed) + if (!eb->file_closed + || eb->iprops) { + apr_hash_t *wcroot_iprops = NULL; + + if (eb->iprops) + { + wcroot_iprops = apr_hash_make(pool); + apr_hash_set(wcroot_iprops, eb->local_abspath, APR_HASH_KEY_STRING, + eb->iprops); + } + /* The node wasn't updated, so we just have to bump its revision */ SVN_ERR(svn_wc__db_op_bump_revisions_post_update(eb->db, eb->local_abspath, @@ -873,6 +894,7 @@ close_edit(void *edit_baton, NULL, NULL, NULL, *eb->target_revision, apr_hash_make(pool), + wcroot_iprops, pool)); } @@ -889,6 +911,7 @@ svn_wc__get_file_external_editor(const s const char *url, const char *repos_root_url, const char *repos_uuid, + apr_array_header_t *iprops, svn_boolean_t use_commit_times, const char *diff3_cmd, const apr_array_header_t *preserved_exts, @@ -924,6 +947,8 @@ svn_wc__get_file_external_editor(const s eb->repos_root_url = apr_pstrdup(edit_pool, repos_root_url); eb->repos_uuid = apr_pstrdup(edit_pool, repos_uuid); + eb->iprops = iprops; + eb->use_commit_times = use_commit_times; eb->ext_patterns = preserved_exts; eb->diff3cmd = diff3_cmd; @@ -1288,6 +1313,7 @@ svn_error_t * svn_wc__external_remove(svn_wc_context_t *wc_ctx, const char *wri_abspath, const char *local_abspath, + svn_boolean_t declaration_only, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *scratch_pool) @@ -1303,9 +1329,12 @@ svn_wc__external_remove(svn_wc_context_t SVN_ERR(svn_wc__db_external_remove(wc_ctx->db, local_abspath, wri_abspath, NULL, scratch_pool)); + if (declaration_only) + return SVN_NO_ERROR; + if (kind == svn_kind_dir) SVN_ERR(svn_wc_remove_from_revision_control2(wc_ctx, local_abspath, - TRUE, FALSE, + TRUE, TRUE, cancel_func, cancel_baton, scratch_pool)); else @@ -1550,7 +1579,7 @@ svn_wc__resolve_relative_external_url(co /* The remaining URLs are relative to either the scheme or server root and can only refer to locations inside that scope, so backpaths are not allowed. */ - if (svn_path_is_backpath_present(url + 2)) + if (svn_path_is_backpath_present(url)) return svn_error_createf(SVN_ERR_BAD_URL, 0, _("The external relative URL '%s' cannot have " "backpaths, i.e. '..'"), Modified: subversion/branches/ev2-export/subversion/libsvn_wc/info.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/info.c?rev=1400556&r1=1400555&r2=1400556&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/libsvn_wc/info.c (original) +++ subversion/branches/ev2-export/subversion/libsvn_wc/info.c Sun Oct 21 02:00:31 2012 @@ -281,6 +281,7 @@ build_info_for_node(svn_wc__info2_t **in if (conflicted) SVN_ERR(svn_wc__read_conflicts(&wc_info->conflicts, db, local_abspath, + TRUE /* ### create tempfiles */, result_pool, scratch_pool)); else wc_info->conflicts = NULL; @@ -475,25 +476,25 @@ svn_wc__get_info(svn_wc_context_t *wc_ct && fetch_actual_only && err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) { - const svn_wc_conflict_description2_t *root_tree_conflict; + svn_boolean_t tree_conflicted; svn_error_t *err2; - err2 = svn_wc__get_tree_conflict(&root_tree_conflict, - wc_ctx, local_abspath, - scratch_pool, iterpool); + err2 = svn_wc__internal_conflicted_p(NULL, NULL, &tree_conflicted, + wc_ctx->db, local_abspath, + iterpool); if ((err2 && err2->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)) { svn_error_clear(err2); return svn_error_trace(err); } - else if (err2 || !root_tree_conflict) + else if (err2 || !tree_conflicted) return svn_error_compose_create(err, err2); svn_error_clear(err); apr_hash_set(fe_baton.tree_conflicts, local_abspath, - APR_HASH_KEY_STRING, root_tree_conflict); + APR_HASH_KEY_STRING, ""); } else SVN_ERR(err); @@ -526,6 +527,7 @@ svn_wc__get_info(svn_wc_context_t *wc_ct SVN_ERR(svn_wc__read_conflicts(&info->wc_info->conflicts, wc_ctx->db, this_abspath, + TRUE /* ### create tempfiles */, iterpool, iterpool)); if (! info->wc_info->conflicts || ! info->wc_info->conflicts->nelts) Modified: subversion/branches/ev2-export/subversion/libsvn_wc/lock.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/lock.c?rev=1400556&r1=1400555&r2=1400556&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/libsvn_wc/lock.c (original) +++ subversion/branches/ev2-export/subversion/libsvn_wc/lock.c Sun Oct 21 02:00:31 2012 @@ -97,7 +97,8 @@ svn_wc__internal_check_wc(int *wc_format { svn_node_kind_t kind; - if (err->apr_err != SVN_ERR_WC_MISSING) + if (err->apr_err != SVN_ERR_WC_MISSING && + err->apr_err != SVN_ERR_WC_UNSUPPORTED_FORMAT) return svn_error_trace(err); svn_error_clear(err); @@ -1529,6 +1530,21 @@ svn_wc__acquire_write_lock(const char ** svn_dirent_local_style(local_abspath, scratch_pool)); + if (lock_anchor && kind == svn_kind_dir) + { + svn_boolean_t is_wcroot; + + SVN_ERR_ASSERT(lock_root_abspath != NULL); + + /* Perform a cheap check to avoid looking for a parent working copy, + which might be very expensive in some specific scenarios */ + SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, local_abspath, + scratch_pool)); + + if (is_wcroot) + lock_anchor = FALSE; + } + if (lock_anchor) { const char *parent_abspath; Modified: subversion/branches/ev2-export/subversion/libsvn_wc/merge.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/merge.c?rev=1400556&r1=1400555&r2=1400556&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/libsvn_wc/merge.c (original) +++ subversion/branches/ev2-export/subversion/libsvn_wc/merge.c Sun Oct 21 02:00:31 2012 @@ -241,13 +241,11 @@ detranslate_wc_file(const char **detrans if (force_copy || keywords || eol || special) { - const char *wcroot_abspath, *temp_dir_abspath; + const char *temp_dir_abspath; const char *detranslated; /* Force a copy into the temporary wc area to avoid having temporary files created below to appear in the actual wc. */ - SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath, mt->db, mt->wri_abspath, - scratch_pool, scratch_pool)); SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath, mt->db, mt->wri_abspath, scratch_pool, scratch_pool)); @@ -531,7 +529,8 @@ preserve_pre_merge_files(svn_skel_t **wo SVN_ERR(svn_io_copy_file(left_abspath, tmp_left, TRUE, scratch_pool)); /* And create a wq item to remove the file later */ - SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, tmp_left, + SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, wcroot_abspath, + tmp_left, result_pool, scratch_pool)); last_items = svn_wc__wq_merge(last_items, work_item, result_pool); @@ -547,7 +546,8 @@ preserve_pre_merge_files(svn_skel_t **wo SVN_ERR(svn_io_copy_file(right_abspath, tmp_right, TRUE, scratch_pool)); /* And create a wq item to remove the file later */ - SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, tmp_right, + SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, wcroot_abspath, + tmp_right, result_pool, scratch_pool)); last_items = svn_wc__wq_merge(last_items, work_item, result_pool); @@ -597,7 +597,7 @@ preserve_pre_merge_files(svn_skel_t **wo *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool); /* And maybe delete some tempfiles */ - SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, + SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, wcroot_abspath, detranslated_target_copy, result_pool, scratch_pool)); *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool); @@ -626,6 +626,8 @@ merge_file_trivial(svn_skel_t **work_ite const char *detranslated_target_abspath, svn_boolean_t dry_run, svn_wc__db_t *db, + svn_cancel_func_t cancel_func, + void *cancel_baton, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { @@ -670,6 +672,43 @@ merge_file_trivial(svn_skel_t **work_ite *merge_outcome = svn_wc_merge_merged; if (!dry_run) { + const char *wcroot_abspath; + svn_boolean_t delete_src = FALSE; + + /* The right_abspath might be outside our working copy. In that + case we should copy the file to a safe location before + installing to avoid breaking the workqueue. + + This matches the behavior in preserve_pre_merge_files */ + + SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath, + db, target_abspath, + scratch_pool, scratch_pool)); + + if (!svn_dirent_is_child(wcroot_abspath, right_abspath, NULL)) + { + svn_stream_t *tmp_src; + svn_stream_t *tmp_dst; + + SVN_ERR(svn_stream_open_readonly(&tmp_src, right_abspath, + scratch_pool, + scratch_pool)); + + SVN_ERR(svn_wc__open_writable_base(&tmp_dst, &right_abspath, + NULL, NULL, + db, target_abspath, + scratch_pool, + scratch_pool)); + + SVN_ERR(svn_stream_copy3(tmp_src, tmp_dst, + cancel_func, cancel_baton, + scratch_pool)); + + /* no need to strdup right_abspath, as the wq_build_() + call already does that for us */ + delete_src = TRUE; + } + SVN_ERR(svn_wc__wq_build_file_install( &work_item, db, target_abspath, right_abspath, FALSE /* use_commit_times */, @@ -677,6 +716,16 @@ merge_file_trivial(svn_skel_t **work_ite result_pool, scratch_pool)); *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool); + + if (delete_src) + { + SVN_ERR(svn_wc__wq_build_file_remove( + &work_item, db, wcroot_abspath, + right_abspath, + result_pool, scratch_pool)); + *work_items = svn_wc__wq_merge(*work_items, work_item, + result_pool); + } } } @@ -786,9 +835,7 @@ merge_text_file(svn_skel_t **work_items, result_pool, scratch_pool)); *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool); - /* Track the three conflict files in the metadata. - * ### TODO WC-NG: Do this outside the work queue: see - * svn_wc__wq_tmp_build_set_text_conflict_markers()'s doc string. */ + /* Track the conflict marker files in the metadata. */ if (!*conflict_skel) *conflict_skel = svn_wc__conflict_skel_create(result_pool); @@ -842,8 +889,8 @@ merge_text_file(svn_skel_t **work_items, done: /* Remove the tempfile after use */ - SVN_ERR(svn_wc__wq_build_file_remove(&work_item, - mt->db, result_target, + SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, mt->local_abspath, + result_target, result_pool, scratch_pool)); *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool); @@ -1019,7 +1066,8 @@ svn_wc__internal_merge(svn_skel_t **work SVN_ERR(merge_file_trivial(work_items, merge_outcome, left_abspath, right_abspath, target_abspath, detranslated_target_abspath, - dry_run, db, result_pool, scratch_pool)); + dry_run, db, cancel_func, cancel_baton, + result_pool, scratch_pool)); if (*merge_outcome == svn_wc_merge_no_merge) { if (is_binary) Modified: subversion/branches/ev2-export/subversion/libsvn_wc/node.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/node.c?rev=1400556&r1=1400555&r2=1400556&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/libsvn_wc/node.c (original) +++ subversion/branches/ev2-export/subversion/libsvn_wc/node.c Sun Oct 21 02:00:31 2012 @@ -768,30 +768,12 @@ svn_wc__node_get_deleted_ancestor(const } svn_error_t * -svn_wc__node_is_status_server_excluded(svn_boolean_t *is_server_excluded, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *scratch_pool) -{ - svn_wc__db_status_t status; - - SVN_ERR(svn_wc__db_read_info(&status, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - wc_ctx->db, local_abspath, - scratch_pool, scratch_pool)); - *is_server_excluded = (status == svn_wc__db_status_server_excluded); - - return SVN_NO_ERROR; -} - -svn_error_t * -svn_wc__node_is_status_not_present(svn_boolean_t *is_not_present, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *scratch_pool) +svn_wc__node_is_not_present(svn_boolean_t *is_not_present, + svn_boolean_t *is_excluded, + svn_boolean_t *is_server_excluded, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *scratch_pool) { svn_wc__db_status_t status; @@ -802,27 +784,15 @@ svn_wc__node_is_status_not_present(svn_b NULL, NULL, NULL, NULL, NULL, wc_ctx->db, local_abspath, scratch_pool, scratch_pool)); - *is_not_present = (status == svn_wc__db_status_not_present); - return SVN_NO_ERROR; -} + if (is_not_present) + *is_not_present = (status == svn_wc__db_status_not_present); -svn_error_t * -svn_wc__node_is_status_excluded(svn_boolean_t *is_excluded, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *scratch_pool) -{ - svn_wc__db_status_t status; + if (is_excluded) + *is_excluded = (status == svn_wc__db_status_excluded); - SVN_ERR(svn_wc__db_read_info(&status, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - wc_ctx->db, local_abspath, - scratch_pool, scratch_pool)); - *is_excluded = (status == svn_wc__db_status_excluded); + if (is_server_excluded) + *is_server_excluded = (status == svn_wc__db_status_server_excluded); return SVN_NO_ERROR; } @@ -1379,6 +1349,15 @@ svn_wc__internal_get_origin(svn_boolean_ return SVN_NO_ERROR; /* Local addition */ } + /* We don't know how the following error condition can be fulfilled + * but we have seen that happening in the wild. Better to create + * an error than a SEGFAULT. */ + if (status == svn_wc__db_status_incomplete && !original_repos_relpath) + return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, + _("Incomplete copy information on path '%s'."), + svn_dirent_local_style(local_abspath, + scratch_pool)); + *repos_relpath = svn_relpath_join( original_repos_relpath, svn_dirent_skip_ancestor(op_root_abspath, Modified: subversion/branches/ev2-export/subversion/libsvn_wc/props.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/props.c?rev=1400556&r1=1400555&r2=1400556&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/libsvn_wc/props.c (original) +++ subversion/branches/ev2-export/subversion/libsvn_wc/props.c Sun Oct 21 02:00:31 2012 @@ -46,6 +46,7 @@ #include "svn_wc.h" #include "svn_utf.h" #include "svn_diff.h" +#include "svn_sorts.h" #include "private/svn_wc_private.h" #include "private/svn_mergeinfo_private.h" @@ -1207,7 +1208,7 @@ svn_wc__merge_props(svn_skel_t **conflic *new_actual_props = NULL; if (!server_baseprops) - server_baseprops = pristine_props; + server_baseprops = apr_hash_copy(scratch_pool, pristine_props); their_props = apr_hash_copy(scratch_pool, server_baseprops); @@ -1227,7 +1228,9 @@ svn_wc__merge_props(svn_skel_t **conflic const char *propname; svn_boolean_t conflict_remains; const svn_prop_t *incoming_change; - const svn_string_t *from_val, *to_val, *base_val; + const svn_string_t *base_val; /* Pristine in WC */ + const svn_string_t *from_val; /* Merge left */ + const svn_string_t *to_val; /* Merge right */ svn_pool_clear(iterpool); @@ -2330,3 +2333,151 @@ svn_wc__has_magic_property(const apr_arr } return FALSE; } + +/* Remove all prop name value pairs from PROP_HASH where the property + name is not PROPNAME. */ +static void +filter_unwanted_props(apr_hash_t *prop_hash, + const char * propname, + apr_pool_t *scratch_pool) +{ + apr_hash_index_t *hi; + + for (hi = apr_hash_first(scratch_pool, prop_hash); + hi; + hi = apr_hash_next(hi)) + { + const char *ipropname = svn__apr_hash_index_key(hi); + + if (strcmp(ipropname, propname) != 0) + apr_hash_set(prop_hash, ipropname, APR_HASH_KEY_STRING, NULL); + } + return; +} + +svn_error_t * +svn_wc__get_iprops(apr_array_header_t **inherited_props, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + const char *propname, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + int i; + apr_array_header_t *cached_iprops = NULL; + const char *parent_abspath = local_abspath; + svn_boolean_t is_wc_root = FALSE; + apr_pool_t *iterpool = svn_pool_create(scratch_pool); + + SVN_ERR_ASSERT(inherited_props); + *inherited_props = apr_array_make(result_pool, 1, + sizeof(svn_prop_inherited_item_t *)); + + /* Walk up to the root of the WC looking for inherited properties. When we + reach the WC root also check for cached inherited properties. */ + while (TRUE) + { + apr_hash_t *actual_props; + + svn_pool_clear(iterpool); + + SVN_ERR(svn_wc_is_wc_root2(&is_wc_root, wc_ctx, parent_abspath, + iterpool)); + if (is_wc_root) + { + const char *child_repos_relpath; + + SVN_ERR(svn_wc__node_get_repos_relpath(&child_repos_relpath, + wc_ctx, parent_abspath, + iterpool, iterpool)); + + /* If the WC root is also the root of the repository then by + definition there are no inheritable properties to be had. */ + if (child_repos_relpath[0] != '\0') + { + /* Grab the cached inherited properties for the WC root. */ + SVN_ERR(svn_wc__db_read_cached_iprops(&cached_iprops, + wc_ctx->db, + parent_abspath, + scratch_pool, + iterpool)); + } + } + + /* If PARENT_ABSPATH is a true parent of LOCAL_ABSPATH, then + LOCAL_ABSPATH can inherit properties from it. */ + if (strcmp(local_abspath, parent_abspath) != 0) + { + SVN_ERR(svn_wc__db_read_props(&actual_props, wc_ctx->db, + parent_abspath, result_pool, + iterpool)); + if (actual_props) + { + /* If we only want PROPNAME filter out any other properties. */ + if (propname) + filter_unwanted_props(actual_props, propname, iterpool); + + if (apr_hash_count(actual_props)) + { + svn_prop_inherited_item_t *iprop_elt = + apr_pcalloc(result_pool, + sizeof(svn_prop_inherited_item_t)); + iprop_elt->path_or_url = apr_pstrdup(result_pool, + parent_abspath); + iprop_elt->prop_hash = actual_props; + /* Build the output array in depth-first order. */ + svn_sort__array_insert(&iprop_elt, *inherited_props, 0); + } + } + } + + /* Inheritance only goes as far as the nearest WC root. */ + if (is_wc_root) + break; + + /* Keep looking for the WC root. */ + parent_abspath = svn_dirent_dirname(parent_abspath, scratch_pool); + } + + if (cached_iprops) + { + for (i = cached_iprops->nelts - 1; i >= 0; i--) + { + svn_prop_inherited_item_t *cached_iprop = + APR_ARRAY_IDX(cached_iprops, i, svn_prop_inherited_item_t *); + + /* An empty property hash in the iprops cache means there are no + inherited properties. */ + if (apr_hash_count(cached_iprop->prop_hash) == 0) + continue; + + if (propname) + filter_unwanted_props(cached_iprop->prop_hash, propname, + scratch_pool); + + /* If we didn't filter everything then keep this iprop. */ + if (apr_hash_count(cached_iprop->prop_hash)) + svn_sort__array_insert(&cached_iprop, *inherited_props, 0); + } + } + + svn_pool_destroy(iterpool); + return SVN_NO_ERROR; +} + +svn_error_t * +svn_wc__get_cached_iprop_children(apr_hash_t **iprop_paths, + svn_depth_t depth, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + SVN_ERR(svn_wc__db_get_children_with_cached_iprops(iprop_paths, + depth, + local_abspath, + wc_ctx->db, + result_pool, + scratch_pool)); + return SVN_NO_ERROR; +} Modified: subversion/branches/ev2-export/subversion/libsvn_wc/status.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/status.c?rev=1400556&r1=1400555&r2=1400556&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/libsvn_wc/status.c (original) +++ subversion/branches/ev2-export/subversion/libsvn_wc/status.c Sun Oct 21 02:00:31 2012 @@ -1354,7 +1354,19 @@ get_dir_status(const struct walk_status_ /* Handle "this-dir" first. */ if (! skip_this_dir) { -#ifdef HAVE_SYMLINK + /* This code is not conditional on HAVE_SYMLINK as some systems that do + not allow creating symlinks (!HAVE_SYMLINK) can still encounter + symlinks (or in case of Windows also 'Junctions') created by other + methods. + + Without this block a working copy in the root of a junction is + reported as an obstruction, because the junction itself is reported as + special. + + Systems that have no symlink support at all, would always see + dirent->special as FALSE, so even there enabling this code shouldn't + produce problems. + */ if (dirent->special) { svn_io_dirent2_t *this_dirent = svn_io_dirent2_dup(dirent, iterpool); @@ -1375,7 +1387,6 @@ get_dir_status(const struct walk_status_ iterpool)); } else -#endif SVN_ERR(send_status_structure(wb, local_abspath, parent_repos_root_url, parent_repos_relpath, Modified: subversion/branches/ev2-export/subversion/libsvn_wc/tree_conflicts.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/tree_conflicts.c?rev=1400556&r1=1400555&r2=1400556&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/libsvn_wc/tree_conflicts.c (original) +++ subversion/branches/ev2-export/subversion/libsvn_wc/tree_conflicts.c Sun Oct 21 02:00:31 2012 @@ -78,7 +78,6 @@ const svn_token_map_t svn_wc__conflict_r { "replaced", svn_wc_conflict_reason_replaced }, { "unversioned", svn_wc_conflict_reason_unversioned }, { "moved-away", svn_wc_conflict_reason_moved_away }, - { "moved-away-and-edited", svn_wc_conflict_reason_moved_away_and_edited }, { "moved-here", svn_wc_conflict_reason_moved_here }, { NULL } }; @@ -183,11 +182,12 @@ read_node_version_info(const svn_wc_conf skel->children->next->next->next->next)); kind = (svn_node_kind_t)n; - *version_info = svn_wc_conflict_version_create(repos_root, - repos_relpath, - peg_rev, - kind, - result_pool); + *version_info = svn_wc_conflict_version_create2(repos_root, + NULL, + repos_relpath, + peg_rev, + kind, + result_pool); return SVN_NO_ERROR; } @@ -473,7 +473,7 @@ svn_wc__get_tree_conflict(const svn_wc_c SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath)); SVN_ERR(svn_wc__read_conflicts(&conflicts, - wc_ctx->db, local_abspath, + wc_ctx->db, local_abspath, FALSE, scratch_pool, scratch_pool)); if (!conflicts || conflicts->nelts == 0)
