2 * copy-cmd.c -- Subversion copy command
4 * ====================================================================
5 * Copyright (c) 2000-2007 CollabNet. All rights reserved.
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
13 * This software consists of voluntary contributions made by many
14 * individuals. For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
19 /* ==================================================================== */
25 #include "svn_client.h"
27 #include "svn_error.h"
30 #include "svn_private_config.h"
35 /* This implements the `svn_opt_subcommand_t' interface. */
37 svn_cl__copy(apr_getopt_t
*os
,
41 svn_cl__opt_state_t
*opt_state
= ((svn_cl__cmd_baton_t
*) baton
)->opt_state
;
42 svn_client_ctx_t
*ctx
= ((svn_cl__cmd_baton_t
*) baton
)->ctx
;
43 apr_array_header_t
*targets
, *sources
;
44 const char *src_path
, *dst_path
;
45 svn_boolean_t srcs_are_urls
, dst_is_url
;
46 svn_commit_info_t
*commit_info
= NULL
;
50 SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets
, os
,
53 if (targets
->nelts
< 2)
54 return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS
, 0, NULL
);
56 /* Get the src list and associated peg revs */
57 sources
= apr_array_make(pool
, targets
->nelts
- 1,
58 sizeof(svn_client_copy_source_t
*));
59 for (i
= 0; i
< (targets
->nelts
- 1); i
++)
61 const char *target
= APR_ARRAY_IDX(targets
, i
, const char *);
62 svn_client_copy_source_t
*source
= apr_palloc(pool
, sizeof(*source
));
64 svn_opt_revision_t
*peg_revision
= apr_palloc(pool
,
65 sizeof(*peg_revision
));
67 SVN_ERR(svn_opt_parse_path(peg_revision
, &src
, target
, pool
));
69 source
->revision
= &(opt_state
->start_revision
);
70 source
->peg_revision
= peg_revision
;
72 APR_ARRAY_PUSH(sources
, svn_client_copy_source_t
*) = source
;
75 /* Figure out which type of trace editor to use.
76 If the src_paths are not homogeneous, setup_copy will return an error. */
77 src_path
= APR_ARRAY_IDX(targets
, 0, const char *);
78 srcs_are_urls
= svn_path_is_url(src_path
);
79 dst_path
= APR_ARRAY_IDX(targets
, targets
->nelts
- 1, const char *);
80 apr_array_pop(targets
);
81 dst_is_url
= svn_path_is_url(dst_path
);
83 if ((! srcs_are_urls
) && (! dst_is_url
))
86 if (! opt_state
->quiet
)
87 svn_cl__get_notifier(&ctx
->notify_func2
, &ctx
->notify_baton2
,
88 FALSE
, FALSE
, FALSE
, pool
);
90 else if ((! srcs_are_urls
) && (dst_is_url
))
92 /* WC->URL : Use notification. */
95 We'd like to use the notifier, but we MAY have a couple of
96 problems with that, the same problems that used to apply to
99 1) We don't know where the commit editor for this case will
100 be anchored with respect to the repository, so we can't
103 2) While we do know where the commit editor will be driven
104 from with respect to our working copy, we don't know what
105 basenames will be chosen for our committed things. So a
106 copy of dir1/foo.c to http://.../dir2/foo-copy-c would
107 display like: "Adding dir1/foo-copy.c", which could be a
111 else if ((srcs_are_urls
) && (! dst_is_url
))
113 /* URL->WC : Use checkout-style notification. */
114 if (! opt_state
->quiet
)
115 svn_cl__get_notifier(&ctx
->notify_func2
, &ctx
->notify_baton2
, TRUE
,
118 /* else URL -> URL, meaning that no notification is needed. */
122 ctx
->log_msg_func3
= NULL
;
123 if (opt_state
->message
|| opt_state
->filedata
|| opt_state
->revprop_table
)
124 return svn_error_create
125 (SVN_ERR_CL_UNNECESSARY_LOG_MESSAGE
, NULL
,
126 _("Local, non-commit operations do not take a log message "
127 "or revision properties"));
130 if (ctx
->log_msg_func3
)
131 SVN_ERR(svn_cl__make_log_msg_baton(&(ctx
->log_msg_baton3
), opt_state
,
132 NULL
, ctx
->config
, pool
));
134 ctx
->revprop_table
= opt_state
->revprop_table
;
136 err
= svn_client_copy4(&commit_info
, sources
, dst_path
, TRUE
,
137 opt_state
->parents
, ctx
, pool
);
139 if (ctx
->log_msg_func3
)
140 SVN_ERR(svn_cl__cleanup_log_msg(ctx
->log_msg_baton3
, err
));
144 if (commit_info
&& ! opt_state
->quiet
)
145 SVN_ERR(svn_cl__print_commit_info(commit_info
, pool
));