Follow-up to r29036: Now that the "mergeinfo" transaction file is no
[svn.git] / contrib / client-side / svn-push / svn-push.c
blobe24bddfc4d2dac197017018177e6b6c91c7dea84
1 /* svn-push.c --- propagate changesets from one (networked) repository to
2 * a different (networked) repository.
4 * ====================================================================
5 * Copyright (c) 2000-2006 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 * ====================================================================
18 #include <stdio.h>
20 #include "svn_pools.h"
21 #include "svn_path.h"
22 #include "svn_ra.h"
23 #include "svn_delta.h"
24 #include "svn_config.h"
25 #include "svn_cmdline.h"
27 /* Implements svn_commit_callback2_t. */
28 static svn_error_t *
29 my_commit_callback (const svn_commit_info_t *ci, void *baton, apr_pool_t *pool)
31 printf ("Commiting Rev. %ld at date \"%s\", by "
32 "author \"%s\"\n", ci->revision, ci->date, ci->author);
33 if (ci->post_commit_err)
34 printf ("Post-commit Error: %s\n", ci->post_commit_err);
35 return SVN_NO_ERROR;
39 /* Implements svn_ra_callbacks2_t.open_tmp_file */
40 static svn_error_t *
41 open_tmp_file (apr_file_t **fp, void *callback_baton, apr_pool_t *pool)
43 const char *path;
45 SVN_ERR (svn_io_temp_dir (&path, pool));
46 path = svn_path_join (path, "tempfile", pool);
47 SVN_ERR (svn_io_open_unique_file (fp, NULL, path, ".tmp", TRUE, pool));
49 return SVN_NO_ERROR;
53 svn_error_t *(*old_change_file_prop) (void *file_baton,
54 const char *name,
55 const svn_string_t *value,
56 apr_pool_t *pool);
58 /* Implements svn_ra_callbacks2_t.change_file_prop */
59 static svn_error_t *
60 new_change_file_prop (void *file_baton, const char *name,
61 const svn_string_t *value, apr_pool_t *pool)
63 if (svn_property_kind (NULL, name) != svn_prop_regular_kind)
64 return SVN_NO_ERROR;
65 else
66 return old_change_file_prop (file_baton, name, value, pool);
70 svn_error_t *(*old_change_dir_prop) (void *dir_baton,
71 const char *name,
72 const svn_string_t *value,
73 apr_pool_t *pool);
75 /* Implements svn_ra_callbacks2_t.change_dir_prop */
76 static svn_error_t *
77 new_change_dir_prop (void *dir_baton, const char *name,
78 const svn_string_t *value, apr_pool_t *pool)
80 if (svn_property_kind (NULL, name) != svn_prop_regular_kind)
81 return SVN_NO_ERROR;
82 else
83 return old_change_dir_prop (dir_baton, name, value, pool);
87 static svn_error_t *
88 do_job (const char *src_url, const char *dest_url, int start_rev, int end_rev,
89 apr_pool_t *pool)
91 apr_hash_t *config;
92 svn_config_t *cfg;
93 svn_auth_baton_t *ab;
94 svn_ra_callbacks2_t *callbacks;
95 svn_ra_session_t *ra_src, *ra_dest;
96 const svn_delta_editor_t *editor;
97 svn_delta_editor_t *my_editor;
98 void *edit_baton;
99 const svn_ra_reporter2_t *reporter;
100 void *report_baton;
102 SVN_ERR (svn_config_get_config (&config, NULL, pool));
103 cfg = apr_hash_get (config, SVN_CONFIG_CATEGORY_CONFIG, APR_HASH_KEY_STRING);
105 SVN_ERR (svn_cmdline_setup_auth_baton (&ab, FALSE, NULL, NULL, NULL, FALSE,
106 cfg, NULL, NULL, pool));
107 SVN_ERR (svn_ra_create_callbacks (&callbacks, pool));
108 callbacks->open_tmp_file = open_tmp_file;
109 callbacks->auth_baton = ab;
111 SVN_ERR (svn_ra_open2 (&ra_dest, dest_url, callbacks, NULL, config, pool));
112 SVN_ERR (svn_ra_open2 (&ra_src, src_url, callbacks, NULL, config, pool));
114 SVN_ERR (svn_ra_get_commit_editor2 (ra_dest, &editor, &edit_baton,
115 "Hello World!", my_commit_callback,
116 NULL, NULL, TRUE, pool));
118 /* Create a copy of the editor so we can hook some calls. */
119 my_editor = apr_palloc (pool, sizeof (*my_editor));
120 *my_editor = *editor;
122 /* Install the editor hooks. */
123 old_change_file_prop = editor->change_file_prop;
124 my_editor->change_file_prop = new_change_file_prop;
125 old_change_dir_prop = editor->change_dir_prop;
126 my_editor->change_dir_prop = new_change_dir_prop;
128 SVN_ERR (svn_ra_do_diff (ra_src, &reporter, &report_baton,
129 end_rev, "", TRUE, TRUE, src_url,
130 my_editor, edit_baton, pool));
131 SVN_ERR (reporter->set_path (report_baton, "", start_rev, 0, NULL, pool));
132 SVN_ERR (reporter->finish_report (report_baton, pool));
134 return SVN_NO_ERROR;
138 /* Version compatibility check */
139 static svn_error_t *
140 check_lib_versions (void)
142 static const svn_version_checklist_t checklist[] =
144 { "svn_subr", svn_subr_version },
145 { "svn_delta", svn_delta_version },
146 { "svn_ra", svn_ra_version },
147 { NULL, NULL }
150 SVN_VERSION_DEFINE (my_version);
151 return svn_ver_check_list (&my_version, checklist);
156 main (int argc, char *argv[])
158 apr_pool_t *pool;
159 svn_error_t *error = NULL;
160 int start_rev, end_rev;
161 char *src_url, *dest_url;
163 if (svn_cmdline_init ("svn-push", stderr) != EXIT_SUCCESS)
164 return EXIT_FAILURE;
166 if (argc != 5 ||
167 strcmp (argv[1], "-r") != 0 ||
168 sscanf (argv[2], "%i:%i", &start_rev, &end_rev) != 2)
170 fprintf(stderr, "%s", "Usage : svn-push -r N:M SRC_URL DEST_URL\n");
171 return EXIT_FAILURE;
174 src_url = argv[3];
175 dest_url = argv[4];
177 pool = svn_pool_create (NULL);
179 /* Check library versions */
180 error = check_lib_versions ();
181 if (error) goto error;
183 error = do_job (src_url, dest_url, start_rev, end_rev, pool);
184 if (error) goto error;
186 svn_pool_destroy (pool);
187 return EXIT_SUCCESS;
189 error:
190 svn_handle_error2 (error, stderr, FALSE, "svn-push: ");
191 return EXIT_FAILURE;