Deleted Added
full compact
svnsync.c (302408) svnsync.c (362181)
1/*
2 * ====================================================================
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance

--- 29 unchanged lines hidden (view full) ---

38#include "private/svn_opt_private.h"
39#include "private/svn_ra_private.h"
40#include "private/svn_cmdline_private.h"
41
42#include "sync.h"
43
44#include "svn_private_config.h"
45
1/*
2 * ====================================================================
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance

--- 29 unchanged lines hidden (view full) ---

38#include "private/svn_opt_private.h"
39#include "private/svn_ra_private.h"
40#include "private/svn_cmdline_private.h"
41
42#include "sync.h"
43
44#include "svn_private_config.h"
45
46#include <apr_signal.h>
47#include <apr_uuid.h>
48
49static svn_opt_subcommand_t initialize_cmd,
50 synchronize_cmd,
51 copy_revprops_cmd,
52 info_cmd,
53 help_cmd;
54

--- 11 unchanged lines hidden (view full) ---

66 svnsync_opt_config_options,
67 svnsync_opt_source_prop_encoding,
68 svnsync_opt_disable_locking,
69 svnsync_opt_version,
70 svnsync_opt_trust_server_cert,
71 svnsync_opt_trust_server_cert_failures_src,
72 svnsync_opt_trust_server_cert_failures_dst,
73 svnsync_opt_allow_non_empty,
46#include <apr_uuid.h>
47
48static svn_opt_subcommand_t initialize_cmd,
49 synchronize_cmd,
50 copy_revprops_cmd,
51 info_cmd,
52 help_cmd;
53

--- 11 unchanged lines hidden (view full) ---

65 svnsync_opt_config_options,
66 svnsync_opt_source_prop_encoding,
67 svnsync_opt_disable_locking,
68 svnsync_opt_version,
69 svnsync_opt_trust_server_cert,
70 svnsync_opt_trust_server_cert_failures_src,
71 svnsync_opt_trust_server_cert_failures_dst,
72 svnsync_opt_allow_non_empty,
73 svnsync_opt_skip_unchanged,
74 svnsync_opt_steal_lock
75};
76
77#define SVNSYNC_OPTS_DEFAULT svnsync_opt_non_interactive, \
78 svnsync_opt_force_interactive, \
79 svnsync_opt_no_auth_cache, \
80 svnsync_opt_auth_username, \
81 svnsync_opt_auth_password, \
82 svnsync_opt_trust_server_cert, \
83 svnsync_opt_trust_server_cert_failures_src, \
84 svnsync_opt_trust_server_cert_failures_dst, \
85 svnsync_opt_source_username, \
86 svnsync_opt_source_password, \
87 svnsync_opt_sync_username, \
88 svnsync_opt_sync_password, \
89 svnsync_opt_config_dir, \
90 svnsync_opt_config_options
91
74 svnsync_opt_steal_lock
75};
76
77#define SVNSYNC_OPTS_DEFAULT svnsync_opt_non_interactive, \
78 svnsync_opt_force_interactive, \
79 svnsync_opt_no_auth_cache, \
80 svnsync_opt_auth_username, \
81 svnsync_opt_auth_password, \
82 svnsync_opt_trust_server_cert, \
83 svnsync_opt_trust_server_cert_failures_src, \
84 svnsync_opt_trust_server_cert_failures_dst, \
85 svnsync_opt_source_username, \
86 svnsync_opt_source_password, \
87 svnsync_opt_sync_username, \
88 svnsync_opt_sync_password, \
89 svnsync_opt_config_dir, \
90 svnsync_opt_config_options
91
92static const svn_opt_subcommand_desc2_t svnsync_cmd_table[] =
92static const svn_opt_subcommand_desc3_t svnsync_cmd_table[] =
93 {
93 {
94 { "initialize", initialize_cmd, { "init" },
95 N_("usage: svnsync initialize DEST_URL SOURCE_URL\n"
96 "\n"
94 { "initialize", initialize_cmd, { "init" }, {N_(
95 "usage: svnsync initialize DEST_URL SOURCE_URL\n"
96 "\n"), N_(
97 "Initialize a destination repository for synchronization from\n"
98 "another repository.\n"
97 "Initialize a destination repository for synchronization from\n"
98 "another repository.\n"
99 "\n"
99 "\n"), N_(
100 "If the source URL is not the root of a repository, only the\n"
101 "specified part of the repository will be synchronized.\n"
100 "If the source URL is not the root of a repository, only the\n"
101 "specified part of the repository will be synchronized.\n"
102 "\n"
102 "\n"), N_(
103 "The destination URL must point to the root of a repository which\n"
104 "has been configured to allow revision property changes. In\n"
105 "the general case, the destination repository must contain no\n"
106 "committed revisions. Use --allow-non-empty to override this\n"
107 "restriction, which will cause svnsync to assume that any revisions\n"
108 "already present in the destination repository perfectly mirror\n"
109 "their counterparts in the source repository. (This is useful\n"
110 "when initializing a copy of a repository as a mirror of that same\n"
111 "repository, for example.)\n"
103 "The destination URL must point to the root of a repository which\n"
104 "has been configured to allow revision property changes. In\n"
105 "the general case, the destination repository must contain no\n"
106 "committed revisions. Use --allow-non-empty to override this\n"
107 "restriction, which will cause svnsync to assume that any revisions\n"
108 "already present in the destination repository perfectly mirror\n"
109 "their counterparts in the source repository. (This is useful\n"
110 "when initializing a copy of a repository as a mirror of that same\n"
111 "repository, for example.)\n"
112 "\n"
112 "\n"), N_(
113 "You should not commit to, or make revision property changes in,\n"
114 "the destination repository by any method other than 'svnsync'.\n"
115 "In other words, the destination repository should be a read-only\n"
113 "You should not commit to, or make revision property changes in,\n"
114 "the destination repository by any method other than 'svnsync'.\n"
115 "In other words, the destination repository should be a read-only\n"
116 "mirror of the source repository.\n"),
116 "mirror of the source repository.\n"
117 )},
117 { SVNSYNC_OPTS_DEFAULT, svnsync_opt_source_prop_encoding, 'q',
118 svnsync_opt_allow_non_empty, svnsync_opt_disable_locking,
119 svnsync_opt_steal_lock, 'M' } },
118 { SVNSYNC_OPTS_DEFAULT, svnsync_opt_source_prop_encoding, 'q',
119 svnsync_opt_allow_non_empty, svnsync_opt_disable_locking,
120 svnsync_opt_steal_lock, 'M' } },
120 { "synchronize", synchronize_cmd, { "sync" },
121 N_("usage: svnsync synchronize DEST_URL [SOURCE_URL]\n"
122 "\n"
121 { "synchronize", synchronize_cmd, { "sync" }, {N_(
122 "usage: svnsync synchronize DEST_URL [SOURCE_URL]\n"
123 "\n"), N_(
123 "Transfer all pending revisions to the destination from the source\n"
124 "with which it was initialized.\n"
124 "Transfer all pending revisions to the destination from the source\n"
125 "with which it was initialized.\n"
125 "\n"
126 "\n"), N_(
126 "If SOURCE_URL is provided, use that as the source repository URL,\n"
127 "ignoring what is recorded in the destination repository as the\n"
128 "source URL. Specifying SOURCE_URL is recommended in particular\n"
129 "if untrusted users/administrators may have write access to the\n"
127 "If SOURCE_URL is provided, use that as the source repository URL,\n"
128 "ignoring what is recorded in the destination repository as the\n"
129 "source URL. Specifying SOURCE_URL is recommended in particular\n"
130 "if untrusted users/administrators may have write access to the\n"
130 "DEST_URL repository.\n"),
131 "DEST_URL repository.\n"
132 )},
131 { SVNSYNC_OPTS_DEFAULT, svnsync_opt_source_prop_encoding, 'q',
132 svnsync_opt_disable_locking, svnsync_opt_steal_lock, 'M' } },
133 { SVNSYNC_OPTS_DEFAULT, svnsync_opt_source_prop_encoding, 'q',
134 svnsync_opt_disable_locking, svnsync_opt_steal_lock, 'M' } },
133 { "copy-revprops", copy_revprops_cmd, { 0 },
134 N_("usage:\n"
135 "\n"
135 { "copy-revprops", copy_revprops_cmd, { 0 }, {N_(
136 "usage:\n"
137 "\n"), N_(
136 " 1. svnsync copy-revprops DEST_URL [SOURCE_URL]\n"
137 " 2. svnsync copy-revprops DEST_URL REV[:REV2]\n"
138 " 1. svnsync copy-revprops DEST_URL [SOURCE_URL]\n"
139 " 2. svnsync copy-revprops DEST_URL REV[:REV2]\n"
138 "\n"
140 "\n"), N_(
139 "Copy the revision properties in a given range of revisions to the\n"
140 "destination from the source with which it was initialized. If the\n"
141 "revision range is not specified, it defaults to all revisions in\n"
142 "the DEST_URL repository. Note also that the 'HEAD' revision is the\n"
143 "latest in DEST_URL, not necessarily the latest in SOURCE_URL.\n"
141 "Copy the revision properties in a given range of revisions to the\n"
142 "destination from the source with which it was initialized. If the\n"
143 "revision range is not specified, it defaults to all revisions in\n"
144 "the DEST_URL repository. Note also that the 'HEAD' revision is the\n"
145 "latest in DEST_URL, not necessarily the latest in SOURCE_URL.\n"
144 "\n"
146 "\n"), N_(
145 "If SOURCE_URL is provided, use that as the source repository URL,\n"
146 "ignoring what is recorded in the destination repository as the\n"
147 "source URL. Specifying SOURCE_URL is recommended in particular\n"
148 "if untrusted users/administrators may have write access to the\n"
149 "DEST_URL repository.\n"
147 "If SOURCE_URL is provided, use that as the source repository URL,\n"
148 "ignoring what is recorded in the destination repository as the\n"
149 "source URL. Specifying SOURCE_URL is recommended in particular\n"
150 "if untrusted users/administrators may have write access to the\n"
151 "DEST_URL repository.\n"
150 "\n"
151 "Form 2 is deprecated syntax, equivalent to specifying \"-rREV[:REV2]\".\n"),
152 "\n"), N_(
153 "Unless you need to trigger the destination repositoy's revprop\n"
154 "change hooks for all revision properties, it is recommended to use\n"
155 "the --skip-unchanged option for best performance.\n"
156 "\n"), N_(
157 "Form 2 is deprecated syntax, equivalent to specifying \"-rREV[:REV2]\".\n"
158 )},
152 { SVNSYNC_OPTS_DEFAULT, svnsync_opt_source_prop_encoding, 'q', 'r',
159 { SVNSYNC_OPTS_DEFAULT, svnsync_opt_source_prop_encoding, 'q', 'r',
153 svnsync_opt_disable_locking, svnsync_opt_steal_lock, 'M' } },
154 { "info", info_cmd, { 0 },
155 N_("usage: svnsync info DEST_URL\n"
156 "\n"
160 svnsync_opt_disable_locking, svnsync_opt_steal_lock,
161 svnsync_opt_skip_unchanged, 'M' } },
162 { "info", info_cmd, { 0 }, {N_(
163 "usage: svnsync info DEST_URL\n"
164 "\n"), N_(
157 "Print information about the synchronization destination repository\n"
165 "Print information about the synchronization destination repository\n"
158 "located at DEST_URL.\n"),
166 "located at DEST_URL.\n"
167 )},
159 { SVNSYNC_OPTS_DEFAULT } },
168 { SVNSYNC_OPTS_DEFAULT } },
160 { "help", help_cmd, { "?", "h" },
161 N_("usage: svnsync help [SUBCOMMAND...]\n"
162 "\n"
163 "Describe the usage of this program or its subcommands.\n"),
169 { "help", help_cmd, { "?", "h" }, {N_(
170 "usage: svnsync help [SUBCOMMAND...]\n"
171 "\n"), N_(
172 "Describe the usage of this program or its subcommands.\n"
173 )},
164 { 0 } },
174 { 0 } },
165 { NULL, NULL, { 0 }, NULL, { 0 } }
175 { NULL, NULL, { 0 }, {NULL}, { 0 } }
166 };
167
168static const apr_getopt_option_t svnsync_options[] =
169 {
170 {"quiet", 'q', 0,
171 N_("print as little as possible") },
172 {"revision", 'r', 1,
173 N_("operate on revision ARG (or range ARG1:ARG2)\n"
174 " "
175 "A revision argument can be one of:\n"
176 " "
177 " NUMBER revision number\n"
178 " "
179 " 'HEAD' latest in repository") },
180 {"allow-non-empty", svnsync_opt_allow_non_empty, 0,
181 N_("allow a non-empty destination repository") },
176 };
177
178static const apr_getopt_option_t svnsync_options[] =
179 {
180 {"quiet", 'q', 0,
181 N_("print as little as possible") },
182 {"revision", 'r', 1,
183 N_("operate on revision ARG (or range ARG1:ARG2)\n"
184 " "
185 "A revision argument can be one of:\n"
186 " "
187 " NUMBER revision number\n"
188 " "
189 " 'HEAD' latest in repository") },
190 {"allow-non-empty", svnsync_opt_allow_non_empty, 0,
191 N_("allow a non-empty destination repository") },
192 {"skip-unchanged", svnsync_opt_skip_unchanged, 0,
193 N_("don't copy unchanged revision properties") },
182 {"non-interactive", svnsync_opt_non_interactive, 0,
183 N_("do no interactive prompting (default is to prompt\n"
184 " "
185 "only if standard input is a terminal device)")},
186 {"force-interactive", svnsync_opt_force_interactive, 0,
187 N_("do interactive prompting even if standard input\n"
188 " "
189 "is not a terminal device")},

--- 87 unchanged lines hidden (view full) ---

277 N_("show help on a subcommand")},
278 {NULL, '?', 0,
279 N_("show help on a subcommand")},
280 { 0, 0, 0, 0 }
281 };
282
283typedef struct opt_baton_t {
284 svn_boolean_t non_interactive;
194 {"non-interactive", svnsync_opt_non_interactive, 0,
195 N_("do no interactive prompting (default is to prompt\n"
196 " "
197 "only if standard input is a terminal device)")},
198 {"force-interactive", svnsync_opt_force_interactive, 0,
199 N_("do interactive prompting even if standard input\n"
200 " "
201 "is not a terminal device")},

--- 87 unchanged lines hidden (view full) ---

289 N_("show help on a subcommand")},
290 {NULL, '?', 0,
291 N_("show help on a subcommand")},
292 { 0, 0, 0, 0 }
293 };
294
295typedef struct opt_baton_t {
296 svn_boolean_t non_interactive;
285 struct {
297 struct {
286 svn_boolean_t trust_server_cert_unknown_ca;
287 svn_boolean_t trust_server_cert_cn_mismatch;
288 svn_boolean_t trust_server_cert_expired;
289 svn_boolean_t trust_server_cert_not_yet_valid;
290 svn_boolean_t trust_server_cert_other_failure;
291 } src_trust, dst_trust;
292 svn_boolean_t no_auth_cache;
293 svn_auth_baton_t *source_auth_baton;

--- 4 unchanged lines hidden (view full) ---

298 const char *sync_password;
299 const char *config_dir;
300 apr_hash_t *config;
301 const char *source_prop_encoding;
302 svn_boolean_t disable_locking;
303 svn_boolean_t steal_lock;
304 svn_boolean_t quiet;
305 svn_boolean_t allow_non_empty;
298 svn_boolean_t trust_server_cert_unknown_ca;
299 svn_boolean_t trust_server_cert_cn_mismatch;
300 svn_boolean_t trust_server_cert_expired;
301 svn_boolean_t trust_server_cert_not_yet_valid;
302 svn_boolean_t trust_server_cert_other_failure;
303 } src_trust, dst_trust;
304 svn_boolean_t no_auth_cache;
305 svn_auth_baton_t *source_auth_baton;

--- 4 unchanged lines hidden (view full) ---

310 const char *sync_password;
311 const char *config_dir;
312 apr_hash_t *config;
313 const char *source_prop_encoding;
314 svn_boolean_t disable_locking;
315 svn_boolean_t steal_lock;
316 svn_boolean_t quiet;
317 svn_boolean_t allow_non_empty;
318 svn_boolean_t skip_unchanged;
306 svn_boolean_t version;
307 svn_boolean_t help;
308 svn_opt_revision_t start_rev;
309 svn_opt_revision_t end_rev;
310} opt_baton_t;
311
312
313
314
315/*** Helper functions ***/
316
317
319 svn_boolean_t version;
320 svn_boolean_t help;
321 svn_opt_revision_t start_rev;
322 svn_opt_revision_t end_rev;
323} opt_baton_t;
324
325
326
327
328/*** Helper functions ***/
329
330
318/* Global record of whether the user has requested cancellation. */
319static volatile sig_atomic_t cancelled = FALSE;
320
321
322/* Callback function for apr_signal(). */
323static void
324signal_handler(int signum)
325{
326 apr_signal(signum, SIG_IGN);
327 cancelled = TRUE;
328}
329
330
331/* Cancellation callback function. */
331/* Cancellation callback function. */
332static svn_error_t *
333check_cancel(void *baton)
334{
335 if (cancelled)
336 return svn_error_create(SVN_ERR_CANCELLED, NULL, _("Caught signal"));
337 else
338 return SVN_NO_ERROR;
339}
332static svn_cancel_func_t check_cancel = 0;
340
333
341
342/* Check that the version of libraries in use match what we expect. */
343static svn_error_t *
344check_lib_versions(void)
345{
346 static const svn_version_checklist_t checklist[] =
347 {
348 { "svn_subr", svn_subr_version },
349 { "svn_delta", svn_delta_version },

--- 67 unchanged lines hidden (view full) ---

417/* Baton for the various subcommands to share. */
418typedef struct subcommand_baton_t {
419 /* common to all subcommands */
420 apr_hash_t *config;
421 svn_ra_callbacks2_t source_callbacks;
422 svn_ra_callbacks2_t sync_callbacks;
423 svn_boolean_t quiet;
424 svn_boolean_t allow_non_empty;
334/* Check that the version of libraries in use match what we expect. */
335static svn_error_t *
336check_lib_versions(void)
337{
338 static const svn_version_checklist_t checklist[] =
339 {
340 { "svn_subr", svn_subr_version },
341 { "svn_delta", svn_delta_version },

--- 67 unchanged lines hidden (view full) ---

409/* Baton for the various subcommands to share. */
410typedef struct subcommand_baton_t {
411 /* common to all subcommands */
412 apr_hash_t *config;
413 svn_ra_callbacks2_t source_callbacks;
414 svn_ra_callbacks2_t sync_callbacks;
415 svn_boolean_t quiet;
416 svn_boolean_t allow_non_empty;
417 svn_boolean_t skip_unchanged; /* Enable optimization for revprop changes. */
425 const char *to_url;
426
427 /* initialize, synchronize, and copy-revprops only */
428 const char *source_prop_encoding;
429
430 /* initialize only */
431 const char *from_url;
432

--- 154 unchanged lines hidden (view full) ---

587
588
589/* Write the set of revision properties REV_PROPS to revision REV to the
590 * repository associated with RA session SESSION.
591 * Omit any properties whose names are in the svnsync property name space,
592 * and set *FILTERED_COUNT to the number of properties thus omitted.
593 * REV_PROPS is a hash mapping (char *)propname to (svn_string_t *)propval.
594 *
418 const char *to_url;
419
420 /* initialize, synchronize, and copy-revprops only */
421 const char *source_prop_encoding;
422
423 /* initialize only */
424 const char *from_url;
425

--- 154 unchanged lines hidden (view full) ---

580
581
582/* Write the set of revision properties REV_PROPS to revision REV to the
583 * repository associated with RA session SESSION.
584 * Omit any properties whose names are in the svnsync property name space,
585 * and set *FILTERED_COUNT to the number of properties thus omitted.
586 * REV_PROPS is a hash mapping (char *)propname to (svn_string_t *)propval.
587 *
588 * If OLD_REV_PROPS is not NULL, skip all properties that did not change.
589 * Note that this implies that hook scripts won't be triggered anymore for
590 * those revprops that did not change.
591 *
595 * All allocations will be done in a subpool of POOL.
596 */
597static svn_error_t *
598write_revprops(int *filtered_count,
599 svn_ra_session_t *session,
600 svn_revnum_t rev,
601 apr_hash_t *rev_props,
592 * All allocations will be done in a subpool of POOL.
593 */
594static svn_error_t *
595write_revprops(int *filtered_count,
596 svn_ra_session_t *session,
597 svn_revnum_t rev,
598 apr_hash_t *rev_props,
599 apr_hash_t *old_rev_props,
602 apr_pool_t *pool)
603{
604 apr_pool_t *subpool = svn_pool_create(pool);
605 apr_hash_index_t *hi;
606
607 *filtered_count = 0;
608
609 for (hi = apr_hash_first(pool, rev_props); hi; hi = apr_hash_next(hi))
610 {
611 const char *propname = apr_hash_this_key(hi);
612 const svn_string_t *propval = apr_hash_this_val(hi);
613
614 svn_pool_clear(subpool);
615
616 if (strncmp(propname, SVNSYNC_PROP_PREFIX,
617 sizeof(SVNSYNC_PROP_PREFIX) - 1) != 0)
618 {
600 apr_pool_t *pool)
601{
602 apr_pool_t *subpool = svn_pool_create(pool);
603 apr_hash_index_t *hi;
604
605 *filtered_count = 0;
606
607 for (hi = apr_hash_first(pool, rev_props); hi; hi = apr_hash_next(hi))
608 {
609 const char *propname = apr_hash_this_key(hi);
610 const svn_string_t *propval = apr_hash_this_val(hi);
611
612 svn_pool_clear(subpool);
613
614 if (strncmp(propname, SVNSYNC_PROP_PREFIX,
615 sizeof(SVNSYNC_PROP_PREFIX) - 1) != 0)
616 {
617 if (old_rev_props)
618 {
619 /* Skip the RA call for any no-op propset. */
620 const svn_string_t *old_value = svn_hash_gets(old_rev_props,
621 propname);
622 if ((!old_value && !propval)
623 || (old_value && propval
624 && svn_string_compare(old_value, propval)))
625 continue;
626 }
627
619 SVN_ERR(svn_ra_change_rev_prop2(session, rev, propname, NULL,
620 propval, subpool));
621 }
622 else
623 {
624 *filtered_count += 1;
625 }
626 }

--- 45 unchanged lines hidden (view full) ---

672/* Copy all the revision properties, except for those that have the
673 * "svn:sync-" prefix, from revision REV of the repository associated
674 * with RA session FROM_SESSION, to the repository associated with RA
675 * session TO_SESSION.
676 *
677 * If SYNC is TRUE, then properties on the destination revision that
678 * do not exist on the source revision will be removed.
679 *
628 SVN_ERR(svn_ra_change_rev_prop2(session, rev, propname, NULL,
629 propval, subpool));
630 }
631 else
632 {
633 *filtered_count += 1;
634 }
635 }

--- 45 unchanged lines hidden (view full) ---

681/* Copy all the revision properties, except for those that have the
682 * "svn:sync-" prefix, from revision REV of the repository associated
683 * with RA session FROM_SESSION, to the repository associated with RA
684 * session TO_SESSION.
685 *
686 * If SYNC is TRUE, then properties on the destination revision that
687 * do not exist on the source revision will be removed.
688 *
689 * If SKIP_UNCHANGED is TRUE, skip any no-op revprop changes. This also
690 * prevents hook scripts from firing for those unchanged revprops. Has
691 * no effect if SYNC is FALSE.
692 *
680 * If QUIET is FALSE, then log_properties_copied() is called to log that
681 * properties were copied for revision REV.
682 *
683 * Make sure the values of svn:* revision properties use only LF (\n)
684 * line ending style, correcting their values as necessary. The number
685 * of properties that were normalized is returned in *NORMALIZED_COUNT.
686 */
687static svn_error_t *
688copy_revprops(svn_ra_session_t *from_session,
689 svn_ra_session_t *to_session,
690 svn_revnum_t rev,
691 svn_boolean_t sync,
693 * If QUIET is FALSE, then log_properties_copied() is called to log that
694 * properties were copied for revision REV.
695 *
696 * Make sure the values of svn:* revision properties use only LF (\n)
697 * line ending style, correcting their values as necessary. The number
698 * of properties that were normalized is returned in *NORMALIZED_COUNT.
699 */
700static svn_error_t *
701copy_revprops(svn_ra_session_t *from_session,
702 svn_ra_session_t *to_session,
703 svn_revnum_t rev,
704 svn_boolean_t sync,
705 svn_boolean_t skip_unchanged,
692 svn_boolean_t quiet,
693 const char *source_prop_encoding,
694 int *normalized_count,
695 apr_pool_t *pool)
696{
697 apr_pool_t *subpool = svn_pool_create(pool);
698 apr_hash_t *existing_props, *rev_props;
699 int filtered_count = 0;

--- 9 unchanged lines hidden (view full) ---

709 SVN_ERR(svn_ra_rev_proplist(from_session, rev, &rev_props, subpool));
710
711 /* If necessary, normalize encoding and line ending style and return the count
712 of EOL-normalized properties in int *NORMALIZED_COUNT. */
713 SVN_ERR(svnsync_normalize_revprops(rev_props, normalized_count,
714 source_prop_encoding, pool));
715
716 /* Copy all but the svn:svnsync properties. */
706 svn_boolean_t quiet,
707 const char *source_prop_encoding,
708 int *normalized_count,
709 apr_pool_t *pool)
710{
711 apr_pool_t *subpool = svn_pool_create(pool);
712 apr_hash_t *existing_props, *rev_props;
713 int filtered_count = 0;

--- 9 unchanged lines hidden (view full) ---

723 SVN_ERR(svn_ra_rev_proplist(from_session, rev, &rev_props, subpool));
724
725 /* If necessary, normalize encoding and line ending style and return the count
726 of EOL-normalized properties in int *NORMALIZED_COUNT. */
727 SVN_ERR(svnsync_normalize_revprops(rev_props, normalized_count,
728 source_prop_encoding, pool));
729
730 /* Copy all but the svn:svnsync properties. */
717 SVN_ERR(write_revprops(&filtered_count, to_session, rev, rev_props, pool));
731 SVN_ERR(write_revprops(&filtered_count, to_session, rev, rev_props,
732 skip_unchanged ? existing_props : NULL, pool));
718
719 /* Delete those properties that were in TARGET but not in SOURCE */
720 if (sync)
721 SVN_ERR(remove_props_not_in_source(to_session, rev,
722 rev_props, existing_props, pool));
723
724 if (! quiet)
725 SVN_ERR(log_properties_copied(filtered_count > 0, rev, pool));

--- 19 unchanged lines hidden (view full) ---

745{
746 subcommand_baton_t *b = apr_pcalloc(pool, sizeof(*b));
747 b->config = opt_baton->config;
748 b->source_callbacks.open_tmp_file = open_tmp_file;
749 b->source_callbacks.auth_baton = opt_baton->source_auth_baton;
750 b->sync_callbacks.open_tmp_file = open_tmp_file;
751 b->sync_callbacks.auth_baton = opt_baton->sync_auth_baton;
752 b->quiet = opt_baton->quiet;
733
734 /* Delete those properties that were in TARGET but not in SOURCE */
735 if (sync)
736 SVN_ERR(remove_props_not_in_source(to_session, rev,
737 rev_props, existing_props, pool));
738
739 if (! quiet)
740 SVN_ERR(log_properties_copied(filtered_count > 0, rev, pool));

--- 19 unchanged lines hidden (view full) ---

760{
761 subcommand_baton_t *b = apr_pcalloc(pool, sizeof(*b));
762 b->config = opt_baton->config;
763 b->source_callbacks.open_tmp_file = open_tmp_file;
764 b->source_callbacks.auth_baton = opt_baton->source_auth_baton;
765 b->sync_callbacks.open_tmp_file = open_tmp_file;
766 b->sync_callbacks.auth_baton = opt_baton->sync_auth_baton;
767 b->quiet = opt_baton->quiet;
768 b->skip_unchanged = opt_baton->skip_unchanged;
753 b->allow_non_empty = opt_baton->allow_non_empty;
754 b->to_url = to_url;
755 b->source_prop_encoding = opt_baton->source_prop_encoding;
756 b->from_url = from_url;
757 b->start_rev = start_rev;
758 b->end_rev = end_rev;
759 return b;
760}

--- 39 unchanged lines hidden (view full) ---

800 if (from_url && (! baton->allow_non_empty))
801 return svn_error_createf
802 (APR_EINVAL, NULL,
803 _("Destination repository is already synchronizing from '%s'"),
804 from_url->data);
805
806 /* Now fill in our bookkeeping info in the dest repository. */
807
769 b->allow_non_empty = opt_baton->allow_non_empty;
770 b->to_url = to_url;
771 b->source_prop_encoding = opt_baton->source_prop_encoding;
772 b->from_url = from_url;
773 b->start_rev = start_rev;
774 b->end_rev = end_rev;
775 return b;
776}

--- 39 unchanged lines hidden (view full) ---

816 if (from_url && (! baton->allow_non_empty))
817 return svn_error_createf
818 (APR_EINVAL, NULL,
819 _("Destination repository is already synchronizing from '%s'"),
820 from_url->data);
821
822 /* Now fill in our bookkeeping info in the dest repository. */
823
808 SVN_ERR(svn_ra_open4(&from_session, NULL, baton->from_url, NULL,
824 SVN_ERR(svn_ra_open5(&from_session, NULL, NULL, baton->from_url, NULL,
809 &(baton->source_callbacks), baton,
810 baton->config, pool));
811 SVN_ERR(svn_ra_get_repos_root2(from_session, &root_url, pool));
812
813 /* If we're doing a partial replay, we have to check first if the server
814 supports this. */
815 if (strcmp(root_url, baton->from_url) != 0)
816 {

--- 37 unchanged lines hidden (view full) ---

854 /* Copy all non-svnsync revprops from the LATEST rev in the source
855 repository into the destination, notifying about normalized
856 props, if any. When LATEST is 0, this serves the practical
857 purpose of initializing data that would otherwise be overlooked
858 by the sync process (which is going to begin with r1). When
859 LATEST is not 0, this really serves merely aesthetic and
860 informational purposes, keeping the output of this command
861 consistent while allowing folks to see what the latest revision is. */
825 &(baton->source_callbacks), baton,
826 baton->config, pool));
827 SVN_ERR(svn_ra_get_repos_root2(from_session, &root_url, pool));
828
829 /* If we're doing a partial replay, we have to check first if the server
830 supports this. */
831 if (strcmp(root_url, baton->from_url) != 0)
832 {

--- 37 unchanged lines hidden (view full) ---

870 /* Copy all non-svnsync revprops from the LATEST rev in the source
871 repository into the destination, notifying about normalized
872 props, if any. When LATEST is 0, this serves the practical
873 purpose of initializing data that would otherwise be overlooked
874 by the sync process (which is going to begin with r1). When
875 LATEST is not 0, this really serves merely aesthetic and
876 informational purposes, keeping the output of this command
877 consistent while allowing folks to see what the latest revision is. */
862 SVN_ERR(copy_revprops(from_session, to_session, latest, FALSE, baton->quiet,
863 baton->source_prop_encoding, &normalized_rev_props_count,
864 pool));
878 SVN_ERR(copy_revprops(from_session, to_session, latest, FALSE, FALSE,
879 baton->quiet, baton->source_prop_encoding,
880 &normalized_rev_props_count, pool));
865
866 SVN_ERR(log_properties_normalized(normalized_rev_props_count, 0, pool));
867
868 /* TODO: It would be nice if we could set the dest repos UUID to be
869 equal to the UUID of the source repos, at least optionally. That
870 way people could check out/log/diff using a local fast mirror,
871 but switch --relocate to the actual final repository in order to
872 make changes... But at this time, the RA layer doesn't have a

--- 104 unchanged lines hidden (view full) ---

977
978 /* ### TODO: Should we validate that FROM_URL_STR->data matches any
979 provided FROM_URL here? */
980 if (! from_url)
981 SVN_ERR(svn_opt__arg_canonicalize_url(&from_url, from_url_str->data,
982 pool));
983
984 /* Open the session to copy the revision data. */
881
882 SVN_ERR(log_properties_normalized(normalized_rev_props_count, 0, pool));
883
884 /* TODO: It would be nice if we could set the dest repos UUID to be
885 equal to the UUID of the source repos, at least optionally. That
886 way people could check out/log/diff using a local fast mirror,
887 but switch --relocate to the actual final repository in order to
888 make changes... But at this time, the RA layer doesn't have a

--- 104 unchanged lines hidden (view full) ---

993
994 /* ### TODO: Should we validate that FROM_URL_STR->data matches any
995 provided FROM_URL here? */
996 if (! from_url)
997 SVN_ERR(svn_opt__arg_canonicalize_url(&from_url, from_url_str->data,
998 pool));
999
1000 /* Open the session to copy the revision data. */
985 SVN_ERR(svn_ra_open4(from_session, NULL, from_url, from_uuid_str->data,
1001 SVN_ERR(svn_ra_open5(from_session, NULL, NULL, from_url, from_uuid_str->data,
986 callbacks, baton, config, pool));
987
988 return SVN_NO_ERROR;
989}
990
991/* Set *TARGET_SESSION_P to an RA session associated with the target
992 * repository of the synchronization.
993 */
994static svn_error_t *
995open_target_session(svn_ra_session_t **target_session_p,
996 subcommand_baton_t *baton,
997 apr_pool_t *pool)
998{
999 svn_ra_session_t *target_session;
1002 callbacks, baton, config, pool));
1003
1004 return SVN_NO_ERROR;
1005}
1006
1007/* Set *TARGET_SESSION_P to an RA session associated with the target
1008 * repository of the synchronization.
1009 */
1010static svn_error_t *
1011open_target_session(svn_ra_session_t **target_session_p,
1012 subcommand_baton_t *baton,
1013 apr_pool_t *pool)
1014{
1015 svn_ra_session_t *target_session;
1000 SVN_ERR(svn_ra_open4(&target_session, NULL, baton->to_url, NULL,
1016 SVN_ERR(svn_ra_open5(&target_session, NULL, NULL, baton->to_url, NULL,
1001 &(baton->sync_callbacks), baton, baton->config, pool));
1002 SVN_ERR(check_if_session_is_at_repos_root(target_session, baton->to_url, pool));
1003
1004 *target_session_p = target_session;
1005 return SVN_NO_ERROR;
1006}
1007
1008/* Replay baton, used during synchronization. */

--- 358 unchanged lines hidden (view full) ---

1367
1368 /* If necessary, normalize encoding and line ending style, and add the number
1369 of EOL-normalized properties to the overall count in the replay baton. */
1370 SVN_ERR(svnsync_normalize_revprops(filtered, &normalized_count,
1371 rb->sb->source_prop_encoding, pool));
1372 rb->normalized_rev_props_count += normalized_count;
1373
1374 SVN_ERR(write_revprops(&filtered_count, rb->to_session, revision, filtered,
1017 &(baton->sync_callbacks), baton, baton->config, pool));
1018 SVN_ERR(check_if_session_is_at_repos_root(target_session, baton->to_url, pool));
1019
1020 *target_session_p = target_session;
1021 return SVN_NO_ERROR;
1022}
1023
1024/* Replay baton, used during synchronization. */

--- 358 unchanged lines hidden (view full) ---

1383
1384 /* If necessary, normalize encoding and line ending style, and add the number
1385 of EOL-normalized properties to the overall count in the replay baton. */
1386 SVN_ERR(svnsync_normalize_revprops(filtered, &normalized_count,
1387 rb->sb->source_prop_encoding, pool));
1388 rb->normalized_rev_props_count += normalized_count;
1389
1390 SVN_ERR(write_revprops(&filtered_count, rb->to_session, revision, filtered,
1375 subpool));
1391 NULL, subpool));
1376
1377 /* Remove all extra properties in TARGET. */
1378 SVN_ERR(remove_props_not_in_source(rb->to_session, revision,
1379 rev_props, existing_props, subpool));
1380
1381 svn_pool_clear(subpool);
1382
1383 rev_str = svn_string_createf(subpool, "%ld", revision);

--- 89 unchanged lines hidden (view full) ---

1473 "committed to the destination without using svnsync?"),
1474 copying, last_merged, to_latest);
1475 }
1476 else if (copying == to_latest)
1477 {
1478 if (copying > last_merged)
1479 {
1480 SVN_ERR(copy_revprops(from_session, to_session, to_latest, TRUE,
1392
1393 /* Remove all extra properties in TARGET. */
1394 SVN_ERR(remove_props_not_in_source(rb->to_session, revision,
1395 rev_props, existing_props, subpool));
1396
1397 svn_pool_clear(subpool);
1398
1399 rev_str = svn_string_createf(subpool, "%ld", revision);

--- 89 unchanged lines hidden (view full) ---

1489 "committed to the destination without using svnsync?"),
1490 copying, last_merged, to_latest);
1491 }
1492 else if (copying == to_latest)
1493 {
1494 if (copying > last_merged)
1495 {
1496 SVN_ERR(copy_revprops(from_session, to_session, to_latest, TRUE,
1481 baton->quiet, baton->source_prop_encoding,
1497 baton->skip_unchanged, baton->quiet,
1498 baton->source_prop_encoding,
1482 &normalized_rev_props_count, pool));
1483 last_merged = copying;
1484 last_merged_rev = svn_string_create
1485 (apr_psprintf(pool, "%ld", last_merged), pool);
1486 }
1487
1488 /* Now update last merged rev and drop currently changing.
1489 Note that the order here is significant, if we do them

--- 20 unchanged lines hidden (view full) ---

1510 "committed to the destination without "
1511 "using svnsync?"),
1512 to_latest, last_merged);
1513 }
1514
1515 /* Now check to see if there are any revisions to copy. */
1516 SVN_ERR(svn_ra_get_latest_revnum(from_session, &from_latest, pool));
1517
1499 &normalized_rev_props_count, pool));
1500 last_merged = copying;
1501 last_merged_rev = svn_string_create
1502 (apr_psprintf(pool, "%ld", last_merged), pool);
1503 }
1504
1505 /* Now update last merged rev and drop currently changing.
1506 Note that the order here is significant, if we do them

--- 20 unchanged lines hidden (view full) ---

1527 "committed to the destination without "
1528 "using svnsync?"),
1529 to_latest, last_merged);
1530 }
1531
1532 /* Now check to see if there are any revisions to copy. */
1533 SVN_ERR(svn_ra_get_latest_revnum(from_session, &from_latest, pool));
1534
1518 if (from_latest < last_merged)
1535 if (from_latest <= last_merged)
1519 return SVN_NO_ERROR;
1520
1521 /* Ok, so there are new revisions, iterate over them copying them
1522 into the destination repository. */
1523 SVN_ERR(make_replay_baton(&rb, from_session, to_session, baton, pool));
1524
1525 /* For compatibility with older svnserve versions, check first if we
1526 support adding revprops to the commit. */

--- 117 unchanged lines hidden (view full) ---

1644 "been synchronized yet"), baton->end_rev);
1645
1646 /* Now, copy all the requested revisions, in the requested order. */
1647 step = (baton->start_rev > baton->end_rev) ? -1 : 1;
1648 for (i = baton->start_rev; i != baton->end_rev + step; i = i + step)
1649 {
1650 int normalized_count;
1651 SVN_ERR(check_cancel(NULL));
1536 return SVN_NO_ERROR;
1537
1538 /* Ok, so there are new revisions, iterate over them copying them
1539 into the destination repository. */
1540 SVN_ERR(make_replay_baton(&rb, from_session, to_session, baton, pool));
1541
1542 /* For compatibility with older svnserve versions, check first if we
1543 support adding revprops to the commit. */

--- 117 unchanged lines hidden (view full) ---

1661 "been synchronized yet"), baton->end_rev);
1662
1663 /* Now, copy all the requested revisions, in the requested order. */
1664 step = (baton->start_rev > baton->end_rev) ? -1 : 1;
1665 for (i = baton->start_rev; i != baton->end_rev + step; i = i + step)
1666 {
1667 int normalized_count;
1668 SVN_ERR(check_cancel(NULL));
1652 SVN_ERR(copy_revprops(from_session, to_session, i, TRUE, baton->quiet,
1669 SVN_ERR(copy_revprops(from_session, to_session, i, TRUE,
1670 baton->skip_unchanged, baton->quiet,
1653 baton->source_prop_encoding, &normalized_count,
1654 pool));
1655 normalized_rev_props_count += normalized_count;
1656 }
1657
1658 /* Notify about normalized props, if any. */
1659 SVN_ERR(log_properties_normalized(normalized_rev_props_count, 0, pool));
1660

--- 91 unchanged lines hidden (view full) ---

1752 return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL);
1753 if (os->argc - os->ind < 1)
1754 return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
1755
1756 /* If there are two args, the last one is either a revision range or
1757 the source URL. */
1758 if (os->argc - os->ind == 2)
1759 {
1671 baton->source_prop_encoding, &normalized_count,
1672 pool));
1673 normalized_rev_props_count += normalized_count;
1674 }
1675
1676 /* Notify about normalized props, if any. */
1677 SVN_ERR(log_properties_normalized(normalized_rev_props_count, 0, pool));
1678

--- 91 unchanged lines hidden (view full) ---

1770 return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL);
1771 if (os->argc - os->ind < 1)
1772 return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
1773
1774 /* If there are two args, the last one is either a revision range or
1775 the source URL. */
1776 if (os->argc - os->ind == 2)
1777 {
1760 const char *arg_str = os->argv[os->argc - 1];
1761 const char *utf_arg_str;
1778 const char *arg_str;
1762
1779
1763 SVN_ERR(svn_utf_cstring_to_utf8(&utf_arg_str, arg_str, pool));
1780 SVN_ERR(svn_utf_cstring_to_utf8(&arg_str, os->argv[os->argc - 1],
1781 pool));
1764
1782
1765 if (! svn_path_is_url(utf_arg_str))
1783 if (! svn_path_is_url(arg_str))
1766 {
1767 /* This is the old "... TO_URL REV[:REV2]" syntax.
1768 Revisions come only from this argument. (We effectively
1769 pop that last argument from the end of the argument list
1770 so svn_opt__args_to_target_array() can do its thang.) */
1771 os->argc--;
1772
1773 if ((opt_baton->start_rev.kind != svn_opt_revision_unspecified)

--- 145 unchanged lines hidden (view full) ---

1919 const char *ra_desc_start
1920 = _("The following repository access (RA) modules are available:\n\n");
1921
1922 svn_stringbuf_t *version_footer = svn_stringbuf_create(ra_desc_start,
1923 pool);
1924
1925 SVN_ERR(svn_ra_print_modules(version_footer, pool));
1926
1784 {
1785 /* This is the old "... TO_URL REV[:REV2]" syntax.
1786 Revisions come only from this argument. (We effectively
1787 pop that last argument from the end of the argument list
1788 so svn_opt__args_to_target_array() can do its thang.) */
1789 os->argc--;
1790
1791 if ((opt_baton->start_rev.kind != svn_opt_revision_unspecified)

--- 145 unchanged lines hidden (view full) ---

1937 const char *ra_desc_start
1938 = _("The following repository access (RA) modules are available:\n\n");
1939
1940 svn_stringbuf_t *version_footer = svn_stringbuf_create(ra_desc_start,
1941 pool);
1942
1943 SVN_ERR(svn_ra_print_modules(version_footer, pool));
1944
1927 SVN_ERR(svn_opt_print_help4(os, "svnsync",
1945 SVN_ERR(svn_opt_print_help5(os, "svnsync",
1928 opt_baton ? opt_baton->version : FALSE,
1929 opt_baton ? opt_baton->quiet : FALSE,
1930 /*###opt_state ? opt_state->verbose :*/ FALSE,
1931 version_footer->data, header,
1932 svnsync_cmd_table, svnsync_options, NULL,
1933 NULL, pool));
1934
1935 return SVN_NO_ERROR;

--- 6 unchanged lines hidden (view full) ---

1942/*
1943 * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error,
1944 * either return an error to be displayed, or set *EXIT_CODE to non-zero and
1945 * return SVN_NO_ERROR.
1946 */
1947static svn_error_t *
1948sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
1949{
1946 opt_baton ? opt_baton->version : FALSE,
1947 opt_baton ? opt_baton->quiet : FALSE,
1948 /*###opt_state ? opt_state->verbose :*/ FALSE,
1949 version_footer->data, header,
1950 svnsync_cmd_table, svnsync_options, NULL,
1951 NULL, pool));
1952
1953 return SVN_NO_ERROR;

--- 6 unchanged lines hidden (view full) ---

1960/*
1961 * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error,
1962 * either return an error to be displayed, or set *EXIT_CODE to non-zero and
1963 * return SVN_NO_ERROR.
1964 */
1965static svn_error_t *
1966sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
1967{
1950 const svn_opt_subcommand_desc2_t *subcommand = NULL;
1968 const svn_opt_subcommand_desc3_t *subcommand = NULL;
1951 apr_array_header_t *received_opts;
1952 opt_baton_t opt_baton;
1953 svn_config_t *config;
1954 apr_status_t apr_err;
1955 apr_getopt_t *os;
1956 svn_error_t *err;
1957 int opt_id, i;
1958 const char *username = NULL, *source_username = NULL, *sync_username = NULL;

--- 104 unchanged lines hidden (view full) ---

2063 break;
2064
2065 case svnsync_opt_sync_password:
2066 opt_err = svn_utf_cstring_to_utf8(&sync_password, opt_arg, pool);
2067 break;
2068
2069 case svnsync_opt_config_dir:
2070 {
1969 apr_array_header_t *received_opts;
1970 opt_baton_t opt_baton;
1971 svn_config_t *config;
1972 apr_status_t apr_err;
1973 apr_getopt_t *os;
1974 svn_error_t *err;
1975 int opt_id, i;
1976 const char *username = NULL, *source_username = NULL, *sync_username = NULL;

--- 104 unchanged lines hidden (view full) ---

2081 break;
2082
2083 case svnsync_opt_sync_password:
2084 opt_err = svn_utf_cstring_to_utf8(&sync_password, opt_arg, pool);
2085 break;
2086
2087 case svnsync_opt_config_dir:
2088 {
2071 const char *path_utf8;
2072 opt_err = svn_utf_cstring_to_utf8(&path_utf8, opt_arg, pool);
2089 const char *path;
2090 opt_err = svn_utf_cstring_to_utf8(&path, opt_arg, pool);
2073
2074 if (!opt_err)
2091
2092 if (!opt_err)
2075 opt_baton.config_dir = svn_dirent_internal_style(path_utf8, pool);
2093 opt_baton.config_dir = svn_dirent_internal_style(path, pool);
2076 }
2077 break;
2078 case svnsync_opt_config_options:
2079 if (!config_options)
2080 config_options =
2081 apr_array_make(pool, 1,
2082 sizeof(svn_cmdline__config_argument_t*));
2083

--- 19 unchanged lines hidden (view full) ---

2103 case svnsync_opt_version:
2104 opt_baton.version = TRUE;
2105 break;
2106
2107 case svnsync_opt_allow_non_empty:
2108 opt_baton.allow_non_empty = TRUE;
2109 break;
2110
2094 }
2095 break;
2096 case svnsync_opt_config_options:
2097 if (!config_options)
2098 config_options =
2099 apr_array_make(pool, 1,
2100 sizeof(svn_cmdline__config_argument_t*));
2101

--- 19 unchanged lines hidden (view full) ---

2121 case svnsync_opt_version:
2122 opt_baton.version = TRUE;
2123 break;
2124
2125 case svnsync_opt_allow_non_empty:
2126 opt_baton.allow_non_empty = TRUE;
2127 break;
2128
2129 case svnsync_opt_skip_unchanged:
2130 opt_baton.skip_unchanged = TRUE;
2131 break;
2132
2111 case 'q':
2112 opt_baton.quiet = TRUE;
2113 break;
2114
2115 case 'r':
2116 if (svn_opt_parse_revision(&opt_baton.start_rev,
2117 &opt_baton.end_rev,
2118 opt_arg, pool) != 0)

--- 48 unchanged lines hidden (view full) ---

2167 }
2168 }
2169
2170 if (opt_err)
2171 return opt_err;
2172 }
2173
2174 if (opt_baton.help)
2133 case 'q':
2134 opt_baton.quiet = TRUE;
2135 break;
2136
2137 case 'r':
2138 if (svn_opt_parse_revision(&opt_baton.start_rev,
2139 &opt_baton.end_rev,
2140 opt_arg, pool) != 0)

--- 48 unchanged lines hidden (view full) ---

2189 }
2190 }
2191
2192 if (opt_err)
2193 return opt_err;
2194 }
2195
2196 if (opt_baton.help)
2175 subcommand = svn_opt_get_canonical_subcommand2(svnsync_cmd_table, "help");
2197 subcommand = svn_opt_get_canonical_subcommand3(svnsync_cmd_table, "help");
2176
2177 /* The --non-interactive and --force-interactive options are mutually
2178 * exclusive. */
2179 if (opt_baton.non_interactive && force_interactive)
2180 {
2181 return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
2182 _("--non-interactive and --force-interactive "
2183 "are mutually exclusive"));

--- 63 unchanged lines hidden (view full) ---

2247
2248 if (subcommand == NULL)
2249 {
2250 if (os->ind >= os->argc)
2251 {
2252 if (opt_baton.version)
2253 {
2254 /* Use the "help" subcommand to handle "--version". */
2198
2199 /* The --non-interactive and --force-interactive options are mutually
2200 * exclusive. */
2201 if (opt_baton.non_interactive && force_interactive)
2202 {
2203 return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
2204 _("--non-interactive and --force-interactive "
2205 "are mutually exclusive"));

--- 63 unchanged lines hidden (view full) ---

2269
2270 if (subcommand == NULL)
2271 {
2272 if (os->ind >= os->argc)
2273 {
2274 if (opt_baton.version)
2275 {
2276 /* Use the "help" subcommand to handle "--version". */
2255 static const svn_opt_subcommand_desc2_t pseudo_cmd =
2256 { "--version", help_cmd, {0}, "",
2277 static const svn_opt_subcommand_desc3_t pseudo_cmd =
2278 { "--version", help_cmd, {0}, {""},
2257 {svnsync_opt_version, /* must accept its own option */
2258 'q', /* --quiet */
2259 } };
2260
2261 subcommand = &pseudo_cmd;
2262 }
2263 else
2264 {
2265 SVN_ERR(help_cmd(NULL, NULL, pool));
2266 *exit_code = EXIT_FAILURE;
2267 return SVN_NO_ERROR;
2268 }
2269 }
2270 else
2271 {
2279 {svnsync_opt_version, /* must accept its own option */
2280 'q', /* --quiet */
2281 } };
2282
2283 subcommand = &pseudo_cmd;
2284 }
2285 else
2286 {
2287 SVN_ERR(help_cmd(NULL, NULL, pool));
2288 *exit_code = EXIT_FAILURE;
2289 return SVN_NO_ERROR;
2290 }
2291 }
2292 else
2293 {
2272 const char *first_arg = os->argv[os->ind++];
2273 subcommand = svn_opt_get_canonical_subcommand2(svnsync_cmd_table,
2294 const char *first_arg;
2295
2296 SVN_ERR(svn_utf_cstring_to_utf8(&first_arg, os->argv[os->ind++],
2297 pool));
2298 subcommand = svn_opt_get_canonical_subcommand3(svnsync_cmd_table,
2274 first_arg);
2275 if (subcommand == NULL)
2276 {
2277 SVN_ERR(help_cmd(NULL, NULL, pool));
2278 *exit_code = EXIT_FAILURE;
2279 return SVN_NO_ERROR;
2280 }
2281 }
2282 }
2283
2284 for (i = 0; i < received_opts->nelts; ++i)
2285 {
2286 opt_id = APR_ARRAY_IDX(received_opts, i, int);
2287
2288 if (opt_id == 'h' || opt_id == '?')
2289 continue;
2290
2299 first_arg);
2300 if (subcommand == NULL)
2301 {
2302 SVN_ERR(help_cmd(NULL, NULL, pool));
2303 *exit_code = EXIT_FAILURE;
2304 return SVN_NO_ERROR;
2305 }
2306 }
2307 }
2308
2309 for (i = 0; i < received_opts->nelts; ++i)
2310 {
2311 opt_id = APR_ARRAY_IDX(received_opts, i, int);
2312
2313 if (opt_id == 'h' || opt_id == '?')
2314 continue;
2315
2291 if (! svn_opt_subcommand_takes_option3(subcommand, opt_id, NULL))
2316 if (! svn_opt_subcommand_takes_option4(subcommand, opt_id, NULL))
2292 {
2293 const char *optstr;
2294 const apr_getopt_option_t *badopt =
2317 {
2318 const char *optstr;
2319 const apr_getopt_option_t *badopt =
2295 svn_opt_get_option_from_code2(opt_id, svnsync_options, subcommand,
2320 svn_opt_get_option_from_code3(opt_id, svnsync_options, subcommand,
2296 pool);
2297 svn_opt_format_option(&optstr, badopt, FALSE, pool);
2298 if (subcommand->name[0] == '-')
2299 {
2300 SVN_ERR(help_cmd(NULL, NULL, pool));
2301 }
2302 else
2303 {

--- 15 unchanged lines hidden (view full) ---

2319 svn_cmdline__apply_config_options(opt_baton.config, config_options,
2320 "svnsync: ", "--config-option"));
2321 }
2322
2323 config = svn_hash_gets(opt_baton.config, SVN_CONFIG_CATEGORY_CONFIG);
2324
2325 opt_baton.source_prop_encoding = source_prop_encoding;
2326
2321 pool);
2322 svn_opt_format_option(&optstr, badopt, FALSE, pool);
2323 if (subcommand->name[0] == '-')
2324 {
2325 SVN_ERR(help_cmd(NULL, NULL, pool));
2326 }
2327 else
2328 {

--- 15 unchanged lines hidden (view full) ---

2344 svn_cmdline__apply_config_options(opt_baton.config, config_options,
2345 "svnsync: ", "--config-option"));
2346 }
2347
2348 config = svn_hash_gets(opt_baton.config, SVN_CONFIG_CATEGORY_CONFIG);
2349
2350 opt_baton.source_prop_encoding = source_prop_encoding;
2351
2327 apr_signal(SIGINT, signal_handler);
2352 check_cancel = svn_cmdline__setup_cancellation_handler();
2328
2353
2329#ifdef SIGBREAK
2330 /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
2331 apr_signal(SIGBREAK, signal_handler);
2332#endif
2333
2334#ifdef SIGHUP
2335 apr_signal(SIGHUP, signal_handler);
2336#endif
2337
2338#ifdef SIGTERM
2339 apr_signal(SIGTERM, signal_handler);
2340#endif
2341
2342#ifdef SIGPIPE
2343 /* Disable SIGPIPE generation for the platforms that have it. */
2344 apr_signal(SIGPIPE, SIG_IGN);
2345#endif
2346
2347#ifdef SIGXFSZ
2348 /* Disable SIGXFSZ generation for the platforms that have it,
2349 otherwise working with large files when compiled against an APR
2350 that doesn't have large file support will crash the program,
2351 which is uncool. */
2352 apr_signal(SIGXFSZ, SIG_IGN);
2353#endif
2354
2355 err = svn_cmdline_create_auth_baton2(
2356 &opt_baton.source_auth_baton,
2357 opt_baton.non_interactive,
2358 opt_baton.source_username,
2359 opt_baton.source_password,
2360 opt_baton.config_dir,
2361 opt_baton.no_auth_cache,
2362 opt_baton.src_trust.trust_server_cert_unknown_ca,

--- 63 unchanged lines hidden (view full) ---

2426
2427 if (err)
2428 {
2429 exit_code = EXIT_FAILURE;
2430 svn_cmdline_handle_exit_error(err, NULL, "svnsync: ");
2431 }
2432
2433 svn_pool_destroy(pool);
2354 err = svn_cmdline_create_auth_baton2(
2355 &opt_baton.source_auth_baton,
2356 opt_baton.non_interactive,
2357 opt_baton.source_username,
2358 opt_baton.source_password,
2359 opt_baton.config_dir,
2360 opt_baton.no_auth_cache,
2361 opt_baton.src_trust.trust_server_cert_unknown_ca,

--- 63 unchanged lines hidden (view full) ---

2425
2426 if (err)
2427 {
2428 exit_code = EXIT_FAILURE;
2429 svn_cmdline_handle_exit_error(err, NULL, "svnsync: ");
2430 }
2431
2432 svn_pool_destroy(pool);
2433
2434 svn_cmdline__cancellation_exit();
2435
2434 return exit_code;
2435}
2436 return exit_code;
2437}