Modified: subversion/branches/addremove/subversion/libsvn_subr/version.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_subr/version.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_subr/version.c (original) +++ subversion/branches/addremove/subversion/libsvn_subr/version.c Sat May 23 14:16:56 2020 @@ -41,7 +41,7 @@ svn_boolean_t svn_ver_compatible(const s const svn_version_t *lib_version) { /* With normal development builds the matching rules are stricter - that for release builds, to avoid inadvertantly using the wrong + that for release builds, to avoid inadvertently using the wrong libraries. For backward compatibility testing of development builds one can use --disable-full-version-match to cause a development build to use the release build rules. This allows @@ -143,7 +143,7 @@ svn_version_extended(svn_boolean_t verbo info->build_time = __TIME__; info->build_host = SVN_BUILD_HOST; info->copyright = apr_pstrdup - (pool, _("Copyright (C) 2017 The Apache Software Foundation.\n" + (pool, _("Copyright (C) 2020 The Apache Software Foundation.\n" "This software consists of contributions made by many people;\n" "see the NOTICE file for more information.\n" "Subversion is open source software, see "
Modified: subversion/branches/addremove/subversion/libsvn_subr/win32_crashrpt.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_subr/win32_crashrpt.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_subr/win32_crashrpt.c (original) +++ subversion/branches/addremove/subversion/libsvn_subr/win32_crashrpt.c Sat May 23 14:16:56 2020 @@ -45,9 +45,6 @@ typedef int win32_crashrpt__dummy; /*** Global variables ***/ static HANDLE dbghelp_dll = INVALID_HANDLE_VALUE; -/* Email address where the crash reports should be sent too. */ -#define CRASHREPORT_EMAIL "us...@subversion.apache.org" - #define DBGHELP_DLL "dbghelp.dll" #define LOGFILE_PREFIX "svn-crash-log" @@ -774,7 +771,7 @@ svn__unhandled_exception_filter(PEXCEPTI "usernames and passwords etc.)\n", log_filename, dmp_filename, - CRASHREPORT_EMAIL); + SVN_WIN32_CRASHREPORT_EMAIL); if (getenv("SVN_DBG_STACKTRACES_TO_STDERR") != NULL) { Modified: subversion/branches/addremove/subversion/libsvn_subr/win32_crypto.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_subr/win32_crypto.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_subr/win32_crypto.c (original) +++ subversion/branches/addremove/subversion/libsvn_subr/win32_crypto.c Sat May 23 14:16:56 2020 @@ -395,16 +395,29 @@ windows_validate_certificate(svn_boolean memset(&chain_para, 0, sizeof(chain_para)); chain_para.cbSize = sizeof(chain_para); + /* Don't hit the wire for URL based objects and revocation checks, as + that may cause stalls, network timeouts or spurious errors in cases + such as with the remote OCSP and CRL endpoints being inaccessible or + unreliable. + + For this particular case of the SVN_AUTH_SSL_UNKNOWNCA cert failure + override we should be okay with just the data that we have immediately + available on the local machine. + */ if (CertGetCertificateChain(NULL, cert_context, NULL, NULL, &chain_para, CERT_CHAIN_CACHE_END_CERT | - CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, + CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL | + CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT | + CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY, NULL, &chain_context)) { CERT_CHAIN_POLICY_PARA policy_para; CERT_CHAIN_POLICY_STATUS policy_status; policy_para.cbSize = sizeof(policy_para); - policy_para.dwFlags = 0; + /* We only use the local data for revocation checks, so they may + fail with errors like CRYPT_E_REVOCATION_OFFLINE; ignore those. */ + policy_para.dwFlags = CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS; policy_para.pvExtraPolicyPara = NULL; policy_status.cbSize = sizeof(policy_status); Modified: subversion/branches/addremove/subversion/libsvn_subr/win32_xlate.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_subr/win32_xlate.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_subr/win32_xlate.c (original) +++ subversion/branches/addremove/subversion/libsvn_subr/win32_xlate.c Sat May 23 14:16:56 2020 @@ -65,8 +65,8 @@ initialize_com(void *baton, apr_pool_t* if (hr == RPC_E_CHANGED_MODE) { - /* COM already initalized for multi-threaded object concurrency. We are - neutral to object concurrency so try to initalize it in the same way + /* COM already initialized for multi-threaded object concurrency. We are + neutral to object concurrency so try to initialize it in the same way for us, to keep an handle open. */ hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); } Modified: subversion/branches/addremove/subversion/libsvn_subr/x509info.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_subr/x509info.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_subr/x509info.c (original) +++ subversion/branches/addremove/subversion/libsvn_subr/x509info.c Sat May 23 14:16:56 2020 @@ -128,7 +128,7 @@ typedef struct asn1_oid { const char *long_label; } asn1_oid; -#define CONSTANT_PAIR(c) (unsigned char *)(c), sizeof((c)) - 1 +#define CONSTANT_PAIR(c) (const unsigned char *)(c), sizeof((c)) - 1 static const asn1_oid asn1_oids[] = { { CONSTANT_PAIR(SVN_X509_OID_COMMON_NAME), "CN", "commonName" }, Modified: subversion/branches/addremove/subversion/libsvn_subr/x509parse.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_subr/x509parse.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_subr/x509parse.c (original) +++ subversion/branches/addremove/subversion/libsvn_subr/x509parse.c Sat May 23 14:16:56 2020 @@ -263,12 +263,33 @@ x509_get_alg(const unsigned char **p, co if (*p == end) return SVN_NO_ERROR; - /* - * assume the algorithm parameters must be NULL - */ - err = asn1_get_tag(p, end, &len, ASN1_NULL); - if (err) - return svn_error_create(SVN_ERR_X509_CERT_INVALID_ALG, err, NULL); + /* The OID encoding of 1.2.840.113549.1.1.10 (id-RSASSA-PSS) */ +#define OID_RSASSA_PSS "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0a" + + if (equal(alg->p, alg->len, OID_RSASSA_PSS, sizeof(OID_RSASSA_PSS) - 1)) + { + /* Skip over algorithm parameters for id-RSASSA-PSS (RFC 8017) + * + * RSASSA-PSS-params ::= SEQUENCE { + * hashAlgorithm [0] HashAlgorithm DEFAULT sha1, + * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, + * saltLength [2] INTEGER DEFAULT 20, + * trailerField [3] TrailerField DEFAULT trailerFieldBC + * } + */ + err = asn1_get_tag(p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE); + if (err) + return svn_error_create(SVN_ERR_X509_CERT_INVALID_ALG, err, NULL); + + *p += len; + } + else + { + /* Algorithm parameters must be NULL for other algorithms */ + err = asn1_get_tag(p, end, &len, ASN1_NULL); + if (err) + return svn_error_create(SVN_ERR_X509_CERT_INVALID_ALG, err, NULL); + } if (*p != end) { @@ -861,7 +882,7 @@ x509name_to_utf8_string(const x509_name /* Both BMP and UNIVERSAL should always be in Big Endian (aka * network byte order). But rumor has it that there are certs - * out there with other endianess and even Byte Order Marks. + * out there with other endianness and even Byte Order Marks. * If we actually run into these, we might need to do something * about it. */ @@ -895,7 +916,7 @@ x509name_to_utf8_string(const x509_name /* This leaves two types out there in the wild. PrintableString, * which is just a subset of ASCII and IA5 which is ASCII (though - * 0x24 '$' and 0x23 '#' may be defined with differnet symbols + * 0x24 '$' and 0x23 '#' may be defined with different symbols * depending on the location, in practice it seems everyone just * treats it as ASCII). Since these are just ASCII run through * the fuzzy_escape code to deal with anything that isn't actually @@ -958,7 +979,7 @@ is_hostname(const char *str) if (i + 1 != len) { if (str[i + 1] == '.') - return FALSE; /* '-' preceeds a '.' */ + return FALSE; /* '-' precedes a '.' */ } else return FALSE; /* '-' is at end of string */ Modified: subversion/branches/addremove/subversion/libsvn_wc/README URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/README?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/README (original) +++ subversion/branches/addremove/subversion/libsvn_wc/README Sat May 23 14:16:56 2020 @@ -94,6 +94,10 @@ copies. .svn/wc.db /* SQLite database containing node metadata. */ pristine/ /* Sharded directory containing base files. */ tmp/ /* Local tmp area. */ + experimental/ /* Data for experimental features. */ + shelves/ /* Used by 1.10.x shelves implementation */ + entries /* Stub file. */ + format /* Stub file. */ `wc.db': A self-contained SQLite database containing all the metadata Subversion @@ -109,6 +113,17 @@ copies. Pristines are used for sending diffs back to the server, etc. +`experimental': + Experimental (unstable) features store their data here. + +`shelves': + Subversion 1.10's "svn shelve" command stores shelved changes here. + This directory is not used by any other minor release line. + +`entries', `format': + These stub files exist only to enable a pre-1.7 client to yield a clearer + error message. + How the client applies an update delta -------------------------------------- Modified: subversion/branches/addremove/subversion/libsvn_wc/conflicts.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/conflicts.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/conflicts.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/conflicts.c Sat May 23 14:16:56 2020 @@ -539,6 +539,7 @@ svn_wc__conflict_skel_add_tree_conflict( svn_wc_conflict_reason_t reason, svn_wc_conflict_action_t action, const char *move_src_op_root_abspath, + const char *move_dst_op_root_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { @@ -555,18 +556,33 @@ svn_wc__conflict_skel_add_tree_conflict( tree_conflict = svn_skel__make_empty_list(result_pool); - if (reason == svn_wc_conflict_reason_moved_away - && move_src_op_root_abspath) + if (reason == svn_wc_conflict_reason_moved_away) { - const char *move_src_op_root_relpath; + if (move_dst_op_root_abspath) + { + const char *move_dst_op_root_relpath; - SVN_ERR(svn_wc__db_to_relpath(&move_src_op_root_relpath, - db, wri_abspath, - move_src_op_root_abspath, - result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_to_relpath(&move_dst_op_root_relpath, + db, wri_abspath, + move_dst_op_root_abspath, + result_pool, scratch_pool)); - svn_skel__prepend_str(move_src_op_root_relpath, tree_conflict, - result_pool); + svn_skel__prepend_str(move_dst_op_root_relpath, tree_conflict, + result_pool); + } + + if (move_src_op_root_abspath) + { + const char *move_src_op_root_relpath; + + SVN_ERR(svn_wc__db_to_relpath(&move_src_op_root_relpath, + db, wri_abspath, + move_src_op_root_abspath, + result_pool, scratch_pool)); + + svn_skel__prepend_str(move_src_op_root_relpath, tree_conflict, + result_pool); + } } svn_skel__prepend_str(svn_token__to_word(action_map, action), @@ -644,7 +660,7 @@ svn_wc__conflict_skel_resolve(svn_boolea /* If no conflicted property names left */ if (!c->next->next->children) { - /* Remove the propery conflict skel from the linked list */ + /* Remove the property conflict skel from the linked list */ *pconflict = (*pconflict)->next; continue; } @@ -932,6 +948,7 @@ svn_error_t * svn_wc__conflict_read_tree_conflict(svn_wc_conflict_reason_t *reason, svn_wc_conflict_action_t *action, const char **move_src_op_root_abspath, + const char **move_dst_op_root_abspath, svn_wc__db_t *db, const char *wri_abspath, const svn_skel_t *conflict_skel, @@ -981,10 +998,10 @@ svn_wc__conflict_read_tree_conflict(svn_ c = c->next; - if (move_src_op_root_abspath) + if (move_src_op_root_abspath || move_dst_op_root_abspath) { /* Only set for update and switch tree conflicts */ - if (c && is_moved_away) + if (c && is_moved_away && move_src_op_root_abspath) { const char *move_src_op_root_relpath = apr_pstrmemdup(scratch_pool, c->data, c->len); @@ -994,8 +1011,25 @@ svn_wc__conflict_read_tree_conflict(svn_ move_src_op_root_relpath, result_pool, scratch_pool)); } - else + else if (move_src_op_root_abspath) *move_src_op_root_abspath = NULL; + + if (c) + c = c->next; + + if (c && is_moved_away && move_dst_op_root_abspath) + { + const char *move_dst_op_root_relpath + = apr_pstrmemdup(scratch_pool, c->data, c->len); + + SVN_ERR(svn_wc__db_from_relpath(move_dst_op_root_abspath, + db, wri_abspath, + move_dst_op_root_relpath, + result_pool, scratch_pool)); + } + else if (move_dst_op_root_abspath) + *move_dst_op_root_abspath = NULL; + } return SVN_NO_ERROR; @@ -1352,7 +1386,7 @@ generate_propconflict(svn_boolean_t *con } case svn_wc_conflict_choose_merged: { - if (!cdesc->merged_file + if (!cdesc->merged_file && (!result->merged_file && !result->merged_value)) return svn_error_create (SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, @@ -1801,7 +1835,7 @@ read_tree_conflict_desc(svn_wc_conflict_ svn_wc_conflict_action_t action; SVN_ERR(svn_wc__conflict_read_tree_conflict( - &reason, &action, NULL, + &reason, &action, NULL, NULL, db, local_abspath, conflict_skel, scratch_pool, scratch_pool)); if (reason == svn_wc_conflict_reason_missing) @@ -2347,7 +2381,7 @@ svn_wc__read_conflict_descriptions2_t(co apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - return svn_wc__read_conflicts(conflicts, NULL, wc_ctx->db, local_abspath, + return svn_wc__read_conflicts(conflicts, NULL, wc_ctx->db, local_abspath, FALSE, FALSE, result_pool, scratch_pool); } @@ -2603,7 +2637,7 @@ resolve_prop_conflict_on_node(svn_boolea return SVN_NO_ERROR; } -/* +/* * Record a tree conflict resolution failure due to error condition ERR * in the RESOLVE_LATER hash table. If the hash table is not available * (meaning the caller does not wish to retry resolution later), or if @@ -2676,7 +2710,7 @@ resolve_tree_conflict_on_node(svn_boolea SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, &src_op_root_abspath, - db, local_abspath, + NULL, db, local_abspath, conflicts, scratch_pool, scratch_pool)); @@ -2748,6 +2782,7 @@ resolve_tree_conflict_on_node(svn_boolea SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, &src_op_root_abspath, + NULL, db, local_abspath, new_conflicts, scratch_pool, @@ -3483,7 +3518,7 @@ svn_wc__conflict_tree_update_break_moved return SVN_NO_ERROR; SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, - &src_op_root_abspath, + &src_op_root_abspath, NULL, wc_ctx->db, local_abspath, conflict_skel, scratch_pool, scratch_pool)); @@ -3569,7 +3604,7 @@ svn_wc__conflict_tree_update_raise_moved if (!tree_conflicted) return SVN_NO_ERROR; - SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, NULL, + SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, NULL, NULL, wc_ctx->db, local_abspath, conflict_skel, scratch_pool, scratch_pool)); @@ -3648,7 +3683,7 @@ svn_wc__conflict_tree_update_moved_away_ return SVN_NO_ERROR; SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, - &src_op_root_abspath, + &src_op_root_abspath, NULL, wc_ctx->db, local_abspath, conflict_skel, scratch_pool, scratch_pool)); @@ -3734,8 +3769,8 @@ svn_wc__conflict_tree_update_incoming_mo return SVN_NO_ERROR; SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change, &incoming_change, - NULL, wc_ctx->db, local_abspath, - conflict_skel, + NULL, NULL, wc_ctx->db, + local_abspath, conflict_skel, scratch_pool, scratch_pool)); /* Make sure the expected conflict is recorded. */ @@ -3803,8 +3838,8 @@ svn_wc__conflict_tree_update_local_add(s return SVN_NO_ERROR; SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change, &incoming_change, - NULL, wc_ctx->db, local_abspath, - conflict_skel, + NULL, NULL, wc_ctx->db, + local_abspath, conflict_skel, scratch_pool, scratch_pool)); /* Make sure the expected conflict is recorded. */ @@ -3853,9 +3888,9 @@ svn_wc__guess_incoming_move_target_nodes apr_size_t longest_ancestor_len = 0; *possible_targets = apr_array_make(result_pool, 1, sizeof(const char *)); - SVN_ERR(svn_wc__find_repos_node_in_wc(&candidates, wc_ctx->db, victim_abspath, - moved_to_repos_relpath, - scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__db_find_repos_node_in_wc(&candidates, wc_ctx->db, victim_abspath, + moved_to_repos_relpath, + scratch_pool, scratch_pool)); /* Find a "useful move target" node in our set of candidates. * Since there is no way to be certain, filter out nodes which seem @@ -3864,7 +3899,7 @@ svn_wc__guess_incoming_move_target_nodes * cannot be modified (e.g. replaced or deleted nodes) don't count. * Nodes which are of a different node kind don't count either. * Ignore switched nodes as well, since that is an unlikely case during - * update/swtich/merge conflict resolution. And externals shouldn't even + * update/switch/merge conflict resolution. And externals shouldn't even * be on our candidate list in the first place. * If multiple candidates match these criteria, choose the one which * shares the longest common ancestor with the victim. */ @@ -3903,7 +3938,7 @@ svn_wc__guess_incoming_move_target_nodes status != svn_wc__db_status_added) continue; - if (node_kind != victim_node_kind) + if (victim_node_kind != svn_node_none && node_kind != victim_node_kind) continue; SVN_ERR(svn_wc__db_is_switched(&is_wcroot, &is_switched, NULL, @@ -3930,8 +3965,8 @@ svn_wc__guess_incoming_move_target_nodes { insert_index = (*possible_targets)->nelts; /* append */ } - svn_sort__array_insert(*possible_targets, &moved_to_abspath, - insert_index); + SVN_ERR(svn_sort__array_insert2(*possible_targets, &moved_to_abspath, + insert_index)); } svn_pool_destroy(iterpool); Modified: subversion/branches/addremove/subversion/libsvn_wc/conflicts.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/conflicts.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/conflicts.h (original) +++ subversion/branches/addremove/subversion/libsvn_wc/conflicts.h Sat May 23 14:16:56 2020 @@ -219,6 +219,11 @@ svn_wc__conflict_skel_add_prop_conflict( MOVE_SRC_OP_ROOT_ABSPATH should be A for a conflict associated with (1), MOVE_SRC_OP_ROOT_ABSPATH should be A/B for a conflict associated with (2). + MOVE_DST_OP_ROOT_ABSPATH is the op-root of the move target (i.e. the + op-root of the corresponding copy). This needs to be stored because + moves in the NODE table do not always persist after an update, while + the conflict resolver may need information about the pre-update state + of the move. It is an error to add another tree conflict to a conflict skel that already contains a tree conflict. (It is not an error, at this level, @@ -233,6 +238,7 @@ svn_wc__conflict_skel_add_tree_conflict( svn_wc_conflict_reason_t local_change, svn_wc_conflict_action_t incoming_change, const char *move_src_op_root_abspath, + const char *move_dst_op_root_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool); @@ -253,7 +259,7 @@ svn_wc__conflict_skel_add_tree_conflict( resolve/remove the tree conflict in CONFLICT_SKEL. If COMPLETELY_RESOLVED is not NULL, then set *COMPLETELY_RESOLVED to TRUE, - when no conflict registration is left in CONFLICT_SKEL after editting, + when no conflict registration is left in CONFLICT_SKEL after editing, otherwise to FALSE. Allocate data stored in the skel in RESULT_POOL. @@ -364,6 +370,7 @@ svn_error_t * svn_wc__conflict_read_tree_conflict(svn_wc_conflict_reason_t *local_change, svn_wc_conflict_action_t *incoming_change, const char **move_src_op_root_abspath, + const char **move_dst_op_root_abspath, svn_wc__db_t *db, const char *wri_abspath, const svn_skel_t *conflict_skel, Modified: subversion/branches/addremove/subversion/libsvn_wc/copy.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/copy.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/copy.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/copy.c Sat May 23 14:16:56 2020 @@ -148,7 +148,7 @@ copy_to_tmpdir(svn_skel_t **work_item, } else if (*kind == svn_node_dir && !file_copy) { - /* Just build a new direcory from the workqueue */ + /* Just build a new directory from the workqueue */ SVN_ERR(svn_wc__wq_build_dir_install(work_item, db, dst_abspath, result_pool, scratch_pool)); Modified: subversion/branches/addremove/subversion/libsvn_wc/deprecated.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/deprecated.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/deprecated.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/deprecated.c Sat May 23 14:16:56 2020 @@ -1091,6 +1091,33 @@ svn_wc_add(const char *path, /*** From revert.c ***/ svn_error_t * +svn_wc_revert5(svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_depth_t depth, + svn_boolean_t use_commit_times, + const apr_array_header_t *changelist_filter, + svn_boolean_t clear_changelists, + svn_boolean_t metadata_only, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool) +{ + SVN_ERR(svn_wc_revert6(wc_ctx, local_abspath, + depth, + use_commit_times, + changelist_filter, + clear_changelists, + metadata_only, + TRUE /*added_keep_local*/, + cancel_func, cancel_baton, + notify_func, notify_baton, + scratch_pool)); + return SVN_NO_ERROR; +} + +svn_error_t * svn_wc_revert4(svn_wc_context_t *wc_ctx, const char *local_abspath, svn_depth_t depth, @@ -2069,8 +2096,7 @@ svn_wc_get_diff_editor6(const svn_delta_ result_pool, scratch_pool)); if (reverse_order) - diff_processor = svn_diff__tree_processor_reverse_create( - diff_processor, NULL, result_pool); + diff_processor = svn_diff__tree_processor_reverse_create(diff_processor, result_pool); if (! show_copies_as_adds) diff_processor = svn_diff__tree_processor_copy_as_changed_create( Modified: subversion/branches/addremove/subversion/libsvn_wc/diff_local.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/diff_local.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/diff_local.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/diff_local.c Sat May 23 14:16:56 2020 @@ -433,8 +433,7 @@ diff_status_callback(void *baton, /* Public Interface */ svn_error_t * -svn_wc__diff7(const char **root_relpath, - svn_boolean_t *root_is_dir, +svn_wc__diff7(svn_boolean_t anchor_at_given_paths, svn_wc_context_t *wc_ctx, const char *local_abspath, svn_depth_t depth, @@ -459,26 +458,30 @@ svn_wc__diff7(const char **root_relpath, eb.anchor_abspath = local_abspath; - if (root_relpath) + if (anchor_at_given_paths) { + /* Anchor the underlying diff processor at the parent of + LOCAL_ABSPATH (if possible), and adjust so the outgoing + DIFF_PROCESSOR is always anchored at LOCAL_ABSPATH. */ + /* ### Why anchor the underlying diff processor at the parent? */ svn_boolean_t is_wcroot; SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, wc_ctx->db, local_abspath, scratch_pool)); if (!is_wcroot) - eb.anchor_abspath = svn_dirent_dirname(local_abspath, scratch_pool); + { + const char *relpath; + + eb.anchor_abspath = svn_dirent_dirname(local_abspath, scratch_pool); + relpath = svn_dirent_basename(local_abspath, NULL); + diff_processor = svn_diff__tree_processor_filter_create( + diff_processor, relpath, scratch_pool); + } } else if (kind != svn_node_dir) eb.anchor_abspath = svn_dirent_dirname(local_abspath, scratch_pool); - if (root_relpath) - *root_relpath = apr_pstrdup(result_pool, - svn_dirent_skip_ancestor(eb.anchor_abspath, - local_abspath)); - if (root_is_dir) - *root_is_dir = (kind == svn_node_dir); - /* Apply changelist filtering to the output */ if (changelist_filter && changelist_filter->nelts) { @@ -487,7 +490,7 @@ svn_wc__diff7(const char **root_relpath, SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelist_filter, result_pool)); diff_processor = svn_wc__changelist_filter_tree_processor_create( - diff_processor, wc_ctx, local_abspath, + diff_processor, wc_ctx, eb.anchor_abspath, changelist_hash, result_pool); } @@ -572,7 +575,7 @@ svn_wc_diff6(svn_wc_context_t *wc_ctx, processor = svn_diff__tree_processor_copy_as_changed_create(processor, scratch_pool); - return svn_error_trace(svn_wc__diff7(NULL, NULL, + return svn_error_trace(svn_wc__diff7(FALSE, wc_ctx, local_abspath, depth, ignore_ancestry, Modified: subversion/branches/addremove/subversion/libsvn_wc/entries.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/entries.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/entries.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/entries.c Sat May 23 14:16:56 2020 @@ -781,7 +781,7 @@ read_one_entry(const svn_wc_entry_t **ne if (parent_root_url != NULL && strcmp(original_root_url, parent_root_url) == 0) { - + const char *relpath_to_entry = svn_dirent_is_child( op_root_abspath, entry_abspath, NULL); const char *entry_repos_relpath = svn_relpath_join( @@ -1049,7 +1049,7 @@ read_entries_new(apr_hash_t **result_ent svn_pool_clear(iterpool); SVN_ERR(read_one_entry(&entry, - db, dir_abspath, + db, dir_abspath, wcroot, dir_relpath, name, parent_entry, result_pool, iterpool)); Modified: subversion/branches/addremove/subversion/libsvn_wc/lock.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/lock.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/lock.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/lock.c Sat May 23 14:16:56 2020 @@ -592,7 +592,7 @@ open_single(svn_wc_adm_access_t **adm_ac KIND can be NULL. ### note: this function should go away when we move to a single - ### adminstrative area. */ + ### administrative area. */ static svn_error_t * adm_available(svn_boolean_t *available, svn_node_kind_t *kind, Modified: subversion/branches/addremove/subversion/libsvn_wc/node.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/node.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/node.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/node.c Sat May 23 14:16:56 2020 @@ -1126,3 +1126,31 @@ svn_wc__node_was_moved_here(const char * return SVN_NO_ERROR; } + +svn_error_t * +svn_wc__find_working_nodes_with_basename(apr_array_header_t **abspaths, + const char *wri_abspath, + const char *basename, + svn_node_kind_t kind, + svn_wc_context_t *wc_ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + return svn_error_trace(svn_wc__db_find_working_nodes_with_basename( + abspaths, wc_ctx->db, wri_abspath, basename, kind, + result_pool, scratch_pool)); +} + +svn_error_t * +svn_wc__find_copies_of_repos_path(apr_array_header_t **abspaths, + const char *wri_abspath, + const char *repos_relpath, + svn_node_kind_t kind, + svn_wc_context_t *wc_ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + return svn_error_trace(svn_wc__db_find_copies_of_repos_path( + abspaths, wc_ctx->db, wri_abspath, repos_relpath, + kind, result_pool, scratch_pool)); +} Modified: subversion/branches/addremove/subversion/libsvn_wc/props.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/props.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/props.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/props.c Sat May 23 14:16:56 2020 @@ -2236,7 +2236,9 @@ svn_wc_canonicalize_svn_prop(const svn_s if (duplicate_targets->nelts > 1) { more_str = apr_psprintf(/*scratch_*/pool, - _(" (%d more duplicate targets found)"), + Q_(" (%d more duplicate target found)", + " (%d more duplicate targets found)", + duplicate_targets->nelts - 1), duplicate_targets->nelts - 1); } return svn_error_createf( Modified: subversion/branches/addremove/subversion/libsvn_wc/questions.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/questions.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/questions.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/questions.c Sat May 23 14:16:56 2020 @@ -476,7 +476,7 @@ internal_conflicted_p(svn_boolean_t *tex svn_wc_conflict_action_t action; SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, NULL, - db, local_abspath, + NULL, db, local_abspath, conflicts, scratch_pool, scratch_pool)); Modified: subversion/branches/addremove/subversion/libsvn_wc/revert.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/revert.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/revert.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/revert.c Sat May 23 14:16:56 2020 @@ -62,6 +62,18 @@ the addition of all the directory's children. Again, svn_wc_remove_from_revision_control() should do the trick. + - For a copy, we remove the item from disk as well. The thinking here + is that Subversion is responsible for the existence of the item: it + must have been created by something like 'svn copy' or 'svn merge'. + + - For a plain add, removing the file or directory from disk is optional. + The user's idea of Subversion's involvement could be either that + Subversion was just responsible for adding an existing item to version + control, as with 'svn add', and so should not be responsible for + deleting it from disk; or that Subversion is responsible for the + existence of the item, e.g. if created by 'svn patch' or svn mkdir'. + It depends on the use case. + Deletes - Restore properties to their unmodified state. @@ -285,6 +297,7 @@ revert_restore(svn_boolean_t *run_wq, svn_boolean_t metadata_only, svn_boolean_t use_commit_times, svn_boolean_t revert_root, + svn_boolean_t added_keep_local, const struct svn_wc__db_info_t *info, svn_cancel_func_t cancel_func, void *cancel_baton, @@ -344,8 +357,9 @@ revert_restore(svn_boolean_t *run_wq, } else { - if (!copied_here) + if (added_keep_local && !copied_here) { + /* It is a plain add, and we want to keep the local file/dir. */ if (notify_func && notify_required) notify_func(notify_baton, svn_wc_create_notify(local_abspath, @@ -359,8 +373,17 @@ revert_restore(svn_boolean_t *run_wq, scratch_pool)); return SVN_NO_ERROR; } + else if (!copied_here) + { + /* It is a plain add, and we don't want to keep the local file/dir. */ + status = svn_wc__db_status_not_present; + kind = svn_node_none; + recorded_size = SVN_INVALID_FILESIZE; + recorded_time = 0; + } else { + /* It is a copy, so we don't want to keep the local file/dir. */ /* ### Initialise to values which prevent the code below from * ### trying to restore anything to disk. * ### 'status' should be status_unknown but that doesn't exist. */ @@ -429,6 +452,7 @@ revert_restore(svn_boolean_t *run_wq, SVN_ERR(revert_restore(run_wq, db, child_abspath, depth, metadata_only, use_commit_times, FALSE /* revert root */, + added_keep_local, apr_hash_this_val(hi), cancel_func, cancel_baton, notify_func, notify_baton, @@ -536,11 +560,7 @@ revert_wc_data(svn_boolean_t *run_wq, /* If we expect a versioned item to be present then check that any item on disk matches the versioned item, if it doesn't match then fix it or delete it. */ - if (on_disk != svn_node_none - && status != svn_wc__db_status_server_excluded - && status != svn_wc__db_status_deleted - && status != svn_wc__db_status_excluded - && status != svn_wc__db_status_not_present) + if (on_disk != svn_node_none) { if (on_disk == svn_node_dir && kind != svn_node_dir) { @@ -560,7 +580,11 @@ revert_wc_data(svn_boolean_t *run_wq, on_disk = svn_node_none; } } - else if (on_disk == svn_node_file) + else if (on_disk == svn_node_file + && status != svn_wc__db_status_server_excluded + && status != svn_wc__db_status_deleted + && status != svn_wc__db_status_excluded + && status != svn_wc__db_status_not_present) { svn_boolean_t modified; apr_hash_t *props; @@ -712,6 +736,7 @@ revert(svn_wc__db_t *db, svn_boolean_t use_commit_times, svn_boolean_t clear_changelists, svn_boolean_t metadata_only, + svn_boolean_t added_keep_local, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, @@ -762,6 +787,7 @@ revert(svn_wc__db_t *db, err = svn_error_trace( revert_restore(&run_queue, db, local_abspath, depth, metadata_only, use_commit_times, TRUE /* revert root */, + added_keep_local, info, cancel_func, cancel_baton, notify_func, notify_baton, scratch_pool)); @@ -791,6 +817,7 @@ revert_changelist(svn_wc__db_t *db, apr_hash_t *changelist_hash, svn_boolean_t clear_changelists, svn_boolean_t metadata_only, + svn_boolean_t added_keep_local, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, @@ -809,7 +836,7 @@ revert_changelist(svn_wc__db_t *db, scratch_pool)) SVN_ERR(revert(db, local_abspath, svn_depth_empty, use_commit_times, clear_changelists, - metadata_only, + metadata_only, added_keep_local, cancel_func, cancel_baton, notify_func, notify_baton, scratch_pool)); @@ -845,6 +872,7 @@ revert_changelist(svn_wc__db_t *db, SVN_ERR(revert_changelist(db, child_abspath, depth, use_commit_times, changelist_hash, clear_changelists, metadata_only, + added_keep_local, cancel_func, cancel_baton, notify_func, notify_baton, iterpool)); @@ -871,6 +899,7 @@ revert_partial(svn_wc__db_t *db, svn_boolean_t use_commit_times, svn_boolean_t clear_changelists, svn_boolean_t metadata_only, + svn_boolean_t added_keep_local, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, @@ -892,6 +921,7 @@ revert_partial(svn_wc__db_t *db, children. */ SVN_ERR(revert(db, local_abspath, svn_depth_empty, use_commit_times, clear_changelists, metadata_only, + added_keep_local, cancel_func, cancel_baton, notify_func, notify_baton, iterpool)); @@ -926,7 +956,7 @@ revert_partial(svn_wc__db_t *db, /* Revert just this node (depth=empty). */ SVN_ERR(revert(db, child_abspath, svn_depth_empty, use_commit_times, clear_changelists, - metadata_only, + metadata_only, added_keep_local, cancel_func, cancel_baton, notify_func, notify_baton, iterpool)); @@ -939,13 +969,14 @@ revert_partial(svn_wc__db_t *db, svn_error_t * -svn_wc_revert5(svn_wc_context_t *wc_ctx, +svn_wc_revert6(svn_wc_context_t *wc_ctx, const char *local_abspath, svn_depth_t depth, svn_boolean_t use_commit_times, const apr_array_header_t *changelist_filter, svn_boolean_t clear_changelists, svn_boolean_t metadata_only, + svn_boolean_t added_keep_local, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, @@ -963,6 +994,7 @@ svn_wc_revert5(svn_wc_context_t *wc_ctx, changelist_hash, clear_changelists, metadata_only, + added_keep_local, cancel_func, cancel_baton, notify_func, notify_baton, scratch_pool)); @@ -972,6 +1004,7 @@ svn_wc_revert5(svn_wc_context_t *wc_ctx, return svn_error_trace(revert(wc_ctx->db, local_abspath, depth, use_commit_times, clear_changelists, metadata_only, + added_keep_local, cancel_func, cancel_baton, notify_func, notify_baton, scratch_pool)); @@ -986,6 +1019,7 @@ svn_wc_revert5(svn_wc_context_t *wc_ctx, return svn_error_trace(revert_partial(wc_ctx->db, local_abspath, depth, use_commit_times, clear_changelists, metadata_only, + added_keep_local, cancel_func, cancel_baton, notify_func, notify_baton, scratch_pool)); Modified: subversion/branches/addremove/subversion/libsvn_wc/tree_conflicts.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/tree_conflicts.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/tree_conflicts.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/tree_conflicts.c Sat May 23 14:16:56 2020 @@ -442,7 +442,7 @@ svn_wc__add_tree_conflict(svn_wc_context conflict->local_abspath, conflict->reason, conflict->action, - NULL, + NULL, NULL, scratch_pool, scratch_pool)); switch (conflict->operation) Modified: subversion/branches/addremove/subversion/libsvn_wc/update_editor.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/update_editor.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/update_editor.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/update_editor.c Sat May 23 14:16:56 2020 @@ -1235,9 +1235,11 @@ open_root(void *edit_baton, db->shadowed = TRUE; else if (have_work) { + const char *move_dst_op_root_abspath; const char *move_src_root_abspath; - SVN_ERR(svn_wc__db_base_moved_to(NULL, NULL, &move_src_root_abspath, + SVN_ERR(svn_wc__db_base_moved_to(NULL, &move_dst_op_root_abspath, + &move_src_root_abspath, NULL, eb->db, db->local_abspath, pool, pool)); @@ -1252,7 +1254,8 @@ open_root(void *edit_baton, tree_conflict, eb->db, move_src_root_abspath, svn_wc_conflict_reason_moved_away, svn_wc_conflict_action_edit, - move_src_root_abspath, pool, pool)); + move_src_root_abspath, + move_dst_op_root_abspath, pool, pool)); if (strcmp(db->local_abspath, move_src_root_abspath)) { @@ -1345,6 +1348,7 @@ check_tree_conflict(svn_skel_t **pconfli svn_wc_conflict_reason_t reason = SVN_WC_CONFLICT_REASON_NONE; svn_boolean_t modified = FALSE; const char *move_src_op_root_abspath = NULL; + const char *move_dst_op_root_abspath = NULL; *pconflict = NULL; @@ -1397,8 +1401,8 @@ check_tree_conflict(svn_skel_t **pconfli case svn_wc__db_status_deleted: { - SVN_ERR(svn_wc__db_base_moved_to(NULL, NULL, NULL, - &move_src_op_root_abspath, + SVN_ERR(svn_wc__db_base_moved_to(NULL, &move_dst_op_root_abspath, + NULL, &move_src_op_root_abspath, eb->db, local_abspath, scratch_pool, scratch_pool)); if (move_src_op_root_abspath) @@ -1454,7 +1458,7 @@ check_tree_conflict(svn_skel_t **pconfli * Therefore, we need to start a separate crawl here. */ SVN_ERR(svn_wc__node_has_local_mods(&modified, NULL, - eb->db, local_abspath, FALSE, + eb->db, local_abspath, TRUE, eb->cancel_func, eb->cancel_baton, scratch_pool)); @@ -1530,6 +1534,7 @@ check_tree_conflict(svn_skel_t **pconfli reason, action, move_src_op_root_abspath, + move_dst_op_root_abspath, result_pool, scratch_pool)); return SVN_NO_ERROR; @@ -2007,11 +2012,13 @@ add_directory(const char *path, { svn_wc_conflict_reason_t reason; const char *move_src_op_root_abspath; + const char *move_dst_op_root_abspath; /* So this deletion wasn't just a deletion, it is actually a replacement. Let's install a better tree conflict. */ SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, &move_src_op_root_abspath, + &move_dst_op_root_abspath, eb->db, db->local_abspath, tree_conflict, @@ -2024,6 +2031,7 @@ add_directory(const char *path, eb->db, db->local_abspath, reason, svn_wc_conflict_action_replace, move_src_op_root_abspath, + move_dst_op_root_abspath, db->pool, scratch_pool)); /* And now stop checking for conflicts here and just perform @@ -2148,8 +2156,8 @@ add_directory(const char *path, tree_conflict, eb->db, db->local_abspath, svn_wc_conflict_reason_unversioned, - svn_wc_conflict_action_add, NULL, - db->pool, scratch_pool)); + svn_wc_conflict_action_add, + NULL, NULL, db->pool, scratch_pool)); db->edit_conflict = tree_conflict; } } @@ -2336,7 +2344,7 @@ open_directory(const char *path, db->edit_conflict = tree_conflict; /* Other modifications wouldn't be a tree conflict */ - SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL, + SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL, NULL, eb->db, db->local_abspath, tree_conflict, db->pool, db->pool)); @@ -3220,11 +3228,13 @@ add_file(const char *path, { svn_wc_conflict_reason_t reason; const char *move_src_op_root_abspath; + const char *move_dst_op_root_abspath; /* So this deletion wasn't just a deletion, it is actually a replacement. Let's install a better tree conflict. */ SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, &move_src_op_root_abspath, + &move_dst_op_root_abspath, eb->db, fb->local_abspath, tree_conflict, @@ -3237,6 +3247,7 @@ add_file(const char *path, eb->db, fb->local_abspath, reason, svn_wc_conflict_action_replace, move_src_op_root_abspath, + move_dst_op_root_abspath, fb->pool, scratch_pool)); /* And now stop checking for conflicts here and just perform @@ -3363,7 +3374,7 @@ add_file(const char *path, eb->db, fb->local_abspath, svn_wc_conflict_reason_unversioned, svn_wc_conflict_action_add, - NULL, + NULL, NULL, fb->pool, scratch_pool)); } } @@ -3528,7 +3539,7 @@ open_file(const char *path, fb->edit_conflict = tree_conflict; /* Other modifications wouldn't be a tree conflict */ - SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL, + SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL, NULL, eb->db, fb->local_abspath, tree_conflict, scratch_pool, scratch_pool)); @@ -3797,7 +3808,7 @@ change_file_prop(void *file_baton, eb->db, fb->local_abspath, svn_wc_conflict_reason_edited, svn_wc_conflict_action_replace, - NULL, + NULL, NULL, fb->pool, scratch_pool)); SVN_ERR(complete_conflict(fb->edit_conflict, fb->edit_baton, Modified: subversion/branches/addremove/subversion/libsvn_wc/upgrade.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/upgrade.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/upgrade.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/upgrade.c Sat May 23 14:16:56 2020 @@ -1237,7 +1237,7 @@ svn_wc__upgrade_conflict_skel_from_raw(s db, wri_abspath, tc->reason, tc->action, - NULL, + NULL, NULL, scratch_pool, scratch_pool)); @@ -1667,7 +1667,7 @@ svn_wc__upgrade_sdb(int *result_format, "use the current client"), svn_dirent_local_style(wcroot_abspath, scratch_pool), - start_format); + start_format); /* ### need lock-out. only one upgrade at a time. note that other code ### cannot use this un-upgraded database until we finish the upgrade. */ Modified: subversion/branches/addremove/subversion/libsvn_wc/wc-queries.sql URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/wc-queries.sql?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/wc-queries.sql (original) +++ subversion/branches/addremove/subversion/libsvn_wc/wc-queries.sql Sat May 23 14:16:56 2020 @@ -122,6 +122,17 @@ WHERE wc_id = ?1 AND local_relpath = ?2 ORDER BY op_depth DESC LIMIT 1 +-- STMT_SELECT_PRESENT_HIGHEST_WORKING_NODES_BY_BASENAME_AND_KIND +SELECT presence, local_relpath +FROM nodes n +WHERE wc_id = ?1 AND local_relpath = RELPATH_JOIN(parent_relpath, ?2) + AND kind = ?3 + AND presence in (MAP_NORMAL, MAP_INCOMPLETE) + AND op_depth = (SELECT MAX(op_depth) + FROM NODES w + WHERE w.wc_id = ?1 + AND w.local_relpath = n.local_relpath) + -- STMT_SELECT_ACTUAL_NODE SELECT changelist, properties, conflict_data FROM actual_node @@ -254,7 +265,7 @@ WHERE wc_id = ?1 AND IS_STRICT_DESCENDAN -- STMT_DELETE_BASE_RECURSIVE DELETE FROM nodes -WHERE wc_id = ?1 AND (local_relpath = ?2 +WHERE wc_id = ?1 AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2)) AND op_depth = 0 @@ -1796,6 +1807,17 @@ WHERE wc_id = ?1 SELECT 1 FROM sqlite_master WHERE name='sqlite_stat1' AND type='table' LIMIT 1 +-- STMT_SELECT_COPIES_OF_REPOS_RELPATH +SELECT local_relpath +FROM nodes n +WHERE wc_id = ?1 AND repos_path = ?2 AND kind = ?3 + AND presence = MAP_NORMAL + AND op_depth = (SELECT MAX(op_depth) + FROM NODES w + WHERE w.wc_id = ?1 + AND w.local_relpath = n.local_relpath) +ORDER BY local_relpath ASC + /* ------------------------------------------------------------------------- */ /* Grab all the statements related to the schema. */ Modified: subversion/branches/addremove/subversion/libsvn_wc/wc.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/wc.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/wc.h (original) +++ subversion/branches/addremove/subversion/libsvn_wc/wc.h Sat May 23 14:16:56 2020 @@ -159,6 +159,7 @@ extern "C" { * * == 1.8.x shipped with format 31 * == 1.9.x shipped with format 31 + * == 1.10.x shipped with format 31 * * Please document any further format changes here. */ @@ -288,6 +289,7 @@ struct svn_wc_traversal_info_t #define SVN_WC__ADM_TMP "tmp" #define SVN_WC__ADM_PRISTINE "pristine" #define SVN_WC__ADM_NONEXISTENT_PATH "nonexistent-path" +#define SVN_WC__ADM_EXPERIMENTAL "experimental" /* The basename of the ".prej" file, if a directory ever has property conflicts. This .prej file will appear *within* the conflicted Modified: subversion/branches/addremove/subversion/libsvn_wc/wc_db.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/wc_db.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/wc_db.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/wc_db.c Sat May 23 14:16:56 2020 @@ -514,7 +514,7 @@ create_repos_id(apr_int64_t *repos_id, above query and the insertion below. We're simply going to ignore that, as it means two processes are *modifying* the working copy at the same time, *and* new repositores are becoming visible. - This is rare enough, let alone the miniscule chance of hitting + This is rare enough, let alone the minuscule chance of hitting this race condition. Further, simply failing out will leave the database in a consistent state, and the user can just re-run the failed operation. */ @@ -2374,7 +2374,7 @@ db_base_remove(svn_wc__db_wcroot_t *wcro /* For file externals we only want to place a not present marker if there is a BASE parent */ - + svn_relpath_split(&parent_local_relpath, &name, local_relpath, scratch_pool); @@ -6808,7 +6808,7 @@ svn_wc__db_op_mark_resolved_internal(svn return SVN_NO_ERROR; conflicts = svn_skel__parse(conflict_data, conflict_len, scratch_pool); - + SVN_ERR(svn_wc__conflict_skel_resolve(&resolved_all, conflicts, db, wcroot->abspath, @@ -6945,7 +6945,7 @@ revert_maybe_raise_moved_away(svn_wc__db } SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, - NULL, + NULL, NULL, db, wcroot->abspath, conflict, scratch_pool, @@ -8097,7 +8097,7 @@ struct op_delete_baton_t { * Note that the following sequence results in the same DB state: * mv A B; mv B/F B/G * We do not care about the order the moves were performed in. - * For details, see http://wiki.apache.org/subversion/MultiLayerMoves + * For details, see https://cwiki.apache.org/confluence/display/SVN/MultiLayerMoves */ struct moved_node_t { /* The source of the move. */ @@ -8502,7 +8502,7 @@ delete_node(void *baton, scratch_pool, iterpool)); if (!mn->local_relpath) - svn_sort__array_delete(moved_nodes, i--, 1); + SVN_ERR(svn_sort__array_delete2(moved_nodes, i--, 1)); } } @@ -10910,7 +10910,7 @@ db_read_inherited_props(apr_array_header iprop_elt->prop_hash = node_props; /* Build the output array in depth-first order. */ - svn_sort__array_insert(iprops, &iprop_elt, 0); + SVN_ERR(svn_sort__array_insert2(iprops, &iprop_elt, 0)); } } } @@ -10946,7 +10946,7 @@ db_read_inherited_props(apr_array_header /* If we didn't filter everything then keep this iprop. */ if (apr_hash_count(cached_iprop->prop_hash)) - svn_sort__array_insert(iprops, &cached_iprop, 0); + SVN_ERR(svn_sort__array_insert2(iprops, &cached_iprop, 0)); } } @@ -16631,8 +16631,8 @@ db_process_commit_queue(svn_wc__db_t *db iterpool), iterpool, iterpool)); - lock_remove_txn(queue->wcroot, cqi->local_relpath, work_item, - iterpool); + SVN_ERR(lock_remove_txn(queue->wcroot, cqi->local_relpath, + work_item, iterpool)); } if (cqi->remove_changelist) SVN_ERR(svn_wc__db_op_set_changelist(db, @@ -16684,12 +16684,12 @@ svn_wc__db_process_commit_queue(svn_wc__ } svn_error_t * -svn_wc__find_repos_node_in_wc(apr_array_header_t **local_abspath_list, - svn_wc__db_t *db, - const char *wri_abspath, - const char *repos_relpath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +svn_wc__db_find_repos_node_in_wc(apr_array_header_t **local_abspath_list, + svn_wc__db_t *db, + const char *wri_abspath, + const char *repos_relpath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { svn_wc__db_wcroot_t *wcroot; const char *wri_relpath; @@ -16722,7 +16722,95 @@ svn_wc__find_repos_node_in_wc(apr_array_ SVN_ERR(svn_sqlite__step(&have_row, stmt)); } - + + return svn_error_trace(svn_sqlite__reset(stmt)); +} + +svn_error_t * +svn_wc__db_find_working_nodes_with_basename(apr_array_header_t **local_abspaths, + svn_wc__db_t *db, + const char *wri_abspath, + const char *basename, + svn_node_kind_t kind, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_wc__db_wcroot_t *wcroot; + const char *wri_relpath; + svn_sqlite__stmt_t *stmt; + svn_boolean_t have_row; + + SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath)); + + SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &wri_relpath, db, + wri_abspath, scratch_pool, + scratch_pool)); + VERIFY_USABLE_WCROOT(wcroot); + + SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, + STMT_SELECT_PRESENT_HIGHEST_WORKING_NODES_BY_BASENAME_AND_KIND)); + SVN_ERR(svn_sqlite__bindf(stmt, "ist", wcroot->wc_id, basename, + kind_map, kind)); + SVN_ERR(svn_sqlite__step(&have_row, stmt)); + + *local_abspaths = apr_array_make(result_pool, 1, sizeof(const char *)); + + while (have_row) + { + const char *local_relpath; + const char *local_abspath; + + local_relpath = svn_sqlite__column_text(stmt, 1, NULL); + local_abspath = svn_dirent_join(wcroot->abspath, local_relpath, + result_pool); + APR_ARRAY_PUSH(*local_abspaths, const char *) = local_abspath; + SVN_ERR(svn_sqlite__step(&have_row, stmt)); + } + + return svn_error_trace(svn_sqlite__reset(stmt)); +} + +svn_error_t * +svn_wc__db_find_copies_of_repos_path(apr_array_header_t **local_abspaths, + svn_wc__db_t *db, + const char *wri_abspath, + const char *repos_relpath, + svn_node_kind_t kind, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_wc__db_wcroot_t *wcroot; + const char *wri_relpath; + svn_sqlite__stmt_t *stmt; + svn_boolean_t have_row; + + SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath)); + + SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &wri_relpath, db, + wri_abspath, scratch_pool, + scratch_pool)); + VERIFY_USABLE_WCROOT(wcroot); + + SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, + STMT_SELECT_COPIES_OF_REPOS_RELPATH)); + SVN_ERR(svn_sqlite__bindf(stmt, "ist", wcroot->wc_id, repos_relpath, + kind_map, kind)); + SVN_ERR(svn_sqlite__step(&have_row, stmt)); + + *local_abspaths = apr_array_make(result_pool, 1, sizeof(const char *)); + + while (have_row) + { + const char *local_relpath; + const char *local_abspath; + + local_relpath = svn_sqlite__column_text(stmt, 0, NULL); + local_abspath = svn_dirent_join(wcroot->abspath, local_relpath, + result_pool); + APR_ARRAY_PUSH(*local_abspaths, const char *) = local_abspath; + SVN_ERR(svn_sqlite__step(&have_row, stmt)); + } + return svn_error_trace(svn_sqlite__reset(stmt)); } Modified: subversion/branches/addremove/subversion/libsvn_wc/wc_db.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/wc_db.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/wc_db.h (original) +++ subversion/branches/addremove/subversion/libsvn_wc/wc_db.h Sat May 23 14:16:56 2020 @@ -961,7 +961,7 @@ typedef struct svn_wc__db_install_data_t /* Open a writable stream to a temporary text base, ready for installing into the pristine store. Set *STREAM to the opened stream. The temporary file will have an arbitrary unique name. Return as *INSTALL_DATA a baton - for eiter installing or removing the file + for either installing or removing the file Arrange that, on stream closure, *MD5_CHECKSUM and *SHA1_CHECKSUM will be set to the MD-5 and SHA-1 checksums respectively of that file. @@ -3505,12 +3505,48 @@ svn_wc__required_lock_for_resolve(const * which has been replaced. */ svn_error_t * -svn_wc__find_repos_node_in_wc(apr_array_header_t **local_abspath_list, - svn_wc__db_t *db, - const char *wri_abspath, - const char *repos_relpath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool); +svn_wc__db_find_repos_node_in_wc(apr_array_header_t **local_abspath_list, + svn_wc__db_t *db, + const char *wri_abspath, + const char *repos_relpath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Return an array of const char * elements, which represent local absolute + * paths for nodes, within the working copy indicated by WRI_ABSPATH, which + * have a basename matching BASENAME and have node kind KIND. + * If no such nodes exist, return an empty array. + * + * This function returns only paths to nodes which are present in the highest + * layer of the WC. In other words, paths to deleted and/or excluded nodes are + * never returned. + */ +svn_error_t * +svn_wc__db_find_working_nodes_with_basename(apr_array_header_t **local_abspaths, + svn_wc__db_t *db, + const char *wri_abspath, + const char *basename, + svn_node_kind_t kind, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Return an array of const char * elements, which represent local absolute + * paths for nodes, within the working copy indicated by WRI_ABSPATH, which + * are copies of REPOS_RELPATH and have node kind KIND. + * If no such nodes exist, return an empty array. + * + * This function returns only paths to nodes which are present in the highest + * layer of the WC. In other words, paths to deleted and/or excluded nodes are + * never returned. + */ +svn_error_t * +svn_wc__db_find_copies_of_repos_path(apr_array_header_t **local_abspaths, + svn_wc__db_t *db, + const char *wri_abspath, + const char *repos_relpath, + svn_node_kind_t kind, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); /* @} */ typedef svn_error_t * (*svn_wc__db_verify_cb_t)(void *baton, Modified: subversion/branches/addremove/subversion/libsvn_wc/wc_db_private.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/wc_db_private.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/wc_db_private.h (original) +++ subversion/branches/addremove/subversion/libsvn_wc/wc_db_private.h Sat May 23 14:16:56 2020 @@ -434,7 +434,7 @@ svn_wc__db_op_make_copy_internal(svn_wc_ MOVE_DST_RELPATH is X DELETE_RELPATH is A - X/C can be calculated if necessesary, like with the other + X/C can be calculated if necessary, like with the other scan functions. This function returns SVN_ERR_WC_PATH_NOT_FOUND if LOCAL_RELPATH didn't Modified: subversion/branches/addremove/subversion/libsvn_wc/wc_db_update_move.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/wc_db_update_move.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/wc_db_update_move.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/wc_db_update_move.c Sat May 23 14:16:56 2020 @@ -95,7 +95,7 @@ * to avoid tree conflicts where the "incoming" and "local" change both * originated in the working copy, because the resolver code cannot handle * such tree conflicts at present. - * + * * The whole drive occurs as one single wc.db transaction. At the end * of the transaction the destination NODES table should have a WORKING * layer that is equivalent to the WORKING layer found in the copied victim @@ -411,6 +411,11 @@ create_tree_conflict(svn_skel_t **confli ? svn_dirent_join(wcroot->abspath, move_src_op_root_relpath, scratch_pool) : NULL; + const char *move_dst_op_root_abspath + = dst_op_root_relpath + ? svn_dirent_join(wcroot->abspath, + dst_op_root_relpath, scratch_pool) + : NULL; const char *old_repos_relpath_part = old_repos_relpath && old_version ? svn_relpath_skip_ancestor(old_version->path_in_repos, @@ -468,7 +473,7 @@ create_tree_conflict(svn_skel_t **confli SVN_ERR(svn_wc__conflict_read_tree_conflict(&existing_reason, &existing_action, - &existing_abspath, + &existing_abspath, NULL, db, wcroot->abspath, conflict, scratch_pool, @@ -500,6 +505,7 @@ create_tree_conflict(svn_skel_t **confli reason, action, move_src_op_root_abspath, + move_dst_op_root_abspath, result_pool, scratch_pool)); @@ -1050,7 +1056,7 @@ tc_editor_incoming_add_file(node_move_ba SVN_ERR(svn_wc__wq_build_file_remove(&work_item, b->db, b->wcroot->abspath, src_abspath, scratch_pool, scratch_pool)); - + work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool); } @@ -2169,11 +2175,12 @@ suitable_for_move(svn_wc__db_wcroot_t *w while (have_row) { svn_revnum_t node_revision = svn_sqlite__column_revnum(stmt, 2); - const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL); + const char *child_relpath; const char *relpath; svn_pool_clear(iterpool); + child_relpath = svn_sqlite__column_text(stmt, 0, iterpool); relpath = svn_relpath_skip_ancestor(local_relpath, child_relpath); relpath = svn_relpath_join(repos_relpath, relpath, iterpool); @@ -2520,7 +2527,7 @@ update_incoming_moved_node(node_move_bat SVN_ERR(svn_stream_open_unique(&temp_stream, &temp_abspath, wctemp_abspath, svn_io_file_del_none, scratch_pool, scratch_pool)); - err = svn_stream_copy3(working_stream, temp_stream, + err = svn_stream_copy3(working_stream, temp_stream, b->cancel_func, b->cancel_baton, scratch_pool); if (err && err->apr_err == SVN_ERR_CANCELLED) @@ -2685,7 +2692,7 @@ update_incoming_move(svn_revnum_t *old_r * recorded for any tree conflicts created during the editor drive. * We assume this path contains no local changes, and create local changes * in DST_RELPATH corresponding to changes contained in the conflict victim. - * + * * DST_OP_DEPTH is used to infer the "op-root" of the incoming move. This * "op-root" is virtual because all nodes belonging to the incoming move * live in the BASE tree. It is used for constructing repository paths @@ -2981,7 +2988,7 @@ tc_editor_update_add_new_file(added_node nb->skip = TRUE; return SVN_NO_ERROR; } - + /* Check for obstructions. */ local_abspath = svn_dirent_join(nb->b->wcroot->abspath, nb->local_relpath, scratch_pool); @@ -3582,7 +3589,7 @@ svn_wc__db_update_local_add(svn_wc__db_t VERIFY_USABLE_WCROOT(wcroot); SVN_WC__DB_WITH_TXN(update_local_add(&new_rev, db, wcroot, - local_relpath, + local_relpath, cancel_func, cancel_baton, scratch_pool), wcroot); @@ -4099,7 +4106,7 @@ fetch_conflict_details(int *src_op_depth SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, action, - &move_src_op_root_abspath, + &move_src_op_root_abspath, NULL, db, local_abspath, conflict_skel, result_pool, scratch_pool)); @@ -4251,7 +4258,7 @@ svn_wc__db_op_raise_moved_away(svn_wc__d scratch_pool), wcroot); - /* These version numbers are valid for update/switch notifications + /* These version numbers are valid for update/switch notifications only! */ SVN_ERR(svn_wc__db_update_move_list_notify(wcroot, (left_version Modified: subversion/branches/addremove/subversion/libsvn_wc/wc_db_wcroot.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/wc_db_wcroot.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/wc_db_wcroot.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/wc_db_wcroot.c Sat May 23 14:16:56 2020 @@ -528,6 +528,7 @@ svn_wc__db_wcroot_parse_local_abspath(sv const char *adm_relpath; /* Non-NULL if WCROOT is found through a symlink: */ const char *symlink_wcroot_abspath = NULL; + apr_pool_t *iterpool; /* ### we need more logic for finding the database (if it is located ### outside of the wcroot) and then managing all of that within DB. @@ -613,16 +614,20 @@ svn_wc__db_wcroot_parse_local_abspath(sv database in the right place. If we find it... great! If not, then peel off some components, and try again. */ + iterpool = svn_pool_create(scratch_pool); adm_relpath = svn_wc_get_adm_dir(scratch_pool); while (TRUE) { svn_error_t *err; svn_node_kind_t adm_subdir_kind; - const char *adm_subdir = svn_dirent_join(local_abspath, adm_relpath, - scratch_pool); + const char *adm_subdir; - SVN_ERR(svn_io_check_path(adm_subdir, &adm_subdir_kind, scratch_pool)); + svn_pool_clear(iterpool); + + adm_subdir = svn_dirent_join(local_abspath, adm_relpath, iterpool); + + SVN_ERR(svn_io_check_path(adm_subdir, &adm_subdir_kind, iterpool)); if (adm_subdir_kind == svn_node_dir) { @@ -673,7 +678,7 @@ svn_wc__db_wcroot_parse_local_abspath(sv if (!moved_upwards || always_check) { SVN_ERR(get_old_version(&wc_format, local_abspath, - scratch_pool)); + iterpool)); if (wc_format != 0) break; } @@ -697,7 +702,7 @@ svn_wc__db_wcroot_parse_local_abspath(sv SVN_ERR(svn_io_check_resolved_path(local_abspath, &resolved_kind, - scratch_pool)); + iterpool)); if (resolved_kind == svn_node_dir) { /* Is this directory recorded in our hash? */ @@ -973,6 +978,7 @@ try_symlink_as_dir: } while (strcmp(scan_abspath, local_abspath) != 0); + svn_pool_destroy(iterpool); return SVN_NO_ERROR; } Modified: subversion/branches/addremove/subversion/libsvn_wc/wcroot_anchor.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_wc/wcroot_anchor.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_wc/wcroot_anchor.c (original) +++ subversion/branches/addremove/subversion/libsvn_wc/wcroot_anchor.c Sat May 23 14:16:56 2020 @@ -183,6 +183,28 @@ svn_wc__get_wcroot(const char **wcroot_a svn_error_t * +svn_wc__get_experimental_dir(char **dir, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + const char *wcroot_abspath; + + SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, wc_ctx, local_abspath, + scratch_pool, scratch_pool)); + *dir = svn_dirent_join(wcroot_abspath, + SVN_WC_ADM_DIR_NAME "/" SVN_WC__ADM_EXPERIMENTAL, + result_pool); + + /* Ensure the directory exists. (Other versions of svn don't create it.) */ + SVN_ERR(svn_io_make_dir_recursively(*dir, scratch_pool)); + + return SVN_NO_ERROR; +} + + +svn_error_t * svn_wc_get_actual_target2(const char **anchor, const char **target, svn_wc_context_t *wc_ctx,