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

« back to all changes in this revision

Viewing changes to subversion/svn/mergeinfo-cmd.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:
55
55
  return SVN_NO_ERROR;
56
56
}
57
57
 
 
58
/* Draw a diagram (by printing text to the console) summarizing the state
 
59
 * of merging between two branches, given the merge description
 
60
 * indicated by YCA, BASE, RIGHT, TARGET, REINTEGRATE_LIKE. */
 
61
static svn_error_t *
 
62
mergeinfo_diagram(const char *yca_url,
 
63
                  const char *base_url,
 
64
                  const char *right_url,
 
65
                  const char *target_url,
 
66
                  svn_revnum_t yca_rev,
 
67
                  svn_revnum_t base_rev,
 
68
                  svn_revnum_t right_rev,
 
69
                  svn_revnum_t target_rev,
 
70
                  const char *repos_root_url,
 
71
                  svn_boolean_t target_is_wc,
 
72
                  svn_boolean_t reintegrate_like,
 
73
                  apr_pool_t *pool)
 
74
{
 
75
  /* The graph occupies 4 rows of text, and the annotations occupy
 
76
   * another 2 rows above and 2 rows below.  The graph is constructed
 
77
   * from left to right in discrete sections ("columns"), each of which
 
78
   * can have a different width (measured in characters).  Each element in
 
79
   * the array is either a text string of the appropriate width, or can
 
80
   * be NULL to draw a blank cell. */
 
81
#define ROWS 8
 
82
#define COLS 4
 
83
  const char *g[ROWS][COLS] = {{0}};
 
84
  int col_width[COLS];
 
85
  int row, col;
 
86
 
 
87
  /* The YCA (that is, the branching point).  And an ellipsis, because we
 
88
   * don't show information about earlier merges */
 
89
  g[0][0] = apr_psprintf(pool, "  %-8ld  ", yca_rev);
 
90
  g[1][0] =     "  |         ";
 
91
  if (strcmp(yca_url, right_url) == 0)
 
92
    {
 
93
      g[2][0] = "-------| |--";
 
94
      g[3][0] = "   \\        ";
 
95
      g[4][0] = "    \\       ";
 
96
      g[5][0] = "     --| |--";
 
97
    }
 
98
  else if (strcmp(yca_url, target_url) == 0)
 
99
    {
 
100
      g[2][0] = "     --| |--";
 
101
      g[3][0] = "    /       ";
 
102
      g[4][0] = "   /        ";
 
103
      g[5][0] = "-------| |--";
 
104
    }
 
105
  else
 
106
    {
 
107
      g[2][0] = "     --| |--";
 
108
      g[3][0] = "... /       ";
 
109
      g[4][0] = "    \\       ";
 
110
      g[5][0] = "     --| |--";
 
111
    }
 
112
 
 
113
  /* The last full merge */
 
114
  if ((base_rev > yca_rev) && reintegrate_like)
 
115
    {
 
116
      g[2][2] = "---------";
 
117
      g[3][2] = "  /      ";
 
118
      g[4][2] = " /       ";
 
119
      g[5][2] = "---------";
 
120
      g[6][2] = "|        ";
 
121
      g[7][2] = apr_psprintf(pool, "%-8ld ", base_rev);
 
122
    }
 
123
  else if (base_rev > yca_rev)
 
124
    {
 
125
      g[0][2] = apr_psprintf(pool, "%-8ld ", base_rev);
 
126
      g[1][2] = "|        ";
 
127
      g[2][2] = "---------";
 
128
      g[3][2] = " \\       ";
 
129
      g[4][2] = "  \\      ";
 
130
      g[5][2] = "---------";
 
131
    }
 
132
  else
 
133
    {
 
134
      g[2][2] = "---------";
 
135
      g[3][2] = "         ";
 
136
      g[4][2] = "         ";
 
137
      g[5][2] = "---------";
 
138
    }
 
139
 
 
140
  /* The tips of the branches */
 
141
    {
 
142
      g[0][3] = apr_psprintf(pool, "%-8ld", right_rev);
 
143
      g[1][3] = "|       ";
 
144
      g[2][3] = "-       ";
 
145
      g[3][3] = "        ";
 
146
      g[4][3] = "        ";
 
147
      g[5][3] = "-       ";
 
148
      g[6][3] = "|       ";
 
149
      g[7][3] = target_is_wc ? "WC      "
 
150
                             : apr_psprintf(pool, "%-8ld", target_rev);
 
151
    }
 
152
 
 
153
  /* Find the width of each column, so we know how to print blank cells */
 
154
  for (col = 0; col < COLS; col++)
 
155
    {
 
156
      col_width[col] = 0;
 
157
      for (row = 0; row < ROWS; row++)
 
158
        {
 
159
          if (g[row][col] && ((int)strlen(g[row][col]) > col_width[col]))
 
160
            col_width[col] = (int)strlen(g[row][col]);
 
161
        }
 
162
    }
 
163
 
 
164
  /* Column headings */
 
165
  SVN_ERR(svn_cmdline_printf(pool,
 
166
            "    %s\n"
 
167
            "    |         %s\n"
 
168
            "    |         |        %s\n"
 
169
            "    |         |        |         %s\n"
 
170
            "\n",
 
171
            _("youngest common ancestor"), _("last full merge"),
 
172
            _("tip of branch"), _("repository path")));
 
173
 
 
174
  /* Print the diagram, row by row */
 
175
  for (row = 0; row < ROWS; row++)
 
176
    {
 
177
      SVN_ERR(svn_cmdline_fputs("  ", stdout, pool));
 
178
      for (col = 0; col < COLS; col++)
 
179
        {
 
180
          if (g[row][col])
 
181
            {
 
182
              SVN_ERR(svn_cmdline_fputs(g[row][col], stdout, pool));
 
183
            }
 
184
          else
 
185
            {
 
186
              /* Print <column-width> spaces */
 
187
              SVN_ERR(svn_cmdline_printf(pool, "%*s", col_width[col], ""));
 
188
            }
 
189
        }
 
190
      if (row == 2)
 
191
        SVN_ERR(svn_cmdline_printf(pool, "  %s",
 
192
                svn_uri_skip_ancestor(repos_root_url, right_url, pool)));
 
193
      if (row == 5)
 
194
        SVN_ERR(svn_cmdline_printf(pool, "  %s",
 
195
                svn_uri_skip_ancestor(repos_root_url, target_url, pool)));
 
196
      SVN_ERR(svn_cmdline_fputs("\n", stdout, pool));
 
197
    }
 
198
 
 
199
  return SVN_NO_ERROR;
 
200
}
 
