Modified: subversion/branches/svn-info-detail/subversion/libsvn_client/merge.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_client/merge.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_client/merge.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_client/merge.c Tue Feb 24 15:23:33 2015 @@ -6131,8 +6131,9 @@ insert_parent_and_sibs_of_sw_absent_del_ } /*(parent == NULL) */ /* Add all of PARENT's non-missing children that are not already present.*/ - SVN_ERR(svn_wc__node_get_children(&children, ctx->wc_ctx, - parent_abspath, FALSE, pool, pool)); + SVN_ERR(svn_wc__node_get_children_of_working_node(&children, ctx->wc_ctx, + parent_abspath, + pool, pool)); iterpool = svn_pool_create(pool); for (i = 0; i < children->nelts; i++) { @@ -6614,7 +6615,7 @@ get_mergeinfo_paths(apr_array_header_t * SVN_ERR(svn_wc__node_get_children_of_working_node( &immediate_children, ctx->wc_ctx, - target->abspath, FALSE, scratch_pool, scratch_pool)); + target->abspath, scratch_pool, scratch_pool)); for (j = 0; j < immediate_children->nelts; j++) { @@ -6698,9 +6699,10 @@ get_mergeinfo_paths(apr_array_header_t * const apr_array_header_t *children; int j; - SVN_ERR(svn_wc__node_get_children(&children, + SVN_ERR(svn_wc__node_get_children_of_working_node( + &children, ctx->wc_ctx, - child->abspath, FALSE, + child->abspath, iterpool, iterpool)); for (j = 0; j < children->nelts; j++) { @@ -10269,7 +10271,7 @@ ensure_wc_is_suitable_merge_target(const svn_boolean_t is_modified; SVN_ERR(svn_wc__has_local_mods(&is_modified, ctx->wc_ctx, - target_abspath, + target_abspath, TRUE, ctx->cancel_func, ctx->cancel_baton, scratch_pool));
Modified: subversion/branches/svn-info-detail/subversion/libsvn_client/patch.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_client/patch.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_client/patch.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_client/patch.c Tue Feb 24 15:23:33 2015 @@ -326,7 +326,8 @@ obtain_eol_and_keywords_for_file(apr_has const char *rev_str; const char *author; const char *url; - const char *root_url; + const char *repos_root_url; + const char *repos_relpath; SVN_ERR(svn_wc__node_get_changed_info(&changed_rev, &changed_date, @@ -335,15 +336,17 @@ obtain_eol_and_keywords_for_file(apr_has scratch_pool, scratch_pool)); rev_str = apr_psprintf(scratch_pool, "%ld", changed_rev); - SVN_ERR(svn_wc__node_get_url(&url, wc_ctx, - local_abspath, - scratch_pool, scratch_pool)); - SVN_ERR(svn_wc__node_get_repos_info(NULL, NULL, &root_url, NULL, + SVN_ERR(svn_wc__node_get_repos_info(NULL, &repos_relpath, &repos_root_url, + NULL, wc_ctx, local_abspath, scratch_pool, scratch_pool)); + url = svn_path_url_add_component2(repos_root_url, repos_relpath, + scratch_pool); + SVN_ERR(svn_subst_build_keywords3(keywords, keywords_val->data, - rev_str, url, root_url, changed_date, + rev_str, url, repos_root_url, + changed_date, author, result_pool)); } @@ -1592,7 +1595,7 @@ static svn_error_t * get_hunk_info(hunk_info_t **hi, patch_target_t *target, target_content_t *content, svn_diff_hunk_t *hunk, svn_linenum_t fuzz, - apr_int64_t previous_offset, + svn_linenum_t previous_offset, svn_boolean_t ignore_whitespace, svn_boolean_t is_prop_hunk, svn_cancel_func_t cancel_func, void *cancel_baton, @@ -2272,7 +2275,7 @@ apply_one_patch(patch_target_t **patch_t int i; static const svn_linenum_t MAX_FUZZ = 2; apr_hash_index_t *hash_index; - apr_int64_t previous_offset = 0; + svn_linenum_t previous_offset = 0; SVN_ERR(init_patch_target(&target, patch, abs_wc_path, wc_ctx, strip_count, remove_tempfiles, result_pool, scratch_pool)); Modified: subversion/branches/svn-info-detail/subversion/libsvn_ra/ra_loader.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_ra/ra_loader.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_ra/ra_loader.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_ra/ra_loader.c Tue Feb 24 15:23:33 2015 @@ -1004,7 +1004,7 @@ svn_error_t *svn_ra_get_file_revs2(svn_r if (include_merged_revisions) SVN_ERR(svn_ra__assert_mergeinfo_capable_server(session, NULL, pool)); - if (start > end) + if (start > end || !SVN_IS_VALID_REVNUM(start)) SVN_ERR( svn_ra__assert_capable_server(session, SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE, @@ -1014,7 +1014,8 @@ svn_error_t *svn_ra_get_file_revs2(svn_r err = session->vtable->get_file_revs(session, path, start, end, include_merged_revisions, handler, handler_baton, pool); - if (err && (err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)) + if (err && (err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED) + && !include_merged_revisions) { svn_error_clear(err); @@ -1022,7 +1023,7 @@ svn_error_t *svn_ra_get_file_revs2(svn_r err = svn_ra__file_revs_from_log(session, path, start, end, handler, handler_baton, pool); } - return err; + return svn_error_trace(err); } svn_error_t *svn_ra_lock(svn_ra_session_t *session, Modified: subversion/branches/svn-info-detail/subversion/libsvn_repos/commit.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_repos/commit.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_repos/commit.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_repos/commit.c Tue Feb 24 15:23:33 2015 @@ -201,7 +201,7 @@ invoke_commit_cb(svn_commit_callback2_t commit_info->date = date ? date->data : NULL; commit_info->author = author ? author->data : NULL; commit_info->post_commit_err = post_commit_errstr; - /* commit_info->repos_root = NULL; ### Fixed up in ra-local handling */ + /* commit_info->repos_root is not set by the repos layer, only by RA layers */ return svn_error_trace(commit_cb(commit_info, commit_baton, scratch_pool)); } Modified: subversion/branches/svn-info-detail/subversion/libsvn_repos/load-fs-vtable.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_repos/load-fs-vtable.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_repos/load-fs-vtable.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_repos/load-fs-vtable.c Tue Feb 24 15:23:33 2015 @@ -726,6 +726,7 @@ set_revision_property(void *baton, struct revision_baton *rb = baton; struct parse_baton *pb = rb->pb; svn_boolean_t is_date = strcmp(name, SVN_PROP_REVISION_DATE) == 0; + svn_prop_t *prop; /* If we're skipping this revision, we're done here. */ if (rb->skipped) @@ -735,32 +736,16 @@ set_revision_property(void *baton, if (is_date && pb->ignore_dates) return SVN_NO_ERROR; - if (rb->rev > 0) - { - svn_prop_t *prop = &APR_ARRAY_PUSH(rb->revprops, svn_prop_t); - - /* Collect property changes to apply them in one FS call in - close_revision. */ - prop->name = apr_pstrdup(rb->pool, name); - prop->value = svn_string_dup(value, rb->pool); - - /* Remember any datestamp that passes through! (See comment in - close_revision() below.) */ - if (is_date) - rb->datestamp = svn_string_dup(value, rb->pool); - } - else if (rb->rev == 0) - { - /* Special case: set revision 0 properties when loading into an - 'empty' filesystem. */ - svn_revnum_t youngest_rev; - - SVN_ERR(svn_fs_youngest_rev(&youngest_rev, pb->fs, rb->pool)); - - if (youngest_rev == 0) - SVN_ERR(change_rev_prop(pb->repos, 0, name, value, - pb->validate_props, rb->pool)); - } + /* Collect property changes to apply them in one FS call in + close_revision. */ + prop = &APR_ARRAY_PUSH(rb->revprops, svn_prop_t); + prop->name = apr_pstrdup(rb->pool, name); + prop->value = svn_string_dup(value, rb->pool); + + /* Remember any datestamp that passes through! (See comment in + close_revision() below.) */ + if (is_date) + rb->datestamp = svn_string_dup(value, rb->pool); return SVN_NO_ERROR; } @@ -1018,11 +1003,41 @@ close_revision(void *baton) const char *txn_name = NULL; apr_hash_t *hooks_env; - /* If we're skipping this revision or it has an invalid revision - number, we're done here. */ - if (rb->skipped || (rb->rev <= 0)) + /* If we're skipping this revision we're done here. */ + if (rb->skipped) return SVN_NO_ERROR; + if (rb->rev == 0) + { + /* Special case: set revision 0 properties when loading into an + 'empty' filesystem. */ + svn_revnum_t youngest_rev; + + SVN_ERR(svn_fs_youngest_rev(&youngest_rev, pb->fs, rb->pool)); + + if (youngest_rev == 0) + { + apr_hash_t *orig_props; + apr_hash_t *new_props; + apr_array_header_t *diff; + int i; + + SVN_ERR(svn_fs_revision_proplist(&orig_props, pb->fs, 0, rb->pool)); + new_props = svn_prop_array_to_hash(rb->revprops, rb->pool); + SVN_ERR(svn_prop_diffs(&diff, new_props, orig_props, rb->pool)); + + for (i = 0; i < diff->nelts; i++) + { + const svn_prop_t *prop = &APR_ARRAY_IDX(diff, i, svn_prop_t); + + SVN_ERR(change_rev_prop(pb->repos, 0, prop->name, prop->value, + pb->validate_props, rb->pool)); + } + } + + return SVN_NO_ERROR; + } + /* If the dumpstream doesn't have an 'svn:date' property and we aren't ignoring the dates in the dumpstream altogether, remove any 'svn:date' revision property that was set by FS layer when Modified: subversion/branches/svn-info-detail/subversion/libsvn_repos/rev_hunt.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_repos/rev_hunt.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_repos/rev_hunt.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_repos/rev_hunt.c Tue Feb 24 15:23:33 2015 @@ -1559,6 +1559,18 @@ svn_repos_get_file_revs2(svn_repos_t *re struct send_baton sb; int mainline_pos, merged_pos; + if (!SVN_IS_VALID_REVNUM(start) + || !SVN_IS_VALID_REVNUM(end)) + { + svn_revnum_t youngest_rev; + SVN_ERR(svn_fs_youngest_rev(&youngest_rev, repos->fs, scratch_pool)); + + if (!SVN_IS_VALID_REVNUM(start)) + start = youngest_rev; + if (!SVN_IS_VALID_REVNUM(end)) + end = youngest_rev; + } + if (end < start) { if (include_merged_revisions) Modified: subversion/branches/svn-info-detail/subversion/libsvn_subr/cache-membuffer.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_subr/cache-membuffer.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_subr/cache-membuffer.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_subr/cache-membuffer.c Tue Feb 24 15:23:33 2015 @@ -1819,6 +1819,61 @@ svn_cache__membuffer_cache_create(svn_me return SVN_NO_ERROR; } +svn_error_t * +svn_cache__membuffer_clear(svn_membuffer_t *cache) +{ + apr_size_t seg; + apr_size_t segment_count = cache->segment_count; + + /* Length of the group_initialized array in bytes. + See also svn_cache__membuffer_cache_create(). */ + apr_size_t group_init_size + = 1 + (cache->group_count + cache->spare_group_count) + / (8 * GROUP_INIT_GRANULARITY); + + /* Clear segment by segment. This implies that other thread may read + and write to other segments after we cleared them and before the + last segment is done. + + However, that is no different from a write request coming through + right after we cleared all segments because dependencies between + cache entries (recursive lookup / access locks) are not allowed. + */ + for (seg = 0; seg < segment_count; ++seg) + { + /* Unconditionally acquire the write lock. */ + SVN_ERR(force_write_lock_cache(&cache[seg])); + + /* Mark all groups as "not initialized", which implies "empty". */ + cache[seg].first_spare_group = NO_INDEX; + cache[seg].max_spare_used = 0; + + memset(cache[seg].group_initialized, 0, group_init_size); + + /* Unlink L1 contents. */ + cache[seg].l1.first = NO_INDEX; + cache[seg].l1.last = NO_INDEX; + cache[seg].l1.next = NO_INDEX; + cache[seg].l1.current_data = cache[seg].l1.start_offset; + + /* Unlink L2 contents. */ + cache[seg].l2.first = NO_INDEX; + cache[seg].l2.last = NO_INDEX; + cache[seg].l2.next = NO_INDEX; + cache[seg].l2.current_data = cache[seg].l2.start_offset; + + /* Reset content counters. */ + cache[seg].data_used = 0; + cache[seg].used_entries = 0; + + /* Segment may be used again. */ + SVN_ERR(unlock_cache(&cache[seg], SVN_NO_ERROR)); + } + + /* done here */ + return SVN_NO_ERROR; +} + /* Look for the cache entry in group GROUP_INDEX of CACHE, identified * by the hash value TO_FIND and set *FOUND accordingly. * Modified: subversion/branches/svn-info-detail/subversion/libsvn_subr/cache.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_subr/cache.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_subr/cache.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_subr/cache.c Tue Feb 24 15:23:33 2015 @@ -102,6 +102,11 @@ svn_cache__has_key(svn_boolean_t *found, apr_pool_t *scratch_pool) { *found = FALSE; +#ifdef SVN_DEBUG + if (cache->pretend_empty) + return SVN_NO_ERROR; +#endif + return handle_error(cache, (cache->vtable->has_key)(found, cache->cache_internal, Modified: subversion/branches/svn-info-detail/subversion/libsvn_subr/sqlite.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_subr/sqlite.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_subr/sqlite.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_subr/sqlite.c Tue Feb 24 15:23:33 2015 @@ -1477,8 +1477,6 @@ struct function_wrapper_baton_t { svn_sqlite__func_t func; void *baton; - - apr_pool_t *scratch_pool; }; static void @@ -1488,22 +1486,12 @@ wrapped_func(sqlite3_context *context, { struct function_wrapper_baton_t *fwb = sqlite3_user_data(context); svn_sqlite__context_t sctx; - svn_sqlite__value_t **local_vals = - apr_palloc(fwb->scratch_pool, - sizeof(svn_sqlite__value_t *) * argc); svn_error_t *err; - int i; + void *void_values = values; sctx.context = context; - for (i = 0; i < argc; i++) - { - local_vals[i] = apr_palloc(fwb->scratch_pool, sizeof(*local_vals[i])); - local_vals[i]->value = values[i]; - } - - err = fwb->func(&sctx, argc, local_vals, fwb->scratch_pool); - svn_pool_clear(fwb->scratch_pool); + err = fwb->func(&sctx, argc, void_values, fwb->baton); if (err) { @@ -1515,6 +1503,7 @@ wrapped_func(sqlite3_context *context, } } + svn_error_t * svn_sqlite__create_scalar_function(svn_sqlite__db_t *db, const char *func_name, @@ -1527,7 +1516,6 @@ svn_sqlite__create_scalar_function(svn_s struct function_wrapper_baton_t *fwb = apr_pcalloc(db->state_pool, sizeof(*fwb)); - fwb->scratch_pool = svn_pool_create(db->state_pool); fwb->func = func; fwb->baton = baton; @@ -1545,13 +1533,15 @@ svn_sqlite__create_scalar_function(svn_s int svn_sqlite__value_type(svn_sqlite__value_t *val) { - return sqlite3_value_type(val->value); + void *v = val; + return sqlite3_value_type(v); } const char * svn_sqlite__value_text(svn_sqlite__value_t *val) { - return (const char *) sqlite3_value_text(val->value); + void *v = val; + return (const char *) sqlite3_value_text(v); } void Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/adm_ops.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/adm_ops.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_wc/adm_ops.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_wc/adm_ops.c Tue Feb 24 15:23:33 2015 @@ -680,7 +680,8 @@ svn_wc_add4(svn_wc_context_t *wc_ctx, repos_relpath, repos_root_url, repos_uuid, copyfrom_rev, - NULL /* children */, FALSE, depth, + NULL /* children */, depth, + FALSE /* is_move */, NULL /* conflicts */, NULL /* work items */, scratch_pool)); Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/conflicts.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/conflicts.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_wc/conflicts.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_wc/conflicts.c Tue Feb 24 15:23:33 2015 @@ -1365,18 +1365,24 @@ generate_propconflict(svn_boolean_t *con { svn_stringbuf_t *merged_stringbuf; - if (!cdesc->merged_file && !result->merged_file) + if (!cdesc->merged_file + && (!result->merged_file && !result->merged_value)) return svn_error_create (SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL, _("Conflict callback violated API:" " returned no merged file")); - SVN_ERR(svn_stringbuf_from_file2(&merged_stringbuf, - result->merged_file ? - result->merged_file : - cdesc->merged_file, - scratch_pool)); - new_value = svn_stringbuf__morph_into_string(merged_stringbuf); + if (result->merged_value) + new_value = result->merged_value; + else + { + SVN_ERR(svn_stringbuf_from_file2(&merged_stringbuf, + result->merged_file ? + result->merged_file : + cdesc->merged_file, + scratch_pool)); + new_value = svn_stringbuf__morph_into_string(merged_stringbuf); + } *conflict_remains = FALSE; break; } @@ -2336,6 +2342,7 @@ resolve_prop_conflict_on_node(svn_boolea const char *conflicted_propname, svn_wc_conflict_choice_t conflict_choice, const char *merged_file, + const svn_string_t *merged_value, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *scratch_pool) @@ -2396,21 +2403,27 @@ resolve_prop_conflict_on_node(svn_boolea resolve_from = their_props; break; case svn_wc_conflict_choose_merged: - if (merged_file && conflicted_propname[0] != '\0') + if ((merged_file || merged_value) && conflicted_propname[0] != '\0') { apr_hash_t *actual_props; - svn_stream_t *stream; - svn_string_t *merged_propval; SVN_ERR(svn_wc__db_read_props(&actual_props, db, local_abspath, scratch_pool, scratch_pool)); resolve_from = actual_props; - SVN_ERR(svn_stream_open_readonly(&stream, merged_file, - scratch_pool, scratch_pool)); - SVN_ERR(svn_string_from_stream(&merged_propval, stream, - scratch_pool, scratch_pool)); - svn_hash_sets(resolve_from, conflicted_propname, merged_propval); + if (!merged_value) + { + svn_stream_t *stream; + svn_string_t *merged_propval; + + SVN_ERR(svn_stream_open_readonly(&stream, merged_file, + scratch_pool, scratch_pool)); + SVN_ERR(svn_string_from_stream(&merged_propval, stream, + scratch_pool, scratch_pool)); + + merged_value = merged_propval; + } + svn_hash_sets(resolve_from, conflicted_propname, merged_value); } else resolve_from = NULL; @@ -2734,7 +2747,8 @@ svn_wc__mark_resolved_prop_conflicts(svn return svn_error_trace(resolve_prop_conflict_on_node( &ignored_result, db, local_abspath, conflicts, "", - svn_wc_conflict_choose_merged, NULL, + svn_wc_conflict_choose_merged, + NULL, NULL, NULL, NULL, scratch_pool)); } @@ -2824,7 +2838,10 @@ conflict_status_walker(void *baton, cd = APR_ARRAY_IDX(conflicts, i, const svn_wc_conflict_description2_t *); - if ((cd->kind == svn_wc_conflict_kind_property && !cswb->resolve_prop) + if ((cd->kind == svn_wc_conflict_kind_property + && (!cswb->resolve_prop + || (*cswb->resolve_prop != '\0' + && strcmp(cswb->resolve_prop, cd->property_name) != 0))) || (cd->kind == svn_wc_conflict_kind_text && !cswb->resolve_text) || (cd->kind == svn_wc_conflict_kind_tree && !cswb->resolve_tree)) { @@ -2853,8 +2870,6 @@ conflict_status_walker(void *baton, switch (cd->kind) { case svn_wc_conflict_kind_tree: - if (!cswb->resolve_tree) - break; SVN_ERR(resolve_tree_conflict_on_node(&did_resolve, db, local_abspath, conflict, @@ -2871,9 +2886,6 @@ conflict_status_walker(void *baton, break; case svn_wc_conflict_kind_text: - if (!cswb->resolve_text) - break; - SVN_ERR(build_text_conflict_resolve_items( &work_items, &resolved, @@ -2897,15 +2909,6 @@ conflict_status_walker(void *baton, break; case svn_wc_conflict_kind_property: - if (!cswb->resolve_prop) - break; - - if (*cswb->resolve_prop != '\0' && - strcmp(cswb->resolve_prop, cd->property_name) != 0) - { - break; /* This is not the property we want to resolve. */ - } - SVN_ERR(resolve_prop_conflict_on_node(&did_resolve, db, local_abspath, @@ -2915,6 +2918,9 @@ conflict_status_walker(void *baton, result ? result->merged_file : NULL, + result + ? result->merged_value + : NULL, cswb->cancel_func, cswb->cancel_baton, iterpool)); @@ -3118,7 +3124,7 @@ svn_wc_create_conflict_result(svn_wc_con { svn_wc_conflict_result_t *result = apr_pcalloc(pool, sizeof(*result)); result->choice = choice; - result->merged_file = merged_file; + result->merged_file = apr_pstrdup(pool, merged_file); result->save_merged = FALSE; /* If we add more fields to svn_wc_conflict_result_t, add them here. */ Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/copy.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/copy.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_wc/copy.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_wc/copy.c Tue Feb 24 15:23:33 2015 @@ -965,18 +965,18 @@ remove_node_conflict_markers(svn_wc__db_ { const char *marker_abspath; const char *child_relpath; - const char *child_abpath; + const char *child_abspath; marker_abspath = APR_ARRAY_IDX(markers, i, const char *); - child_relpath = svn_dirent_is_child(src_dir, marker_abspath, NULL); + child_relpath = svn_dirent_skip_ancestor(src_dir, marker_abspath); if (child_relpath) { - child_abpath = svn_dirent_join(dst_dir, child_relpath, - scratch_pool); + child_abspath = svn_dirent_join(dst_dir, child_relpath, + scratch_pool); - SVN_ERR(svn_io_remove_file2(child_abpath, TRUE, scratch_pool)); + SVN_ERR(svn_io_remove_file2(child_abspath, TRUE, scratch_pool)); } } } @@ -996,7 +996,9 @@ remove_node_conflict_markers(svn_wc__db_ static svn_error_t * remove_all_conflict_markers(svn_wc__db_t *db, const char *src_dir_abspath, - const char *wc_dir_abspath, + const char *dst_dir_abspath, + svn_cancel_func_t cancel_func, + void *cancel_baton, apr_pool_t *scratch_pool) { apr_pool_t *iterpool = svn_pool_create(scratch_pool); @@ -1020,13 +1022,16 @@ remove_all_conflict_markers(svn_wc__db_t const char *name = apr_hash_this_key(hi); struct svn_wc__db_info_t *info = apr_hash_this_val(hi); + if (cancel_func) + SVN_ERR(cancel_func(cancel_baton)); + if (info->conflicted) { svn_pool_clear(iterpool); SVN_ERR(remove_node_conflict_markers( db, svn_dirent_join(src_dir_abspath, name, iterpool), - svn_dirent_join(wc_dir_abspath, name, iterpool), + svn_dirent_join(dst_dir_abspath, name, iterpool), iterpool)); } if (info->kind == svn_node_dir) @@ -1035,7 +1040,8 @@ remove_all_conflict_markers(svn_wc__db_t SVN_ERR(remove_all_conflict_markers( db, svn_dirent_join(src_dir_abspath, name, iterpool), - svn_dirent_join(wc_dir_abspath, name, iterpool), + svn_dirent_join(dst_dir_abspath, name, iterpool), + cancel_func, cancel_baton, iterpool)); } } @@ -1093,7 +1099,25 @@ svn_wc__move2(svn_wc_context_t *wc_ctx, is still in a valid state. So be careful when switching this over to the workqueue. */ if (!metadata_only) - SVN_ERR(svn_io_file_rename(src_abspath, dst_abspath, scratch_pool)); + { + svn_error_t *err; + + err = svn_error_trace(svn_io_file_rename(src_abspath, dst_abspath, + scratch_pool)); + + /* Let's try if we can keep wc.db consistent even when the move + fails. Deleting the target is a wc.db only operation, while + going forward (delaying the error) would try to change + conflict markers, which might also fail. */ + if (err) + return svn_error_trace( + svn_error_compose_create( + err, + svn_wc__db_op_delete(wc_ctx->db, dst_abspath, NULL, TRUE, + NULL, NULL, cancel_func, cancel_baton, + NULL, NULL, + scratch_pool))); + } SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -1105,11 +1129,20 @@ svn_wc__move2(svn_wc_context_t *wc_ctx, if (kind == svn_node_dir) SVN_ERR(remove_all_conflict_markers(db, src_abspath, dst_abspath, + cancel_func, cancel_baton, scratch_pool)); if (conflicted) - SVN_ERR(remove_node_conflict_markers(db, src_abspath, dst_abspath, - scratch_pool)); + { + /* When we moved a directory, we moved the conflict markers + with the target... if we moved a file we only moved the + file itself and the markers are still in the old location */ + SVN_ERR(remove_node_conflict_markers(db, src_abspath, + (kind == svn_node_dir) + ? dst_abspath + : src_abspath, + scratch_pool)); + } SVN_ERR(svn_wc__db_op_delete(db, src_abspath, record_on_delete ? dst_abspath : NULL, Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/crop.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/crop.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_wc/crop.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_wc/crop.c Tue Feb 24 15:23:33 2015 @@ -53,7 +53,7 @@ crop_children(svn_wc__db_t *db, void *notify_baton, svn_cancel_func_t cancel_func, void *cancel_baton, - apr_pool_t *pool) + apr_pool_t *scratch_pool) { const apr_array_header_t *children; apr_pool_t *iterpool; @@ -65,7 +65,7 @@ crop_children(svn_wc__db_t *db, if (cancel_func) SVN_ERR(cancel_func(cancel_baton)); - iterpool = svn_pool_create(pool); + iterpool = svn_pool_create(scratch_pool); if (dir_depth == svn_depth_unknown) dir_depth = svn_depth_infinity; @@ -76,8 +76,8 @@ crop_children(svn_wc__db_t *db, iterpool)); /* Looping over current directory's SVN entries: */ - SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath, pool, - iterpool)); + SVN_ERR(svn_wc__db_base_get_children(&children, db, local_abspath, + scratch_pool, iterpool)); for (i = 0; i < children->nelts; i++) { @@ -86,6 +86,8 @@ crop_children(svn_wc__db_t *db, svn_wc__db_status_t child_status; svn_node_kind_t kind; svn_depth_t child_depth; + svn_boolean_t have_work; + svn_depth_t remove_below; svn_pool_clear(iterpool); @@ -96,86 +98,80 @@ crop_children(svn_wc__db_t *db, NULL,NULL, NULL, NULL, &child_depth, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, &have_work, db, child_abspath, iterpool, iterpool)); - if (child_status == svn_wc__db_status_server_excluded || - child_status == svn_wc__db_status_excluded || - child_status == svn_wc__db_status_not_present) + if (have_work) + { + svn_boolean_t modified, all_deletes; + + if (child_status != svn_wc__db_status_deleted) + continue; /* Leave local additions alone */ + + SVN_ERR(svn_wc__node_has_local_mods(&modified, &all_deletes, + db, child_abspath, FALSE, + cancel_func, cancel_baton, + iterpool)); + + if (modified && !all_deletes) + continue; /* Something interesting is still there */ + } + + remove_below = (kind == svn_node_dir) + ? svn_depth_immediates + : svn_depth_files; + + if ((child_status == svn_wc__db_status_server_excluded || + child_status == svn_wc__db_status_excluded || + child_status == svn_wc__db_status_not_present)) { - svn_depth_t remove_below = (kind == svn_node_dir) - ? svn_depth_immediates - : svn_depth_files; if (new_depth < remove_below) SVN_ERR(svn_wc__db_base_remove(db, child_abspath, FALSE /* keep_as_working */, - FALSE /* queue_deletes */, - FALSE /* remove_locks */, + FALSE, FALSE, SVN_INVALID_REVNUM, NULL, NULL, iterpool)); - continue; + continue; /* No recurse */ } - else if (kind == svn_node_file) + + if (new_depth < remove_below) { - if (new_depth == svn_depth_empty) - SVN_ERR(svn_wc__db_op_remove_node(NULL, - db, child_abspath, - TRUE /* destroy */, - FALSE /* destroy_changes */, - SVN_INVALID_REVNUM, - svn_wc__db_status_not_present, - svn_node_none, - NULL, NULL, + svn_boolean_t modified, all_deletes; + + SVN_ERR(svn_wc__node_has_local_mods(&modified, &all_deletes, + db, child_abspath, FALSE, cancel_func, cancel_baton, iterpool)); - else - continue; - } - else if (kind == svn_node_dir) - { - if (new_depth < svn_depth_immediates) + if (!modified || all_deletes) { - SVN_ERR(svn_wc__db_op_remove_node(NULL, - db, child_abspath, - TRUE /* destroy */, - FALSE /* destroy_changes */, - SVN_INVALID_REVNUM, - svn_wc__db_status_not_present, - svn_node_none, - NULL, NULL, - cancel_func, cancel_baton, - iterpool)); - } - else - { - SVN_ERR(crop_children(db, - child_abspath, - child_depth, - svn_depth_empty, - notify_func, - notify_baton, - cancel_func, - cancel_baton, - iterpool)); - continue; + SVN_ERR(svn_wc__db_base_remove(db, child_abspath, + FALSE, FALSE, FALSE, + SVN_INVALID_REVNUM, + NULL, NULL, iterpool)); + if (notify_func) + { + svn_wc_notify_t *notify; + notify = svn_wc_create_notify(child_abspath, + svn_wc_notify_delete, + iterpool); + (*notify_func)(notify_baton, notify, iterpool); + } + + continue; /* No recurse */ } - } - else - { - return svn_error_createf - (SVN_ERR_NODE_UNKNOWN_KIND, NULL, _("Unknown node kind for '%s'"), - svn_dirent_local_style(child_abspath, iterpool)); + + /* Fall through: recurse:*/ } - if (notify_func) + if (kind == svn_node_dir) { - svn_wc_notify_t *notify; - notify = svn_wc_create_notify(child_abspath, - svn_wc_notify_delete, - iterpool); - (*notify_func)(notify_baton, notify, iterpool); + SVN_ERR(crop_children(db, child_abspath, + child_depth, svn_depth_empty, + notify_func, notify_baton, + cancel_func, cancel_baton, + iterpool)); } } @@ -197,6 +193,8 @@ svn_wc_exclude(svn_wc_context_t *wc_ctx, svn_wc__db_status_t status; svn_node_kind_t kind; svn_revnum_t revision; + svn_depth_t depth; + svn_boolean_t modified, all_deletes; const char *repos_relpath, *repos_root, *repos_uuid; SVN_ERR(svn_wc__db_is_switched(&is_root, &is_switched, NULL, @@ -221,7 +219,7 @@ svn_wc_exclude(svn_wc_context_t *wc_ctx, SVN_ERR(svn_wc__db_read_info(&status, &kind, &revision, &repos_relpath, &repos_root, &repos_uuid, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &depth, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, wc_ctx->db, local_abspath, @@ -258,29 +256,41 @@ svn_wc_exclude(svn_wc_context_t *wc_ctx, break; /* Ok to exclude */ } - /* Remove all working copy data below local_abspath */ - SVN_ERR(svn_wc__db_op_remove_node(NULL, - wc_ctx->db, local_abspath, - TRUE /* destroy */, - FALSE /* destroy_changes */, - revision, - svn_wc__db_status_excluded, - kind, - NULL, NULL, - cancel_func, cancel_baton, - scratch_pool)); - - SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath, - cancel_func, cancel_baton, - scratch_pool)); - - if (notify_func) - { - svn_wc_notify_t *notify; - notify = svn_wc_create_notify(local_abspath, - svn_wc_notify_exclude, - scratch_pool); - notify_func(notify_baton, notify, scratch_pool); + SVN_ERR(svn_wc__node_has_local_mods(&modified, &all_deletes, + wc_ctx->db, local_abspath, FALSE, + cancel_func, cancel_baton, + scratch_pool)); + + if (!modified || all_deletes) + { + /* Remove all working copy data below local_abspath */ + SVN_ERR(svn_wc__db_base_remove(wc_ctx->db, local_abspath, + FALSE /* keep_working */, + FALSE, TRUE, + revision, + NULL, NULL, + scratch_pool)); + + SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath, + cancel_func, cancel_baton, + scratch_pool)); + + if (notify_func) + { + svn_wc_notify_t *notify; + notify = svn_wc_create_notify(local_abspath, + svn_wc_notify_exclude, + scratch_pool); + notify_func(notify_baton, notify, scratch_pool); + } + } + else + { + /* Do the next best thing: retry below this path */ + SVN_ERR(crop_children(wc_ctx->db, local_abspath, depth, svn_depth_empty, + notify_func, notify_baton, + cancel_func, cancel_baton, + scratch_pool)); } return SVN_NO_ERROR; Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/delete.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/delete.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_wc/delete.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_wc/delete.c Tue Feb 24 15:23:33 2015 @@ -431,9 +431,6 @@ svn_wc__internal_remove_from_revision_co db, local_abspath, destroy_wf /* destroy_wc */, destroy_wf /* destroy_changes */, - SVN_INVALID_REVNUM, - svn_wc__db_status_not_present, - svn_node_none, NULL, NULL, cancel_func, cancel_baton, scratch_pool)); Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/diff_editor.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/diff_editor.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_wc/diff_editor.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_wc/diff_editor.c Tue Feb 24 15:23:33 2015 @@ -1051,8 +1051,12 @@ svn_wc__diff_local_only_dir(svn_wc__db_t copyfrom_src->repos_relpath = original_repos_relpath; } + /* svn_wc__db_status_incomplete should never happen, as the result won't be + stable or guaranteed related to what is in the repository for this + revision, but without this it would be hard to diagnose that status... */ assert(kind == svn_node_dir && (status == svn_wc__db_status_normal + || status == svn_wc__db_status_incomplete || status == svn_wc__db_status_added || (status == svn_wc__db_status_deleted && diff_pristine))); @@ -1167,12 +1171,12 @@ svn_wc__diff_local_only_dir(svn_wc__db_t if (!skip) { apr_hash_t *right_props; - if (diff_pristine) - SVN_ERR(svn_wc__db_read_pristine_props(&right_props, db, local_abspath, - scratch_pool, scratch_pool)); + + if (props_mod && !diff_pristine) + SVN_ERR(svn_wc__db_read_props(&right_props, db, local_abspath, + scratch_pool, scratch_pool)); else - SVN_ERR(svn_wc__get_actual_props(&right_props, db, local_abspath, - scratch_pool, scratch_pool)); + right_props = svn_prop_hash_dup(pristine_props, scratch_pool); SVN_ERR(processor->dir_added(relpath, copyfrom_src, Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/entries.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/entries.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_wc/entries.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_wc/entries.c Tue Feb 24 15:23:33 2015 @@ -48,6 +48,7 @@ #include "svn_private_config.h" #include "private/svn_wc_private.h" #include "private/svn_sqlite.h" +#include "token-map.h" #define MAYBE_ALLOC(x,p) ((x) ? (x) : apr_pcalloc((p), sizeof(*(x)))) @@ -1452,23 +1453,31 @@ insert_node(svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool) { svn_sqlite__stmt_t *stmt; + svn_boolean_t present = (node->presence == svn_wc__db_status_normal + || node->presence == svn_wc__db_status_incomplete); SVN_ERR_ASSERT(node->op_depth > 0 || node->repos_relpath); SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE)); - SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnnnsnrisnnni", + SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnnnsn", node->wc_id, node->local_relpath, node->op_depth, node->parent_relpath, /* Setting depth for files? */ - svn_depth_to_word(node->depth), - node->changed_rev, - node->changed_date, - node->changed_author, - node->recorded_time)); + (node->kind == svn_node_dir && present) + ? svn_depth_to_word(node->depth) + : NULL)); - if (node->repos_relpath) + if (present && node->repos_relpath) + { + SVN_ERR(svn_sqlite__bind_revnum(stmt, 11, node->changed_rev)); + SVN_ERR(svn_sqlite__bind_int64(stmt, 12, node->changed_date)); + SVN_ERR(svn_sqlite__bind_text(stmt, 13, node->changed_author)); + } + + if (node->repos_relpath + && node->presence != svn_wc__db_status_base_deleted) { SVN_ERR(svn_sqlite__bind_int64(stmt, 5, node->repos_id)); @@ -1477,26 +1486,14 @@ insert_node(svn_sqlite__db_t *sdb, SVN_ERR(svn_sqlite__bind_revnum(stmt, 7, node->revision)); } - if (node->presence == svn_wc__db_status_normal) - SVN_ERR(svn_sqlite__bind_text(stmt, 8, "normal")); - else if (node->presence == svn_wc__db_status_not_present) - SVN_ERR(svn_sqlite__bind_text(stmt, 8, "not-present")); - else if (node->presence == svn_wc__db_status_base_deleted) - SVN_ERR(svn_sqlite__bind_text(stmt, 8, "base-deleted")); - else if (node->presence == svn_wc__db_status_incomplete) - SVN_ERR(svn_sqlite__bind_text(stmt, 8, "incomplete")); - 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, "server-excluded")); + SVN_ERR(svn_sqlite__bind_token(stmt, 8, presence_map, node->presence)); if (node->kind == svn_node_none) SVN_ERR(svn_sqlite__bind_text(stmt, 10, "unknown")); else - SVN_ERR(svn_sqlite__bind_text(stmt, 10, - svn_node_kind_to_word(node->kind))); + SVN_ERR(svn_sqlite__bind_token(stmt, 10, kind_map, node->kind)); - if (node->kind == svn_node_file) + if (node->kind == svn_node_file && present) { if (!node->checksum && node->op_depth == 0 @@ -1510,19 +1507,25 @@ insert_node(svn_sqlite__db_t *sdb, SVN_ERR(svn_sqlite__bind_checksum(stmt, 14, node->checksum, scratch_pool)); + + if (node->repos_relpath) + { + if (node->recorded_size != SVN_INVALID_FILESIZE) + SVN_ERR(svn_sqlite__bind_int64(stmt, 16, node->recorded_size)); + + SVN_ERR(svn_sqlite__bind_int64(stmt, 17, node->recorded_time)); + } } - if (node->properties) /* ### Never set, props done later */ + /* ### Never set, props done later */ + if (node->properties && present && node->repos_relpath) SVN_ERR(svn_sqlite__bind_properties(stmt, 15, node->properties, scratch_pool)); - if (node->recorded_size != SVN_INVALID_FILESIZE) - SVN_ERR(svn_sqlite__bind_int64(stmt, 16, node->recorded_size)); - if (node->file_external) SVN_ERR(svn_sqlite__bind_int(stmt, 20, 1)); - if (node->inherited_props) + if (node->inherited_props && present) SVN_ERR(svn_sqlite__bind_iprops(stmt, 23, node->inherited_props, scratch_pool)); @@ -1801,6 +1804,10 @@ write_entry(struct write_baton **entry_n if (entry->copied) { + db_node_t *work = parent_node->work + ? parent_node->work + : parent_node->below_work; + if (entry->copyfrom_url) { working_node->repos_id = repos_id; @@ -1810,20 +1817,37 @@ write_entry(struct write_baton **entry_n working_node->revision = entry->copyfrom_rev; working_node->op_depth = svn_wc__db_op_depth_for_upgrade(local_relpath); + + if (work && work->repos_relpath + && work->repos_id == repos_id + && work->revision == entry->copyfrom_rev) + { + const char *name; + + name = svn_relpath_skip_ancestor(work->repos_relpath, + working_node->repos_relpath); + + if (name + && !strcmp(name, svn_relpath_basename(local_relpath, NULL))) + { + working_node->op_depth = work->op_depth; + } + } } - else if (parent_node->work && parent_node->work->repos_relpath) + else if (work && work->repos_relpath) { working_node->repos_id = repos_id; working_node->repos_relpath - = svn_relpath_join(parent_node->work->repos_relpath, + = svn_relpath_join(work->repos_relpath, svn_relpath_basename(local_relpath, NULL), result_pool); - working_node->revision = parent_node->work->revision; - working_node->op_depth = parent_node->work->op_depth; + working_node->revision = work->revision; + working_node->op_depth = work->op_depth; } else if (parent_node->below_work && parent_node->below_work->repos_relpath) { + /* Parent deleted, this not-present or similar */ working_node->repos_id = repos_id; working_node->repos_relpath = svn_relpath_join(parent_node->below_work->repos_relpath, @@ -1837,6 +1861,29 @@ write_entry(struct write_baton **entry_n _("No copyfrom URL for '%s'"), svn_dirent_local_style(local_relpath, scratch_pool)); + + if (work && work->op_depth != working_node->op_depth + && work->repos_relpath + && work->repos_id == working_node->repos_id + && work->presence == svn_wc__db_status_normal + && !below_working_node) + { + /* Introduce a not-present node! */ + below_working_node = MAYBE_ALLOC(below_working_node, scratch_pool); + + below_working_node->wc_id = wc_id; + below_working_node->op_depth = work->op_depth; + below_working_node->local_relpath = local_relpath; + below_working_node->parent_relpath = parent_relpath; + + below_working_node->presence = svn_wc__db_status_not_present; + below_working_node->repos_id = repos_id; + below_working_node->repos_relpath = working_node->local_relpath; + + SVN_ERR(insert_node(sdb, below_working_node, scratch_pool)); + + below_working_node = NULL; /* Don't write a present intermediate! */ + } } if (entry->conflict_old) @@ -1909,11 +1956,6 @@ write_entry(struct write_baton **entry_n WRITE_ENTRY_ASSERT(conflict->kind == svn_wc_conflict_kind_tree); - /* Fix dubious data stored by old clients, local adds don't have - a repository URL. */ - if (conflict->reason == svn_wc_conflict_reason_added) - conflict->src_left_version = NULL; - SVN_ERR(svn_wc__serialize_conflict(&new_skel, conflict, scratch_pool, scratch_pool)); @@ -2140,17 +2182,18 @@ write_entry(struct write_baton **entry_n below_working_node->presence = svn_wc__db_status_normal; below_working_node->kind = entry->kind; below_working_node->repos_id = work->repos_id; + below_working_node->revision = work->revision; /* This is just guessing. If the node below would have been switched or if it was updated to a different version, the guess would fail. But we don't have better information pre wc-ng :( */ if (work->repos_relpath) below_working_node->repos_relpath - = svn_relpath_join(work->repos_relpath, entry->name, + = svn_relpath_join(work->repos_relpath, + svn_relpath_basename(local_relpath, NULL), result_pool); else below_working_node->repos_relpath = NULL; - below_working_node->revision = parent_node->work->revision; /* The revert_base checksum isn't available in the entry structure, so the caller provides it. */ @@ -2294,6 +2337,11 @@ write_entry(struct write_baton **entry_n { working_node->op_depth = parent_node->work->op_depth; } + else if (working_node->presence == svn_wc__db_status_excluded + && parent_node->work) + { + working_node->op_depth = parent_node->work->op_depth; + } else if (!entry->copied) { working_node->op_depth @@ -2660,11 +2708,11 @@ svn_wc_walk_entries3(const char *path, svn_wc__db_t *db = svn_wc__adm_get_db(adm_access); svn_error_t *err; svn_node_kind_t kind; - svn_depth_t depth; + svn_wc__db_status_t status; SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); - err = svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, &depth, NULL, NULL, + err = svn_wc__db_read_info(&status, &kind, 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, @@ -2683,7 +2731,9 @@ svn_wc_walk_entries3(const char *path, walk_baton, pool); } - if (kind == svn_node_file || depth == svn_depth_exclude) + if (kind == svn_node_file + || status == svn_wc__db_status_excluded + || status == svn_wc__db_status_server_excluded) { const svn_wc_entry_t *entry; @@ -2692,27 +2742,24 @@ svn_wc_walk_entries3(const char *path, ### we should not call handle_error for an error the *callback* ### gave us. let it deal with the problem before returning. */ - if (!show_hidden) - { - svn_boolean_t hidden; - SVN_ERR(svn_wc__db_node_hidden(&hidden, db, local_abspath, pool)); - - if (hidden) - { - /* The fool asked to walk a "hidden" node. Report the node as - unversioned. - - ### this is incorrect behavior. see depth_test 36. the walk - ### API will be revamped to avoid entry structures. we should - ### be able to solve the problem with the new API. (since we - ### shouldn't return a hidden entry here) */ - return walk_callbacks->handle_error( - path, svn_error_createf( - SVN_ERR_UNVERSIONED_RESOURCE, NULL, - _("'%s' is not under version control"), - svn_dirent_local_style(local_abspath, pool)), - walk_baton, pool); - } + if (!show_hidden + && (status == svn_wc__db_status_not_present + || status == svn_wc__db_status_excluded + || status == svn_wc__db_status_server_excluded)) + { + /* The fool asked to walk a "hidden" node. Report the node as + unversioned. + + ### this is incorrect behavior. see depth_test 36. the walk + ### API will be revamped to avoid entry structures. we should + ### be able to solve the problem with the new API. (since we + ### shouldn't return a hidden entry here) */ + return walk_callbacks->handle_error( + path, svn_error_createf( + SVN_ERR_UNVERSIONED_RESOURCE, NULL, + _("'%s' is not under version control"), + svn_dirent_local_style(local_abspath, pool)), + walk_baton, pool); } SVN_ERR(svn_wc__get_entry(&entry, db, local_abspath, FALSE, Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/externals.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/externals.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_wc/externals.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_wc/externals.c Tue Feb 24 15:23:33 2015 @@ -1496,9 +1496,7 @@ svn_wc__external_remove(svn_wc_context_t else { SVN_ERR(svn_wc__db_base_remove(wc_ctx->db, local_abspath, - FALSE /* keep_as_working */, - TRUE /* queue_deletes */, - FALSE /* remove_locks */, + FALSE, FALSE, FALSE, SVN_INVALID_REVNUM, NULL, NULL, scratch_pool)); SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath, Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/info.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/info.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_wc/info.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_wc/info.c Tue Feb 24 15:23:33 2015 @@ -141,7 +141,6 @@ build_info_for_node(svn_wc__info2_t **in { /* Root or child of copy */ tmpinfo->rev = original_revision; - repos_relpath = original_repos_relpath; if (op_root) { @@ -167,34 +166,6 @@ build_info_for_node(svn_wc__info2_t **in } } } - else if (op_root) - { - /* Local addition */ - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath, - &tmpinfo->repos_root_URL, - &tmpinfo->repos_UUID, - NULL, NULL, NULL, NULL, - db, local_abspath, - result_pool, scratch_pool)); - - if (have_base) - SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, &tmpinfo->rev, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, NULL, - db, local_abspath, - scratch_pool, scratch_pool)); - } - else - { - /* Child of copy. ### Not WC-NG like */ - SVN_ERR(svn_wc__internal_get_origin(NULL, &tmpinfo->rev, - &repos_relpath, - &tmpinfo->repos_root_URL, - &tmpinfo->repos_UUID, NULL, NULL, - db, local_abspath, TRUE, - result_pool, scratch_pool)); - } /* ### We should be able to avoid both these calls with the information from read_info() in most cases */ @@ -222,14 +193,20 @@ build_info_for_node(svn_wc__info2_t **in else wc_info->schedule = svn_wc_schedule_add; } - SVN_ERR(svn_wc__db_read_url(&tmpinfo->URL, db, local_abspath, - result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_read_repos_info(NULL, &repos_relpath, + &tmpinfo->repos_root_URL, + &tmpinfo->repos_UUID, + db, local_abspath, + result_pool, scratch_pool)); + + tmpinfo->URL = svn_path_url_add_component2(tmpinfo->repos_root_URL, + repos_relpath, result_pool); } else if (status == svn_wc__db_status_deleted) { - const char *work_del_abspath; + svn_wc__db_status_t w_status; - SVN_ERR(svn_wc__db_read_pristine_info(NULL, NULL, + SVN_ERR(svn_wc__db_read_pristine_info(&w_status, &tmpinfo->kind, &tmpinfo->last_changed_rev, &tmpinfo->last_changed_date, &tmpinfo->last_changed_author, @@ -239,51 +216,32 @@ build_info_for_node(svn_wc__info2_t **in db, local_abspath, result_pool, scratch_pool)); + if (w_status == svn_wc__db_status_deleted) + { + /* We have a working not-present status. We don't know anything + about this node, but it *is visible* in STATUS. + + Let's tell that it is excluded */ + + wc_info->depth = svn_depth_exclude; + tmpinfo->kind = svn_node_unknown; + } + /* And now fetch the url and revision of what will be deleted */ SVN_ERR(svn_wc__db_scan_deletion(NULL, &wc_info->moved_to_abspath, - &work_del_abspath, NULL, + NULL, NULL, db, local_abspath, scratch_pool, scratch_pool)); - if (work_del_abspath != NULL) - { - /* This is a deletion within a copied subtree. Get the copied-from - * revision. */ - const char *added_abspath = svn_dirent_dirname(work_del_abspath, - scratch_pool); - - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath, - &tmpinfo->repos_root_URL, - &tmpinfo->repos_UUID, - NULL, NULL, NULL, - &tmpinfo->rev, - db, added_abspath, - result_pool, scratch_pool)); - - tmpinfo->URL = svn_path_url_add_component2( - tmpinfo->repos_root_URL, - svn_relpath_join(repos_relpath, - svn_dirent_skip_ancestor(added_abspath, - local_abspath), - scratch_pool), - result_pool); - } - else - { - SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, &tmpinfo->rev, - &repos_relpath, - &tmpinfo->repos_root_URL, - &tmpinfo->repos_UUID, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - db, local_abspath, - result_pool, scratch_pool)); - - tmpinfo->URL = svn_path_url_add_component2(tmpinfo->repos_root_URL, - repos_relpath, - result_pool); - } + + SVN_ERR(svn_wc__db_read_repos_info(&tmpinfo->rev, &repos_relpath, + &tmpinfo->repos_root_URL, + &tmpinfo->repos_UUID, + db, local_abspath, + result_pool, scratch_pool)); wc_info->schedule = svn_wc_schedule_delete; + tmpinfo->URL = svn_path_url_add_component2(tmpinfo->repos_root_URL, + repos_relpath, result_pool); } else if (status == svn_wc__db_status_not_present || status == svn_wc__db_status_server_excluded) @@ -291,6 +249,21 @@ build_info_for_node(svn_wc__info2_t **in *info = NULL; return SVN_NO_ERROR; } + else if (status == svn_wc__db_status_excluded && !repos_relpath) + { + /* We have a WORKING exclude. Avoid segfault on no repos info */ + + SVN_ERR(svn_wc__db_read_repos_info(NULL, &repos_relpath, + &tmpinfo->repos_root_URL, + &tmpinfo->repos_UUID, + db, local_abspath, + result_pool, scratch_pool)); + + wc_info->schedule = svn_wc_schedule_normal; + tmpinfo->URL = svn_path_url_add_component2(tmpinfo->repos_root_URL, + repos_relpath, result_pool); + tmpinfo->wc_info->depth = svn_depth_exclude; + } else { /* Just a BASE node. We have all the info we need */ @@ -298,10 +271,10 @@ build_info_for_node(svn_wc__info2_t **in repos_relpath, result_pool); wc_info->schedule = svn_wc_schedule_normal; - } - if (status == svn_wc__db_status_excluded) - tmpinfo->wc_info->depth = svn_depth_exclude; + if (status == svn_wc__db_status_excluded) + wc_info->depth = svn_depth_exclude; + } /* A default */ tmpinfo->size = SVN_INVALID_FILESIZE; @@ -544,15 +517,14 @@ svn_wc__get_info(svn_wc_context_t *wc_ct if (!repos_root_url) { - SVN_ERR(svn_wc__internal_get_repos_info(NULL, NULL, - &repos_root_url, - &repos_uuid, - wc_ctx->db, - svn_dirent_dirname( + SVN_ERR(svn_wc__db_read_repos_info(NULL, NULL, + &repos_root_url, + &repos_uuid, + wc_ctx->db, + svn_dirent_dirname( this_abspath, iterpool), - scratch_pool, - iterpool)); + scratch_pool, iterpool)); } info->repos_root_URL = repos_root_url; Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/node.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/node.c?rev=1661981&r1=1661980&r2=1661981&view=diff ============================================================================== --- subversion/branches/svn-info-detail/subversion/libsvn_wc/node.c (original) +++ subversion/branches/svn-info-detail/subversion/libsvn_wc/node.c Tue Feb 24 15:23:33 2015 @@ -54,18 +54,14 @@ /* Set *CHILDREN_ABSPATHS to a new array of the full paths formed by joining - * each name in REL_CHILDREN onto DIR_ABSPATH. If SHOW_HIDDEN is false then - * omit any paths that are reported as 'hidden' by svn_wc__db_node_hidden(). + * each name in REL_CHILDREN onto DIR_ABSPATH. * * Allocate the output array and its elements in RESULT_POOL. */ -static svn_error_t * -filter_and_make_absolute(const apr_array_header_t **children_abspaths, - svn_wc_context_t *wc_ctx, - const char *dir_abspath, - const apr_array_header_t *rel_children, - svn_boolean_t show_hidden, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +static void +make_absolute(const apr_array_header_t **children_abspaths, + const char *dir_abspath, + const apr_array_header_t *rel_children, + apr_pool_t *result_pool) { apr_array_header_t *children; int i; @@ -74,29 +70,13 @@ filter_and_make_absolute(const apr_array sizeof(const char *)); for (i = 0; i < rel_children->nelts; i++) { - const char *child_abspath = svn_dirent_join(dir_abspath, - APR_ARRAY_IDX(rel_children, - i, - const char *), - result_pool); - - /* Don't add hidden nodes to *CHILDREN if we don't want them. */ - if (!show_hidden) - { - svn_boolean_t child_is_hidden; - - SVN_ERR(svn_wc__db_node_hidden(&child_is_hidden, wc_ctx->db, - child_abspath, scratch_pool)); - if (child_is_hidden) - continue; - } - - APR_ARRAY_PUSH(children, const char *) = child_abspath; + const char *name = APR_ARRAY_IDX(rel_children, i, const char *); + APR_ARRAY_PUSH(children, const char *) = + svn_dirent_join(dir_abspath, name, + result_pool); } *children_abspaths = children; - - return SVN_NO_ERROR; } @@ -104,136 +84,36 @@ svn_error_t * svn_wc__node_get_children_of_working_node(const apr_array_header_t **children, svn_wc_context_t *wc_ctx, const char *dir_abspath, - svn_boolean_t show_hidden, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - const apr_array_header_t *rel_children; + const apr_array_header_t *child_names; - SVN_ERR(svn_wc__db_read_children_of_working_node(&rel_children, + SVN_ERR(svn_wc__db_read_children_of_working_node(&child_names, wc_ctx->db, dir_abspath, scratch_pool, scratch_pool)); - SVN_ERR(filter_and_make_absolute(children, wc_ctx, dir_abspath, - rel_children, show_hidden, - result_pool, scratch_pool)); + make_absolute(children, dir_abspath, child_names, result_pool); return SVN_NO_ERROR; } - -svn_error_t * -svn_wc__node_get_children(const apr_array_header_t **children, - svn_wc_context_t *wc_ctx, - const char *dir_abspath, - svn_boolean_t show_hidden, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - const apr_array_header_t *rel_children; - - SVN_ERR(svn_wc__db_read_children(&rel_children, wc_ctx->db, dir_abspath, - scratch_pool, scratch_pool)); - SVN_ERR(filter_and_make_absolute(children, wc_ctx, dir_abspath, - rel_children, show_hidden, - result_pool, scratch_pool)); - return SVN_NO_ERROR; -} - svn_error_t * -svn_wc__internal_get_repos_info(svn_revnum_t *revision, - const char **repos_relpath, - const char **repos_root_url, - const char **repos_uuid, - svn_wc__db_t *db, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - svn_wc__db_status_t status; - svn_boolean_t have_work; - - SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, repos_relpath, - repos_root_url, repos_uuid, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, &have_work, - db, local_abspath, - result_pool, scratch_pool)); - - if ((repos_relpath ? *repos_relpath != NULL : TRUE) - && (repos_root_url ? *repos_root_url != NULL: TRUE) - && (repos_uuid ? *repos_uuid != NULL : TRUE)) - return SVN_NO_ERROR; /* We got the requested information */ - - if (!have_work) /* not-present, (server-)excluded? */ - { - return SVN_NO_ERROR; /* Can't fetch more */ - } - - if (status == svn_wc__db_status_deleted) - { - const char *base_del_abspath, *wrk_del_abspath; - - SVN_ERR(svn_wc__db_scan_deletion(&base_del_abspath, NULL, - &wrk_del_abspath, NULL, - db, local_abspath, - scratch_pool, scratch_pool)); - - if (base_del_abspath) - { - SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, repos_relpath, - repos_root_url, repos_uuid, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, - db, base_del_abspath, - result_pool, scratch_pool)); - - /* If we have a repos_relpath, it is of the op-root */ - if (repos_relpath) - *repos_relpath = svn_relpath_join(*repos_relpath, - svn_dirent_skip_ancestor(base_del_abspath, - local_abspath), - result_pool); - /* We keep revision as SVN_INVALID_REVNUM */ - } - else if (wrk_del_abspath) - { - const char *op_root_abspath = NULL; - - SVN_ERR(svn_wc__db_scan_addition(NULL, repos_relpath - ? &op_root_abspath : NULL, - repos_relpath, repos_root_url, - repos_uuid, NULL, NULL, NULL, NULL, - db, svn_dirent_dirname( - wrk_del_abspath, - scratch_pool), - result_pool, scratch_pool)); - - /* If we have a repos_relpath, it is of the op-root */ - if (repos_relpath) - *repos_relpath = svn_relpath_join( - *repos_relpath, - svn_dirent_skip_ancestor(op_root_abspath, - local_abspath), - result_pool); - } - } - else /* added, or WORKING incomplete */ - { - /* We have an addition. scan_addition() will find the intended - repository location by scanning up the tree. */ - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, - repos_relpath, repos_root_url, - repos_uuid, NULL, NULL, NULL, NULL, - db, local_abspath, - result_pool, scratch_pool)); - } - - SVN_ERR_ASSERT(repos_root_url == NULL || *repos_root_url != NULL); - SVN_ERR_ASSERT(repos_uuid == NULL || *repos_uuid != NULL); +svn_wc__node_get_not_present_children(const apr_array_header_t **children, + svn_wc_context_t *wc_ctx, + const char *dir_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + const apr_array_header_t *child_names; + + SVN_ERR(svn_wc__db_base_read_not_present_children( + &child_names, + wc_ctx->db, dir_abspath, + scratch_pool, scratch_pool)); + make_absolute(children, dir_abspath, child_names, result_pool); return SVN_NO_ERROR; } + svn_error_t * svn_wc__node_get_repos_info(svn_revnum_t *revision, const char **repos_relpath, @@ -245,12 +125,12 @@ svn_wc__node_get_repos_info(svn_revnum_t apr_pool_t *scratch_pool) { return svn_error_trace( - svn_wc__internal_get_repos_info(revision, - repos_relpath, - repos_root_url, - repos_uuid, - wc_ctx->db, local_abspath, - result_pool, scratch_pool)); + svn_wc__db_read_repos_info(revision, + repos_relpath, + repos_root_url, + repos_uuid, + wc_ctx->db, local_abspath, + result_pool, scratch_pool)); } /* Convert DB_KIND into the appropriate NODE_KIND value. @@ -344,8 +224,18 @@ svn_wc__node_get_url(const char **url, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - return svn_error_trace(svn_wc__db_read_url(url, wc_ctx->db, local_abspath, - result_pool, scratch_pool)); + const char *repos_root_url; + const char *repos_relpath; + + SVN_ERR(svn_wc__db_read_repos_info(NULL, &repos_relpath, &repos_root_url, + NULL, + wc_ctx->db, local_abspath, + scratch_pool, scratch_pool)); + + *url = svn_path_url_add_component2(repos_root_url, repos_relpath, + result_pool); + + return SVN_NO_ERROR; } /* A recursive node-walker, helper for svn_wc__internal_walk_children(). @@ -517,33 +407,6 @@ svn_wc__internal_walk_children(svn_wc__d } svn_error_t * -svn_wc__node_get_deleted_ancestor(const char **deleted_ancestor_abspath, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - svn_wc__db_status_t status; - - *deleted_ancestor_abspath = NULL; - - 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)); - - if (status == svn_wc__db_status_deleted) - SVN_ERR(svn_wc__db_scan_deletion(deleted_ancestor_abspath, NULL, NULL, - NULL, wc_ctx->db, local_abspath, - result_pool, scratch_pool)); - - return SVN_NO_ERROR; -} - -svn_error_t * svn_wc__node_is_not_present(svn_boolean_t *is_not_present, svn_boolean_t *is_excluded, svn_boolean_t *is_server_excluded,
