diff options
Diffstat (limited to 'subversion/libsvn_delta/compat.c')
-rw-r--r-- | subversion/libsvn_delta/compat.c | 95 |
1 files changed, 59 insertions, 36 deletions
diff --git a/subversion/libsvn_delta/compat.c b/subversion/libsvn_delta/compat.c index 470efa2..dfa9743 100644 --- a/subversion/libsvn_delta/compat.c +++ b/subversion/libsvn_delta/compat.c @@ -36,6 +36,8 @@ #include "svn_private_config.h" #include "private/svn_delta_private.h" +#include "private/svn_sorts_private.h" +#include "svn_private_config.h" struct file_rev_handler_wrapper_baton { @@ -188,6 +190,7 @@ struct change_node apr_hash_t *props; /* new/final set of props to apply */ + svn_boolean_t contents_changed; /* the file contents changed */ const char *contents_abspath; /* file containing new fulltext */ svn_checksum_t *checksum; /* checksum of new fulltext */ @@ -292,7 +295,7 @@ get_children(struct ev2_edit_baton *eb, for (hi = apr_hash_first(pool, eb->changes); hi; hi = apr_hash_next(hi)) { - const char *repos_relpath = svn__apr_hash_index_key(hi); + const char *repos_relpath = apr_hash_this_key(hi); const char *child; /* Find potential children. */ @@ -347,17 +350,26 @@ process_actions(struct ev2_edit_baton *eb, return SVN_NO_ERROR; } - if (change->contents_abspath != NULL) + if (change->contents_changed) { /* We can only set text on files. */ /* ### validate we aren't overwriting KIND? */ kind = svn_node_file; - /* ### the checksum might be in CHANGE->CHECKSUM */ - SVN_ERR(svn_io_file_checksum2(&checksum, change->contents_abspath, - svn_checksum_sha1, scratch_pool)); - SVN_ERR(svn_stream_open_readonly(&contents, change->contents_abspath, - scratch_pool, scratch_pool)); + if (change->contents_abspath) + { + /* ### the checksum might be in CHANGE->CHECKSUM */ + SVN_ERR(svn_io_file_checksum2(&checksum, change->contents_abspath, + svn_checksum_sha1, scratch_pool)); + SVN_ERR(svn_stream_open_readonly(&contents, change->contents_abspath, + scratch_pool, scratch_pool)); + } + else + { + contents = svn_stream_empty(scratch_pool); + checksum = svn_checksum_empty_checksum(svn_checksum_sha1, + scratch_pool); + } } if (change->props != NULL) @@ -399,7 +411,7 @@ process_actions(struct ev2_edit_baton *eb, else { /* If this file was added, but apply_txdelta() was not - called (ie. no CONTENTS_ABSPATH), then we're adding + called (i.e., CONTENTS_CHANGED is FALSE), then we're adding an empty file. */ if (change->contents_abspath == NULL) { @@ -440,8 +452,8 @@ process_actions(struct ev2_edit_baton *eb, change->changing, NULL, props)); else SVN_ERR(svn_editor_alter_file(eb->editor, repos_relpath, - change->changing, props, - checksum, contents)); + change->changing, + checksum, contents, props)); } return SVN_NO_ERROR; @@ -789,6 +801,26 @@ window_handler(svn_txdelta_window_t *window, void *baton) return svn_error_trace(err); } +/* Lazy-open handler for getting a read-only stream of the delta base. */ +static svn_error_t * +open_delta_base(svn_stream_t **stream, void *baton, + apr_pool_t *result_pool, apr_pool_t *scratch_pool) +{ + const char *const delta_base = baton; + return svn_stream_open_readonly(stream, delta_base, + result_pool, scratch_pool); +} + +/* Lazy-open handler for opening a stream for the delta result. */ +static svn_error_t * +open_delta_target(svn_stream_t **stream, void *baton, + apr_pool_t *result_pool, apr_pool_t *scratch_pool) +{ + const char **delta_target = baton; + return svn_stream_open_unique(stream, delta_target, NULL, + svn_io_file_del_on_pool_cleanup, + result_pool, scratch_pool); +} static svn_error_t * ev2_apply_textdelta(void *file_baton, @@ -802,10 +834,9 @@ ev2_apply_textdelta(void *file_baton, struct handler_baton *hb = apr_pcalloc(handler_pool, sizeof(*hb)); struct change_node *change; svn_stream_t *target; - /* ### fix this. for now, we know this has a "short" lifetime. */ - apr_pool_t *scratch_pool = handler_pool; change = locate_change(fb->eb, fb->path); + SVN_ERR_ASSERT(!change->contents_changed); SVN_ERR_ASSERT(change->contents_abspath == NULL); SVN_ERR_ASSERT(!SVN_IS_VALID_REVNUM(change->changing) || change->changing == fb->base_revision); @@ -814,12 +845,14 @@ ev2_apply_textdelta(void *file_baton, if (! fb->delta_base) hb->source = svn_stream_empty(handler_pool); else - SVN_ERR(svn_stream_open_readonly(&hb->source, fb->delta_base, handler_pool, - scratch_pool)); + hb->source = svn_stream_lazyopen_create(open_delta_base, + (char*)fb->delta_base, + FALSE, handler_pool); - SVN_ERR(svn_stream_open_unique(&target, &change->contents_abspath, NULL, - svn_io_file_del_on_pool_cleanup, - fb->eb->edit_pool, scratch_pool)); + change->contents_changed = TRUE; + target = svn_stream_lazyopen_create(open_delta_target, + &change->contents_abspath, + FALSE, fb->eb->edit_pool); svn_txdelta_apply(hb->source, target, NULL, NULL, @@ -1106,6 +1139,7 @@ add_file_cb(void *baton, change->kind = svn_node_file; change->deleting = replaces_rev; change->props = svn_prop_hash_dup(props, eb->edit_pool); + change->contents_changed = TRUE; change->contents_abspath = tmp_filename; change->checksum = svn_checksum_dup(md5_checksum, eb->edit_pool); @@ -1183,9 +1217,9 @@ static svn_error_t * alter_file_cb(void *baton, const char *relpath, svn_revnum_t revision, - apr_hash_t *props, const svn_checksum_t *checksum, svn_stream_t *contents, + apr_hash_t *props, apr_pool_t *scratch_pool) { struct editor_baton *eb = baton; @@ -1199,12 +1233,12 @@ alter_file_cb(void *baton, if (contents) { /* We may need to re-checksum these contents */ - if (!(checksum && checksum->kind == svn_checksum_md5)) + if (checksum && checksum->kind == svn_checksum_md5) + md5_checksum = (svn_checksum_t *)checksum; + else contents = svn_stream_checksummed2(contents, &md5_checksum, NULL, svn_checksum_md5, TRUE, scratch_pool); - else - md5_checksum = (svn_checksum_t *)checksum; /* Spool the contents to a tempfile, and provide that to the driver. */ SVN_ERR(svn_stream_open_unique(&tmp_stream, &tmp_filename, NULL, @@ -1223,6 +1257,7 @@ alter_file_cb(void *baton, change->props = svn_prop_hash_dup(props, eb->edit_pool); if (contents != NULL) { + change->contents_changed = TRUE; change->contents_abspath = tmp_filename; change->checksum = svn_checksum_dup(md5_checksum, eb->edit_pool); } @@ -1235,8 +1270,8 @@ static svn_error_t * alter_symlink_cb(void *baton, const char *relpath, svn_revnum_t revision, - apr_hash_t *props, const char *target, + apr_hash_t *props, apr_pool_t *scratch_pool) { /* ### should we verify the kind is truly a symlink? */ @@ -1331,17 +1366,6 @@ move_cb(void *baton, return SVN_NO_ERROR; } -/* This implements svn_editor_cb_rotate_t */ -static svn_error_t * -rotate_cb(void *baton, - const apr_array_header_t *relpaths, - const apr_array_header_t *revisions, - apr_pool_t *scratch_pool) -{ - SVN__NOT_IMPLEMENTED(); -} - - static int count_components(const char *relpath) { @@ -1640,7 +1664,7 @@ apply_change(void **dir_baton, /* Make this an FS path by prepending "/" */ if (copyfrom_url[0] != '/') copyfrom_url = apr_pstrcat(scratch_pool, "/", - copyfrom_url, NULL); + copyfrom_url, SVN_VA_NULL); } copyfrom_rev = change->copyfrom_rev; @@ -1673,7 +1697,7 @@ apply_change(void **dir_baton, else SVN_ERR(drive_ev1_props(eb, relpath, change, file_baton, scratch_pool)); - if (change->contents_abspath) + if (change->contents_changed && change->contents_abspath) { svn_txdelta_window_handler_t handler; void *handler_baton; @@ -1889,7 +1913,6 @@ svn_delta__editor_from_delta(svn_editor_t **editor_p, delete_cb, copy_cb, move_cb, - rotate_cb, complete_cb, abort_cb }; |