201
 
 
202
/* Display a summary of the state of merging between the two branches
 
203
 * SOURCE_PATH_OR_URL@SOURCE_REVISION and
 
204
 * TARGET_PATH_OR_URL@TARGET_REVISION. */
 
205
static svn_error_t *
 
206
mergeinfo_summary(
 
207
                  const char *source_path_or_url,
 
208
                  const svn_opt_revision_t *source_revision,
 
209
                  const char *target_path_or_url,
 
210
                  const svn_opt_revision_t *target_revision,
 
211
                  svn_client_ctx_t *ctx,
 
212
                  apr_pool_t *pool)
 
213
{
 
214
  const char *yca_url, *base_url, *right_url, *target_url;
 
215
  svn_revnum_t yca_rev, base_rev, right_rev, target_rev;
 
216
  const char *repos_root_url;
 
217
  svn_boolean_t target_is_wc, is_reintegration;
 
218
 
 
219
  target_is_wc = (! svn_path_is_url(target_path_or_url))
 
220
                 && (target_revision->kind == svn_opt_revision_unspecified
 
221
                     || target_revision->kind == svn_opt_revision_working);
 
222
  SVN_ERR(svn_client_get_merging_summary(
 
223
            &is_reintegration,
 
224
            &yca_url, &yca_rev,
 
225
            &base_url, &base_rev,
 
226
            &right_url, &right_rev,
 
227
            &target_url, &target_rev,
 
228
            &repos_root_url,
 
229
            source_path_or_url, source_revision,
 
230
            target_path_or_url, target_revision,
 
231
            ctx, pool, pool));
 
232
 
 
233
  SVN_ERR(mergeinfo_diagram(yca_url, base_url, right_url, target_url,
 
234
                            yca_rev, base_rev, right_rev, target_rev,
 
235
                            repos_root_url, target_is_wc, is_reintegration,
 
236
                            pool));
 
237
 
 
238
  return SVN_NO_ERROR;
 
239
}
 
240
 
58
241
/* This implements the `svn_opt_subcommand_t' interface. */
59
242
svn_error_t *
60
243
svn_cl__mergeinfo(apr_getopt_t *os,
66
249
  apr_array_header_t *targets;
67
250
  const char *source, *target;
68
251
  svn_opt_revision_t src_peg_revision, tgt_peg_revision;
 
252
  svn_opt_revision_t *src_start_revision, *src_end_revision;
69
253
  /* Default to depth empty. */
70
 
  svn_depth_t depth = opt_state->depth == svn_depth_unknown
71
 
    ? svn_depth_empty : opt_state->depth;
 
254
  svn_depth_t depth = (opt_state->depth == svn_depth_unknown)
 
255
                      ? svn_depth_empty : opt_state->depth;
72
256
 
73
257
  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
74
258
                                                      opt_state->targets,
75
259
                                                      ctx, FALSE, pool));
76
260
 
77
 
  /* We expect a single source URL followed by a single target --
78
 
     nothing more, nothing less. */
 
261
  /* Parse the arguments: SOURCE[@REV] optionally followed by TARGET[@REV]. */
79
262
  if (targets->nelts < 1)
