47
47
#include "svn_props.h"
49
49
#include "client.h"
50
#include "private/svn_ra_private.h"
51
#include "private/svn_sorts_private.h"
50
52
#include "private/svn_subr_private.h"
51
#include "private/svn_ra_private.h"
52
53
#include "private/svn_magic.h"
54
55
#include "svn_private_config.h"
56
/* Import context baton.
58
### TODO: Add the following items to this baton:
59
/` import editor/baton. `/
60
const svn_delta_editor_t *editor;
63
/` Client context baton `/
64
svn_client_ctx_t `ctx;
66
/` Paths (keys) excluded from the import (values ignored) `/
57
/* Import context baton. */
69
59
typedef struct import_ctx_t
71
61
/* Whether any changes were made to the repository */
656
655
void *root_baton;
657
656
apr_array_header_t *batons = NULL;
658
657
const char *edit_path = "";
659
import_ctx_t *import_ctx = apr_pcalloc(pool, sizeof(*import_ctx));
658
import_ctx_t import_ctx = { FALSE };
660
659
const svn_io_dirent2_t *dirent;
662
import_ctx->autoprops = autoprops;
663
svn_magic__init(&import_ctx->magic_cookie, pool);
665
/* Get a root dir baton. We pass an invalid revnum to open_root
666
to mean "base this on the youngest revision". Should we have an
667
SVN_YOUNGEST_REVNUM defined for these purposes? */
668
SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM,
661
*updated_repository = FALSE;
663
import_ctx.autoprops = autoprops;
664
SVN_ERR(svn_magic__init(&import_ctx.magic_cookie, ctx->config, pool));
666
/* Get a root dir baton. We pass the revnum we used for testing our
667
assumptions and obtaining inherited properties. */
668
SVN_ERR(editor->open_root(edit_baton, base_rev, pool, &root_baton));
671
670
/* Import a file or a directory tree. */
672
671
SVN_ERR(svn_io_stat_dirent2(&dirent, local_abspath, FALSE, FALSE,
847
SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
849
867
SVN_ERR(svn_client_open_ra_session2(&ra_session, url, NULL,
850
868
ctx, scratch_pool, iterpool));
870
SVN_ERR(svn_ra_get_latest_revnum(ra_session, &base_rev, iterpool));
852
872
/* Figure out all the path components we need to create just to have
853
873
a place to stick our imported tree. */
854
SVN_ERR(svn_ra_check_path(ra_session, "", SVN_INVALID_REVNUM, &kind,
874
SVN_ERR(svn_ra_check_path(ra_session, "", base_rev, &kind, iterpool));
857
876
/* We can import into directories, but if a file already exists, that's
895
913
SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table,
896
914
log_msg, ctx, scratch_pool));
916
/* Obtain properties before opening the commit editor, as at that point we are
917
not allowed to use the existing ra-session */
918
if (! no_ignore /*|| ! no_autoprops*/)
920
SVN_ERR(svn_ra_get_dir2(ra_session, NULL, NULL, &url_props, "",
921
base_rev, SVN_DIRENT_KIND, scratch_pool));
923
SVN_ERR(svn_ra_get_inherited_props(ra_session, &inherited_props, "", base_rev,
924
scratch_pool, iterpool));
898
927
/* Fetch RA commit editor. */
899
928
SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
900
929
svn_client__get_shim_callbacks(ctx->wc_ctx,
907
936
/* Get inherited svn:auto-props, svn:global-ignores, and
908
937
svn:ignores for the location we are importing to. */
909
938
if (!no_autoprops)
910
SVN_ERR(svn_client__get_all_auto_props(&autoprops, url, ctx,
911
scratch_pool, iterpool));
940
/* ### This should use inherited_props and url_props to avoid creating
941
another ra session to obtain the same values, but using a possibly
942
different HEAD revision */
943
SVN_ERR(svn_client__get_all_auto_props(&autoprops, url, ctx,
944
scratch_pool, iterpool));
914
948
global_ignores = NULL;
919
svn_opt_revision_t rev;
920
953
apr_array_header_t *config_ignores;
921
apr_hash_t *local_ignores_hash;
923
SVN_ERR(svn_client__get_inherited_ignores(&global_ignores, url, ctx,
924
scratch_pool, iterpool));
957
global_ignores = apr_array_make(scratch_pool, 64, sizeof(const char *));
925
959
SVN_ERR(svn_wc_get_default_ignores(&config_ignores, ctx->config,
927
961
global_ignores = apr_array_append(scratch_pool, global_ignores,
930
rev.kind = svn_opt_revision_head;
931
SVN_ERR(svn_client_propget5(&local_ignores_hash, NULL, SVN_PROP_IGNORE, url,
932
&rev, &rev, NULL, svn_depth_empty, NULL, ctx,
933
scratch_pool, scratch_pool));
964
val = svn_hash_gets(url_props, SVN_PROP_INHERITABLE_IGNORES);
966
svn_cstring_split_append(global_ignores, val->data, "\n\r\t\v ",
967
FALSE, scratch_pool);
969
for (i = 0; i < inherited_props->nelts; i++)
971
svn_prop_inherited_item_t *elt = APR_ARRAY_IDX(
972
inherited_props, i, svn_prop_inherited_item_t *);
974
val = svn_hash_gets(elt->prop_hash, SVN_PROP_INHERITABLE_IGNORES);
977
svn_cstring_split_append(global_ignores, val->data, "\n\r\t\v ",
978
FALSE, scratch_pool);
934
980
local_ignores_arr = apr_array_make(scratch_pool, 1, sizeof(const char *));
936
if (apr_hash_count(local_ignores_hash))
982
val = svn_hash_gets(url_props, SVN_PROP_IGNORE);
938
svn_string_t *propval = svn_hash_gets(local_ignores_hash, url);
941
svn_cstring_split_append(local_ignores_arr, propval->data,
942
"\n\r\t\v ", FALSE, scratch_pool);
986
svn_cstring_split_append(local_ignores_arr, val->data,
987
"\n\r\t\v ", FALSE, scratch_pool);
947
/* If an error occurred during the commit, abort the edit and return
948
the error. We don't even care if the abort itself fails. */
949
if ((err = import(local_abspath, new_entries, editor, edit_baton,
950
depth, excludes, autoprops, local_ignores_arr,
951
global_ignores, no_ignore, no_autoprops,
952
ignore_unknown_node_types, filter_callback,
953
filter_baton, ctx, iterpool)))
991
/* If an error occurred during the commit, properly abort the edit. */
992
err = svn_error_trace(import(&updated_repository,
993
local_abspath, url, new_entries, editor,
994
edit_baton, depth, base_rev, excludes,
995
autoprops, local_ignores_arr, global_ignores,
996
no_ignore, no_autoprops,
997
ignore_unknown_node_types, filter_callback,
998
filter_baton, ctx, iterpool));
1000
svn_pool_destroy(iterpool);
1002
if (err || !updated_repository)
955
1004
return svn_error_compose_create(
957
editor->abort_edit(edit_baton, iterpool));
1006
editor->abort_edit(edit_baton, scratch_pool));
960
svn_pool_destroy(iterpool);
962
1009
return SVN_NO_ERROR;