2 * commit-cmd.c -- Check changes into the repository.
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
21 * ====================================================================
24 /* ==================================================================== */
30 #include <apr_general.h>
33 #include "svn_error.h"
34 #include "svn_error_codes.h"
36 #include "svn_client.h"
38 #include "svn_dirent_uri.h"
39 #include "svn_error.h"
40 #include "svn_config.h"
43 #include "svn_private_config.h"
47 /* Wrapper notify_func2 function and baton for warning about
48 reduced-depth commits of copied directories. */
49 struct copy_warning_notify_baton
51 svn_wc_notify_func2_t wrapped_func;
58 copy_warning_notify_func(void *baton,
59 const svn_wc_notify_t *notify,
62 struct copy_warning_notify_baton *b = baton;
64 /* Call the wrapped notification system (if any). */
66 b->wrapped_func(b->wrapped_baton, notify, pool);
68 /* If we're being notified about a copy of a directory when our
69 commit depth is less-than-infinite, and we've not already warned
70 about this situation, then warn about it (and remember that we
73 && (b->depth < svn_depth_infinity)
74 && (notify->kind == svn_node_dir)
75 && ((notify->action == svn_wc_notify_commit_copied) ||
76 (notify->action == svn_wc_notify_commit_copied_replaced)))
79 err = svn_cmdline_printf(pool,
80 _("svn: The depth of this commit is '%s', "
81 "but copies are always performed "
82 "recursively in the repository.\n"),
83 svn_depth_to_word(b->depth));
84 /* ### FIXME: Try to return this error showhow? */
87 /* We'll only warn once. */
95 /* This implements the `svn_opt_subcommand_t' interface. */
97 svn_cl__commit(apr_getopt_t *os,
102 svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
103 svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
104 apr_array_header_t *targets;
105 apr_array_header_t *condensed_targets;
106 const char *base_dir;
108 svn_boolean_t no_unlock = FALSE;
109 struct copy_warning_notify_baton cwnb;
111 SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
115 SVN_ERR_W(svn_cl__check_targets_are_local_paths(targets),
116 _("Commit targets must be local paths"));
118 /* Add "." if user passed 0 arguments. */
119 svn_opt_push_implicit_dot_target(targets, pool);
121 SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, pool));
123 /* Condense the targets (like commit does)... */
124 SVN_ERR(svn_dirent_condense_targets(&base_dir, &condensed_targets, targets,
127 if ((! condensed_targets) || (! condensed_targets->nelts))
129 const char *parent_dir, *base_name;
131 SVN_ERR(svn_wc_get_actual_target2(&parent_dir, &base_name, ctx->wc_ctx,
132 base_dir, pool, pool));
134 base_dir = apr_pstrdup(pool, parent_dir);
137 if (opt_state->depth == svn_depth_unknown)
138 opt_state->depth = svn_depth_infinity;
141 ? svn_hash_gets(ctx->config, SVN_CONFIG_CATEGORY_CONFIG)
144 SVN_ERR(svn_config_get_bool(cfg, &no_unlock,
145 SVN_CONFIG_SECTION_MISCELLANY,
146 SVN_CONFIG_OPTION_NO_UNLOCK, FALSE));
148 /* We're creating a new log message baton because we can use our base_dir
149 to store the temp file, instead of the current working directory. The
150 client might not have write access to their working directory, but they
151 better have write access to the directory they're committing. */
152 SVN_ERR(svn_cl__make_log_msg_baton(&(ctx->log_msg_baton3),
156 /* Copies are done server-side, and cheaply, which means they're
157 effectively always done with infinite depth. This is a potential
158 cause of confusion for users trying to commit copied subtrees in
159 part by restricting the commit's depth. See issues #3699 and #3752. */
160 if (opt_state->depth < svn_depth_infinity)
162 cwnb.wrapped_func = ctx->notify_func2;
163 cwnb.wrapped_baton = ctx->notify_baton2;
164 cwnb.depth = opt_state->depth;
166 ctx->notify_func2 = copy_warning_notify_func;
167 ctx->notify_baton2 = &cwnb;
171 err = svn_client_commit6(targets,
174 opt_state->keep_changelists,
175 TRUE /* commit_as_operations */,
176 opt_state->include_externals, /* file externals */
177 opt_state->include_externals, /* dir externals */
178 opt_state->changelists,
179 opt_state->revprop_table,
181 ? NULL : svn_cl__print_commit_info),
185 SVN_ERR(svn_cl__cleanup_log_msg(ctx->log_msg_baton3, err, pool));