80
263
    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
81
264
                            _("Not enough arguments given"));
82
265
  if (targets->nelts > 2)
83
266
    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
84
267
                            _("Too many arguments given"));
85
 
 
86
 
  /* Parse the SOURCE-URL[@REV] argument. */
87
268
  SVN_ERR(svn_opt_parse_path(&src_peg_revision, &source,
88
269
                             APR_ARRAY_IDX(targets, 0, const char *), pool));
89
 
 
90
 
  /* Parse the TARGET[@REV] argument (if provided). */
91
270
  if (targets->nelts == 2)
92
271
    {
93
272
      SVN_ERR(svn_opt_parse_path(&tgt_peg_revision, &target,
101
280
    }
102
281
 
103
282
  /* If no peg-rev was attached to the source URL, assume HEAD. */
 
283
  /* ### But what if SOURCE is a WC path not a URL -- shouldn't we then use
 
284
   *     BASE (but not WORKING: that would be inconsistent with 'svn merge')? */
104
285
  if (src_peg_revision.kind == svn_opt_revision_unspecified)
105
286
    src_peg_revision.kind = svn_opt_revision_head;
106
287
 
107
288
  /* If no peg-rev was attached to a URL target, then assume HEAD; if
108
289
     no peg-rev was attached to a non-URL target, then assume BASE. */
 
290
  /* ### But we would like to be able to examine a working copy with an
 
291
         uncommitted merge in it, so change this to use WORKING not BASE? */
109
292
  if (tgt_peg_revision.kind == svn_opt_revision_unspecified)
110
293
    {
111
294
      if (svn_path_is_url(target))
114
297
        tgt_peg_revision.kind = svn_opt_revision_base;
115
298
    }
116
299
 
 
300
  src_start_revision = &(opt_state->start_revision);
 
301
  if (opt_state->end_revision.kind == svn_opt_revision_unspecified)
 
302
    src_end_revision = src_start_revision;
 
303
  else
 
304
    src_end_revision = &(opt_state->end_revision);
 
305
 
117
306
  /* Do the real work, depending on the requested data flavor. */
118
307
  if (opt_state->show_revs == svn_cl__show_revs_merged)
119
308
    {
120
 
      SVN_ERR(svn_client_mergeinfo_log(TRUE, target, &tgt_peg_revision,
121
 
                                       source, &src_peg_revision,
122
 
                                       print_log_rev, NULL,
123
 
                                       TRUE, depth, NULL, ctx,
124
 
                                       pool));
 
309
      apr_array_header_t *revprops;
 
310
 
 
311
      /* We need only revisions number, not revision properties. */
 
312
      revprops = apr_array_make(pool, 0, sizeof(const char *));
 
313
 
 
314
      SVN_ERR(svn_client_mergeinfo_log2(TRUE, target, &tgt_peg_revision,
 
315
                                        source, &src_peg_revision,
 
316
                                        src_start_revision,
 
317
                                        src_end_revision,
 
318
                                        print_log_rev, NULL,
 
319
                                        TRUE, depth, revprops, ctx,
 
320
                                        pool));
125
321
    }
126
322
  else if (opt_state->show_revs == svn_cl__show_revs_eligible)
127
323
    {
128
 
      SVN_ERR(svn_client_mergeinfo_log(FALSE, target, &tgt_peg_revision,
129
 
                                       source, &src_peg_revision,
130
 
                                       print_log_rev, NULL,
131
 
                                       TRUE, depth, NULL, ctx,
132
 
                                       pool));
 
324
      apr_array_header_t *revprops;
 
325
 
 
326
      /* We need only revisions number, not revision properties. */
 
327
      revprops = apr_array_make(pool, 0, sizeof(const char *));
 
328
 
 
329
      SVN_ERR(svn_client_mergeinfo_log2(FALSE, target, &tgt_peg_revision,
 
330
                                        source, &src_peg_revision,
 
331
                                        src_start_revision,
 
332
                                        src_end_revision,
 
333
                                        print_log_rev, NULL,
 
334
                                        TRUE, depth, revprops, ctx,
 
335
                                        pool));
 
336
    }
 
337
  else
 
338
    {
 
339
      if ((opt_state->start_revision.kind != svn_opt_revision_unspecified)
 
340
          || (opt_state->end_revision.kind != svn_opt_revision_unspecified))
 
341
        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
 
342
                                _("--revision (-r) option valid only with "
 
343
                                  "--show-revs option"));
 
344
      if (opt_state->depth != svn_depth_unknown)
 
345
        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
 
346
                                _("Depth specification options valid only "
 
347
                                  "with --show-revs option"));
 
348
 
 
349
      SVN_ERR(mergeinfo_summary(source, &src_peg_revision,
 
350
                                target, &tgt_peg_revision,
 
351
                                ctx, pool));
133
352
    }
134
353
  return SVN_NO_ERROR;
135
354
}