You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2011/05/08 14:48:21 UTC
svn commit: r1100727 - in /subversion/trunk/subversion:
include/private/svn_wc_private.h libsvn_wc/externals.c
Author: rhuijben
Date: Sun May 8 12:48:20 2011
New Revision: 1100727
URL: http://svn.apache.org/viewvc?rev=1100727&view=rev
Log:
Checkpoint my work in progress on the file external editor. This code is
currently still unused but should be fully operational in the next few
days (if not hours).
* subversion/include/private/svn_wc_private.h
(svn_wc__get_file_external_editor): Update argument list with requirements
for the backend and the caller.
* subversion/libsvn_wc/externals.c
(includes): Remove a few unused headers. Add adm_files.h
(edit_baton): Add many new variables.
(add_file): Use edit baton as file baton.
(open_file): Retrieve the information we need for updating.
(apply_textdelta): Handle incoming file changes.
(change_file_prop): Store property changes.
(close_file): Verify the result of apply_textdelta.
(svn_wc__get_file_external_editor): Store more information in the baton.
Modified:
subversion/trunk/subversion/include/private/svn_wc_private.h
subversion/trunk/subversion/libsvn_wc/externals.c
Modified: subversion/trunk/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_wc_private.h?rev=1100727&r1=1100726&r2=1100727&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_wc_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_wc_private.h Sun May 8 12:48:20 2011
@@ -77,12 +77,15 @@ svn_wc__set_file_external_location(svn_w
svn_error_t *
svn_wc__get_file_external_editor(const svn_delta_editor_t **editor,
void **edit_baton,
- const char *switch_url,
svn_revnum_t *target_revision,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
+ const char *url,
+ const char *repos_root_url,
+ const char *repos_uuid,
svn_boolean_t use_commit_times,
const char *diff3_cmd,
+ const apr_array_header_t *preserved_exts,
svn_wc_conflict_resolver_func2_t conflict_func,
void *conflict_baton,
svn_cancel_func_t cancel_func,
Modified: subversion/trunk/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/externals.c?rev=1100727&r1=1100726&r2=1100727&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/externals.c (original)
+++ subversion/trunk/subversion/libsvn_wc/externals.c Sun May 8 12:48:20 2011
@@ -29,8 +29,6 @@
#include <apr_pools.h>
#include <apr_hash.h>
#include <apr_tables.h>
-#include <apr_file_io.h>
-#include <apr_strings.h>
#include <apr_general.h>
#include "svn_types.h"
@@ -44,10 +42,10 @@
#include "svn_hash.h"
#include "svn_wc.h"
-#include "private/svn_mergeinfo_private.h"
#include "private/svn_skel.h"
#include "wc.h"
+#include "adm_files.h"
#include "props.h"
#include "translate.h"
#include "workqueue.h"
@@ -378,11 +376,35 @@ struct edit_baton
apr_pool_t *pool;
svn_wc__db_t *db;
+ const char *wri_abspath;
const char *local_abspath;
const char *name;
+ /* Information from the caller */
+ svn_boolean_t use_commit_times;
+
+ const char *url;
+ const char *repos_root_url;
+ const char *repos_uuid;
+
+ svn_cancel_func_t cancel_func;
+ void *cancel_baton;
+ svn_wc_notify_func2_t notify_func;
+ void *notify_baton;
+
svn_revnum_t *target_revision;
- svn_revnum_t base_revision;
+
+ /* What was there before the update */
+ svn_revnum_t original_revision;
+ const svn_checksum_t *original_checksum;
+
+ /* What we are installing now */
+ const char *new_pristine_abspath;
+ svn_checksum_t *new_sha1_checksum;
+ svn_checksum_t *new_md5_checksum;
+
+ /* List of incoming propchanges */
+ apr_array_header_t *propchanges;
};
/* svn_delta_editor_t function for svn_wc__get_file_external_editor */
@@ -425,7 +447,8 @@ add_file(const char *path,
svn_dirent_local_style(eb->local_abspath,
file_pool));
- eb->base_revision = SVN_INVALID_REVNUM;
+ *file_baton = eb;
+ eb->original_revision = SVN_INVALID_REVNUM;
return SVN_NO_ERROR;
}
@@ -439,25 +462,88 @@ open_file(const char *path,
void **file_baton)
{
struct edit_baton *eb = parent_baton;
+ svn_wc__db_status_t status;
+ svn_wc__db_kind_t kind;
+ svn_boolean_t update_root;
if (strcmp(path, eb->name))
return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
_("This editor can only update '%s'"),
svn_dirent_local_style(eb->local_abspath,
file_pool));
- eb->base_revision = base_revision;
+ *file_baton = eb;
+ SVN_ERR(svn_wc__db_base_get_info(&status, &kind, &eb->original_revision,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ &eb->original_checksum,
+ NULL, NULL, NULL, &update_root, NULL,
+ eb->db, eb->local_abspath,
+ eb->pool, file_pool));
+ if (kind != svn_wc__db_kind_file
+ || status != svn_wc__db_status_normal
+ || !update_root)
+ 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,
+ file_pool));
return SVN_NO_ERROR;
}
/* svn_delta_editor_t function for svn_wc__get_file_external_editor */
static svn_error_t *
apply_textdelta(void *file_baton,
- const char *base_checksum,
+ const char *base_checksum_digest,
apr_pool_t *pool,
svn_txdelta_window_handler_t *handler,
void **handler_baton)
{
+ struct edit_baton *eb = file_baton;
+ svn_stream_t *src_stream;
+ svn_stream_t *dest_stream;
+
+ if (eb->original_checksum)
+ {
+ if (base_checksum_digest)
+ {
+ svn_checksum_t *expected_checksum;
+ const svn_checksum_t *original_md5;
+
+ SVN_ERR(svn_checksum_parse_hex(&expected_checksum, svn_checksum_md5,
+ base_checksum_digest, pool));
+
+ if (eb->original_checksum->kind != svn_checksum_md5)
+ SVN_ERR(svn_wc__db_pristine_get_md5(&original_md5,
+ eb->db, eb->wri_abspath,
+ eb->original_checksum,
+ pool, pool));
+ else
+ original_md5 = eb->original_checksum;
+
+ if (!svn_checksum_match(expected_checksum, original_md5))
+ return svn_error_return(svn_checksum_mismatch_err(
+ expected_checksum,
+ original_md5,
+ pool,
+ _("Base checksum mismatch for '%s'"),
+ svn_dirent_local_style(eb->local_abspath,
+ pool)));
+ }
+
+ SVN_ERR(svn_wc__db_pristine_read(&src_stream, NULL, eb->db,
+ eb->wri_abspath, eb->original_checksum,
+ pool, pool));
+ }
+ else
+ src_stream = svn_stream_empty(pool);
+
+ SVN_ERR(svn_wc__open_writable_base(&dest_stream, &eb->new_pristine_abspath,
+ &eb->new_md5_checksum,
+ &eb->new_sha1_checksum,
+ eb->db, eb->wri_abspath,
+ pool, pool));
+
+ svn_txdelta_apply(src_stream, dest_stream, NULL, eb->local_abspath, pool,
+ handler, handler_baton);
return SVN_NO_ERROR;
}
@@ -469,27 +555,141 @@ change_file_prop(void *file_baton,
const svn_string_t *value,
apr_pool_t *pool)
{
+ struct edit_baton *eb = file_baton;
+ svn_prop_t *propchange;
+
+ propchange = apr_array_push(eb->propchanges);
+ propchange->name = apr_pstrdup(eb->pool, name);
+ propchange->value = value ? svn_string_dup(value, eb->pool) : NULL;
+
return SVN_NO_ERROR;
}
/* svn_delta_editor_t function for svn_wc__get_file_external_editor */
static svn_error_t *
close_file(void *file_baton,
- const char *text_checksum,
+ const char *expected_md5_digest,
apr_pool_t *pool)
{
+ struct edit_baton *eb = file_baton;
+
+ if (expected_md5_digest)
+ {
+ svn_checksum_t *expected_md5_checksum;
+ const svn_checksum_t *actual_md5_checksum = eb->new_md5_checksum;
+
+ SVN_ERR(svn_checksum_parse_hex(&expected_md5_checksum, svn_checksum_md5,
+ expected_md5_digest, pool));
+
+ if (actual_md5_checksum == NULL)
+ {
+ SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ &actual_md5_checksum, NULL, NULL,
+ NULL, NULL, NULL,
+ eb->db, eb->local_abspath,
+ pool, pool));
+
+ if (actual_md5_checksum != NULL
+ && actual_md5_checksum->kind != svn_checksum_md5)
+ {
+ SVN_ERR(svn_wc__db_pristine_get_md5(&actual_md5_checksum,
+ eb->db, eb->wri_abspath,
+ actual_md5_checksum,
+ pool, pool));
+ }
+ }
+
+ if (! svn_checksum_match(expected_md5_checksum, actual_md5_checksum))
+ return svn_checksum_mismatch_err(
+ expected_md5_checksum,
+ actual_md5_checksum, pool,
+ _("Checksum mismatch for '%s'"),
+ svn_dirent_local_style(eb->local_abspath, pool));
+ }
+
+ if (eb->new_sha1_checksum)
+ SVN_ERR(svn_wc__db_pristine_install(eb->db, eb->new_pristine_abspath,
+ eb->new_sha1_checksum,
+ eb->new_md5_checksum, pool));
+
+ /* ### TODO: Merge the changes */
+
+ {
+ svn_skel_t *work_items;
+ const char *repos_relpath = svn_uri_is_child(eb->repos_root_url,
+ eb->url, pool);
+
+ /* ###### COMPLETE HACK: This just overwrites whatever there was.
+ ###### Don't enable this code */
+/* SVN_ERR(svn_wc__wq_build_file_install(&work_items, eb->db,
+ eb->local_abspath,
+ NULL, eb->use_commit_times, TRUE,
+ pool, pool));
+
+ SVN_ERR(svn_wc__db_base_add_file(eb->db, eb->local_abspath,
+ repos_relpath,
+ eb->repos_root_url,
+ eb->repos_uuid,
+ *eb->target_revision,
+ apr_hash_make(pool),
+ 1,
+ 1,
+ "somebody",
+ eb->new_sha1_checksum,
+ NULL, NULL,
+ FALSE, NULL,
+ FALSE, FALSE,
+ work_items,
+ pool));
+
+ {
+ svn_opt_revision_t peg_rev, rev;
+ peg_rev.kind = svn_opt_revision_number;
+ peg_rev.value.number = *eb->target_revision;
+ rev.kind = svn_opt_revision_number;
+ rev.value.number = *eb->target_revision;
+ SVN_ERR(svn_wc__db_temp_op_set_file_external(eb->db, eb->local_abspath,
+ repos_relpath, &peg_rev,
+ &rev, pool));
+ }
+
+ SVN_ERR(svn_wc__wq_run(eb->db, eb->wri_abspath,
+ eb->cancel_func, eb->cancel_baton, pool));*/
+ }
+
+ if (eb->notify_func)
+ {
+ svn_wc_notify_action_t action;
+ svn_wc_notify_t *notify;
+
+ if (SVN_IS_VALID_REVNUM(eb->original_revision))
+ action = svn_wc_notify_update_update;
+ else
+ action = svn_wc_notify_update_add;
+
+ notify = svn_wc_create_notify(eb->local_abspath, action, pool);
+ notify->old_revision = eb->original_revision;
+ notify->revision = *eb->target_revision;
+
+ eb->notify_func(eb->notify_baton, notify, pool);
+ }
+
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__get_file_external_editor(const svn_delta_editor_t **editor,
void **edit_baton,
- const char *switch_url,
svn_revnum_t *target_revision,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
+ const char *url,
+ const char *repos_root_url,
+ const char *repos_uuid,
svn_boolean_t use_commit_times,
const char *diff3_cmd,
+ const apr_array_header_t *preserved_exts,
svn_wc_conflict_resolver_func2_t conflict_func,
void *conflict_baton,
svn_cancel_func_t cancel_func,
@@ -507,9 +707,23 @@ svn_wc__get_file_external_editor(const s
eb->pool = edit_pool;
eb->db = db;
eb->local_abspath = apr_pstrdup(edit_pool, local_abspath);
+ eb->wri_abspath = svn_dirent_dirname(local_abspath, edit_pool);
eb->name = svn_dirent_basename(eb->local_abspath, NULL);
eb->target_revision = target_revision;
+ eb->url = apr_pstrdup(edit_pool, url);
+ eb->repos_root_url = apr_pstrdup(edit_pool, repos_root_url);
+ eb->repos_uuid = apr_pstrdup(edit_pool, repos_uuid);
+
+ eb->use_commit_times = use_commit_times;
+
+ eb->cancel_func = cancel_func;
+ eb->cancel_baton = cancel_baton;
+ eb->notify_func = notify_func;
+ eb->notify_baton = notify_baton;
+
+ eb->propchanges = apr_array_make(edit_pool, 1, sizeof(svn_prop_t));
+
tree_editor->open_root = open_root;
tree_editor->set_target_revision = set_target_revision;
tree_editor->add_file = add_file;