summaryrefslogtreecommitdiff
path: root/subversion/libsvn_client/import.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_client/import.c')
-rw-r--r--subversion/libsvn_client/import.c84
1 files changed, 57 insertions, 27 deletions
diff --git a/subversion/libsvn_client/import.c b/subversion/libsvn_client/import.c
index b5ee0776def77..ae67e9ad43b57 100644
--- a/subversion/libsvn_client/import.c
+++ b/subversion/libsvn_client/import.c
@@ -73,32 +73,59 @@ typedef struct import_ctx_t
apr_hash_t *autoprops;
} import_ctx_t;
+typedef struct open_txdelta_stream_baton_t
+{
+ svn_boolean_t need_reset;
+ svn_stream_t *stream;
+} open_txdelta_stream_baton_t;
+
+/* Implements svn_txdelta_stream_open_func_t */
+static svn_error_t *
+open_txdelta_stream(svn_txdelta_stream_t **txdelta_stream_p,
+ void *baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ open_txdelta_stream_baton_t *b = baton;
+
+ if (b->need_reset)
+ {
+ /* Under rare circumstances, we can be restarted and would need to
+ * supply the delta stream again. In this case, reset the base
+ * stream. */
+ SVN_ERR(svn_stream_reset(b->stream));
+ }
+
+ /* Get the delta stream (delta against the empty string). */
+ svn_txdelta2(txdelta_stream_p, svn_stream_empty(result_pool),
+ b->stream, FALSE, result_pool);
+ b->need_reset = TRUE;
+ return SVN_NO_ERROR;
+}
/* Apply LOCAL_ABSPATH's contents (as a delta against the empty string) to
FILE_BATON in EDITOR. Use POOL for any temporary allocation.
PROPERTIES is the set of node properties set on this file.
- Fill DIGEST with the md5 checksum of the sent file; DIGEST must be
- at least APR_MD5_DIGESTSIZE bytes long. */
+ Return the resulting checksum in *RESULT_MD5_CHECKSUM_P. */
/* ### how does this compare against svn_wc_transmit_text_deltas2() ??? */
static svn_error_t *
-send_file_contents(const char *local_abspath,
+send_file_contents(svn_checksum_t **result_md5_checksum_p,
+ const char *local_abspath,
void *file_baton,
const svn_delta_editor_t *editor,
apr_hash_t *properties,
- unsigned char *digest,
apr_pool_t *pool)
{
svn_stream_t *contents;
- svn_txdelta_window_handler_t handler;
- void *handler_baton;
const svn_string_t *eol_style_val = NULL, *keywords_val = NULL;
svn_boolean_t special = FALSE;
svn_subst_eol_style_t eol_style;
const char *eol;
apr_hash_t *keywords;
+ open_txdelta_stream_baton_t baton = { 0 };
/* If there are properties, look for EOL-style and keywords ones. */
if (properties)
@@ -111,10 +138,6 @@ send_file_contents(const char *local_abspath,
special = TRUE;
}
- /* Get an editor func that wants to consume the delta stream. */
- SVN_ERR(editor->apply_textdelta(file_baton, NULL, pool,
- &handler, &handler_baton));
-
if (eol_style_val)
svn_subst_eol_style_from_value(&eol_style, &eol, eol_style_val->data);
else
@@ -168,10 +191,17 @@ send_file_contents(const char *local_abspath,
}
}
- /* Send the file's contents to the delta-window handler. */
- return svn_error_trace(svn_txdelta_send_stream(contents, handler,
- handler_baton, digest,
- pool));
+ /* Arrange the stream to calculate the resulting MD5. */
+ contents = svn_stream_checksummed2(contents, result_md5_checksum_p, NULL,
+ svn_checksum_md5, TRUE, pool);
+ /* Send the contents. */
+ baton.need_reset = FALSE;
+ baton.stream = svn_stream_disown(contents, pool);
+ SVN_ERR(editor->apply_textdelta_stream(editor, file_baton, NULL,
+ open_txdelta_stream, &baton, pool));
+ SVN_ERR(svn_stream_close(contents));
+
+ return SVN_NO_ERROR;
}
@@ -198,7 +228,7 @@ import_file(const svn_delta_editor_t *editor,
{
void *file_baton;
const char *mimetype = NULL;
- unsigned char digest[APR_MD5_DIGESTSIZE];
+ svn_checksum_t *result_md5_checksum;
const char *text_checksum;
apr_hash_t* properties;
apr_hash_index_t *hi;
@@ -262,13 +292,11 @@ import_file(const svn_delta_editor_t *editor,
}
/* Now, transmit the file contents. */
- SVN_ERR(send_file_contents(local_abspath, file_baton, editor,
- properties, digest, pool));
+ SVN_ERR(send_file_contents(&result_md5_checksum, local_abspath,
+ file_baton, editor, properties, pool));
/* Finally, close the file. */
- text_checksum =
- svn_checksum_to_cstring(svn_checksum__from_digest_md5(digest, pool), pool);
-
+ text_checksum = svn_checksum_to_cstring(result_md5_checksum, pool);
return svn_error_trace(editor->close_file(file_baton, text_checksum, pool));
}
@@ -577,26 +605,26 @@ import_dir(const svn_delta_editor_t *editor,
}
-/* Recursively import PATH to a repository using EDITOR and
- * EDIT_BATON. PATH can be a file or directory.
+/* Recursively import LOCAL_ABSPATH to a repository using EDITOR and
+ * EDIT_BATON. LOCAL_ABSPATH can be a file or directory.
*
* Sets *UPDATED_REPOSITORY to TRUE when the repository was modified by
* a successfull commit, otherwise to FALSE.
*
- * DEPTH is the depth at which to import PATH; it behaves as for
- * svn_client_import4().
+ * DEPTH is the depth at which to import LOCAL_ABSPATH; it behaves as for
+ * svn_client_import5().
*
* BASE_REV is the revision to use for the root of the commit. We
* checked the preconditions against this revision.
*
* NEW_ENTRIES is an ordered array of path components that must be
* created in the repository (where the ordering direction is
- * parent-to-child). If PATH is a directory, NEW_ENTRIES may be empty
+ * parent-to-child). If LOCAL_ABSPATH is a directory, NEW_ENTRIES may be empty
* -- the result is an import which creates as many new entries in the
* top repository target directory as there are importable entries in
- * the top of PATH; but if NEW_ENTRIES is not empty, its last item is
+ * the top of LOCAL_ABSPATH; but if NEW_ENTRIES is not empty, its last item is
* the name of a new subdirectory in the repository to hold the
- * import. If PATH is a file, NEW_ENTRIES may not be empty, and its
+ * import. If LOCAL_ABSPATH is a file, NEW_ENTRIES may not be empty, and its
* last item is the name used for the file in the repository. If
* NEW_ENTRIES contains more than one item, all but the last item are
* the names of intermediate directories that are created before the
@@ -624,6 +652,8 @@ import_dir(const svn_delta_editor_t *editor,
* If CTX->NOTIFY_FUNC is non-null, invoke it with CTX->NOTIFY_BATON for
* each imported path, passing actions svn_wc_notify_commit_added.
*
+ * URL is used only in the 'commit_finalizing' notification.
+ *
* Use POOL for any temporary allocation.
*
* Note: the repository directory receiving the import was specified