Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509info.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509info.c?rev=1662177&r1=1662176&r2=1662177&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509info.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509info.c Wed Feb 25 08:15:39 2015 @@ -168,7 +168,7 @@ svn_x509_oid_to_string(const unsigned ch } else if (*p < 128) { - /* The remaining values if they're less than 128 are just + /* The remaining values if they're less than 128 are just * the number one to one encoded */ temp = apr_psprintf(scratch_pool, ".%d", *p); p++;
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_wc/adm_ops.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/adm_ops.c?rev=1662177&r1=1662176&r2=1662177&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/adm_ops.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/adm_ops.c Wed Feb 25 08:15:39 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/reuse-ra-session/subversion/libsvn_wc/conflicts.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/conflicts.c?rev=1662177&r1=1662176&r2=1662177&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/conflicts.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/conflicts.c Wed Feb 25 08:15:39 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; } @@ -1772,6 +1778,7 @@ static svn_error_t * read_tree_conflict_desc(svn_wc_conflict_description2_t **desc, svn_wc__db_t *db, const char *local_abspath, + svn_node_kind_t node_kind, const svn_skel_t *conflict_skel, svn_wc_operation_t operation, const svn_wc_conflict_version_t *left_version, @@ -1792,49 +1799,18 @@ read_tree_conflict_desc(svn_wc_conflict_ else if (reason == svn_wc_conflict_reason_unversioned || reason == svn_wc_conflict_reason_obstructed) SVN_ERR(svn_io_check_path(local_abspath, &local_kind, scratch_pool)); - else if (operation == svn_wc_operation_merge) + else if (action == svn_wc_conflict_action_delete + && left_version + && (operation == svn_wc_operation_update + ||operation == svn_wc_operation_switch) + && (reason == svn_wc_conflict_reason_deleted + || reason == svn_wc_conflict_reason_moved_away)) { - /* ### If the merge replaced the node, this will read the kind of - * ### the merge-right node, which is not necessarily the node - * ### kind of the tree conflict victim. - * ### This needs the BASE node kind if the node was not replaced - * ### at the time the merge was run. But if the node was already - * ### replaced before the merge, it needs the kind of the replacing - * ### node. Ideally, we'd store the victim node kind in conflict - * ### storage instead of guessing it here... - */ - /* Read the tree conflict victim's node kind from the working copy, - or if it doesn't exist directly from disk. */ - SVN_ERR(svn_wc__db_read_kind(&local_kind, db, local_abspath, - TRUE /* allow missing */, - FALSE /* show deleted */, - FALSE /* show hidden */, scratch_pool)); - - if (local_kind == svn_node_unknown || local_kind == svn_node_none) - SVN_ERR(svn_io_check_path(local_abspath, &local_kind, scratch_pool)); - } - else if (operation == svn_wc_operation_update || - operation == svn_wc_operation_switch) - { - /* For updates, the left version corresponds to the pre-update state. */ - if (left_version) - local_kind = left_version->node_kind; - else - { - /* No left version is available, so the conflict was flagged - * because of a locally added node which was not part of the - * BASE tree before the update. */ - SVN_ERR(svn_wc__db_read_kind(&local_kind, db, local_abspath, - TRUE /* allow missing */, - TRUE /* show deleted */, - FALSE /* show hidden */, scratch_pool)); - if (local_kind == svn_node_unknown || local_kind == svn_node_none) - SVN_ERR(svn_io_check_path(local_abspath, &local_kind, - scratch_pool)); - } + /* We have nothing locally to take the kind from */ + local_kind = left_version->node_kind; } else - SVN_ERR_MALFUNCTION(); + local_kind = node_kind; *desc = svn_wc_conflict_description_create_tree2(local_abspath, local_kind, operation, @@ -2029,9 +2005,14 @@ svn_wc__conflict_invoke_resolver(svn_wc_ svn_wc_conflict_result_t *result; svn_wc_conflict_description2_t *desc; svn_boolean_t resolved; + svn_node_kind_t node_kind; + + SVN_ERR(svn_wc__db_read_kind(&node_kind, db, local_abspath, TRUE, + TRUE, FALSE, scratch_pool)); SVN_ERR(read_tree_conflict_desc(&desc, - db, local_abspath, conflict_skel, + db, local_abspath, node_kind, + conflict_skel, operation, left_version, right_version, scratch_pool, scratch_pool)); @@ -2126,8 +2107,8 @@ read_prop_conflict_descs(apr_array_heade return SVN_NO_ERROR; } - SVN_ERR(svn_wc__db_base_get_props(&base_props, db, local_abspath, - result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_read_pristine_props(&base_props, db, local_abspath, + result_pool, scratch_pool)); iterpool = svn_pool_create(scratch_pool); for (hi = apr_hash_first(scratch_pool, conflicted_props); hi; @@ -2250,8 +2231,10 @@ svn_wc__read_conflicts(const apr_array_h const apr_array_header_t *locations; const svn_wc_conflict_version_t *left_version = NULL; const svn_wc_conflict_version_t *right_version = NULL; + svn_node_kind_t node_kind; - SVN_ERR(svn_wc__db_read_conflict(&conflict_skel, db, local_abspath, + SVN_ERR(svn_wc__db_read_conflict(&conflict_skel, &node_kind, + db, local_abspath, scratch_pool, scratch_pool)); if (!conflict_skel) @@ -2277,9 +2260,6 @@ svn_wc__read_conflicts(const apr_array_h if (prop_conflicted) { - svn_node_kind_t node_kind - = left_version ? left_version->node_kind : svn_node_unknown; - SVN_ERR(read_prop_conflict_descs(cflcts, db, local_abspath, conflict_skel, create_tempfiles, node_kind, @@ -2304,7 +2284,8 @@ svn_wc__read_conflicts(const apr_array_h svn_wc_conflict_description2_t *desc; SVN_ERR(read_tree_conflict_desc(&desc, - db, local_abspath, conflict_skel, + db, local_abspath, node_kind, + conflict_skel, operation, left_version, right_version, result_pool, scratch_pool)); @@ -2357,9 +2338,11 @@ static svn_error_t * resolve_prop_conflict_on_node(svn_boolean_t *did_resolve, svn_wc__db_t *db, const char *local_abspath, + const svn_skel_t *conflicts, 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) @@ -2372,18 +2355,11 @@ resolve_prop_conflict_on_node(svn_boolea apr_hash_t *old_props; apr_hash_t *resolve_from = NULL; svn_skel_t *work_items = NULL; - svn_skel_t *conflicts; svn_wc_operation_t operation; svn_boolean_t prop_conflicted; *did_resolve = FALSE; - SVN_ERR(svn_wc__db_read_conflict(&conflicts, db, local_abspath, - scratch_pool, scratch_pool)); - - if (!conflicts) - return SVN_NO_ERROR; - SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, &prop_conflicted, NULL, db, local_abspath, conflicts, scratch_pool, scratch_pool)); @@ -2427,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; @@ -2555,19 +2537,31 @@ resolve_tree_conflict_on_node(svn_boolea { /* Break moves for any children moved out of this directory, * and leave this directory deleted. */ - SVN_ERR(svn_wc__db_resolve_break_moved_away_children( - db, local_abspath, src_op_root_abspath, - notify_func, notify_baton, - scratch_pool)); + + if (action != svn_wc_conflict_action_delete) + { + SVN_ERR(svn_wc__db_op_break_moved_away( + db, local_abspath, src_op_root_abspath, TRUE, + notify_func, notify_baton, + scratch_pool)); + *did_resolve = TRUE; + return SVN_NO_ERROR; /* Marked resolved by function*/ + } + /* else # The move is/moves are already broken */ + + *did_resolve = TRUE; } else if (conflict_choice == svn_wc_conflict_choose_mine_conflict) { - /* Raised moved-away conflicts on any children moved out of - * this directory, and leave this directory deleted. + svn_skel_t *new_conflicts; + + /* Raise moved-away conflicts on any children moved out of + * this directory, and leave this directory as-is. + * * The newly conflicted moved-away children will be updated * if they are resolved with 'mine_conflict' as well. */ - err = svn_wc__db_resolve_delete_raise_moved_away( + err = svn_wc__db_op_raise_moved_away( db, local_abspath, notify_func, notify_baton, scratch_pool); @@ -2587,8 +2581,44 @@ resolve_tree_conflict_on_node(svn_boolea return SVN_NO_ERROR; /* Retry after other conflicts */ } - else - *did_resolve = TRUE; + + /* We might now have a moved-away on *this* path, let's + try to resolve that directly if that is the case */ + SVN_ERR(svn_wc__db_read_conflict(&new_conflicts, NULL, + db, local_abspath, + scratch_pool, scratch_pool)); + + if (new_conflicts) + SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, NULL, NULL, + &tree_conflicted, + db, local_abspath, + new_conflicts, + scratch_pool, + scratch_pool)); + + if (!new_conflicts || !tree_conflicted) + { + /* TC is marked resolved by calling + svn_wc__db_resolve_delete_raise_moved_away */ + *did_resolve = TRUE; + return SVN_NO_ERROR; + } + + SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, + &src_op_root_abspath, + db, local_abspath, + new_conflicts, + scratch_pool, + scratch_pool)); + + if (reason != svn_wc_conflict_reason_moved_away) + { + *did_resolve = TRUE; + return SVN_NO_ERROR; /* We fixed one, but... */ + } + + conflicts = new_conflicts; + /* Fall through in moved_away handling */ } else return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, @@ -2599,8 +2629,9 @@ resolve_tree_conflict_on_node(svn_boolea svn_dirent_local_style(local_abspath, scratch_pool)); } - else if (reason == svn_wc_conflict_reason_moved_away - && action == svn_wc_conflict_action_edit) + + if (reason == svn_wc_conflict_reason_moved_away + && action == svn_wc_conflict_action_edit) { /* After updates, we can resolve local moved-away * vs. any incoming change, either by updating the @@ -2640,15 +2671,12 @@ resolve_tree_conflict_on_node(svn_boolea * working copy state instead of updating the move. * Else the move would be left in an invalid state. */ - /* ### This breaks the move but leaves the conflict - ### involving the move until - ### svn_wc__db_op_mark_resolved. */ - SVN_ERR(svn_wc__db_resolve_break_moved_away(db, local_abspath, - src_op_root_abspath, - notify_func, - notify_baton, - scratch_pool)); + SVN_ERR(svn_wc__db_op_break_moved_away(db, local_abspath, + src_op_root_abspath, TRUE, + notify_func, notify_baton, + scratch_pool)); *did_resolve = TRUE; + return SVN_NO_ERROR; /* Conflict is marked resolved */ } else return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, @@ -2727,7 +2755,7 @@ svn_wc__mark_resolved_text_conflict(svn_ svn_skel_t *work_items; svn_skel_t *conflict; - SVN_ERR(svn_wc__db_read_conflict(&conflict, db, local_abspath, + SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, db, local_abspath, scratch_pool, scratch_pool)); if (!conflict) @@ -2754,11 +2782,19 @@ svn_wc__mark_resolved_prop_conflicts(svn apr_pool_t *scratch_pool) { svn_boolean_t ignored_result; + svn_skel_t *conflicts; + + SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, db, local_abspath, + scratch_pool, scratch_pool)); + + if (!conflicts) + return SVN_NO_ERROR; return svn_error_trace(resolve_prop_conflict_on_node( &ignored_result, - db, local_abspath, "", - svn_wc_conflict_choose_merged, NULL, + db, local_abspath, conflicts, "", + svn_wc_conflict_choose_merged, + NULL, NULL, NULL, NULL, scratch_pool)); } @@ -2778,6 +2814,7 @@ struct conflict_status_walker_baton void *cancel_baton; svn_wc_notify_func2_t notify_func; void *notify_baton; + svn_boolean_t resolved_one; apr_hash_t *resolve_later; }; @@ -2832,7 +2869,7 @@ conflict_status_walker(void *baton, iterpool = svn_pool_create(scratch_pool); - SVN_ERR(svn_wc__db_read_conflict(&conflict, db, local_abspath, + SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, db, local_abspath, scratch_pool, scratch_pool)); SVN_ERR(svn_wc__read_conflicts(&conflicts, db, local_abspath, TRUE, @@ -2848,7 +2885,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)) { @@ -2877,8 +2917,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, @@ -2895,9 +2933,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, @@ -2921,23 +2956,18 @@ 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, + conflict, cd->property_name, my_choice, result ? result->merged_file : NULL, + result + ? result->merged_value + : NULL, cswb->cancel_func, cswb->cancel_baton, iterpool)); @@ -2960,6 +2990,9 @@ conflict_status_walker(void *baton, iterpool), iterpool); + if (resolved) + cswb->resolved_one = TRUE; + svn_pool_destroy(iterpool); return SVN_NO_ERROR; @@ -3025,6 +3058,7 @@ svn_wc__resolve_conflicts(svn_wc_context cswb.notify_func = notify_func; cswb.notify_baton = notify_baton; + cswb.resolved_one = FALSE; cswb.resolve_later = (depth != svn_depth_empty) ? apr_hash_make(scratch_pool) : NULL; @@ -3047,10 +3081,12 @@ svn_wc__resolve_conflicts(svn_wc_context cancel_func, cancel_baton, scratch_pool); + /* If we got new tree conflicts (or delayed conflicts) during the initial + walk, we now walk them one by one as closure. */ while (!err && cswb.resolve_later && apr_hash_count(cswb.resolve_later)) { apr_hash_index_t *hi; - svn_boolean_t cleared_one = FALSE; + svn_wc_status3_t *status = NULL; const char *tc_abspath = NULL; if (iterpool) @@ -3060,31 +3096,64 @@ svn_wc__resolve_conflicts(svn_wc_context hi = apr_hash_first(scratch_pool, cswb.resolve_later); cswb.resolve_later = apr_hash_make(scratch_pool); + cswb.resolved_one = FALSE; for (; hi && !err; hi = apr_hash_next(hi)) { - tc_abspath = apr_hash_this_key(hi); + const char *relpath; svn_pool_clear(iterpool); - /* ### TODO: Check if tc_abspath falls within selected depth */ + tc_abspath = apr_hash_this_key(hi); - err = svn_wc_walk_status(wc_ctx, tc_abspath, svn_depth_empty, - FALSE, FALSE, TRUE, NULL, - conflict_status_walker, &cswb, - cancel_func, cancel_baton, - iterpool); + if (cancel_func) + SVN_ERR(cancel_func(cancel_baton)); + + relpath = svn_dirent_skip_ancestor(local_abspath, + tc_abspath); - if (!err && !svn_hash_gets(cswb.resolve_later, tc_abspath)) - cleared_one = TRUE; + if (!relpath + || (depth >= svn_depth_empty + && depth < svn_depth_infinity + && strchr(relpath, '/'))) + { + continue; + } + + SVN_ERR(svn_wc_status3(&status, wc_ctx, tc_abspath, + iterpool, iterpool)); + + if (depth == svn_depth_files + && status->kind == svn_node_dir) + continue; + + err = svn_error_trace(conflict_status_walker(&cswb, tc_abspath, + status, scratch_pool)); } - if (!cleared_one && !err) + /* None of the remaining conflicts got resolved, and non did provide + an error... + + We can fix that if we disable the 'resolve_later' option... + */ + if (!cswb.resolved_one && !err && tc_abspath + && apr_hash_count(cswb.resolve_later)) { - /* Return the error on one of the paths: The last one. */ + /* Run the last resolve operation again. We still have status + and tc_abspath for that one. */ + + cswb.resolve_later = NULL; /* Produce proper error! */ + + /* Recreate the error */ + err = svn_error_trace(conflict_status_walker(&cswb, tc_abspath, + status, scratch_pool)); + + SVN_ERR_ASSERT(err != NULL); + err = svn_error_createf( - SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL, + SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, err, _("Unable to resolve pending conflict on '%s'"), svn_dirent_local_style(tc_abspath, scratch_pool)); + break; } } @@ -3141,7 +3210,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/reuse-ra-session/subversion/libsvn_wc/copy.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/copy.c?rev=1662177&r1=1662176&r2=1662177&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/copy.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/copy.c Wed Feb 25 08:15:39 2015 @@ -258,7 +258,7 @@ copy_versioned_file(svn_wc__db_t *db, svn_error_t *err; /* Is there a text conflict at the source path? */ - SVN_ERR(svn_wc__db_read_conflict(&conflict, db, src_abspath, + SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, db, src_abspath, scratch_pool, scratch_pool)); err = svn_wc__conflict_read_text_conflict(&conflict_working, NULL, NULL, @@ -945,7 +945,7 @@ remove_node_conflict_markers(svn_wc__db_ { svn_skel_t *conflict; - SVN_ERR(svn_wc__db_read_conflict(&conflict, db, src_abspath, + SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, db, src_abspath, scratch_pool, scratch_pool)); /* Do we have conflict markers that should be removed? */ @@ -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/reuse-ra-session/subversion/libsvn_wc/crop.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/crop.c?rev=1662177&r1=1662176&r2=1662177&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/crop.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/crop.c Wed Feb 25 08:15:39 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/reuse-ra-session/subversion/libsvn_wc/delete.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/delete.c?rev=1662177&r1=1662176&r2=1662177&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/delete.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/delete.c Wed Feb 25 08:15:39 2015 @@ -135,7 +135,7 @@ create_delete_wq_items(svn_skel_t **work const apr_array_header_t *markers; int i; - SVN_ERR(svn_wc__db_read_conflict(&conflict, db, local_abspath, + SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, db, local_abspath, scratch_pool, scratch_pool)); SVN_ERR(svn_wc__conflict_read_markers(&markers, db, local_abspath, @@ -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/reuse-ra-session/subversion/libsvn_wc/diff.h URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/diff.h?rev=1662177&r1=1662176&r2=1662177&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/diff.h (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/diff.h Wed Feb 25 08:15:39 2015 @@ -39,7 +39,7 @@ extern "C" { #endif /* __cplusplus */ /* A function to diff locally added and locally copied files. - + Reports the file LOCAL_ABSPATH as ADDED file with relpath RELPATH to PROCESSOR with as parent baton PROCESSOR_PARENT_BATON. @@ -60,7 +60,7 @@ svn_wc__diff_local_only_file(svn_wc__db_ apr_pool_t *scratch_pool); /* A function to diff locally added and locally copied directories. - + Reports the directory LOCAL_ABSPATH and everything below it (limited by DEPTH) as added with relpath RELPATH to PROCESSOR with as parent baton PROCESSOR_PARENT_BATON. Modified: subversion/branches/reuse-ra-session/subversion/libsvn_wc/diff_editor.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/diff_editor.c?rev=1662177&r1=1662176&r2=1662177&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/diff_editor.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/diff_editor.c Wed Feb 25 08:15:39 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/reuse-ra-session/subversion/libsvn_wc/entries.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/entries.c?rev=1662177&r1=1662176&r2=1662177&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/entries.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/entries.c Wed Feb 25 08:15:39 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)))) @@ -881,7 +882,7 @@ read_one_entry(const svn_wc_entry_t **ne 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, + SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, db, entry_abspath, scratch_pool, scratch_pool)); SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, &text_conflicted, @@ -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/reuse-ra-session/subversion/libsvn_wc/externals.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/externals.c?rev=1662177&r1=1662176&r2=1662177&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/externals.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/externals.c Wed Feb 25 08:15:39 2015 @@ -68,6 +68,7 @@ * the revision if the revision is found. Set REV_IDX to the index in * LINE_PARTS where the revision specification starts. Remove from * LINE_PARTS the element(s) that specify the revision. + * Set REV_STR to the element that specifies the revision. * PARENT_DIRECTORY_DISPLAY and LINE are given to return a nice error * string. * @@ -76,6 +77,7 @@ */ static svn_error_t * find_and_remove_externals_revision(int *rev_idx, + const char **rev_str, const char **line_parts, int num_line_parts, svn_wc_external_item2_t *item, @@ -137,6 +139,8 @@ find_and_remove_externals_revision(int * line_parts[j] = line_parts[j+shift_count]; line_parts[num_line_parts-shift_count] = NULL; + *rev_str = apr_psprintf(pool, "-r%s", digits_ptr); + /* Found the revision, so leave the function immediately, do * not continue looking for additional revisions. */ return SVN_NO_ERROR; @@ -158,7 +162,8 @@ find_and_remove_externals_revision(int * } svn_error_t * -svn_wc_parse_externals_description3(apr_array_header_t **externals_p, +svn_wc__parse_externals_description(apr_array_header_t **externals_p, + apr_array_header_t **parser_infos_p, const char *defining_directory, const char *desc, svn_boolean_t canonicalize_url, @@ -166,6 +171,7 @@ svn_wc_parse_externals_description3(apr_ { int i; apr_array_header_t *externals = NULL; + apr_array_header_t *parser_infos = NULL; apr_array_header_t *lines = svn_cstring_split(desc, "\n\r", TRUE, pool); const char *defining_directory_display = svn_path_is_url(defining_directory) ? defining_directory : svn_dirent_local_style(defining_directory, pool); @@ -175,6 +181,10 @@ svn_wc_parse_externals_description3(apr_ if (externals_p) externals = apr_array_make(pool, 1, sizeof(svn_wc_external_item2_t *)); + if (parser_infos_p) + parser_infos = + apr_array_make(pool, 1, sizeof(svn_wc__externals_parser_info_t *)); + for (i = 0; i < lines->nelts; i++) { const char *line = APR_ARRAY_IDX(lines, i, const char *); @@ -186,10 +196,12 @@ svn_wc_parse_externals_description3(apr_ const char *token1; svn_boolean_t token0_is_url; svn_boolean_t token1_is_url; + svn_wc__externals_parser_info_t *info = NULL; /* Index into line_parts where the revision specification started. */ int rev_idx = -1; + const char *rev_str = NULL; if ((! line) || (line[0] == '#')) continue; @@ -209,6 +221,9 @@ svn_wc_parse_externals_description3(apr_ item->revision.kind = svn_opt_revision_unspecified; item->peg_revision.kind = svn_opt_revision_unspecified; + if (parser_infos) + info = apr_pcalloc(pool, sizeof(*info)); + /* * There are six different formats of externals: * @@ -240,6 +255,7 @@ svn_wc_parse_externals_description3(apr_ set item->revision to the parsed revision. */ /* ### ugh. stupid cast. */ SVN_ERR(find_and_remove_externals_revision(&rev_idx, + &rev_str, (const char **)line_parts, num_line_parts, item, defining_directory_display, @@ -290,12 +306,34 @@ svn_wc_parse_externals_description3(apr_ SVN_ERR(svn_opt_parse_path(&item->peg_revision, &item->url, token0, pool)); item->target_dir = token1; + + if (info) + { + info->format = svn_wc__external_description_format_2; + + if (rev_str) + info->rev_str = apr_pstrdup(pool, rev_str); + + if (item->peg_revision.kind != svn_opt_revision_unspecified) + info->peg_rev_str = strrchr(token0, '@'); + } } else { item->target_dir = token0; item->url = token1; item->peg_revision = item->revision; + + if (info) + { + info->format = svn_wc__external_description_format_1; + + if (rev_str) + { + info->rev_str = apr_pstrdup(pool, rev_str); + info->peg_rev_str = info->rev_str; + } + } } SVN_ERR(svn_opt_resolve_revisions(&item->peg_revision, @@ -333,15 +371,34 @@ svn_wc_parse_externals_description3(apr_ if (externals) APR_ARRAY_PUSH(externals, svn_wc_external_item2_t *) = item; + if (parser_infos) + APR_ARRAY_PUSH(parser_infos, svn_wc__externals_parser_info_t *) = info; } if (externals_p) *externals_p = externals; + if (parser_infos_p) + *parser_infos_p = parser_infos; return SVN_NO_ERROR; } svn_error_t * +svn_wc_parse_externals_description3(apr_array_header_t **externals_p, + const char *defining_directory, + const char *desc, + svn_boolean_t canonicalize_url, + apr_pool_t *pool) +{ + return svn_error_trace(svn_wc__parse_externals_description(externals_p, + NULL, + defining_directory, + desc, + canonicalize_url, + pool)); +} + +svn_error_t * svn_wc__externals_find_target_dups(apr_array_header_t **duplicate_targets, apr_array_header_t *externals, apr_pool_t *pool, @@ -1439,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/reuse-ra-session/subversion/libsvn_wc/info.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/info.c?rev=1662177&r1=1662176&r2=1662177&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/info.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/info.c Wed Feb 25 08:15:39 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;
