Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 603AE17874 for ; Mon, 27 Oct 2014 17:30:51 +0000 (UTC) Received: (qmail 775 invoked by uid 500); 27 Oct 2014 17:30:51 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 749 invoked by uid 500); 27 Oct 2014 17:30:51 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 739 invoked by uid 99); 27 Oct 2014 17:30:51 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 27 Oct 2014 17:30:51 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 27 Oct 2014 17:30:47 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 035612388BA2; Mon, 27 Oct 2014 17:28:25 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1634609 [7/11] - in /subversion/branches/move-tracking-2: ./ build/ notes/ subversion/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_delta/ subversion/libsvn_fs/ subversion/libsvn_fs_base/ subv... Date: Mon, 27 Oct 2014 17:28:16 -0000 To: commits@subversion.apache.org From: julianfoad@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20141027172825.035612388BA2@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/copy.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/copy.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/copy.c (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/copy.c Mon Oct 27 17:28:13 2014 @@ -50,7 +50,14 @@ TMPDIR_ABSPATH and return the absolute path of the copy in *DST_ABSPATH. Return the node kind of SRC_ABSPATH in *KIND. If SRC_ABSPATH doesn't exist then set *DST_ABSPATH to NULL to indicate - that no copy was made. */ + that no copy was made. + + If DIRENT is not NULL, it contains the on-disk information of SRC_ABSPATH. + RECORDED_SIZE (if not SVN_INVALID_FILESIZE) contains the recorded size of + SRC_ABSPATH, and RECORDED_TIME the recorded size or 0. + + These values will be used to avoid unneeded work. + */ static svn_error_t * copy_to_tmpdir(svn_skel_t **work_item, svn_node_kind_t *kind, @@ -60,6 +67,9 @@ copy_to_tmpdir(svn_skel_t **work_item, const char *tmpdir_abspath, svn_boolean_t file_copy, svn_boolean_t unversioned, + const svn_io_dirent2_t *dirent, + svn_filesize_t recorded_size, + apr_time_t recorded_time, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *result_pool, @@ -74,8 +84,14 @@ copy_to_tmpdir(svn_skel_t **work_item, *work_item = NULL; - SVN_ERR(svn_io_check_special_path(src_abspath, kind, &is_special, - scratch_pool)); + if (dirent) + { + *kind = dirent->kind; + is_special = dirent->special; + } + else + SVN_ERR(svn_io_check_special_path(src_abspath, kind, &is_special, + scratch_pool)); if (*kind == svn_node_none) { return SVN_NO_ERROR; @@ -104,9 +120,21 @@ copy_to_tmpdir(svn_skel_t **work_item, the timestamp might match, than to examine the destination later as the destination timestamp will never match. */ - SVN_ERR(svn_wc__internal_file_modified_p(&modified, - db, src_abspath, - FALSE, scratch_pool)); + + if (dirent + && dirent->kind == svn_node_file + && recorded_size != SVN_INVALID_FILESIZE + && recorded_size == dirent->filesize + && recorded_time == dirent->mtime) + { + modified = FALSE; /* Recorded matches on-disk. Easy out */ + } + else + { + SVN_ERR(svn_wc__internal_file_modified_p(&modified, db, src_abspath, + FALSE, scratch_pool)); + } + if (!modified) { /* Why create a temp copy if we can just reinstall from pristine? */ @@ -117,6 +145,15 @@ copy_to_tmpdir(svn_skel_t **work_item, return SVN_NO_ERROR; } } + else if (*kind == svn_node_dir && !file_copy) + { + /* Just build a new direcory from the workqueue */ + SVN_ERR(svn_wc__wq_build_dir_install(work_item, + db, dst_abspath, + result_pool, scratch_pool)); + + return SVN_NO_ERROR; + } /* Set DST_TMP_ABSPATH to a temporary unique path. If *KIND is file, leave a file there and then overwrite it; otherwise leave no node on disk at @@ -172,7 +209,14 @@ copy_to_tmpdir(svn_skel_t **work_item, versioned file itself. This also works for versioned symlinks that are stored in the db as - svn_node_file with svn:special set. */ + svn_node_file with svn:special set. + + If DIRENT is not NULL, it contains the on-disk information of SRC_ABSPATH. + RECORDED_SIZE (if not SVN_INVALID_FILESIZE) contains the recorded size of + SRC_ABSPATH, and RECORDED_TIME the recorded size or 0. + + These values will be used to avoid unneeded work. +*/ static svn_error_t * copy_versioned_file(svn_wc__db_t *db, const char *src_abspath, @@ -182,6 +226,9 @@ copy_versioned_file(svn_wc__db_t *db, svn_boolean_t metadata_only, svn_boolean_t conflicted, svn_boolean_t is_move, + const svn_io_dirent2_t *dirent, + svn_filesize_t recorded_size, + apr_time_t recorded_time, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, @@ -248,6 +295,7 @@ copy_versioned_file(svn_wc__db_t *db, dst_abspath, tmpdir_abspath, TRUE /* file_copy */, handle_as_unversioned /* unversioned */, + dirent, recorded_size, recorded_time, cancel_func, cancel_baton, scratch_pool, scratch_pool)); } @@ -265,10 +313,6 @@ copy_versioned_file(svn_wc__db_t *db, scratch_pool); notify->kind = svn_node_file; - /* When we notify that we performed a copy, make sure we already did */ - if (work_items != NULL) - SVN_ERR(svn_wc__wq_run(db, dst_abspath, - cancel_func, cancel_baton, scratch_pool)); (*notify_func)(notify_baton, notify, scratch_pool); } return SVN_NO_ERROR; @@ -282,6 +326,8 @@ copy_versioned_file(svn_wc__db_t *db, data in addition to copying the directory. WITHIN_ONE_WC is TRUE if the copy/move is within a single working copy (root) + + If DIRENT is not NULL, it contains the on-disk information of SRC_ABSPATH. */ static svn_error_t * copy_versioned_dir(svn_wc__db_t *db, @@ -291,6 +337,7 @@ copy_versioned_dir(svn_wc__db_t *db, const char *tmpdir_abspath, svn_boolean_t metadata_only, svn_boolean_t is_move, + const svn_io_dirent2_t *dirent, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, @@ -314,6 +361,7 @@ copy_versioned_dir(svn_wc__db_t *db, tmpdir_abspath, FALSE /* file_copy */, FALSE /* unversioned */, + dirent, SVN_INVALID_FILESIZE, 0, cancel_func, cancel_baton, scratch_pool, scratch_pool)); } @@ -395,6 +443,12 @@ copy_versioned_dir(svn_wc__db_t *db, tmpdir_abspath, metadata_only, info->conflicted, is_move, + disk_children + ? svn_hash_gets(disk_children, + child_name) + : NULL, + info->recorded_size, + info->recorded_time, cancel_func, cancel_baton, NULL, NULL, iterpool)); @@ -404,6 +458,10 @@ copy_versioned_dir(svn_wc__db_t *db, child_src_abspath, child_dst_abspath, dst_op_root_abspath, tmpdir_abspath, metadata_only, is_move, + disk_children + ? svn_hash_gets(disk_children, + child_name) + : NULL, cancel_func, cancel_baton, NULL, NULL, iterpool)); else @@ -422,7 +480,7 @@ copy_versioned_dir(svn_wc__db_t *db, child_dst_abspath, dst_op_root_abspath, is_move, NULL, iterpool)); - /* Don't recurse on children while all we do is creating not-present + /* Don't recurse on children when all we do is creating not-present children */ } else if (info->status == svn_wc__db_status_incomplete) @@ -489,6 +547,7 @@ copy_versioned_dir(svn_wc__db_t *db, SVN_ERR(copy_to_tmpdir(&work_item, NULL, db, unver_src_abspath, unver_dst_abspath, tmpdir_abspath, TRUE /* recursive */, TRUE /* unversioned */, + NULL, SVN_INVALID_FILESIZE, 0, cancel_func, cancel_baton, scratch_pool, iterpool)); @@ -534,6 +593,8 @@ copy_or_move(svn_boolean_t *move_degrade svn_boolean_t within_one_wc; svn_wc__db_status_t src_status; svn_error_t *err; + svn_filesize_t recorded_size; + apr_time_t recorded_time; SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath)); SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath)); @@ -551,7 +612,8 @@ copy_or_move(svn_boolean_t *move_degrade err = svn_wc__db_read_info(&src_status, &src_db_kind, NULL, &src_repos_relpath, &src_repos_root_url, &src_repos_uuid, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + &recorded_size, &recorded_time, NULL, &conflicted, NULL, NULL, NULL, NULL, NULL, NULL, db, src_abspath, scratch_pool, scratch_pool); @@ -775,6 +837,7 @@ copy_or_move(svn_boolean_t *move_degrade err = copy_versioned_file(db, src_abspath, dst_abspath, dst_abspath, tmpdir_abspath, metadata_only, conflicted, is_move, + NULL, recorded_size, recorded_time, cancel_func, cancel_baton, notify_func, notify_baton, scratch_pool); @@ -810,6 +873,7 @@ copy_or_move(svn_boolean_t *move_degrade err = copy_versioned_dir(db, src_abspath, dst_abspath, dst_abspath, tmpdir_abspath, metadata_only, is_move, + NULL /* dirent */, cancel_func, cancel_baton, notify_func, notify_baton, scratch_pool); Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/deprecated.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/deprecated.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/deprecated.c (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/deprecated.c Mon Oct 27 17:28:13 2014 @@ -652,6 +652,24 @@ svn_wc_get_pristine_contents(svn_stream_ return svn_error_trace(svn_wc_context_destroy(wc_ctx)); } +svn_error_t * +svn_wc_queue_committed3(svn_wc_committed_queue_t *queue, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t recurse, + const apr_array_header_t *wcprop_changes, + svn_boolean_t remove_lock, + svn_boolean_t remove_changelist, + const svn_checksum_t *sha1_checksum, + apr_pool_t *scratch_pool) +{ + return svn_error_trace( + svn_wc_queue_committed4(queue, wc_ctx, local_abspath, + recurse, TRUE /* is_committed */, + wcprop_changes, remove_lock, + remove_changelist, sha1_checksum, + scratch_pool)); +} svn_error_t * svn_wc_queue_committed2(svn_wc_committed_queue_t *queue, @@ -668,7 +686,9 @@ svn_wc_queue_committed2(svn_wc_committed const char *local_abspath; const svn_checksum_t *sha1_checksum = NULL; - SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, + svn_wc__adm_get_db(adm_access), + scratch_pool)); SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool)); if (md5_checksum != NULL) @@ -759,15 +779,11 @@ svn_wc_process_committed4(const char *pa const char *local_abspath; const svn_checksum_t *md5_checksum; const svn_checksum_t *sha1_checksum = NULL; - apr_time_t new_date; - apr_hash_t *wcprop_changes_hash; + svn_wc_context_t *wc_ctx; + svn_wc_committed_queue_t *queue; SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); - - if (rev_date) - SVN_ERR(svn_time_from_cstring(&new_date, rev_date, pool)); - else - new_date = 0; + SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool)); if (digest) md5_checksum = svn_checksum__from_digest_md5(digest, pool); @@ -790,15 +806,20 @@ svn_wc_process_committed4(const char *pa SVN_ERR(err); } - wcprop_changes_hash = svn_wc__prop_array_to_hash(wcprop_changes, pool); - SVN_ERR(svn_wc__process_committed_internal(db, local_abspath, recurse, TRUE, - new_revnum, new_date, rev_author, - wcprop_changes_hash, - !remove_lock, !remove_changelist, - sha1_checksum, NULL, pool)); + queue = svn_wc_committed_queue_create(pool); + SVN_ERR(svn_wc_queue_committed3(queue, wc_ctx, local_abspath, recurse, + wcprop_changes, remove_lock, + remove_changelist, + sha1_checksum /* or NULL if not modified + or directory */, + pool)); - /* Run the log file(s) we just created. */ - return svn_error_trace(svn_wc__wq_run(db, local_abspath, NULL, NULL, pool)); + SVN_ERR(svn_wc_process_committed_queue2(queue, wc_ctx, + new_revnum, rev_date, rev_author, + NULL, NULL /* cancel */, + pool)); + + return svn_error_trace(svn_wc_context_destroy(wc_ctx)); } Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c Mon Oct 27 17:28:13 2014 @@ -943,29 +943,62 @@ close_edit(void *edit_baton, { struct edit_baton *eb = edit_baton; - if (!eb->file_closed - || eb->iprops) + if (!eb->file_closed) { - apr_hash_t *wcroot_iprops = NULL; + /* The file wasn't updated, but its url or revision might have... + e.g. switch between branches for relative externals. - if (eb->iprops) - { - wcroot_iprops = apr_hash_make(pool); - svn_hash_sets(wcroot_iprops, eb->local_abspath, eb->iprops); - } - - /* The node wasn't updated, so we just have to bump its revision */ - SVN_ERR(svn_wc__db_op_bump_revisions_post_update(eb->db, - eb->local_abspath, - svn_depth_infinity, - NULL, NULL, NULL, - *eb->target_revision, - apr_hash_make(pool), - wcroot_iprops, - TRUE /* empty update */, - eb->notify_func, - eb->notify_baton, - pool)); + Just bump the information as that is just as expensive as + investigating when we should and shouldn't update it... + and avoid hard to debug edge cases */ + + svn_node_kind_t kind; + const char *old_repos_relpath; + svn_revnum_t changed_rev; + apr_time_t changed_date; + const char *changed_author; + const svn_checksum_t *checksum; + apr_hash_t *pristine_props; + const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url, + eb->url, pool); + + SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, NULL, &old_repos_relpath, + NULL, NULL, &changed_rev, &changed_date, + &changed_author, NULL, &checksum, NULL, + NULL, NULL, &pristine_props, NULL, + eb->db, eb->local_abspath, + pool, pool)); + + if (kind != svn_node_file) + return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, + _("Node '%s' is no existing file external"), + svn_dirent_local_style(eb->local_abspath, + pool)); + + SVN_ERR(svn_wc__db_external_add_file( + eb->db, + eb->local_abspath, + eb->wri_abspath, + repos_relpath, + eb->repos_root_url, + eb->repos_uuid, + *eb->target_revision, + pristine_props, + eb->iprops, + eb->changed_rev, + eb->changed_date, + eb->changed_author, + checksum, + NULL /* clear dav props */, + eb->record_ancestor_abspath, + eb->recorded_repos_relpath, + eb->recorded_peg_revision, + eb->recorded_revision, + FALSE, NULL, + TRUE /* keep_recorded_info */, + NULL /* conflict_skel */, + NULL /* work_items */, + pool)); } return SVN_NO_ERROR; Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/node.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/node.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/node.c (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/node.c Mon Oct 27 17:28:13 2014 @@ -471,6 +471,7 @@ svn_wc__internal_walk_children(svn_wc__d svn_node_kind_t kind; svn_wc__db_status_t status; apr_hash_t *changelist_hash = NULL; + const char *changelist = NULL; SVN_ERR_ASSERT(walk_depth >= svn_depth_empty && walk_depth <= svn_depth_infinity); @@ -483,14 +484,17 @@ svn_wc__internal_walk_children(svn_wc__d SVN_ERR(svn_wc__db_read_info(&status, &db_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, + changelist_hash ? &changelist : NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, db, local_abspath, scratch_pool, scratch_pool)); SVN_ERR(convert_db_kind_to_node_kind(&kind, db_kind, status, show_hidden)); - if (svn_wc__internal_changelist_match(db, local_abspath, - changelist_hash, scratch_pool)) - SVN_ERR(walk_callback(local_abspath, kind, walk_baton, scratch_pool)); + if (!changelist_hash + || (changelist && svn_hash_gets(changelist_hash, changelist))) + { + SVN_ERR(walk_callback(local_abspath, kind, walk_baton, scratch_pool)); + } if (db_kind == svn_node_file || status == svn_wc__db_status_not_present Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/update_editor.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/update_editor.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/update_editor.c (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/update_editor.c Mon Oct 27 17:28:13 2014 @@ -4342,7 +4342,7 @@ close_file(void *file_baton, || strcmp(fb->new_repos_relpath, fb->old_repos_relpath) == 0) { SVN_ERR_ASSERT(prop->value == NULL); - SVN_ERR(svn_wc__db_lock_remove(eb->db, fb->local_abspath, + SVN_ERR(svn_wc__db_lock_remove(eb->db, fb->local_abspath, NULL, scratch_pool)); lock_state = svn_wc_notify_lock_state_unlocked; Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/wc.h URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/wc.h?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/wc.h (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/wc.h Mon Oct 27 17:28:13 2014 @@ -249,52 +249,6 @@ svn_wc__context_create_with_db(svn_wc_co apr_pool_t * svn_wc__get_committed_queue_pool(const struct svn_wc_committed_queue_t *queue); - -/** Internal helper for svn_wc_process_committed_queue2(). - * - * ### If @a queue is NULL, then ...? - * ### else: - * Bump an item from @a queue (the one associated with @a - * local_abspath) to @a new_revnum after a commit succeeds, recursing - * if @a recurse is set. - * - * @a new_date is the (server-side) date of the new revision, or 0. - * - * @a rev_author is the (server-side) author of the new - * revision; it may be @c NULL. - * - * @a new_dav_cache is a hash of dav property changes to be made to - * the @a local_abspath. - * ### [JAF] Is it? See svn_wc_queue_committed3(). It ends up being - * ### assigned as a whole to wc.db:BASE_NODE:dav_cache. - * - * If @a no_unlock is set, don't release any user locks on @a - * local_abspath; otherwise release them as part of this processing. - * - * If @a keep_changelist is set, don't remove any changeset assignments - * from @a local_abspath; otherwise, clear it of such assignments. - * - * If @a sha1_checksum is non-NULL, use it to identify the node's pristine - * text. - * - * Set TOP_OF_RECURSE to TRUE to show that this the top of a possibly - * recursive commit operation. - */ -svn_error_t * -svn_wc__process_committed_internal(svn_wc__db_t *db, - const char *local_abspath, - svn_boolean_t recurse, - svn_boolean_t top_of_recurse, - svn_revnum_t new_revnum, - apr_time_t new_date, - const char *rev_author, - apr_hash_t *new_dav_cache, - svn_boolean_t no_unlock, - svn_boolean_t keep_changelist, - const svn_checksum_t *sha1_checksum, - const svn_wc_committed_queue_t *queue, - apr_pool_t *scratch_pool); - /*** Update traversals. ***/ Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.c (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.c Mon Oct 27 17:28:13 2014 @@ -4700,25 +4700,23 @@ struct op_copy_baton const char *dst_op_root_relpath; }; -/* Helper for svn_wc__db_op_copy(). - * - * Implements svn_sqlite__transaction_callback_t. */ +/* Helper for svn_wc__db_op_copy(). */ static svn_error_t * -op_copy_txn(void * baton, - svn_sqlite__db_t *sdb, +op_copy_txn(svn_wc__db_wcroot_t *wcroot, + struct op_copy_baton *ocb, apr_pool_t *scratch_pool) { - struct op_copy_baton *ocb = baton; int move_op_depth; - if (sdb != ocb->dst_wcroot->sdb) + if (wcroot != ocb->dst_wcroot) { /* Source and destination databases differ; so also start a lock - in the destination database, by calling ourself in a lock. */ + in the destination database, by calling ourself in an extra lock. */ - return svn_error_trace( - svn_sqlite__with_lock(ocb->dst_wcroot->sdb, - op_copy_txn, ocb, scratch_pool)); + SVN_WC__DB_WITH_TXN(op_copy_txn(ocb->dst_wcroot, ocb, scratch_pool), + ocb->dst_wcroot); + + return SVN_NO_ERROR; } /* From this point we can assume a lock in the src and dst databases */ @@ -4769,8 +4767,8 @@ svn_wc__db_op_copy(svn_wc__db_t *db, /* Call with the sdb in src_wcroot. It might call itself again to also obtain a lock in dst_wcroot */ - SVN_ERR(svn_sqlite__with_lock(ocb.src_wcroot->sdb, op_copy_txn, &ocb, - scratch_pool)); + SVN_WC__DB_WITH_TXN(op_copy_txn(ocb.src_wcroot, &ocb, scratch_pool), + ocb.src_wcroot); return SVN_NO_ERROR; } @@ -5212,15 +5210,12 @@ db_op_copy_shadowed_layer(svn_wc__db_wcr return SVN_NO_ERROR; } -/* Helper for svn_wc__db_op_copy_shadowed_layer(). - * - * Implements svn_sqlite__transaction_callback_t. */ +/* Helper for svn_wc__db_op_copy_shadowed_layer(). */ static svn_error_t * -op_copy_shadowed_layer_txn(void *baton, - svn_sqlite__db_t *sdb, +op_copy_shadowed_layer_txn(svn_wc__db_wcroot_t *wcroot, + struct op_copy_baton *ocb, apr_pool_t *scratch_pool) { - struct op_copy_baton *ocb = baton; const char *src_parent_relpath; const char *dst_parent_relpath; int src_op_depth; @@ -5230,15 +5225,16 @@ op_copy_shadowed_layer_txn(void *baton, apr_int64_t repos_id = INVALID_REPOS_ID; svn_revnum_t revision = SVN_INVALID_REVNUM; - if (sdb != ocb->dst_wcroot->sdb) + if (wcroot != ocb->dst_wcroot) { - /* Source and destination databases differ; so also start a lock - in the destination database, by calling ourself in a lock. */ + /* Source and destination databases differ; so also start a lock + in the destination database, by calling ourself in an extra lock. */ - return svn_error_trace( - svn_sqlite__with_lock(ocb->dst_wcroot->sdb, - op_copy_shadowed_layer_txn, - ocb, scratch_pool)); + SVN_WC__DB_WITH_TXN(op_copy_shadowed_layer_txn(ocb->dst_wcroot, ocb, + scratch_pool), + ocb->dst_wcroot); + + return SVN_NO_ERROR; } /* From this point we can assume a lock in the src and dst databases */ @@ -5320,9 +5316,9 @@ svn_wc__db_op_copy_shadowed_layer(svn_wc /* Call with the sdb in src_wcroot. It might call itself again to also obtain a lock in dst_wcroot */ - SVN_ERR(svn_sqlite__with_lock(ocb.src_wcroot->sdb, - op_copy_shadowed_layer_txn, - &ocb, scratch_pool)); + SVN_WC__DB_WITH_TXN(op_copy_shadowed_layer_txn(ocb.src_wcroot, &ocb, + scratch_pool), + ocb.src_wcroot); return SVN_NO_ERROR; } @@ -11925,6 +11921,7 @@ svn_wc__db_lock_add(svn_wc__db_t *db, static svn_error_t * lock_remove_txn(svn_wc__db_wcroot_t *wcroot, const char *local_relpath, + svn_skel_t *work_items, apr_pool_t *scratch_pool) { const char *repos_relpath; @@ -11944,6 +11941,8 @@ lock_remove_txn(svn_wc__db_wcroot_t *wcr SVN_ERR(svn_sqlite__step_done(stmt)); + SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool)); + return SVN_NO_ERROR; } @@ -11951,6 +11950,7 @@ lock_remove_txn(svn_wc__db_wcroot_t *wcr svn_error_t * svn_wc__db_lock_remove(svn_wc__db_t *db, const char *local_abspath, + svn_skel_t *work_items, apr_pool_t *scratch_pool) { svn_wc__db_wcroot_t *wcroot; @@ -11963,7 +11963,7 @@ svn_wc__db_lock_remove(svn_wc__db_t *db, VERIFY_USABLE_WCROOT(wcroot); SVN_WC__DB_WITH_TXN( - lock_remove_txn(wcroot, local_relpath, scratch_pool), + lock_remove_txn(wcroot, local_relpath, work_items, scratch_pool), wcroot); /* There may be some entries, and the lock info is now out of date. */ @@ -15521,3 +15521,514 @@ svn_wc__db_vacuum(svn_wc__db_t *db, return SVN_NO_ERROR; } + +/* Item queued with svn_wc__db_commit_queue_add */ +typedef struct commit_queue_item_t +{ + const char *local_relpath; + svn_boolean_t recurse; /* Use legacy recursion */ + svn_boolean_t committed; /* Process the node as committed */ + svn_boolean_t remove_lock; /* Remove existing lock on node */ + svn_boolean_t remove_changelist; /* Remove changelist on node */ + + /* The pristine text checksum. NULL if the old value should be kept + and for directories */ + const svn_checksum_t *new_sha1_checksum; + + apr_hash_t *new_dav_cache; /* New DAV cache for the node */ +} commit_queue_item_t; + +/* The queue definition for vn_wc__db_create_commit_queue, + svn_wc__db_commit_queue_add and finally svn_wc__db_process_commit_queue */ +struct svn_wc__db_commit_queue_t +{ + svn_wc__db_wcroot_t *wcroot; /* Wcroot for ITEMS */ + apr_array_header_t *items; /* List of commit_queue_item_t* */ + svn_boolean_t have_recurse; /* Is one or more item[x]->recurse TRUE? */ +}; + +/* Create a new svn_wc__db_commit_queue_t instance in RESULT_POOL for the + working copy specified with WRI_ABSPATH */ +svn_error_t * +svn_wc__db_create_commit_queue(svn_wc__db_commit_queue_t **queue, + svn_wc__db_t *db, + const char *wri_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_wc__db_wcroot_t *wcroot; + const char *local_relpath; + svn_wc__db_commit_queue_t *q; + + SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath)); + + SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db, + wri_abspath, result_pool, scratch_pool)); + VERIFY_USABLE_WCROOT(wcroot); + + q = apr_pcalloc(result_pool, sizeof(*q)); + + SVN_ERR_ASSERT(wcroot->sdb); + + q->wcroot = wcroot; + q->items = apr_array_make(result_pool, 64, + sizeof(commit_queue_item_t*)); + q->have_recurse = FALSE; + + *queue = q; + return SVN_NO_ERROR; +} + +svn_error_t * +svn_wc__db_commit_queue_add(svn_wc__db_commit_queue_t *queue, + const char *local_abspath, + svn_boolean_t recurse, + svn_boolean_t is_commited, + svn_boolean_t remove_lock, + svn_boolean_t remove_changelist, + const svn_checksum_t *new_sha1_checksum, + apr_hash_t *new_dav_cache, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + commit_queue_item_t *cqi; + const char *local_relpath; + + local_relpath = svn_dirent_skip_ancestor(queue->wcroot->abspath, + local_abspath); + + if (! local_relpath) + return svn_error_createf( + SVN_ERR_WC_PATH_NOT_FOUND, NULL, + _("The path '%s' is not in the working copy '%s'"), + svn_dirent_local_style(local_abspath, scratch_pool), + svn_dirent_local_style(queue->wcroot->abspath, scratch_pool)); + + cqi = apr_pcalloc(result_pool, sizeof(*cqi)); + cqi->local_relpath = local_relpath; + cqi->recurse = recurse; + cqi->committed = is_commited; + cqi->remove_lock = remove_lock; + cqi->remove_changelist = remove_changelist; + cqi->new_sha1_checksum = new_sha1_checksum; + cqi->new_dav_cache = new_dav_cache; + + queue->have_recurse |= recurse; + + APR_ARRAY_PUSH(queue->items, commit_queue_item_t *) = cqi; + return SVN_NO_ERROR; +} + +/*** Finishing updates and commits. ***/ + +/* Post process an item that is committed in the repository. Collapse layers into + * BASE. Queue work items that will finish a commit of the file or directory + * LOCAL_ABSPATH in DB: + */ +static svn_error_t * +process_committed_leaf(svn_wc__db_t *db, + svn_wc__db_wcroot_t *wcroot, + const char *local_relpath, + svn_boolean_t via_recurse, + svn_wc__db_status_t status, + svn_node_kind_t kind, + svn_boolean_t prop_mods, + const svn_checksum_t *old_checksum, + svn_revnum_t new_revnum, + apr_time_t new_changed_date, + const char *new_changed_author, + apr_hash_t *new_dav_cache, + svn_boolean_t remove_lock, + svn_boolean_t remove_changelist, + const svn_checksum_t *checksum, + apr_pool_t *scratch_pool) +{ + svn_revnum_t new_changed_rev = new_revnum; + svn_skel_t *work_item = NULL; + + { + const char *lock_relpath; + svn_boolean_t locked; + + if (kind == svn_node_dir) + lock_relpath = local_relpath; + else + lock_relpath = svn_relpath_dirname(local_relpath, scratch_pool); + + SVN_ERR(svn_wc__db_wclock_owns_lock_internal(&locked, wcroot, + lock_relpath, FALSE, + scratch_pool)); + + if (!locked) + return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL, + _("No write-lock in '%s'"), + path_for_error_message(wcroot, local_relpath, + scratch_pool)); + + SVN_ERR(flush_entries(wcroot, lock_relpath, svn_depth_empty, + scratch_pool)); + } + + if (status == svn_wc__db_status_deleted) + { + return svn_error_trace( + db_base_remove(wcroot, local_relpath, db, + FALSE /* keep_as_working */, + FALSE /* queue_deletes */, + TRUE /* remove_locks */, + (! via_recurse) + ? new_revnum : SVN_INVALID_REVNUM, + NULL, NULL, + scratch_pool)); + } + else if (status == svn_wc__db_status_not_present) + { + /* We are committing the leaf of a copy operation. + We leave the not-present marker to allow pulling in excluded + children of a copy. + + The next update will remove the not-present marker. */ + + return SVN_NO_ERROR; + } + + SVN_ERR_ASSERT(status == svn_wc__db_status_normal + || status == svn_wc__db_status_incomplete + || status == svn_wc__db_status_added); + + if (kind != svn_node_dir) + { + /* If we sent a delta (meaning: post-copy modification), + then this file will appear in the queue and so we should have + its checksum already. */ + if (checksum == NULL) + { + /* It was copied and not modified. We must have a text + base for it. And the node should have a checksum. */ + SVN_ERR_ASSERT(old_checksum != NULL); + + checksum = old_checksum; + + /* Is the node completely unmodified and are we recursing? */ + if (via_recurse && !prop_mods) + { + /* If a copied node itself is not modified, but the op_root of + the copy is committed we have to make sure that changed_rev, + changed_date and changed_author don't change or the working + copy used for committing will show different last modified + information then a clean checkout of exactly the same + revisions. (Issue #3676) */ + + SVN_ERR(svn_wc__db_read_info_internal( + NULL, NULL, NULL, NULL, NULL, + &new_changed_rev, + &new_changed_date, + &new_changed_author, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, + wcroot, local_relpath, + scratch_pool, scratch_pool)); + } + } + + SVN_ERR(svn_wc__wq_build_file_commit(&work_item, + db, svn_dirent_join(wcroot->abspath, + local_relpath, + scratch_pool), + prop_mods, + scratch_pool, scratch_pool)); + } + + /* The new text base will be found in the pristine store by its checksum. */ + SVN_ERR(commit_node(wcroot, local_relpath, + new_revnum, new_changed_rev, + new_changed_date, new_changed_author, + checksum, + NULL /* new_children */, + new_dav_cache, + !remove_changelist, + !remove_lock, + work_item, + scratch_pool)); + + return SVN_NO_ERROR; +} + +/** Internal helper for svn_wc_process_committed_queue2(). + * Bump a commit item, collapsing local changes with the new repository + * information to a new BASE node. + * + * @a new_date is the (server-side) date of the new revision, or 0. + * + * @a rev_author is the (server-side) author of the new + * revision; it may be @c NULL. + * + * @a new_dav_cache is a hash of all the new dav properties for LOCAL_RELPATH. + * + * If @a remove_lock is set, release any user locks on @a + * local_abspath; otherwise keep them during processing. + * + * If @a remove_changelist is set, clear any changeset assignments + * from @a local_abspath; otherwise, keep such assignments. + * + * If @a new_sha1_checksum is non-NULL, use it to identify the node's pristine + * text. + * + * Set TOP_OF_RECURSE to TRUE to show that this the top of a possibly + * recursive commit operation. (Part of the legacy recurse handling) + */ +static svn_error_t * +process_committed_internal(svn_wc__db_t *db, + svn_wc__db_wcroot_t *wcroot, + const char *local_relpath, + svn_boolean_t recurse, + svn_boolean_t top_of_recurse, + svn_revnum_t new_revnum, + apr_time_t new_date, + const char *rev_author, + apr_hash_t *new_dav_cache, + svn_boolean_t remove_lock, + svn_boolean_t remove_changelist, + const svn_checksum_t *new_sha1_checksum, + apr_hash_t *items_by_relpath, + apr_pool_t *scratch_pool) +{ + svn_wc__db_status_t status; + svn_node_kind_t kind; + const svn_checksum_t *old_checksum; + svn_boolean_t prop_mods; + + SVN_ERR(svn_wc__db_read_info_internal(&status, &kind, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, &old_checksum, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, &prop_mods, NULL, NULL, NULL, + wcroot, local_relpath, + scratch_pool, scratch_pool)); + + /* NOTE: be wary of making crazy semantic changes in this function, since + svn_wc_process_committed4() calls this. */ + + SVN_ERR(process_committed_leaf(db, wcroot, local_relpath, !top_of_recurse, + status, kind, prop_mods, old_checksum, + new_revnum, new_date, rev_author, + new_dav_cache, + remove_lock, remove_changelist, + new_sha1_checksum, + scratch_pool)); + + /* Only check for recursion on nodes that have children */ + if (kind != svn_node_dir + || status == svn_wc__db_status_not_present + || status == svn_wc__db_status_excluded + || status == svn_wc__db_status_server_excluded + /* Node deleted -> then no longer a directory */ + || status == svn_wc__db_status_deleted) + { + return SVN_NO_ERROR; + } + + if (recurse) + { + const apr_array_header_t *children; + apr_pool_t *iterpool = svn_pool_create(scratch_pool); + int i; + + /* Read PATH's entries; this is the absolute path. */ + SVN_ERR(gather_children(&children, wcroot, local_relpath, + scratch_pool, iterpool)); + + /* Recursively loop over all children. */ + for (i = 0; i < children->nelts; i++) + { + const char *name = APR_ARRAY_IDX(children, i, const char *); + const char *this_relpath; + const commit_queue_item_t *cqi; + + svn_pool_clear(iterpool); + + this_relpath = svn_dirent_join(local_relpath, name, iterpool); + + new_sha1_checksum = NULL; + cqi = svn_hash_gets(items_by_relpath, this_relpath); + + if (cqi != NULL) + new_sha1_checksum = cqi->new_sha1_checksum; + + /* Recurse. Pass NULL for NEW_DAV_CACHE, because the + ones present in the current call are only applicable to + this one committed item. */ + SVN_ERR(process_committed_internal( + db, wcroot, this_relpath, + TRUE /* recurse */, + FALSE /* top_of_recurse */, + new_revnum, new_date, + rev_author, + NULL /* new_dav_cache */, + FALSE /* remove_lock */, + remove_changelist, + new_sha1_checksum, + items_by_relpath, + iterpool)); + } + + svn_pool_destroy(iterpool); + } + + return SVN_NO_ERROR; +} + +/* Return TRUE if any item of QUEUE is a parent of ITEM and will be + processed recursively, return FALSE otherwise. + + The algorithmic complexity of this search implementation is O(queue + length), but it's quite quick. +*/ +static svn_boolean_t +have_recursive_parent(const apr_array_header_t *all_items, + const commit_queue_item_t *item, + apr_pool_t *scratch_pool) +{ + const char *local_relpath = item->local_relpath; + int i; + + for (i = 0; i < all_items->nelts; i++) + { + const commit_queue_item_t *qi + = APR_ARRAY_IDX(all_items, i, const commit_queue_item_t *); + + if (qi == item) + continue; + + if (qi->recurse && svn_relpath_skip_ancestor(qi->local_relpath, + local_relpath)) + { + return TRUE; + } + } + + return FALSE; +} + +/* Compare function for svn_sort__array */ +static int +compare_queue_items(const void *v1, + const void *v2) +{ + const commit_queue_item_t *cqi1 + = *(const commit_queue_item_t **)v1; + const commit_queue_item_t *cqi2 + = *(const commit_queue_item_t **)v2; + + return svn_path_compare_paths(cqi1->local_relpath, cqi2->local_relpath); +} + +/* Internal, locked version of svn_wc__db_process_commit_queue */ +static svn_error_t * +db_process_commit_queue(svn_wc__db_t *db, + svn_wc__db_commit_queue_t *queue, + svn_revnum_t new_revnum, + apr_time_t new_date, + const char *new_author, + apr_pool_t *scratch_pool) +{ + apr_hash_t *items_by_relpath = NULL; + int j; + apr_pool_t *iterpool = svn_pool_create(scratch_pool); + + svn_sort__array(queue->items, compare_queue_items); + + if (queue->have_recurse) + { + items_by_relpath = apr_hash_make(scratch_pool); + + for (j = 0; j < queue->items->nelts; j++) + { + commit_queue_item_t *cqi + = APR_ARRAY_IDX(queue->items, j, commit_queue_item_t *); + + svn_hash_sets(items_by_relpath, cqi->local_relpath, cqi); + } + } + + for (j = 0; j < queue->items->nelts; j++) + { + commit_queue_item_t *cqi + = APR_ARRAY_IDX(queue->items, j, commit_queue_item_t *); + + svn_pool_clear(iterpool); + + /* Skip this item if it is a child of a recursive item, because it has + been (or will be) accounted for when that recursive item was (or + will be) processed. */ + if (queue->have_recurse && have_recursive_parent(queue->items, cqi, + iterpool)) + continue; + + if (!cqi->committed) + { + if (cqi->remove_lock) + { + svn_skel_t *work_item; + + SVN_ERR(svn_wc__wq_build_sync_file_flags( + &work_item, + db, + svn_dirent_join( + queue->wcroot->abspath, + cqi->local_relpath, + iterpool), + iterpool, iterpool)); + + lock_remove_txn(queue->wcroot, cqi->local_relpath, work_item, + iterpool); + } + if (cqi->remove_changelist) + SVN_ERR(svn_wc__db_op_set_changelist(db, + svn_dirent_join( + queue->wcroot->abspath, + cqi->local_relpath, + iterpool), + NULL, NULL, + svn_depth_empty, + NULL, NULL, /* notify */ + NULL, NULL, /* cancel */ + iterpool)); + } + else + { + SVN_ERR(process_committed_internal( + db, queue->wcroot, cqi->local_relpath, + cqi->recurse, + TRUE /* top_of_recurse */, + new_revnum, new_date, new_author, + cqi->new_dav_cache, + cqi->remove_lock, + cqi->remove_changelist, + cqi->new_sha1_checksum, + items_by_relpath, + iterpool)); + } + } + + svn_pool_destroy(iterpool); + + return SVN_NO_ERROR; +} + +svn_error_t * +svn_wc__db_process_commit_queue(svn_wc__db_t *db, + svn_wc__db_commit_queue_t *queue, + svn_revnum_t new_revnum, + apr_time_t new_date, + const char *new_author, + apr_pool_t *scratch_pool) +{ + SVN_WC__DB_WITH_TXN(db_process_commit_queue(db, queue, + new_revnum, new_date, + new_author, scratch_pool), + queue->wcroot); + + return SVN_NO_ERROR; +} Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.h URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.h?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.h (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.h Mon Oct 27 17:28:13 2014 @@ -1261,6 +1261,53 @@ svn_wc__db_committable_externals_below(a apr_pool_t *result_pool, apr_pool_t *scratch_pool); +/* Opaque struct for svn_wc__db_create_commit_queue, svn_wc__db_commit_queue_add, + svn_wc__db_process_commit_queue */ +typedef struct svn_wc__db_commit_queue_t svn_wc__db_commit_queue_t; + +/* Create a new svn_wc__db_commit_queue_t instance in RESULT_POOL for the + working copy specified with WRI_ABSPATH */ +svn_error_t * +svn_wc__db_create_commit_queue(svn_wc__db_commit_queue_t **queue, + svn_wc__db_t *db, + const char *wri_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Adds the specified path to the commit queue with the related information. + + See svn_wc_queue_committed4() for argument documentation. + + Note that this function currently DOESN'T copy the passed values to + RESULT_POOL, but expects them to be valid until processing. Otherwise the + only users memory requirements would +- double. + */ +svn_error_t * +svn_wc__db_commit_queue_add(svn_wc__db_commit_queue_t *queue, + const char *local_abspath, + svn_boolean_t recurse, + svn_boolean_t is_commited, + svn_boolean_t remove_lock, + svn_boolean_t remove_changelist, + const svn_checksum_t *new_sha1_checksum, + apr_hash_t *new_dav_cache, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Process the items in QUEUE in a single transaction. Commit workqueue items + for items that need post processing. + + Implementation detail of svn_wc_process_committed_queue2(). + */ +svn_error_t * +svn_wc__db_process_commit_queue(svn_wc__db_t *db, + svn_wc__db_commit_queue_t *queue, + svn_revnum_t new_revnum, + apr_time_t new_date, + const char *new_author, + apr_pool_t *scratch_pool); + + /* Gets a mapping from const char * local abspaths of externals to the const char * local abspath of where they are defined for all externals defined at or below LOCAL_ABSPATH. @@ -2633,10 +2680,12 @@ svn_wc__db_lock_add(svn_wc__db_t *db, apr_pool_t *scratch_pool); -/* Remove any lock for LOCAL_ABSPATH in DB. */ +/* Remove any lock for LOCAL_ABSPATH in DB and install WORK_ITEMS + (if not NULL) in DB */ svn_error_t * svn_wc__db_lock_remove(svn_wc__db_t *db, const char *local_abspath, + svn_skel_t *work_items, apr_pool_t *scratch_pool); Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.c (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.c Mon Oct 27 17:28:13 2014 @@ -1016,8 +1016,8 @@ svn_error_t * svn_wc__wq_build_dir_install(svn_skel_t **work_item, svn_wc__db_t *db, const char *local_abspath, - apr_pool_t *scratch_pool, - apr_pool_t *result_pool) + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { const char *local_relpath; Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.h URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.h?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.h (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.h Mon Oct 27 17:28:13 2014 @@ -215,8 +215,8 @@ svn_error_t * svn_wc__wq_build_dir_install(svn_skel_t **work_item, svn_wc__db_t *db, const char *local_abspath, - apr_pool_t *scratch_pool, - apr_pool_t *result_pool); + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); svn_error_t * svn_wc__wq_build_postupgrade(svn_skel_t **work_item, Modified: subversion/branches/move-tracking-2/subversion/mod_dav_svn/deadprops.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/mod_dav_svn/deadprops.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/mod_dav_svn/deadprops.c (original) +++ subversion/branches/move-tracking-2/subversion/mod_dav_svn/deadprops.c Mon Oct 27 17:28:13 2014 @@ -323,7 +323,7 @@ db_open(apr_pool_t *p, db->p = svn_pool_create(p); /* ### temp hack */ - db->work = svn_stringbuf_ncreate("", 0, db->p); + db->work = svn_stringbuf_create_empty(db->p); /* make our path-based authz callback available to svn_repos_* funcs. */ arb = apr_pcalloc(p, sizeof(*arb)); Modified: subversion/branches/move-tracking-2/subversion/mod_dav_svn/lock.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/mod_dav_svn/lock.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/mod_dav_svn/lock.c (original) +++ subversion/branches/move-tracking-2/subversion/mod_dav_svn/lock.c Mon Oct 27 17:28:13 2014 @@ -787,7 +787,31 @@ append_locks(dav_lockdb *lockdb, DAV_ERR_LOCK_SAVE_LOCK, "Anonymous lock creation is not allowed."); } - else if (serr && (serr->apr_err == SVN_ERR_REPOS_HOOK_FAILURE || + else if (serr && serr->apr_err == SVN_ERR_REPOS_POST_LOCK_HOOK_FAILED) + { + /* The lock was created in the repository, so we should report the node + as locked to the client */ + + /* First log the hook failure, for diagnostics. This clears serr */ + dav_svn__log_err(info->r, + dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, + "Post lock hook failure.", + resource->pool), + APLOG_WARNING); + + /* How can we report the error to the client? + + We can't return an error code, as that would make it impossible + to return the lock details? + + Add yet another custom header? + Just an header doesn't handle a full error chain... + + ### Current behavior: we don't report an error. + */ + + } + else if (serr && (svn_error_find_cause(serr, SVN_ERR_REPOS_HOOK_FAILURE) || serr->apr_err == SVN_ERR_FS_NO_SUCH_LOCK || serr->apr_err == SVN_ERR_FS_LOCK_EXPIRED || SVN_ERR_IS_LOCK_ERROR(serr))) @@ -897,6 +921,22 @@ remove_lock(dav_lockdb *lockdb, DAV_ERR_LOCK_SAVE_LOCK, "Anonymous lock removal is not allowed."); } + else if (serr && serr->apr_err == SVN_ERR_REPOS_POST_UNLOCK_HOOK_FAILED + && !resource->info->repos->is_svn_client) + { + /* Generic DAV clients don't understand the specific error code we + would produce here as being just a warning, so lets produce a + success result. We removed the lock anyway. */ + + /* First log the hook failure, for diagnostics. This clears serr */ + dav_svn__log_err(info->r, + dav_svn__convert_err(serr, + HTTP_INTERNAL_SERVER_ERROR, + "Post unlock hook failure.", + resource->pool), + APLOG_WARNING); + + } else if (serr) return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, "Failed to remove a lock.", @@ -1016,7 +1056,7 @@ refresh_locks(dav_lockdb *lockdb, DAV_ERR_LOCK_SAVE_LOCK, "Anonymous lock refreshing is not allowed."); } - else if (serr && (serr->apr_err == SVN_ERR_REPOS_HOOK_FAILURE || + else if (serr && (svn_error_find_cause(serr, SVN_ERR_REPOS_HOOK_FAILURE) || serr->apr_err == SVN_ERR_FS_NO_SUCH_LOCK || serr->apr_err == SVN_ERR_FS_LOCK_EXPIRED || SVN_ERR_IS_LOCK_ERROR(serr))) Modified: subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c (original) +++ subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c Mon Oct 27 17:28:13 2014 @@ -152,7 +152,7 @@ dav_svn__convert_err(svn_error_t *serr, derr = build_error_chain(pool, purged_serr, status); if (message != NULL - && purged_serr->apr_err != SVN_ERR_REPOS_HOOK_FAILURE) + && !svn_error_find_cause(purged_serr, SVN_ERR_REPOS_HOOK_FAILURE)) /* Don't hide hook failures; we might hide the error text */ derr = dav_push_error(pool, status, purged_serr->apr_err, message, derr); Modified: subversion/branches/move-tracking-2/subversion/svn-bench/cl.h URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn-bench/cl.h?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svn-bench/cl.h (original) +++ subversion/branches/move-tracking-2/subversion/svn-bench/cl.h Mon Oct 27 17:28:13 2014 @@ -90,8 +90,12 @@ typedef struct svn_cl__opt_state_t svn_boolean_t no_revprops; /* retrieve no revprops */ apr_hash_t *revprop_table; /* table of revision properties to get/set */ svn_boolean_t use_merge_history; /* use/display extra merge information */ - svn_boolean_t trust_server_cert; /* trust server SSL certs that would - otherwise be rejected as "untrusted" */ + /* trust server SSL certs that would otherwise be rejected as "untrusted" */ + svn_boolean_t trust_server_cert_unknown_ca; + svn_boolean_t trust_server_cert_cn_mismatch; + svn_boolean_t trust_server_cert_expired; + svn_boolean_t trust_server_cert_not_yet_valid; + svn_boolean_t trust_server_cert_other_failure; } svn_cl__opt_state_t; Modified: subversion/branches/move-tracking-2/subversion/svn-bench/svn-bench.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn-bench/svn-bench.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svn-bench/svn-bench.c (original) +++ subversion/branches/move-tracking-2/subversion/svn-bench/svn-bench.c Mon Oct 27 17:28:13 2014 @@ -67,6 +67,11 @@ typedef enum svn_cl__longopt_t { opt_with_all_revprops, opt_with_no_revprops, opt_trust_server_cert, + opt_trust_server_cert_unknown_ca, + opt_trust_server_cert_cn_mismatch, + opt_trust_server_cert_expired, + opt_trust_server_cert_not_yet_valid, + opt_trust_server_cert_other_failure, opt_changelist } svn_cl__longopt_t; @@ -122,11 +127,29 @@ const apr_getopt_option_t svn_cl__option {"no-auth-cache", opt_no_auth_cache, 0, N_("do not cache authentication tokens")}, {"trust-server-cert", opt_trust_server_cert, 0, - N_("accept SSL server certificates from unknown\n" + N_("deprecated; same as --trust-unknown-ca")}, + {"trust-unknown-ca", opt_trust_server_cert_unknown_ca, 0, + N_("with --non-interactive, accept SSL server\n" " " - "certificate authorities without prompting (but only\n" + "certificates from unknown certificate authorities")}, + {"trust-cn-mismatch", opt_trust_server_cert_cn_mismatch, 0, + N_("with --non-interactive, accept SSL server\n" " " - "with '--non-interactive')") }, + "certificates even if the server hostname does not\n" + " " + "match the certificate's common name attribute")}, + {"trust-expired", opt_trust_server_cert_expired, 0, + N_("with --non-interactive, accept expired SSL server\n" + " " + "certificates")}, + {"trust-not-yet-valid", opt_trust_server_cert_not_yet_valid, 0, + N_("with --non-interactive, accept SSL server\n" + " " + "certificates from the future")}, + {"trust-other-failure", opt_trust_server_cert_other_failure, 0, + N_("with --non-interactive, accept SSL server\n" + " " + "certificates with failures other than the above")}, {"non-interactive", opt_non_interactive, 0, N_("do no interactive prompting")}, {"config-dir", opt_config_dir, 1, @@ -182,7 +205,10 @@ const apr_getopt_option_t svn_cl__option willy-nilly to every invocation of 'svn') . */ const int svn_cl__global_options[] = { opt_auth_username, opt_auth_password, opt_no_auth_cache, opt_non_interactive, - opt_trust_server_cert, opt_config_dir, opt_config_options, 0 + opt_trust_server_cert, opt_trust_server_cert_unknown_ca, + opt_trust_server_cert_cn_mismatch, opt_trust_server_cert_expired, + opt_trust_server_cert_not_yet_valid, opt_trust_server_cert_other_failure, + opt_config_dir, opt_config_options, 0 }; const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] = @@ -578,8 +604,21 @@ sub_main(int *exit_code, int argc, const case opt_non_interactive: opt_state.non_interactive = TRUE; break; - case opt_trust_server_cert: - opt_state.trust_server_cert = TRUE; + case opt_trust_server_cert: /* backwards compat to 1.8 */ + case opt_trust_server_cert_unknown_ca: + opt_state.trust_server_cert_unknown_ca = TRUE; + break; + case opt_trust_server_cert_cn_mismatch: + opt_state.trust_server_cert_cn_mismatch = TRUE; + break; + case opt_trust_server_cert_expired: + opt_state.trust_server_cert_expired = TRUE; + break; + case opt_trust_server_cert_not_yet_valid: + opt_state.trust_server_cert_not_yet_valid = TRUE; + break; + case opt_trust_server_cert_other_failure: + opt_state.trust_server_cert_other_failure = TRUE; break; case 'x': SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.extensions, @@ -756,12 +795,29 @@ sub_main(int *exit_code, int argc, const "are mutually exclusive")); } - /* --trust-server-cert can only be used with --non-interactive */ - if (opt_state.trust_server_cert && !opt_state.non_interactive) + /* --trust-* options can only be used with --non-interactive */ + if (!opt_state.non_interactive) { - return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, - _("--trust-server-cert requires " - "--non-interactive")); + if (opt_state.trust_server_cert_unknown_ca) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--trust-unknown-ca requires " + "--non-interactive")); + if (opt_state.trust_server_cert_cn_mismatch) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--trust-cn-mismatch requires " + "--non-interactive")); + if (opt_state.trust_server_cert_expired) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--trust-expired requires " + "--non-interactive")); + if (opt_state.trust_server_cert_not_yet_valid) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--trust-not-yet-valid requires " + "--non-interactive")); + if (opt_state.trust_server_cert_other_failure) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--trust-other-failure requires " + "--non-interactive")); } /* Ensure that 'revision_ranges' has at least one item, and make @@ -867,17 +923,22 @@ sub_main(int *exit_code, int argc, const #endif /* Set up Authentication stuff. */ - SVN_ERR(svn_cmdline_create_auth_baton(&ab, - opt_state.non_interactive, - opt_state.auth_username, - opt_state.auth_password, - opt_state.config_dir, - opt_state.no_auth_cache, - opt_state.trust_server_cert, - cfg_config, - ctx->cancel_func, - ctx->cancel_baton, - pool)); + SVN_ERR(svn_cmdline_create_auth_baton2( + &ab, + opt_state.non_interactive, + opt_state.auth_username, + opt_state.auth_password, + opt_state.config_dir, + opt_state.no_auth_cache, + opt_state.trust_server_cert_unknown_ca, + opt_state.trust_server_cert_cn_mismatch, + opt_state.trust_server_cert_expired, + opt_state.trust_server_cert_not_yet_valid, + opt_state.trust_server_cert_other_failure, + cfg_config, + ctx->cancel_func, + ctx->cancel_baton, + pool)); ctx->auth_baton = ab; Modified: subversion/branches/move-tracking-2/subversion/svn/auth-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/auth-cmd.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svn/auth-cmd.c (original) +++ subversion/branches/move-tracking-2/subversion/svn/auth-cmd.c Mon Oct 27 17:28:13 2014 @@ -293,7 +293,6 @@ svn_error_t * svn_cl__auth(apr_getopt_t *os, void *baton, apr_pool_t *pool) { svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state; - svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx; const char *config_path; struct walk_credentials_baton_t b; @@ -301,11 +300,17 @@ svn_cl__auth(apr_getopt_t *os, void *bat b.show_passwords = opt_state->show_passwords; b.list = !opt_state->remove; b.delete = opt_state->remove; - - SVN_ERR(svn_cl__args_to_target_array_print_reserved(&b.patterns, os, - opt_state->targets, - ctx, FALSE, - pool)); + b.patterns = apr_array_make(pool, 1, sizeof(const char *)); + for (; os->ind < os->argc; os->ind++) + { + /* The apr_getopt targets are still in native encoding. */ + const char *raw_target = os->argv[os->ind]; + const char *utf8_target; + + SVN_ERR(svn_utf_cstring_to_utf8(&utf8_target, + raw_target, pool)); + APR_ARRAY_PUSH(b.patterns, const char *) = utf8_target; + } SVN_ERR(svn_config_get_user_config_path(&config_path, opt_state->config_dir, NULL, Modified: subversion/branches/move-tracking-2/subversion/svn/checkout-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/checkout-cmd.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svn/checkout-cmd.c (original) +++ subversion/branches/move-tracking-2/subversion/svn/checkout-cmd.c Mon Oct 27 17:28:13 2014 @@ -72,6 +72,7 @@ svn_cl__checkout(apr_getopt_t *os, svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx; apr_pool_t *subpool; apr_array_header_t *targets; + struct svn_cl__check_externals_failed_notify_baton nwb; const char *last_target, *local_dir; int i; @@ -113,6 +114,12 @@ svn_cl__checkout(apr_getopt_t *os, if (! opt_state->quiet) SVN_ERR(svn_cl__notifier_mark_checkout(ctx->notify_baton2)); + nwb.wrapped_func = ctx->notify_func2; + nwb.wrapped_baton = ctx->notify_baton2; + nwb.had_externals_error = FALSE; + ctx->notify_func2 = svn_cl__check_externals_failed_notify_wrapper; + ctx->notify_baton2 = &nwb; + subpool = svn_pool_create(pool); for (i = 0; i < targets->nelts; ++i) { @@ -169,5 +176,10 @@ svn_cl__checkout(apr_getopt_t *os, } svn_pool_destroy(subpool); + if (nwb.had_externals_error) + return svn_error_create(SVN_ERR_CL_ERROR_PROCESSING_EXTERNALS, NULL, + _("Failure occurred processing one or " + "more externals definitions")); + return SVN_NO_ERROR; } Modified: subversion/branches/move-tracking-2/subversion/svn/cl.h URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/cl.h?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svn/cl.h (original) +++ subversion/branches/move-tracking-2/subversion/svn/cl.h Mon Oct 27 17:28:13 2014 @@ -227,8 +227,12 @@ typedef struct svn_cl__opt_state_t svn_cl__show_revs_t show_revs; /* mergeinfo flavor */ svn_depth_t set_depth; /* new sticky ambient depth value */ svn_boolean_t reintegrate; /* use "reintegrate" merge-source heuristic */ - svn_boolean_t trust_server_cert; /* trust server SSL certs that would - otherwise be rejected as "untrusted" */ + /* trust server SSL certs that would otherwise be rejected as "untrusted" */ + svn_boolean_t trust_server_cert_unknown_ca; + svn_boolean_t trust_server_cert_cn_mismatch; + svn_boolean_t trust_server_cert_expired; + svn_boolean_t trust_server_cert_not_yet_valid; + svn_boolean_t trust_server_cert_other_failure; int strip; /* number of leading path components to strip */ svn_boolean_t ignore_keywords; /* do not expand keywords */ svn_boolean_t reverse_diff; /* reverse a diff (e.g. when patching) */ Modified: subversion/branches/move-tracking-2/subversion/svn/svn.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/svn.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svn/svn.c (original) +++ subversion/branches/move-tracking-2/subversion/svn/svn.c Mon Oct 27 17:28:13 2014 @@ -125,6 +125,11 @@ typedef enum svn_cl__longopt_t { opt_show_revs, opt_reintegrate, opt_trust_server_cert, + opt_trust_server_cert_unknown_ca, + opt_trust_server_cert_cn_mismatch, + opt_trust_server_cert_expired, + opt_trust_server_cert_not_yet_valid, + opt_trust_server_cert_other_failure, opt_strip, opt_ignore_keywords, opt_reverse_diff, @@ -236,11 +241,29 @@ const apr_getopt_option_t svn_cl__option {"no-auth-cache", opt_no_auth_cache, 0, N_("do not cache authentication tokens")}, {"trust-server-cert", opt_trust_server_cert, 0, - N_("accept SSL server certificates from unknown\n" + N_("deprecated; same as --trust-unknown-ca")}, + {"trust-unknown-ca", opt_trust_server_cert_unknown_ca, 0, + N_("with --non-interactive, accept SSL server\n" " " - "certificate authorities without prompting (but only\n" + "certificates from unknown certificate authorities")}, + {"trust-cn-mismatch", opt_trust_server_cert_cn_mismatch, 0, + N_("with --non-interactive, accept SSL server\n" " " - "with '--non-interactive')") }, + "certificates even if the server hostname does not\n" + " " + "match the certificate's common name attribute")}, + {"trust-expired", opt_trust_server_cert_expired, 0, + N_("with --non-interactive, accept expired SSL server\n" + " " + "certificates")}, + {"trust-not-yet-valid", opt_trust_server_cert_not_yet_valid, 0, + N_("with --non-interactive, accept SSL server\n" + " " + "certificates from the future")}, + {"trust-other-failure", opt_trust_server_cert_other_failure, 0, + N_("with --non-interactive, accept SSL server\n" + " " + "certificates with failures other than the above")}, {"non-interactive", opt_non_interactive, 0, N_("do no interactive prompting (default is to prompt\n" " " @@ -427,8 +450,11 @@ const apr_getopt_option_t svn_cl__option willy-nilly to every invocation of 'svn') . */ const int svn_cl__global_options[] = { opt_auth_username, opt_auth_password, opt_no_auth_cache, opt_non_interactive, - opt_force_interactive, opt_trust_server_cert, opt_config_dir, - opt_config_options, 0 + opt_force_interactive, opt_trust_server_cert, + opt_trust_server_cert_unknown_ca, opt_trust_server_cert_cn_mismatch, + opt_trust_server_cert_expired, opt_trust_server_cert_not_yet_valid, + opt_trust_server_cert_other_failure, + opt_config_dir, opt_config_options, 0 }; /* Options for giving a log message. (Some of these also have other uses.) @@ -1505,9 +1531,9 @@ const svn_opt_subcommand_desc2_t svn_cl_ " another Subversion client modifying the working copy\n" " ' ' not locked for writing\n" " 'L' locked for writing\n" - " Fourth column: Scheduled commit will contain addition-with-history\n" - " ' ' no history scheduled with commit\n" - " '+' history scheduled with commit\n" + " Fourth column: Scheduled commit will create a copy (addition-with-history)\n" + " ' ' no history scheduled with commit (item was newly added)\n" + " '+' history scheduled with commit (item was copied)\n" " Fifth column: Whether the item is switched or a file external\n" " ' ' normal\n" " 'S' the item has a Switched URL relative to the parent\n" @@ -2124,8 +2150,21 @@ sub_main(int *exit_code, int argc, const case opt_force_interactive: force_interactive = TRUE; break; - case opt_trust_server_cert: - opt_state.trust_server_cert = TRUE; + case opt_trust_server_cert: /* backwards compat to 1.8 */ + case opt_trust_server_cert_unknown_ca: + opt_state.trust_server_cert_unknown_ca = TRUE; + break; + case opt_trust_server_cert_cn_mismatch: + opt_state.trust_server_cert_cn_mismatch = TRUE; + break; + case opt_trust_server_cert_expired: + opt_state.trust_server_cert_expired = TRUE; + break; + case opt_trust_server_cert_not_yet_valid: + opt_state.trust_server_cert_not_yet_valid = TRUE; + break; + case opt_trust_server_cert_other_failure: + opt_state.trust_server_cert_other_failure = TRUE; break; case opt_no_diff_added: opt_state.diff.no_diff_added = TRUE; @@ -2551,12 +2590,29 @@ sub_main(int *exit_code, int argc, const "are mutually exclusive")); } - /* --trust-server-cert can only be used with --non-interactive */ - if (opt_state.trust_server_cert && !opt_state.non_interactive) + /* --trust-* options can only be used with --non-interactive */ + if (!opt_state.non_interactive) { - return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, - _("--trust-server-cert requires " - "--non-interactive")); + if (opt_state.trust_server_cert_unknown_ca) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--trust-unknown-ca requires " + "--non-interactive")); + if (opt_state.trust_server_cert_cn_mismatch) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--trust-cn-mismatch requires " + "--non-interactive")); + if (opt_state.trust_server_cert_expired) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--trust-expired requires " + "--non-interactive")); + if (opt_state.trust_server_cert_not_yet_valid) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--trust-not-yet-valid requires " + "--non-interactive")); + if (opt_state.trust_server_cert_other_failure) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--trust-other-failure requires " + "--non-interactive")); } /* Disallow simultaneous use of both --diff-cmd and @@ -2874,17 +2930,22 @@ sub_main(int *exit_code, int argc, const #endif /* Set up Authentication stuff. */ - SVN_ERR(svn_cmdline_create_auth_baton(&ab, - opt_state.non_interactive, - opt_state.auth_username, - opt_state.auth_password, - opt_state.config_dir, - opt_state.no_auth_cache, - opt_state.trust_server_cert, - cfg_config, - ctx->cancel_func, - ctx->cancel_baton, - pool)); + SVN_ERR(svn_cmdline_create_auth_baton2( + &ab, + opt_state.non_interactive, + opt_state.auth_username, + opt_state.auth_password, + opt_state.config_dir, + opt_state.no_auth_cache, + opt_state.trust_server_cert_unknown_ca, + opt_state.trust_server_cert_cn_mismatch, + opt_state.trust_server_cert_expired, + opt_state.trust_server_cert_not_yet_valid, + opt_state.trust_server_cert_other_failure, + cfg_config, + ctx->cancel_func, + ctx->cancel_baton, + pool)); ctx->auth_baton = ab; Modified: subversion/branches/move-tracking-2/subversion/svn/util.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/util.c?rev=1634609&r1=1634608&r2=1634609&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svn/util.c (original) +++ subversion/branches/move-tracking-2/subversion/svn/util.c Mon Oct 27 17:28:13 2014 @@ -560,8 +560,8 @@ svn_cl__error_checked_fputs(const char * if (fputs(string, stream) == EOF) { - if (errno) - return svn_error_wrap_apr(errno, _("Write error")); + if (apr_get_os_error()) /* is errno on POSIX */ + return svn_error_wrap_apr(apr_get_os_error(), _("Write error")); else return svn_error_create(SVN_ERR_IO_WRITE_ERROR, NULL, NULL); }