Followup to r29625: fix getopt tests.
[svn.git] / subversion / svn / copy-cmd.c
blob73fe52c00b46c76fb78bc0d4bc0d9cf9ed816e91
1 /*
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 /* ==================================================================== */
23 /*** Includes. ***/
25 #include "svn_client.h"
26 #include "svn_path.h"
27 #include "svn_error.h"
28 #include "cl.h"
30 #include "svn_private_config.h"
33 /*** Code. ***/
35 /* This implements the `svn_opt_subcommand_t' interface. */
36 svn_error_t *
37 svn_cl__copy(apr_getopt_t *os,
38 void *baton,
39 apr_pool_t *pool)
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;
47 svn_error_t *err;
48 int i;
50 SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
51 opt_state->targets,
52 pool));
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));
63 const char *src;
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));
68 source->path = src;
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))
85 /* WC->WC */
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. */
93 /* ### todo:
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
97 the old trace_editor:
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
101 use the DST_URL.
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
108 bogus path.
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,
116 FALSE, FALSE, pool);
118 /* else URL -> URL, meaning that no notification is needed. */
120 if (! dst_is_url)
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));
141 else if (err)
142 return err;
144 if (commit_info && ! opt_state->quiet)
145 SVN_ERR(svn_cl__print_commit_info(commit_info, pool));
147 return SVN_NO_ERROR;