summaryrefslogtreecommitdiff
path: root/subversion/libsvn_delta/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_delta/compat.c')
-rw-r--r--subversion/libsvn_delta/compat.c95
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
};