~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to tools/dev/svnraisetreeconflict/svnraisetreeconflict.c

  • Committer: Package Import Robot
  • Author(s): James McCoy, Peter Samuelson, James McCoy
  • Date: 2014-01-12 19:48:33 UTC
  • mfrom: (0.2.10)
  • Revision ID: package-import@ubuntu.com-20140112194833-w3axfwksn296jn5x
Tags: 1.8.5-1
[ Peter Samuelson ]
* New upstream release.  (Closes: #725787) Rediff patches:
  - Remove apr-abi1 (applied upstream), rename apr-abi2 to apr-abi
  - Remove loosen-sqlite-version-check (shouldn't be needed)
  - Remove java-osgi-metadata (applied upstream)
  - svnmucc prompts for a changelog if none is provided. (Closes: #507430)
  - Remove fix-bdb-version-detection, upstream uses "apu-config --dbm-libs"
  - Remove ruby-test-wc (applied upstream)
  - Fix “svn diff -r N file” when file has svn:mime-type set.
    (Closes: #734163)
  - Support specifying an encoding for mod_dav_svn's environment in which
    hooks are run.  (Closes: #601544)
  - Fix ordering of “svnadmin dump” paths with certain APR versions.
    (Closes: #687291)
  - Provide a better error message when authentication fails with an
    svn+ssh:// URL.  (Closes: #273874)
  - Updated Polish translations.  (Closes: #690815)

[ James McCoy ]
* Remove all traces of libneon, replaced by libserf.
* patches/sqlite_3.8.x_workaround: Upstream fix for wc-queries-test test
  failurse.
* Run configure with --with-apache-libexecdir, which allows removing part of
  patches/rpath.
* Re-enable auth-test as upstream has fixed the problem of picking up
  libraries from the environment rather than the build tree.
  (Closes: #654172)
* Point LD_LIBRARY_PATH at the built auth libraries when running the svn
  command during the build.  (Closes: #678224)
* Add a NEWS entry describing how to configure mod_dav_svn to understand
  UTF-8.  (Closes: #566148)
* Remove ancient transitional package, libsvn-ruby.
* Enable compatibility with Sqlite3 versions back to Wheezy.
* Enable hardening flags.  (Closes: #734918)
* patches/build-fixes: Enable verbose build logs.
* Build against the default ruby version.  (Closes: #722393)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* svnraisetreeconflict
 
2
 *
 
3
 * This is a crude command line tool that publishes API to create
 
4
 * tree-conflict markings in a working copy.
 
5
 *
 
6
 * To compile this, go to the root of the Subversion source tree and
 
7
 * call `make svnraisetreeconflict'. You will find the executable file
 
8
 * next to this source file.
 
9
 *
 
10
 * If you want to "install" svnraisetreeconflict, you may call
 
11
 * `make install-tools' in the Subversion source tree root.
 
12
 * (Note: This also installs any other installable tools.)
 
13
 *
 
14
 * svnraisetreeconflict cannot be compiled separate from a Subversion
 
15
 * source tree.
 
16
 *
 
17
 * ====================================================================
 
18
 *    Licensed to the Apache Software Foundation (ASF) under one
 
19
 *    or more contributor license agreements.  See the NOTICE file
 
20
 *    distributed with this work for additional information
 
21
 *    regarding copyright ownership.  The ASF licenses this file
 
22
 *    to you under the Apache License, Version 2.0 (the
 
23
 *    "License"); you may not use this file except in compliance
 
24
 *    with the License.  You may obtain a copy of the License at
 
25
 *
 
26
 *      http://www.apache.org/licenses/LICENSE-2.0
 
27
 *
 
28
 *    Unless required by applicable law or agreed to in writing,
 
29
 *    software distributed under the License is distributed on an
 
30
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 
31
 *    KIND, either express or implied.  See the License for the
 
32
 *    specific language governing permissions and limitations
 
33
 *    under the License.
 
34
 * ====================================================================
 
35
 */
 
36
 
 
37
#include "svn_cmdline.h"
 
38
#include "svn_pools.h"
 
39
#include "svn_wc.h"
 
40
#include "svn_utf.h"
 
41
#include "svn_path.h"
 
42
#include "svn_opt.h"
 
43
#include "svn_version.h"
 
44
 
 
45
#include "private/svn_wc_private.h"
 
46
#include "private/svn_cmdline_private.h"
 
47
 
 
48
#include "svn_private_config.h"
 
49
 
 
50
#define OPT_VERSION SVN_OPT_FIRST_LONGOPT_ID
 
51
 
 
52
/** A statement macro, similar to @c SVN_INT_ERR, but issues a
 
53
 * message saying "svnraisetreeconflict:" instead of "svn:".
 
54
 *
 
55
 * Evaluate @a expr. If it yields an error, handle that error and
 
56
 * return @c EXIT_FAILURE.
 
57
 */
 
58
#define SVNRAISETC_INT_ERR(expr)                                 \
 
59
  do {                                                           \
 
60
    svn_error_t *svn_err__temp = (expr);                         \
 
61
    if (svn_err__temp) {                                         \
 
62
      svn_handle_error2(svn_err__temp, stderr, FALSE,            \
 
63
                        "svnraisetreeconflict: ");               \
 
64
      svn_error_clear(svn_err__temp);                            \
 
65
      return EXIT_FAILURE; }                                     \
 
66
  } while (0)
 
67
 
 
68
static svn_error_t *
 
69
version(apr_pool_t *pool)
 
70
{
 
71
  return svn_opt_print_help4(NULL, "svnraisetreeconflict", TRUE, FALSE, FALSE,
 
72
                             NULL, NULL, NULL, NULL, NULL, NULL, pool);
 
73
}
 
74
 
 
75
static void
 
76
usage(apr_pool_t *pool)
 
77
{
 
78
  svn_error_clear(svn_cmdline_fprintf
 
79
                  (stderr, pool,
 
80
                   _("Type 'svnraisetreeconflict --help' for usage.\n")));
 
81
  exit(1);
 
82
}
 
83
 
 
84
/***************************************************************************
 
85
 * "enum mapping" functions copied from subversion/libsvn_wc/tree_conflicts.c
 
86
 **************************************************************************/
 
87
 
 
88
/* A mapping between a string STR and an enumeration value VAL. */
 
89
typedef struct enum_mapping_t
 
90
{
 
91
  const char *str;
 
92
  int val;
 
93
} enum_mapping_t;
 
94
 
 
95
/* A map for svn_node_kind_t values. */
 
96
static const enum_mapping_t node_kind_map[] =
 
97
{
 
98
  { "none",     svn_node_none },
 
99
  { "file",     svn_node_file },
 
100
  { "dir",      svn_node_dir },
 
101
  { "unknown",  svn_node_unknown },
 
102
  { NULL,              0 }
 
103
};
 
104
 
 
105
/* A map for svn_wc_operation_t values. */
 
106
static const enum_mapping_t operation_map[] =
 
107
{
 
108
  { "update",   svn_wc_operation_update },
 
109
  { "switch",   svn_wc_operation_switch },
 
110
  { "merge",    svn_wc_operation_merge },
 
111
  { NULL,                     0 }
 
112
};
 
113
 
 
114
/* A map for svn_wc_conflict_action_t values. */
 
115
static const enum_mapping_t action_map[] =
 
116
{
 
117
  { "edit",     svn_wc_conflict_action_edit },
 
118
  { "delete",   svn_wc_conflict_action_delete },
 
119
  { "add",      svn_wc_conflict_action_add },
 
120
  { NULL,                            0 }
 
121
};
 
122
 
 
123
/* A map for svn_wc_conflict_reason_t values. */
 
124
static const enum_mapping_t reason_map[] =
 
125
{
 
126
  { "edited",     svn_wc_conflict_reason_edited },
 
127
  { "deleted",    svn_wc_conflict_reason_deleted },
 
128
  { "missing",    svn_wc_conflict_reason_missing },
 
129
  { "obstructed", svn_wc_conflict_reason_obstructed },
 
130
  { "added",      svn_wc_conflict_reason_added },
 
131
  { NULL,                               0 }
 
132
};
 
133
 
 
134
/* Parse the enumeration field pointed to by *START into *RESULT as a plain
 
135
 * 'int', using MAP to convert from strings to enumeration values.
 
136
 * In MAP, a null STR field marks the end of the map.
 
137
 * Don't read further than END.
 
138
 * After reading, make *START point to the character after the field.
 
139
 */
 
140
static svn_error_t *
 
141
read_enum_field(int *result,
 
142
                const enum_mapping_t *map,
 
143
                const char *str,
 
144
                apr_pool_t *pool)
 
145
{
 
146
  int i;
 
147
 
 
148
  /* Find STR in MAP; error if not found. */
 
149
  for (i = 0; ; i++)
 
150
    {
 
151
      if (map[i].str == NULL)
 
152
        return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
 
153
                                 "Unrecognised parameter value: '%s'", str);
 
154
      if (strcmp(str, map[i].str) == 0)
 
155
        break;
 
156
    }
 
157
 
 
158
  *result = map[i].val;
 
159
  return SVN_NO_ERROR;
 
160
}
 
161
 
 
162
static const char*
 
163
get_enum_str(const enum_mapping_t *map,
 
164
             int enum_val)
 
165
{
 
166
  int i;
 
167
  for (i = 0; map[i].str != NULL; i++)
 
168
    {
 
169
      if (map[i].val == enum_val)
 
170
        return map[i].str;
 
171
    }
 
172
  return NULL;
 
173
}
 
174
 
 
175
static void
 
176
print_enum_map(const enum_mapping_t *map,
 
177
               apr_pool_t *pool)
 
178
{
 
179
  int i;
 
180
  for (i = 0; map[i].str != NULL; i++)
 
181
    svn_error_clear(svn_cmdline_fprintf(stdout, pool,
 
182
        " %s", map[i].str));
 
183
}
 
184
 
 
185
static svn_error_t *
 
186
raise_tree_conflict(int argc, const char **argv, apr_pool_t *pool)
 
187
{
 
188
  int i = 0;
 
189
  svn_wc_conflict_version_t *left, *right;
 
190
  svn_wc_conflict_description2_t *c;
 
191
  svn_wc_context_t *wc_ctx;
 
192
 
 
193
  /* Conflict description parameters */
 
194
  const char *wc_path, *wc_abspath;
 
195
  const char *repos_url1, *repos_url2, *path_in_repos1, *path_in_repos2;
 
196
  int operation, action, reason;
 
197
  long peg_rev1, peg_rev2;
 
198
  int kind, kind1, kind2;
 
199
 
 
200
  if (argc != 13)
 
201
    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
 
202
                            "Wrong number of arguments");
 
203
 
 
204
  /* Read the parameters */
 
205
  wc_path = svn_dirent_internal_style(argv[i++], pool);
 
206
  SVN_ERR(read_enum_field(&kind, node_kind_map, argv[i++], pool));
 
207
  SVN_ERR(read_enum_field(&operation, operation_map, argv[i++], pool));
 
208
  SVN_ERR(read_enum_field(&action, action_map, argv[i++], pool));
 
209
  SVN_ERR(read_enum_field(&reason, reason_map, argv[i++], pool));
 
210
  repos_url1 = argv[i++];
 
211
  path_in_repos1 = argv[i++];
 
212
  peg_rev1 = atol(argv[i++]);
 
213
  SVN_ERR(read_enum_field(&kind1, node_kind_map, argv[i++], pool));
 
214
  repos_url2 = argv[i++];
 
215
  path_in_repos2 = argv[i++];
 
216
  peg_rev2 = atol(argv[i++]);
 
217
  SVN_ERR(read_enum_field(&kind2, node_kind_map, argv[i++], pool));
 
218
 
 
219
 
 
220
  /* Allocate and fill in the description data structures */
 
221
  SVN_ERR(svn_dirent_get_absolute(&wc_abspath, wc_path, pool));
 
222
  left = svn_wc_conflict_version_create2(repos_url1, NULL, path_in_repos1,
 
223
                                         peg_rev1, kind1, pool);
 
224
  right = svn_wc_conflict_version_create2(repos_url2, NULL, path_in_repos2,
 
225
                                          peg_rev2, kind2, pool);
 
226
  c = svn_wc_conflict_description_create_tree2(wc_abspath, kind,
 
227
                                              operation, left, right, pool);
 
228
  c->action = (svn_wc_conflict_action_t)action;
 
229
  c->reason = (svn_wc_conflict_reason_t)reason;
 
230
 
 
231
  /* Raise the conflict */
 
232
  SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool));
 
233
  SVN_ERR(svn_wc__add_tree_conflict(wc_ctx, c, pool));
 
234
 
 
235
  return SVN_NO_ERROR;
 
236
}
 
237
 
 
238
 
 
239
static void
 
240
help(const apr_getopt_option_t *options, apr_pool_t *pool)
 
241
{
 
242
  svn_error_clear
 
243
    (svn_cmdline_fprintf
 
244
     (stdout, pool,
 
245
      _("usage: svnraisetreeconflict [OPTIONS] WC_PATH NODE_KIND OPERATION ACTION REASON REPOS_URL1 PATH_IN_REPOS1 PEG_REV1 NODE_KIND1 REPOS_URL2 PATH_IN_REPOS2 PEG_REV2 NODE_KIND2\n\n"
 
246
        "  Mark the working-copy node WC_PATH as being the victim of a tree conflict.\n"
 
247
        "\n"
 
248
        "  WC_PATH's parent directory must be a working copy, otherwise a\n"
 
249
        "  tree conflict cannot be raised.\n"
 
250
        "\n"
 
251
        "Valid options:\n")));
 
252
  while (options->description)
 
253
    {
 
254
      const char *optstr;
 
255
      svn_opt_format_option(&optstr, options, TRUE, pool);
 
256
      svn_error_clear(svn_cmdline_fprintf(stdout, pool, "  %s\n", optstr));
 
257
      ++options;
 
258
    }
 
259
  svn_error_clear(svn_cmdline_fprintf(stdout, pool,
 
260
      _("\n"
 
261
      "Valid enum argument values:\n"
 
262
      "  NODE_KIND, NODE_KIND1, NODE_KIND2:\n"
 
263
      "   ")));
 
264
  print_enum_map(node_kind_map, pool);
 
265
  svn_error_clear(svn_cmdline_fprintf(stdout, pool,
 
266
      _("\n"
 
267
      "  OPERATION:\n"
 
268
      "   ")));
 
269
  print_enum_map(operation_map, pool);
 
270
  svn_error_clear(svn_cmdline_fprintf(stdout, pool,
 
271
      _("\n"
 
272
      "  ACTION (what svn tried to do):\n"
 
273
      "   ")));
 
274
  print_enum_map(action_map, pool);
 
275
  svn_error_clear(svn_cmdline_fprintf(stdout, pool,
 
276
      _("\n"
 
277
      "  REASON (what local change made svn fail):\n"
 
278
      "   ")));
 
279
  print_enum_map(reason_map, pool);
 
280
  svn_error_clear(svn_cmdline_fprintf(stdout, pool,
 
281
      _("\n"
 
282
      "  REPOS_URL1, REPOS_URL2:\n"
 
283
      "    The URL of the repository itself, e.g.: file://usr/repos\n"
 
284
      "  PATH_IN_REPOS1, PATH_IN_REPOS2:\n"
 
285
      "    The complete path of the node in the repository, e.g.: sub/dir/foo\n"
 
286
      "  PEG_REV1, PEG_REV2:\n"
 
287
      "    The revision number at which the given path is relevant.\n"
 
288
      "\n"
 
289
      "Example:\n"
 
290
      "  svnraisetreeconflict ./foo %s %s %s %s file://usr/repos sub/dir/foo 1 %s file://usr/repos sub/dir/foo 3 %s\n\n"),
 
291
      get_enum_str(node_kind_map, svn_node_file),
 
292
      get_enum_str(operation_map, svn_wc_operation_update),
 
293
      get_enum_str(action_map, svn_wc_conflict_action_delete),
 
294
      get_enum_str(reason_map, svn_wc_conflict_reason_deleted),
 
295
      get_enum_str(node_kind_map, svn_node_file),
 
296
      get_enum_str(node_kind_map, svn_node_none)
 
297
      ));
 
298
  exit(0);
 
299
}
 
300
 
 
301
 
 
302
/* Version compatibility check */
 
303
static svn_error_t *
 
304
check_lib_versions(void)
 
305
{
 
306
  static const svn_version_checklist_t checklist[] =
 
307
    {
 
308
      { "svn_subr",   svn_subr_version },
 
309
      { "svn_wc",     svn_wc_version },
 
310
      { NULL, NULL }
 
311
    };
 
312
  SVN_VERSION_DEFINE(my_version);
 
313
 
 
314
  return svn_ver_check_list(&my_version, checklist);
 
315
}
 
316
 
 
317
int
 
318
main(int argc, const char *argv[])
 
319
{
 
320
  apr_pool_t *pool;
 
321
  svn_error_t *err;
 
322
  apr_getopt_t *os;
 
323
  const apr_getopt_option_t options[] =
 
324
    {
 
325
      {"help", 'h', 0, N_("display this help")},
 
326
      {"version", OPT_VERSION, 0,
 
327
       N_("show program version information")},
 
328
      {0,             0,  0,  0}
 
329
    };
 
330
  apr_array_header_t *remaining_argv;
 
331
 
 
332
  /* Initialize the app. */
 
333
  if (svn_cmdline_init("svnraisetreeconflict", stderr) != EXIT_SUCCESS)
 
334
    return EXIT_FAILURE;
 
335
 
 
336
  /* Create our top-level pool.  Use a separate mutexless allocator,
 
337
   * given this application is single threaded.
 
338
   */
 
339
  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
 
340
 
 
341
  /* Check library versions */
 
342
  err = check_lib_versions();
 
343
  if (err)
 
344
    return svn_cmdline_handle_exit_error(err, pool, "svnraisetreeconflict: ");
 
345
 
 
346
#if defined(WIN32) || defined(__CYGWIN__)
 
347
  /* Set the working copy administrative directory name. */
 
348
  if (getenv("SVN_ASP_DOT_NET_HACK"))
 
349
    {
 
350
      err = svn_wc_set_adm_dir("_svn", pool);
 
351
      if (err)
 
352
        return svn_cmdline_handle_exit_error(err, pool, "svnraisetreeconflict: ");
 
353
    }
 
354
#endif
 
355
 
 
356
  err = svn_cmdline__getopt_init(&os, argc, argv, pool);
 
357
  if (err)
 
358
    return svn_cmdline_handle_exit_error(err, pool, "svnraisetreeconflict: ");
 
359
 
 
360
  os->interleave = 1;
 
361
  while (1)
 
362
    {
 
363
      int opt;
 
364
      const char *arg;
 
365
      apr_status_t status = apr_getopt_long(os, options, &opt, &arg);
 
366
      if (APR_STATUS_IS_EOF(status))
 
367
        break;
 
368
      if (status != APR_SUCCESS)
 
369
        usage(pool);  /* this will exit() */
 
370
 
 
371
      switch (opt)
 
372
        {
 
373
        case 'h':
 
374
          help(options, pool);
 
375
          break;
 
376
        case OPT_VERSION:
 
377
          SVNRAISETC_INT_ERR(version(pool));
 
378
          exit(0);
 
379
          break;
 
380
        default:
 
381
          usage(pool);  /* this will exit() */
 
382
        }
 
383
    }
 
384
 
 
385
  /* Convert the remaining arguments to UTF-8. */
 
386
  remaining_argv = apr_array_make(pool, 0, sizeof(const char *));
 
387
  while (os->ind < argc)
 
388
    {
 
389
      const char *s;
 
390
 
 
391
      SVNRAISETC_INT_ERR(svn_utf_cstring_to_utf8(&s, os->argv[os->ind++],
 
392
                                                 pool));
 
393
      APR_ARRAY_PUSH(remaining_argv, const char *) = s;
 
394
    }
 
395
 
 
396
  if (remaining_argv->nelts < 1)
 
397
    usage(pool);  /* this will exit() */
 
398
 
 
399
  /* Do the main task */
 
400
  SVNRAISETC_INT_ERR(raise_tree_conflict(remaining_argv->nelts,
 
401
                                         (const char **)remaining_argv->elts,
 
402
                                         pool));
 
403
 
 
404
  svn_pool_destroy(pool);
 
405
 
 
406
  /* Flush stdout to make sure that the user will see any printing errors. */
 
407
  SVNRAISETC_INT_ERR(svn_cmdline_fflush(stdout));
 
408
 
 
409
  return EXIT_SUCCESS;
 
410
}