Modified: subversion/trunk/subversion/libsvn_wc/adm_crawler.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_crawler.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/adm_crawler.c (original) +++ subversion/trunk/subversion/libsvn_wc/adm_crawler.c Tue Dec 13 09:49:29 2022 @@ -46,6 +46,7 @@ #include "translate.h" #include "workqueue.h" #include "conflicts.h" +#include "textbase.h" #include "svn_private_config.h" @@ -74,13 +75,22 @@ restore_file(svn_wc__db_t *db, apr_pool_t *scratch_pool) { svn_skel_t *work_item; + const char *install_from; + svn_skel_t *cleanup_work_item; + SVN_ERR(svn_wc__textbase_setaside_wq(&install_from, + &cleanup_work_item, + db, local_abspath, NULL, + cancel_func, cancel_baton, + scratch_pool, scratch_pool)); SVN_ERR(svn_wc__wq_build_file_install(&work_item, db, local_abspath, - NULL /* source_abspath */, + install_from, use_commit_times, TRUE /* record_fileinfo */, scratch_pool, scratch_pool)); + work_item = svn_wc__wq_merge(work_item, cleanup_work_item, scratch_pool); + /* ### we need an existing path for wq_add. not entirely WRI_ABSPATH yet */ SVN_ERR(svn_wc__db_wq_add(db, svn_dirent_dirname(local_abspath, scratch_pool), @@ -211,10 +221,10 @@ maybe_restore_node(svn_wc__db_t *db, } svn_error_t * -svn_wc_restore(svn_wc_context_t *wc_ctx, - const char *local_abspath, - svn_boolean_t use_commit_times, - apr_pool_t *scratch_pool) +svn_wc_restore2(svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t use_commit_times, + apr_pool_t *scratch_pool) { /* ### If ever revved: Add cancel func. */ svn_wc__db_status_t status; @@ -297,7 +307,7 @@ svn_wc_restore(svn_wc_context_t *wc_ctx, passed here to avoid another database query. DEPTH_COMPATIBILITY_TRICK means the same thing here as it does - in svn_wc_crawl_revisions5(). + in svn_wc_crawl_revisions6(). If RESTORE_FILES is set, then unexpectedly missing working files will be restored from text-base and NOTIFY_FUNC/NOTIFY_BATON @@ -665,7 +675,7 @@ report_revisions_and_depths(svn_wc__db_t svn_error_t * -svn_wc_crawl_revisions5(svn_wc_context_t *wc_ctx, +svn_wc_crawl_revisions6(svn_wc_context_t *wc_ctx, const char *local_abspath, const svn_ra_reporter3_t *reporter, void *report_baton, @@ -979,8 +989,8 @@ read_and_checksum_pristine_text(svn_stre { svn_stream_t *base_stream; - SVN_ERR(svn_wc__get_pristine_contents(&base_stream, NULL, db, local_abspath, - result_pool, scratch_pool)); + SVN_ERR(svn_wc__textbase_get_contents(&base_stream, db, local_abspath, NULL, + TRUE, result_pool, scratch_pool)); if (base_stream == NULL) { base_stream = svn_stream_empty(result_pool); @@ -1096,11 +1106,11 @@ svn_wc__internal_transmit_text_deltas(sv { svn_stream_t *new_pristine_stream; - SVN_ERR(svn_wc__db_pristine_prepare_install(&new_pristine_stream, - &install_data, - &local_sha1_checksum, NULL, - db, local_abspath, - scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__textbase_prepare_install(&new_pristine_stream, + &install_data, + &local_sha1_checksum, NULL, + db, local_abspath, FALSE, + scratch_pool, scratch_pool)); local_stream = copying_stream(local_stream, new_pristine_stream, scratch_pool); } @@ -1117,11 +1127,23 @@ svn_wc__internal_transmit_text_deltas(sv /* We will be computing a delta against the pristine contents */ /* We need the expected checksum to be an MD-5 checksum rather than a * SHA-1 because we want to pass it to apply_textdelta(). */ - SVN_ERR(read_and_checksum_pristine_text(&base_stream, - &expected_md5_checksum, - &verify_checksum, - db, local_abspath, - scratch_pool, scratch_pool)); + err = read_and_checksum_pristine_text(&base_stream, + &expected_md5_checksum, + &verify_checksum, + db, local_abspath, + scratch_pool, scratch_pool); + if (err && err->apr_err == SVN_ERR_WC_PRISTINE_DEHYDRATED) + { + /* No local pristine contents to delta against, send a fulltext. */ + svn_error_clear(err); + base_stream = svn_stream_empty(scratch_pool); + expected_md5_checksum = NULL; + verify_checksum = NULL; + } + else if (err) + { + return svn_error_trace(err); + } } else { @@ -1227,7 +1249,7 @@ svn_wc__internal_transmit_text_deltas(sv } svn_error_t * -svn_wc_transmit_text_deltas3(const svn_checksum_t **new_text_base_md5_checksum, +svn_wc_transmit_text_deltas4(const svn_checksum_t **new_text_base_md5_checksum, const svn_checksum_t **new_text_base_sha1_checksum, svn_wc_context_t *wc_ctx, const char *local_abspath,
Modified: subversion/trunk/subversion/libsvn_wc/adm_files.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_files.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/adm_files.c (original) +++ subversion/trunk/subversion/libsvn_wc/adm_files.c Tue Dec 13 09:49:29 2022 @@ -161,122 +161,6 @@ make_adm_subdir(const char *path, -/*** Syncing files in the adm area. ***/ - - -svn_error_t * -svn_wc__text_base_path_to_read(const char **result_abspath, - svn_wc__db_t *db, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - svn_wc__db_status_t status; - svn_node_kind_t kind; - const svn_checksum_t *checksum; - - SVN_ERR(svn_wc__db_read_pristine_info(&status, &kind, NULL, NULL, NULL, NULL, - &checksum, NULL, NULL, NULL, - db, local_abspath, - scratch_pool, scratch_pool)); - - /* Sanity */ - if (kind != svn_node_file) - return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL, - _("Can only get the pristine contents of files; " - "'%s' is not a file"), - svn_dirent_local_style(local_abspath, - scratch_pool)); - - if (status == svn_wc__db_status_not_present) - /* We know that the delete of this node has been committed. - This should be the same as if called on an unknown path. */ - return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL, - _("Cannot get the pristine contents of '%s' " - "because its delete is already committed"), - svn_dirent_local_style(local_abspath, - scratch_pool)); - else if (status == svn_wc__db_status_server_excluded - || status == svn_wc__db_status_excluded - || status == svn_wc__db_status_incomplete) - return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, - _("Cannot get the pristine contents of '%s' " - "because it has an unexpected status"), - svn_dirent_local_style(local_abspath, - scratch_pool)); - - if (checksum == NULL) - return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, - _("Node '%s' has no pristine text"), - svn_dirent_local_style(local_abspath, - scratch_pool)); - SVN_ERR(svn_wc__db_pristine_get_path(result_abspath, db, local_abspath, - checksum, - result_pool, scratch_pool)); - return SVN_NO_ERROR; -} - -svn_error_t * -svn_wc__get_pristine_contents(svn_stream_t **contents, - svn_filesize_t *size, - svn_wc__db_t *db, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - svn_wc__db_status_t status; - svn_node_kind_t kind; - const svn_checksum_t *sha1_checksum; - - if (size) - *size = SVN_INVALID_FILESIZE; - - SVN_ERR(svn_wc__db_read_pristine_info(&status, &kind, NULL, NULL, NULL, NULL, - &sha1_checksum, NULL, NULL, NULL, - db, local_abspath, - scratch_pool, scratch_pool)); - - /* Sanity */ - if (kind != svn_node_file) - return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL, - _("Can only get the pristine contents of files; " - "'%s' is not a file"), - svn_dirent_local_style(local_abspath, - scratch_pool)); - - if (status == svn_wc__db_status_added && !sha1_checksum) - { - /* Simply added. The pristine base does not exist. */ - *contents = NULL; - return SVN_NO_ERROR; - } - else if (status == svn_wc__db_status_not_present) - /* We know that the delete of this node has been committed. - This should be the same as if called on an unknown path. */ - return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL, - _("Cannot get the pristine contents of '%s' " - "because its delete is already committed"), - svn_dirent_local_style(local_abspath, - scratch_pool)); - else if (status == svn_wc__db_status_server_excluded - || status == svn_wc__db_status_excluded - || status == svn_wc__db_status_incomplete) - return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, - _("Cannot get the pristine contents of '%s' " - "because it has an unexpected status"), - svn_dirent_local_style(local_abspath, - scratch_pool)); - if (sha1_checksum) - SVN_ERR(svn_wc__db_pristine_read(contents, size, db, local_abspath, - sha1_checksum, - result_pool, scratch_pool)); - else - *contents = NULL; - - return SVN_NO_ERROR; -} - - /*** Opening and closing files in the adm area. ***/ svn_error_t * @@ -323,6 +207,7 @@ init_adm(svn_wc__db_t *db, const char *repos_uuid, svn_revnum_t initial_rev, svn_depth_t depth, + svn_boolean_t store_pristine, apr_pool_t *pool) { /* First, make an empty administrative area. */ @@ -344,7 +229,7 @@ init_adm(svn_wc__db_t *db, /* Create the SDB. */ SVN_ERR(svn_wc__db_init(db, target_format, local_abspath, repos_relpath, repos_root_url, repos_uuid, - initial_rev, depth, pool)); + initial_rev, depth, store_pristine, pool)); /* Stamp ENTRIES and FORMAT files for old clients. */ SVN_ERR(svn_io_file_create(svn_wc__adm_child(local_abspath, @@ -370,6 +255,7 @@ svn_wc__internal_ensure_adm(svn_wc__db_t const char *repos_uuid, svn_revnum_t revision, svn_depth_t depth, + svn_boolean_t store_pristine, apr_pool_t *scratch_pool) { int present_format; @@ -381,6 +267,7 @@ svn_wc__internal_ensure_adm(svn_wc__db_t svn_wc__db_status_t status; const char *db_repos_relpath, *db_repos_root_url, *db_repos_uuid; svn_revnum_t db_revision; + svn_boolean_t wc_store_pristine; SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath)); SVN_ERR_ASSERT(url != NULL); @@ -388,6 +275,24 @@ svn_wc__internal_ensure_adm(svn_wc__db_t SVN_ERR_ASSERT(repos_uuid != NULL); SVN_ERR_ASSERT(repos_relpath != NULL); + if (target_format < SVN_WC__SUPPORTED_VERSION) + return svn_error_createf( + SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL, + _("Working copy format %d is not supported by client version %s."), + target_format, SVN_VER_NUM); + + if (target_format > SVN_WC__VERSION) + return svn_error_createf( + SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL, + _("Working copy format %d can't be created by client version %s."), + target_format, SVN_VER_NUM); + + if (target_format < SVN_WC__HAS_OPTIONAL_PRISTINE && !store_pristine) + return svn_error_createf( + SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL, + _("Working copy format %d does not support the requested capabilities"), + target_format); + SVN_ERR(svn_wc__internal_check_wc(&present_format, db, local_abspath, TRUE, scratch_pool)); @@ -395,22 +300,31 @@ svn_wc__internal_ensure_adm(svn_wc__db_t just create one. */ if (present_format == 0) { - - if (target_format < SVN_WC__SUPPORTED_VERSION) - return svn_error_createf( - SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL, - _("Working copy format %d is not supported by client version %s."), - target_format, SVN_VER_NUM); - - if (target_format > SVN_WC__VERSION) - return svn_error_createf( - SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL, - _("Working copy format %d can't be created by client version %s."), - target_format, SVN_VER_NUM); - return svn_error_trace(init_adm(db, target_format, local_abspath, repos_relpath, repos_root_url, repos_uuid, - revision, depth, scratch_pool)); + revision, depth, store_pristine, + scratch_pool)); + } + else if (present_format != target_format) + { + return svn_error_createf( + SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL, + _("Format %d doesn't match existing format %d in '%s'"), + target_format, present_format, + svn_dirent_local_style(local_abspath, scratch_pool)); + } + + SVN_ERR(svn_wc__db_get_settings(NULL, &wc_store_pristine, db, + local_abspath, scratch_pool)); + + if ((store_pristine && !wc_store_pristine) || + (!store_pristine && wc_store_pristine)) + { + return svn_error_createf( + SVN_ERR_WC_INCOMPATIBLE_SETTINGS, NULL, + _("'%s' is an existing working copy with different '%s' setting"), + svn_dirent_local_style(local_abspath, scratch_pool), + "store-pristine"); } SVN_ERR(svn_wc__db_read_info(&status, NULL, @@ -430,14 +344,6 @@ svn_wc__internal_ensure_adm(svn_wc__db_t if (status != svn_wc__db_status_deleted && status != svn_wc__db_status_not_present) { - /* Check that the existing format matches the requested format. */ - if (present_format != target_format) - return svn_error_createf( - SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL, - _("Format %d doesn't match existing format %d in '%s'"), - target_format, present_format, - svn_dirent_local_style(local_abspath, scratch_pool)); - /* ### Should we match copyfrom_revision? */ if (db_revision != revision) return @@ -509,12 +415,13 @@ svn_wc__ensure_adm(svn_wc_context_t *wc_ const char *repos_uuid, svn_revnum_t revision, svn_depth_t depth, + svn_boolean_t store_pristine, apr_pool_t *scratch_pool) { return svn_error_trace( svn_wc__internal_ensure_adm(wc_ctx->db, target_format, local_abspath, url, repos_root_url, repos_uuid, revision, - depth, scratch_pool)); + depth, store_pristine, scratch_pool)); } svn_error_t * Modified: subversion/trunk/subversion/libsvn_wc/adm_files.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_files.h?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/adm_files.h (original) +++ subversion/trunk/subversion/libsvn_wc/adm_files.h Tue Dec 13 09:49:29 2022 @@ -52,55 +52,6 @@ svn_boolean_t svn_wc__adm_area_exists(co apr_pool_t *pool); -/* Set *CONTENTS to a readonly stream on the pristine text of the working - * version of the file LOCAL_ABSPATH in DB. If the file is locally copied - * or moved to this path, this means the pristine text of the copy source, - * even if the file replaces a previously existing base node at this path. - * - * Set *CONTENTS to NULL if there is no pristine text because the file is - * locally added (even if it replaces an existing base node). Return an - * error if there is no pristine text for any other reason. - * - * If SIZE is not NULL, set *SIZE to the length of the pristine stream in - * BYTES or to SVN_INVALID_FILESIZE if no pristine is available for this - * file. - * - * For more detail, see the description of svn_wc_get_pristine_contents2(). - */ -svn_error_t * -svn_wc__get_pristine_contents(svn_stream_t **contents, - svn_filesize_t *size, - svn_wc__db_t *db, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool); - -/* Set *RESULT_ABSPATH to the absolute path to a readable file containing - the WC-1 "normal text-base" of LOCAL_ABSPATH in DB. - - "Normal text-base" means the same as in svn_wc__text_base_path(). - ### May want to check the callers' exact requirements and replace this - definition with something easier to comprehend. - - What the callers want: - A path to a file that will remain available and unchanged as long as - the caller wants it - such as for the lifetime of RESULT_POOL. - - What the current implementation provides: - A path to the file in the pristine store. This file will be removed or - replaced the next time this or another Subversion client updates the WC. - - If the node LOCAL_ABSPATH has no such pristine text, return an error of - type SVN_ERR_WC_PATH_UNEXPECTED_STATUS. - - Allocate *RESULT_PATH in RESULT_POOL. */ -svn_error_t * -svn_wc__text_base_path_to_read(const char **result_abspath, - svn_wc__db_t *db, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool); - /*** Opening all kinds of adm files ***/ Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original) +++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Tue Dec 13 09:49:29 2022 @@ -53,6 +53,7 @@ #include "adm_files.h" #include "conflicts.h" #include "workqueue.h" +#include "textbase.h" #include "private/svn_dep_compat.h" #include "private/svn_sorts_private.h" @@ -753,13 +754,86 @@ svn_wc_add_from_disk3(svn_wc_context_t * return SVN_NO_ERROR; } -/* Return a path where nothing exists on disk, within the admin directory - belonging to the WCROOT_ABSPATH directory. */ -static const char * -nonexistent_path(const char *wcroot_abspath, apr_pool_t *scratch_pool) + +static svn_error_t * +get_pristine_copy_path(const char **pristine_path_p, + const char *local_abspath, + svn_wc__db_t *db, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { - return svn_wc__adm_child(wcroot_abspath, SVN_WC__ADM_NONEXISTENT_PATH, - scratch_pool); + svn_boolean_t store_pristine; + svn_wc__db_status_t status; + svn_node_kind_t kind; + const svn_checksum_t *checksum; + const char *wcroot_abspath; + + SVN_ERR(svn_wc__db_get_settings(NULL, &store_pristine, db, + local_abspath, scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, + NULL, NULL); + + SVN_ERR(svn_wc__db_read_pristine_info(&status, &kind, NULL, NULL, NULL, NULL, + &checksum, NULL, NULL, NULL, + db, local_abspath, + scratch_pool, scratch_pool)); + + /* Sanity */ + if (kind != svn_node_file) + return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL, + _("Can only get the pristine contents of files; " + "'%s' is not a file"), + svn_dirent_local_style(local_abspath, + scratch_pool)); + + if (status == svn_wc__db_status_not_present) + /* We know that the delete of this node has been committed. + This should be the same as if called on an unknown path. */ + return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL, + _("Cannot get the pristine contents of '%s' " + "because its delete is already committed"), + svn_dirent_local_style(local_abspath, + scratch_pool)); + else if (status == svn_wc__db_status_server_excluded + || status == svn_wc__db_status_excluded + || status == svn_wc__db_status_incomplete) + return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, + _("Cannot get the pristine contents of '%s' " + "because it has an unexpected status"), + svn_dirent_local_style(local_abspath, + scratch_pool)); + + SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath, db, local_abspath, + scratch_pool, scratch_pool)); + + if (checksum == NULL) + { + /* Return a path where nothing exists on disk, within the admin directory + belonging to the WCROOT_ABSPATH directory. */ + *pristine_path_p = svn_wc__adm_child(wcroot_abspath, + SVN_WC__ADM_NONEXISTENT_PATH, + result_pool); + } + else + { + svn_boolean_t present; + + SVN_ERR(svn_wc__db_pristine_check(&present, NULL, db, local_abspath, + checksum, scratch_pool)); + if (!present) + return svn_error_createf(SVN_ERR_WC_DB_ERROR, NULL, + _("The pristine text with checksum '%s' was " + "not found"), + svn_checksum_to_cstring_display(checksum, + scratch_pool)); + + SVN_ERR(svn_wc__db_pristine_get_future_path(pristine_path_p, + wcroot_abspath, checksum, + result_pool, scratch_pool)); + } + + return SVN_NO_ERROR; } @@ -778,37 +852,23 @@ svn_wc_get_pristine_copy_path(const char /* DB is now open. This is seemingly a "light" function that a caller may use repeatedly despite error return values. The rest of this function should aggressively close DB, even in the error case. */ + err = get_pristine_copy_path(pristine_path, local_abspath, db, pool, pool); - err = svn_wc__text_base_path_to_read(pristine_path, db, local_abspath, - pool, pool); - if (err && err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS) - { - /* The node doesn't exist, so return a non-existent path located - in WCROOT/.svn/ */ - const char *wcroot_abspath; - - svn_error_clear(err); - - err = svn_wc__db_get_wcroot(&wcroot_abspath, db, local_abspath, - pool, pool); - if (err == NULL) - *pristine_path = nonexistent_path(wcroot_abspath, pool); - } - - return svn_error_compose_create(err, svn_wc__db_close(db)); + return svn_error_compose_create(err, svn_wc__db_close(db)); } svn_error_t * -svn_wc_get_pristine_contents2(svn_stream_t **contents, +svn_wc_get_pristine_contents3(svn_stream_t **contents, svn_wc_context_t *wc_ctx, const char *local_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - return svn_error_trace(svn_wc__get_pristine_contents(contents, NULL, + return svn_error_trace(svn_wc__textbase_get_contents(contents, wc_ctx->db, local_abspath, + NULL, TRUE, result_pool, scratch_pool)); } @@ -825,13 +885,14 @@ typedef struct get_pristine_lazyopen_bat /* Implements svn_stream_lazyopen_func_t */ static svn_error_t * -get_pristine_lazyopen_func(svn_stream_t **stream, +get_pristine_lazyopen_func(svn_stream_t **stream_p, void *baton, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { get_pristine_lazyopen_baton_t *b = baton; const svn_checksum_t *sha1_checksum; + svn_stream_t *stream; /* svn_wc__db_pristine_read() wants a SHA1, so if we have an MD5, we'll use it to lookup the SHA1. */ @@ -842,9 +903,13 @@ get_pristine_lazyopen_func(svn_stream_t b->wri_abspath, b->checksum, scratch_pool, scratch_pool)); - SVN_ERR(svn_wc__db_pristine_read(stream, NULL, b->wc_ctx->db, + SVN_ERR(svn_wc__db_pristine_read(&stream, NULL, b->wc_ctx->db, b->wri_abspath, sha1_checksum, result_pool, scratch_pool)); + if (!stream) + return svn_error_create(SVN_ERR_WC_PRISTINE_DEHYDRATED, NULL, NULL); + + *stream_p = stream; return SVN_NO_ERROR; } @@ -857,13 +922,14 @@ svn_wc__get_pristine_contents_by_checksu apr_pool_t *scratch_pool) { svn_boolean_t present; + svn_boolean_t hydrated; *contents = NULL; - SVN_ERR(svn_wc__db_pristine_check(&present, wc_ctx->db, wri_abspath, - checksum, scratch_pool)); + SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, wc_ctx->db, + wri_abspath, checksum, scratch_pool)); - if (present) + if (present && hydrated) { get_pristine_lazyopen_baton_t *gpl_baton; Modified: subversion/trunk/subversion/libsvn_wc/conflicts.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/conflicts.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/conflicts.c (original) +++ subversion/trunk/subversion/libsvn_wc/conflicts.c Tue Dec 13 09:49:29 2022 @@ -3365,6 +3365,13 @@ svn_wc_resolved_conflict5(svn_wc_context void *notify_baton, apr_pool_t *scratch_pool) { + svn_boolean_t store_pristine; + + SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath, + scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL); + return svn_error_trace(svn_wc__resolve_conflicts(wc_ctx, local_abspath, depth, resolve_text, resolve_prop, resolve_tree, Modified: subversion/trunk/subversion/libsvn_wc/copy.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/copy.c (original) +++ subversion/trunk/subversion/libsvn_wc/copy.c Tue Dec 13 09:49:29 2022 @@ -38,6 +38,7 @@ #include "workqueue.h" #include "props.h" #include "conflicts.h" +#include "textbase.h" #include "svn_private_config.h" #include "private/svn_wc_private.h" @@ -138,11 +139,20 @@ copy_to_tmpdir(svn_skel_t **work_item, if (!modified) { - /* Why create a temp copy if we can just reinstall from pristine? */ - SVN_ERR(svn_wc__wq_build_file_install(work_item, - db, dst_abspath, NULL, FALSE, - TRUE, + const char *install_from; + svn_skel_t *cleanup_work_item; + + SVN_ERR(svn_wc__textbase_setaside_wq(&install_from, + &cleanup_work_item, + db, src_abspath, NULL, + cancel_func, cancel_baton, + result_pool, scratch_pool)); + SVN_ERR(svn_wc__wq_build_file_install(work_item, db, dst_abspath, + install_from, FALSE, TRUE, result_pool, scratch_pool)); + *work_item = svn_wc__wq_merge(*work_item, cleanup_work_item, + result_pool); + return SVN_NO_ERROR; } } Modified: subversion/trunk/subversion/libsvn_wc/deprecated.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/deprecated.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/deprecated.c (original) +++ subversion/trunk/subversion/libsvn_wc/deprecated.c Tue Dec 13 09:49:29 2022 @@ -155,6 +155,51 @@ gather_traversal_info(svn_wc_context_t * /*** From adm_crawler.c ***/ svn_error_t * +svn_wc_crawl_revisions5(svn_wc_context_t *wc_ctx, + const char *local_abspath, + const svn_ra_reporter3_t *reporter, + void *report_baton, + svn_boolean_t restore_files, + svn_depth_t depth, + svn_boolean_t honor_depth_exclude, + svn_boolean_t depth_compatibility_trick, + svn_boolean_t use_commit_times, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool) +{ + if (restore_files) + { + svn_boolean_t store_pristine; + + SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath, + scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, + NULL, NULL); + } + + SVN_ERR(svn_wc_crawl_revisions6(wc_ctx, + local_abspath, + reporter, + report_baton, + restore_files, + depth, + honor_depth_exclude, + depth_compatibility_trick, + use_commit_times, + cancel_func, + cancel_baton, + notify_func, + notify_baton, + scratch_pool)); + + return SVN_NO_ERROR; +} + +svn_error_t * svn_wc_crawl_revisions4(const char *path, svn_wc_adm_access_t *adm_access, const svn_ra_reporter3_t *reporter, @@ -467,6 +512,37 @@ svn_wc_crawl_revisions(const char *path, } svn_error_t * +svn_wc_transmit_text_deltas3(const svn_checksum_t **new_text_base_md5_checksum, + const svn_checksum_t **new_text_base_sha1_checksum, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t fulltext, + const svn_delta_editor_t *editor, + void *file_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_boolean_t store_pristine; + + SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath, + scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL); + + SVN_ERR(svn_wc_transmit_text_deltas4(new_text_base_md5_checksum, + new_text_base_sha1_checksum, + wc_ctx, + local_abspath, + fulltext, + editor, + file_baton, + result_pool, + scratch_pool)); + + return SVN_NO_ERROR; +} + +svn_error_t * svn_wc_transmit_text_deltas2(const char **tempfile, unsigned char digest[], const char *path, @@ -568,6 +644,27 @@ svn_wc_transmit_prop_deltas(const char * return svn_error_trace(svn_wc_context_destroy(wc_ctx)); } +svn_error_t * +svn_wc_restore(svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t use_commit_times, + apr_pool_t *scratch_pool) +{ + svn_boolean_t store_pristine; + + SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath, + scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL); + + SVN_ERR(svn_wc_restore2(wc_ctx, + local_abspath, + use_commit_times, + scratch_pool)); + + return SVN_NO_ERROR; +} + /*** From adm_files.c ***/ svn_error_t * svn_wc_ensure_adm4(svn_wc_context_t *wc_ctx, @@ -582,7 +679,7 @@ svn_wc_ensure_adm4(svn_wc_context_t *wc_ return svn_error_trace( svn_wc__ensure_adm(wc_ctx, SVN_WC__DEFAULT_VERSION, local_abspath, url, repos_root_url, repos_uuid, revision, depth, - scratch_pool)); + TRUE, scratch_pool)); } svn_error_t * @@ -678,6 +775,29 @@ svn_wc_create_tmp_file2(apr_file_t **fp, /*** From adm_ops.c ***/ svn_error_t * +svn_wc_get_pristine_contents2(svn_stream_t **contents, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_boolean_t store_pristine; + + SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath, + scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL); + + SVN_ERR(svn_wc_get_pristine_contents3(contents, + wc_ctx, + local_abspath, + result_pool, + scratch_pool)); + + return SVN_NO_ERROR; +} + +svn_error_t * svn_wc_get_pristine_contents(svn_stream_t **contents, const char *path, apr_pool_t *result_pool, @@ -1107,6 +1227,45 @@ svn_wc_add(const char *path, /*** From revert.c ***/ svn_error_t * +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, + void *notify_baton, + apr_pool_t *scratch_pool) +{ + svn_boolean_t store_pristine; + + SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath, + scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL); + + SVN_ERR(svn_wc_revert7(wc_ctx, + local_abspath, + depth, + use_commit_times, + changelist_filter, + clear_changelists, + metadata_only, + added_keep_local, + cancel_func, + cancel_baton, + notify_func, + notify_baton, + scratch_pool)); + + return SVN_NO_ERROR; +} + +svn_error_t * svn_wc_revert5(svn_wc_context_t *wc_ctx, const char *local_abspath, svn_depth_t depth, @@ -2098,6 +2257,12 @@ svn_wc_get_diff_editor6(const svn_delta_ apr_pool_t *scratch_pool) { const svn_diff_tree_processor_t *diff_processor; + svn_boolean_t store_pristine; + + SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, anchor_abspath, + scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL); /* --git implies --show-copies-as-adds */ if (use_git_diff_format) @@ -2297,6 +2462,43 @@ svn_wc_get_diff_editor(svn_wc_adm_access } svn_error_t * +svn_wc_diff6(svn_wc_context_t *wc_ctx, + const char *local_abspath, + const svn_wc_diff_callbacks4_t *callbacks, + void *callback_baton, + svn_depth_t depth, + svn_boolean_t ignore_ancestry, + svn_boolean_t show_copies_as_adds, + svn_boolean_t use_git_diff_format, + const apr_array_header_t *changelist_filter, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool) +{ + svn_boolean_t store_pristine; + + SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath, + scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL); + + SVN_ERR(svn_wc_diff7(wc_ctx, + local_abspath, + callbacks, + callback_baton, + depth, + ignore_ancestry, + show_copies_as_adds, + use_git_diff_format, + changelist_filter, + cancel_func, + cancel_baton, + scratch_pool)); + + return SVN_NO_ERROR; +} + +svn_error_t * svn_wc_diff5(svn_wc_adm_access_t *anchor, const char *target, const svn_wc_diff_callbacks3_t *callbacks, @@ -2983,6 +3185,13 @@ svn_wc_get_status_editor5(const svn_delt apr_pool_t *result_pool, apr_pool_t *scratch_pool) { + svn_boolean_t store_pristine; + + SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, anchor_abspath, + scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL); + return svn_error_trace( svn_wc__get_status_editor(editor, edit_baton, set_locks_baton, @@ -3630,6 +3839,13 @@ svn_wc_get_update_editor4(const svn_delt apr_pool_t *result_pool, apr_pool_t *scratch_pool) { + svn_boolean_t store_pristine; + + SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, anchor_abspath, + scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL); + return svn_error_trace( svn_wc__get_update_editor(editor, edit_baton, target_revision, @@ -3816,6 +4032,13 @@ svn_wc_get_switch_editor4(const svn_delt apr_pool_t *result_pool, apr_pool_t *scratch_pool) { + svn_boolean_t store_pristine; + + SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, anchor_abspath, + scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL); + return svn_error_trace( svn_wc__get_switch_editor(editor, edit_baton, target_revision, @@ -4572,6 +4795,61 @@ svn_wc_copy(const char *src_path, /*** From merge.c ***/ svn_error_t * +svn_wc_merge5(enum svn_wc_merge_outcome_t *merge_content_outcome, + enum svn_wc_notify_state_t *merge_props_outcome, + svn_wc_context_t *wc_ctx, + const char *left_abspath, + const char *right_abspath, + const char *target_abspath, + const char *left_label, + const char *right_label, + const char *target_label, + const svn_wc_conflict_version_t *left_version, + const svn_wc_conflict_version_t *right_version, + svn_boolean_t dry_run, + const char *diff3_cmd, + const apr_array_header_t *merge_options, + apr_hash_t *original_props, + const apr_array_header_t *prop_diff, + svn_wc_conflict_resolver_func2_t conflict_func, + void *conflict_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool) +{ + svn_boolean_t store_pristine; + + SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, target_abspath, + scratch_pool)); + if (!store_pristine) + return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL); + + SVN_ERR(svn_wc_merge6(merge_content_outcome, + merge_props_outcome, + wc_ctx, + left_abspath, + right_abspath, + target_abspath, + left_label, + right_label, + target_label, + left_version, + right_version, + dry_run, + diff3_cmd, + merge_options, + original_props, + prop_diff, + conflict_func, + conflict_baton, + cancel_func, + cancel_baton, + scratch_pool)); + + return SVN_NO_ERROR; +} + +svn_error_t * svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome, svn_wc_context_t *wc_ctx, const char *left_abspath, @@ -4901,7 +5179,7 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx, void *notify_baton, apr_pool_t *scratch_pool) { - return svn_wc__upgrade(wc_ctx, local_abspath, SVN_WC__DEFAULT_VERSION, + return svn_wc__upgrade(wc_ctx, local_abspath, SVN_WC__DEFAULT_VERSION, TRUE, repos_info_func, repos_info_baton, cancel_func, cancel_baton, notify_func, notify_baton, Modified: subversion/trunk/subversion/libsvn_wc/diff_editor.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff_editor.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/diff_editor.c (original) +++ subversion/trunk/subversion/libsvn_wc/diff_editor.c Tue Dec 13 09:49:29 2022 @@ -75,6 +75,7 @@ #include "adm_files.h" #include "translate.h" #include "diff.h" +#include "textbase.h" #include "svn_private_config.h" @@ -476,15 +477,17 @@ svn_wc__diff_base_working_diff(svn_wc__d if (skip) return SVN_NO_ERROR; - SVN_ERR(svn_wc__db_pristine_get_path(&pristine_file, - db, local_abspath, checksum, - scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__textbase_setaside(&pristine_file, + db, local_abspath, checksum, + cancel_func, cancel_baton, + scratch_pool, scratch_pool)); if (diff_pristine) - SVN_ERR(svn_wc__db_pristine_get_path(&local_file, - db, local_abspath, - working_checksum, - scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__textbase_setaside(&local_file, + db, local_abspath, + working_checksum, + cancel_func, cancel_baton, + scratch_pool, scratch_pool)); else if (! (had_props || props_mod)) local_file = local_abspath; else if (files_same) @@ -1019,8 +1022,9 @@ svn_wc__diff_local_only_file(svn_wc__db_ right_props = svn_prop_hash_dup(pristine_props, scratch_pool); if (checksum) - SVN_ERR(svn_wc__db_pristine_get_path(&pristine_file, db, local_abspath, - checksum, scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__textbase_setaside(&pristine_file, db, local_abspath, + checksum, cancel_func, cancel_baton, + scratch_pool, scratch_pool)); else pristine_file = NULL; @@ -1415,9 +1419,10 @@ svn_wc__diff_base_only_file(svn_wc__db_t if (skip) return SVN_NO_ERROR; - SVN_ERR(svn_wc__db_pristine_get_path(&pristine_file, - db, local_abspath, checksum, - scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__textbase_setaside(&pristine_file, + db, local_abspath, checksum, + NULL, NULL, + scratch_pool, scratch_pool)); SVN_ERR(processor->file_deleted(relpath, left_src, @@ -2111,17 +2116,17 @@ apply_textdelta(void *file_baton, pool)); } - SVN_ERR(svn_wc__db_pristine_read(&source, NULL, - eb->db, fb->local_abspath, - fb->base_checksum, - pool, pool)); + SVN_ERR(svn_wc__textbase_get_contents(&source, + eb->db, fb->local_abspath, + fb->base_checksum, FALSE, + pool, pool)); } else if (fb->base_checksum) { - SVN_ERR(svn_wc__db_pristine_read(&source, NULL, - eb->db, fb->local_abspath, - fb->base_checksum, - pool, pool)); + SVN_ERR(svn_wc__textbase_get_contents(&source, + eb->db, fb->local_abspath, + fb->base_checksum, FALSE, + pool, pool)); } else source = svn_stream_empty(pool); @@ -2217,10 +2222,11 @@ close_file(void *file_baton, if (! repos_file) { assert(fb->base_checksum); - SVN_ERR(svn_wc__db_pristine_get_path(&repos_file, - eb->db, eb->anchor_abspath, - fb->base_checksum, - scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__textbase_setaside(&repos_file, + eb->db, fb->local_abspath, + fb->base_checksum, + eb->cancel_func, eb->cancel_baton, + scratch_pool, scratch_pool)); } } @@ -2253,10 +2259,11 @@ close_file(void *file_baton, eb->db, fb->local_abspath, scratch_pool, scratch_pool)); assert(checksum); - SVN_ERR(svn_wc__db_pristine_get_path(&localfile, - eb->db, eb->anchor_abspath, - checksum, - scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__textbase_setaside(&localfile, + eb->db, fb->local_abspath, + checksum, + eb->cancel_func, eb->cancel_baton, + scratch_pool, scratch_pool)); } else { Modified: subversion/trunk/subversion/libsvn_wc/diff_local.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff_local.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/diff_local.c (original) +++ subversion/trunk/subversion/libsvn_wc/diff_local.c Tue Dec 13 09:49:29 2022 @@ -547,7 +547,7 @@ svn_wc__diff7(svn_boolean_t anchor_at_gi } svn_error_t * -svn_wc_diff6(svn_wc_context_t *wc_ctx, +svn_wc_diff7(svn_wc_context_t *wc_ctx, const char *local_abspath, const svn_wc_diff_callbacks4_t *callbacks, void *callback_baton, Modified: subversion/trunk/subversion/libsvn_wc/externals.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/externals.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/externals.c (original) +++ subversion/trunk/subversion/libsvn_wc/externals.c Tue Dec 13 09:49:29 2022 @@ -53,6 +53,7 @@ #include "translate.h" #include "workqueue.h" #include "conflicts.h" +#include "textbase.h" #include "svn_private_config.h" @@ -631,19 +632,21 @@ apply_textdelta(void *file_baton, pool))); } - SVN_ERR(svn_wc__db_pristine_read(&src_stream, NULL, eb->db, - eb->wri_abspath, eb->original_checksum, - pool, pool)); + SVN_ERR(svn_wc__textbase_get_contents(&src_stream, eb->db, + eb->local_abspath, + eb->original_checksum, + FALSE, pool, pool)); } else src_stream = svn_stream_empty(pool); - SVN_ERR(svn_wc__db_pristine_prepare_install(&dest_stream, - &eb->install_data, - &eb->new_sha1_checksum, - &eb->new_md5_checksum, - eb->db, eb->wri_abspath, - eb->pool, pool)); + SVN_ERR(svn_wc__textbase_prepare_install(&dest_stream, + &eb->install_data, + &eb->new_sha1_checksum, + &eb->new_md5_checksum, + eb->db, eb->local_abspath, + TRUE, + eb->pool, pool)); svn_txdelta_apply2(src_stream, dest_stream, NULL, eb->local_abspath, pool, handler, handler_baton); @@ -887,13 +890,43 @@ close_file(void *file_baton, } if (install_pristine) { + svn_stream_t *contents; + const char *tmpdir_abspath; + svn_stream_t *tmpstream; + const char *tmpfile_abspath; + + SVN_ERR(svn_wc__db_pristine_read(&contents, NULL, eb->db, + eb->wri_abspath, + eb->new_sha1_checksum, + pool, pool)); + if (!contents) + return svn_error_create(SVN_ERR_WC_PRISTINE_DEHYDRATED, + NULL, NULL); + + SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, + eb->db, eb->wri_abspath, + pool, pool)); + SVN_ERR(svn_stream_open_unique(&tmpstream, &tmpfile_abspath, + tmpdir_abspath, + svn_io_file_del_none, + pool, pool)); + SVN_ERR(svn_stream_copy3(contents, tmpstream, eb->cancel_func, + eb->cancel_baton, pool)); + SVN_ERR(svn_wc__wq_build_file_install(&work_item, eb->db, eb->local_abspath, - NULL, + tmpfile_abspath, eb->use_commit_times, TRUE, pool, pool)); all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool); + + SVN_ERR(svn_wc__wq_build_file_remove(&work_item, eb->db, + eb->wri_abspath, + tmpfile_abspath, + pool, pool)); + + all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool); } } else @@ -1207,8 +1240,8 @@ svn_wc__crawl_file_external(svn_wc_conte if (disk_kind == svn_node_none) { - err = svn_wc_restore(wc_ctx, local_abspath, use_commit_times, - scratch_pool); + err = svn_wc_restore2(wc_ctx, local_abspath, use_commit_times, + scratch_pool); if (err) { Modified: subversion/trunk/subversion/libsvn_wc/info.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/info.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/info.c (original) +++ subversion/trunk/subversion/libsvn_wc/info.c Tue Dec 13 09:49:29 2022 @@ -106,8 +106,9 @@ build_info_for_node(svn_wc__info2_t **in wc_info->copyfrom_rev = SVN_INVALID_REVNUM; - SVN_ERR(svn_wc__db_get_format(&wc_info->wc_format, - db, local_abspath, scratch_pool)); + SVN_ERR(svn_wc__db_get_settings(&wc_info->wc_format, + &wc_info->store_pristine, + db, local_abspath, scratch_pool)); SVN_ERR(svn_wc__db_read_info(&status, &db_kind, &tmpinfo->rev, &repos_relpath, @@ -556,3 +557,16 @@ svn_wc__get_info(svn_wc_context_t *wc_ct return SVN_NO_ERROR; } + +svn_error_t * +svn_wc__get_settings(int *format_p, + svn_boolean_t *store_pristine_p, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *scratch_pool) +{ + SVN_ERR(svn_wc__db_get_settings(format_p, store_pristine_p, wc_ctx->db, + local_abspath, scratch_pool)); + + return SVN_NO_ERROR; +} Modified: subversion/trunk/subversion/libsvn_wc/merge.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/merge.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/merge.c (original) +++ subversion/trunk/subversion/libsvn_wc/merge.c Tue Dec 13 09:49:29 2022 @@ -1202,7 +1202,7 @@ svn_wc__internal_merge(svn_skel_t **work svn_error_t * -svn_wc_merge5(enum svn_wc_merge_outcome_t *merge_content_outcome, +svn_wc_merge6(enum svn_wc_merge_outcome_t *merge_content_outcome, enum svn_wc_notify_state_t *merge_props_outcome, svn_wc_context_t *wc_ctx, const char *left_abspath, Modified: subversion/trunk/subversion/libsvn_wc/questions.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/questions.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/questions.c (original) +++ subversion/trunk/subversion/libsvn_wc/questions.c Tue Dec 13 09:49:29 2022 @@ -79,15 +79,14 @@ /* Set *MODIFIED_P to TRUE if (after translation) VERSIONED_FILE_ABSPATH - * (of VERSIONED_FILE_SIZE bytes) differs from PRISTINE_STREAM (of - * PRISTINE_SIZE bytes), else to FALSE if not. + * (of VERSIONED_FILE_SIZE bytes) differs from pristine file with checksum + * PRISTINE_CHECKSUM, else to FALSE if not. * * If EXACT_COMPARISON is FALSE, translate VERSIONED_FILE_ABSPATH's EOL * style and keywords to repository-normal form according to its properties, - * and compare the result with PRISTINE_STREAM. If EXACT_COMPARISON is - * TRUE, translate PRISTINE_STREAM's EOL style and keywords to working-copy - * form according to VERSIONED_FILE_ABSPATH's properties, and compare the - * result with VERSIONED_FILE_ABSPATH. + * calculate checksum and compare the result with PRISTINE_CHECKSUM. + * If EXACT_COMPARISON is TRUE, also check that VERSIONED_FILE_ABSPATH + * contents remains the same when retranslated according to its properties. * * HAS_PROPS should be TRUE if the file had properties when it was not * modified, otherwise FALSE. @@ -95,8 +94,6 @@ * PROPS_MOD should be TRUE if the file's properties have been changed, * otherwise FALSE. * - * PRISTINE_STREAM will be closed before a successful return. - * * DB is a wc_db; use SCRATCH_POOL for temporary allocation. */ static svn_error_t * @@ -104,20 +101,20 @@ compare_and_verify(svn_boolean_t *modifi svn_wc__db_t *db, const char *versioned_file_abspath, svn_filesize_t versioned_file_size, - svn_stream_t *pristine_stream, - svn_filesize_t pristine_size, + const svn_checksum_t *pristine_checksum, svn_boolean_t has_props, svn_boolean_t props_mod, svn_boolean_t exact_comparison, apr_pool_t *scratch_pool) { - svn_boolean_t same; svn_subst_eol_style_t eol_style; const char *eol_str; apr_hash_t *keywords; svn_boolean_t special = FALSE; svn_boolean_t need_translation; svn_stream_t *v_stream; /* versioned_file */ + svn_checksum_t *v_checksum; + svn_error_t *err; SVN_ERR_ASSERT(svn_dirent_is_absolute(versioned_file_abspath)); @@ -133,6 +130,9 @@ compare_and_verify(svn_boolean_t *modifi !exact_comparison, scratch_pool, scratch_pool)); + if (eol_style == svn_subst_eol_style_unknown) + return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL, NULL, NULL); + need_translation = svn_subst_translation_required(eol_style, eol_str, keywords, special, TRUE); @@ -140,13 +140,20 @@ compare_and_verify(svn_boolean_t *modifi else need_translation = FALSE; - if (! need_translation - && (versioned_file_size != pristine_size)) + if (! need_translation) { - *modified_p = TRUE; + svn_filesize_t pristine_size; + + SVN_ERR(svn_wc__db_pristine_read(NULL, &pristine_size, db, + versioned_file_abspath, pristine_checksum, + scratch_pool, scratch_pool)); + + if (versioned_file_size != pristine_size) + { + *modified_p = TRUE; - /* ### Why did we open the pristine? */ - return svn_error_trace(svn_stream_close(pristine_stream)); + return SVN_NO_ERROR; + } } /* ### Other checks possible? */ @@ -162,46 +169,97 @@ compare_and_verify(svn_boolean_t *modifi /* We don't use APR-level buffering because the comparison function * will do its own buffering. */ apr_file_t *file; - SVN_ERR(svn_io_file_open(&file, versioned_file_abspath, APR_READ, - APR_OS_DEFAULT, scratch_pool)); + err = svn_io_file_open(&file, versioned_file_abspath, APR_READ, + APR_OS_DEFAULT, scratch_pool); + /* Convert EACCESS on working copy path to WC specific error code. */ + if (err && APR_STATUS_IS_EACCES(err->apr_err)) + return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL); + else + SVN_ERR(err); v_stream = svn_stream_from_aprfile2(file, FALSE, scratch_pool); if (need_translation) { - if (!exact_comparison) + const char *pristine_eol_str; + + if (eol_style == svn_subst_eol_style_native) + pristine_eol_str = SVN_SUBST_NATIVE_EOL_STR; + else + pristine_eol_str = eol_str; + + if (exact_comparison) { - if (eol_style == svn_subst_eol_style_native) - eol_str = SVN_SUBST_NATIVE_EOL_STR; - else if (eol_style != svn_subst_eol_style_fixed - && eol_style != svn_subst_eol_style_none) - return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL, - svn_stream_close(v_stream), NULL); + svn_checksum_t *working_checksum; + svn_checksum_t *detranslated_checksum; + svn_checksum_t *retranslated_checksum; + + v_stream = svn_stream_checksummed2(v_stream, + &working_checksum, NULL, + pristine_checksum->kind, TRUE, + scratch_pool); + + v_stream = svn_subst_stream_translated(v_stream, + pristine_eol_str, TRUE, + keywords, FALSE, + scratch_pool); + v_stream = svn_stream_checksummed2(v_stream, + &detranslated_checksum, NULL, + pristine_checksum->kind, TRUE, + scratch_pool); + + v_stream = svn_subst_stream_translated(v_stream, eol_str, FALSE, + keywords, TRUE, + scratch_pool); + v_stream = svn_stream_checksummed2(v_stream, + &retranslated_checksum, NULL, + pristine_checksum->kind, TRUE, + scratch_pool); + + err = svn_stream_copy3(v_stream, svn_stream_empty(scratch_pool), + NULL, NULL, scratch_pool); + /* Convert EACCESS on working copy path to WC specific error code. */ + if (err && APR_STATUS_IS_EACCES(err->apr_err)) + return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL); + else + SVN_ERR(err); + + if (svn_checksum_match(detranslated_checksum, pristine_checksum) && + svn_checksum_match(working_checksum, retranslated_checksum)) + { + *modified_p = FALSE; + } + else + { + *modified_p = TRUE; + } + return SVN_NO_ERROR; + } + else + { /* Wrap file stream to detranslate into normal form, * "repairing" the EOL style if it is inconsistent. */ v_stream = svn_subst_stream_translated(v_stream, - eol_str, + pristine_eol_str, TRUE /* repair */, keywords, FALSE /* expand */, scratch_pool); } - else - { - /* Wrap base stream to translate into working copy form, and - * arrange to throw an error if its EOL style is inconsistent. */ - pristine_stream = svn_subst_stream_translated(pristine_stream, - eol_str, FALSE, - keywords, TRUE, - scratch_pool); - } } } - SVN_ERR(svn_stream_contents_same2(&same, pristine_stream, v_stream, - scratch_pool)); + /* Get checksum of detranslated (normalized) content. */ + err = svn_stream_contents_checksum(&v_checksum, v_stream, + pristine_checksum->kind, + scratch_pool, scratch_pool); + /* Convert EACCESS on working copy path to WC specific error code. */ + if (err && APR_STATUS_IS_EACCES(err->apr_err)) + return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL); + else + SVN_ERR(err); - *modified_p = (! same); + *modified_p = (! svn_checksum_match(v_checksum, pristine_checksum)); return SVN_NO_ERROR; } @@ -213,8 +271,6 @@ svn_wc__internal_file_modified_p(svn_boo svn_boolean_t exact_comparison, apr_pool_t *scratch_pool) { - svn_stream_t *pristine_stream; - svn_filesize_t pristine_size; svn_wc__db_status_t status; svn_node_kind_t kind; const svn_checksum_t *checksum; @@ -302,27 +358,12 @@ svn_wc__internal_file_modified_p(svn_boo } compare_them: - SVN_ERR(svn_wc__db_pristine_read(&pristine_stream, &pristine_size, - db, local_abspath, checksum, - scratch_pool, scratch_pool)); - /* Check all bytes, and verify checksum if requested. */ - { - svn_error_t *err; - err = compare_and_verify(modified_p, db, + SVN_ERR(compare_and_verify(modified_p, db, local_abspath, dirent->filesize, - pristine_stream, pristine_size, - has_props, props_mod, + checksum, has_props, props_mod, exact_comparison, - scratch_pool); - - /* At this point we already opened the pristine file, so we know that - the access denied applies to the working copy path */ - if (err && APR_STATUS_IS_EACCES(err->apr_err)) - return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL); - else - SVN_ERR(err); - } + scratch_pool)); if (!*modified_p) { Modified: subversion/trunk/subversion/libsvn_wc/revert.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/revert.c?rev=1905955&r1=1905954&r2=1905955&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/revert.c (original) +++ subversion/trunk/subversion/libsvn_wc/revert.c Tue Dec 13 09:49:29 2022 @@ -42,6 +42,7 @@ #include "wc.h" #include "adm_files.h" #include "workqueue.h" +#include "textbase.h" #include "svn_private_config.h" #include "private/svn_io_private.h" @@ -714,10 +715,21 @@ revert_wc_data(svn_boolean_t *run_wq, if (kind == svn_node_file) { svn_skel_t *work_item; + const char *install_from; + svn_skel_t *cleanup_work_item; + SVN_ERR(svn_wc__textbase_setaside_wq(&install_from, + &cleanup_work_item, + db, local_abspath, NULL, + cancel_func, cancel_baton, + scratch_pool, scratch_pool)); SVN_ERR(svn_wc__wq_build_file_install(&work_item, db, local_abspath, - NULL, use_commit_times, TRUE, + install_from, + use_commit_times, TRUE, scratch_pool, scratch_pool)); + work_item = svn_wc__wq_merge(work_item, cleanup_work_item, + scratch_pool); + SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool)); *run_wq = TRUE; @@ -969,7 +981,7 @@ revert_partial(svn_wc__db_t *db, svn_error_t * -svn_wc_revert6(svn_wc_context_t *wc_ctx, +svn_wc_revert7(svn_wc_context_t *wc_ctx, const char *local_abspath, svn_depth_t depth, svn_boolean_t use_commit_times,
