You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by iv...@apache.org on 2015/09/11 17:51:34 UTC
svn commit: r1702504 [16/19] - in /subversion/branches/reuse-ra-session: ./
build/ build/ac-macros/ build/generator/ build/generator/templates/
contrib/hook-scripts/ notes/ subversion/bindings/ctypes-python/csvn/ext/
subversion/bindings/javahl/native/ ...
Modified: subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c Fri Sep 11 15:51:30 2015
@@ -128,9 +128,10 @@ svn_cl__accept_from_word(const char *wor
/* Print on stdout a diff that shows incoming conflicting changes
- * corresponding to the conflict described in DESC. */
+ * corresponding to the conflict described in CONFLICT. */
static svn_error_t *
-show_diff(const svn_wc_conflict_description2_t *desc,
+show_diff(const svn_client_conflict_t *conflict,
+ const char *merged_abspath,
const char *path_prefix,
svn_cancel_func_t cancel_func,
void *cancel_baton,
@@ -141,10 +142,13 @@ show_diff(const svn_wc_conflict_descript
svn_diff_t *diff;
svn_stream_t *output;
svn_diff_file_options_t *options;
- const char *merged_file;
+ const char *my_abspath;
+ const char *their_abspath;
- merged_file = svn_client_conflict_get_merged_file(desc);
- if (merged_file)
+ SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath, NULL,
+ &their_abspath,
+ conflict, pool, pool));
+ if (merged_abspath)
{
/* For conflicts recorded by the 'merge' operation, show a diff between
* 'mine' (the working version of the file as it appeared before the
@@ -158,26 +162,26 @@ show_diff(const svn_wc_conflict_descript
*
* This way, the diff is always minimal and clearly identifies changes
* brought into the working copy by the update/switch/merge operation. */
- if (svn_client_conflict_get_operation(desc) == svn_wc_operation_merge)
+ if (svn_client_conflict_get_operation(conflict) == svn_wc_operation_merge)
{
- path1 = svn_client_conflict_get_my_abspath(desc);
+ path1 = my_abspath;
label1 = _("MINE");
}
else
{
- path1 = svn_client_conflict_get_their_abspath(desc);
+ path1 = their_abspath;
label1 = _("THEIRS");
}
- path2 = merged_file;
+ path2 = merged_abspath;
label2 = _("MERGED");
}
else
{
/* There's no merged file, but we can show the
difference between mine and theirs. */
- path1 = svn_client_conflict_get_their_abspath(desc);
+ path1 = their_abspath;
label1 = _("THEIRS");
- path2 = svn_client_conflict_get_my_abspath(desc);
+ path2 = my_abspath;
label2 = _("MINE");
}
@@ -206,9 +210,9 @@ show_diff(const svn_wc_conflict_descript
/* Print on stdout just the conflict hunks of a diff among the 'base', 'their'
- * and 'my' files of DESC. */
+ * and 'my' files of CONFLICT. */
static svn_error_t *
-show_conflicts(const svn_wc_conflict_description2_t *desc,
+show_conflicts(const svn_client_conflict_t *conflict,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *pool)
@@ -216,22 +220,22 @@ show_conflicts(const svn_wc_conflict_des
svn_diff_t *diff;
svn_stream_t *output;
svn_diff_file_options_t *options;
-
+ const char *base_abspath;
+ const char *my_abspath;
+ const char *their_abspath;
+
+ SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
+ &base_abspath, &their_abspath,
+ conflict, pool, pool));
options = svn_diff_file_options_create(pool);
options->ignore_eol_style = TRUE;
SVN_ERR(svn_stream_for_stdout(&output, pool));
- SVN_ERR(svn_diff_file_diff3_2(&diff,
- svn_client_conflict_get_base_abspath(desc),
- svn_client_conflict_get_my_abspath(desc),
- svn_client_conflict_get_their_abspath(desc),
+ SVN_ERR(svn_diff_file_diff3_2(&diff, base_abspath, my_abspath, their_abspath,
options, pool));
/* ### Consider putting the markers/labels from
### svn_wc__merge_internal in the conflict description. */
return svn_diff_file_output_merge3(
- output, diff,
- svn_client_conflict_get_base_abspath(desc),
- svn_client_conflict_get_my_abspath(desc),
- svn_client_conflict_get_their_abspath(desc),
+ output, diff, base_abspath, my_abspath, their_abspath,
_("||||||| ORIGINAL"),
_("<<<<<<< MINE (select with 'mc')"),
_(">>>>>>> THEIRS (select with 'tc')"),
@@ -245,61 +249,49 @@ show_conflicts(const svn_wc_conflict_des
/* Perform a 3-way merge of the conflicting values of a property,
* and write the result to the OUTPUT stream.
*
- * If MERGED_ABSPATH is non-NULL, use it as 'my' version instead of
- * DESC->MY_ABSPATH.
+ * If MERGED_PROPVAL is non-NULL, use it as 'my' version instead of
+ * MY_ABSPATH.
*
* Assume the values are printable UTF-8 text.
*/
static svn_error_t *
merge_prop_conflict(svn_stream_t *output,
- const svn_wc_conflict_description2_t *desc,
- const char *merged_abspath,
+ const svn_string_t *base_propval,
+ const svn_string_t *my_propval,
+ const svn_string_t *their_propval,
+ const svn_string_t *merged_propval,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *pool)
{
- const char *base_abspath = svn_client_conflict_get_base_abspath(desc);
- const char *my_abspath = svn_client_conflict_get_my_abspath(desc);
- const char *their_abspath = svn_client_conflict_get_their_abspath(desc);
svn_diff_file_options_t *options = svn_diff_file_options_create(pool);
svn_diff_t *diff;
- /* If any of the property values is missing, use an empty file instead
+ /* If any of the property values is missing, use an empty value instead
* for the purpose of showing a diff. */
- if (! base_abspath || ! my_abspath || ! their_abspath)
- {
- const char *empty_file;
-
- SVN_ERR(svn_io_open_unique_file3(NULL, &empty_file,
- NULL, svn_io_file_del_on_pool_cleanup,
- pool, pool));
- if (! base_abspath)
- base_abspath = empty_file;
- if (! my_abspath)
- my_abspath = empty_file;
- if (! their_abspath)
- their_abspath = empty_file;
- }
-
+ if (base_propval == NULL)
+ base_propval = svn_string_create_empty(pool);
+ if (my_propval == NULL)
+ my_propval = svn_string_create_empty(pool);
+ if (my_propval == NULL)
+ my_propval = svn_string_create_empty(pool);
+
options->ignore_eol_style = TRUE;
- SVN_ERR(svn_diff_file_diff3_2(&diff,
- base_abspath,
- merged_abspath ? merged_abspath : my_abspath,
- their_abspath,
- options, pool));
- SVN_ERR(svn_diff_file_output_merge3(output, diff,
- base_abspath,
- merged_abspath ? merged_abspath
- : my_abspath,
- their_abspath,
- _("||||||| ORIGINAL"),
- _("<<<<<<< MINE"),
- _(">>>>>>> THEIRS"),
- "=======",
- svn_diff_conflict_display_modified_original_latest,
- cancel_func,
- cancel_baton,
- pool));
+ SVN_ERR(svn_diff_mem_string_diff3(&diff, base_propval,
+ merged_propval ?
+ merged_propval : my_propval,
+ their_propval, options, pool));
+ SVN_ERR(svn_diff_mem_string_output_merge3(
+ output, diff, base_propval,
+ merged_propval ? merged_propval : my_propval, their_propval,
+ _("||||||| ORIGINAL"),
+ _("<<<<<<< MINE"),
+ _(">>>>>>> THEIRS"),
+ "=======",
+ svn_diff_conflict_display_modified_original_latest,
+ cancel_func,
+ cancel_baton,
+ pool));
return SVN_NO_ERROR;
}
@@ -312,8 +304,10 @@ merge_prop_conflict(svn_stream_t *output
* Assume the values are printable UTF-8 text.
*/
static svn_error_t *
-show_prop_conflict(const svn_wc_conflict_description2_t *desc,
- const char *merged_abspath,
+show_prop_conflict(const svn_string_t *base_propval,
+ const svn_string_t *my_propval,
+ const svn_string_t *their_propval,
+ const svn_string_t *merged_propval,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *pool)
@@ -321,13 +315,13 @@ show_prop_conflict(const svn_wc_conflict
svn_stream_t *output;
SVN_ERR(svn_stream_for_stdout(&output, pool));
- SVN_ERR(merge_prop_conflict(output, desc, merged_abspath,
- cancel_func, cancel_baton, pool));
+ SVN_ERR(merge_prop_conflict(output, base_propval, my_propval, their_propval,
+ merged_propval, cancel_func, cancel_baton, pool));
return SVN_NO_ERROR;
}
-/* Run an external editor, passing it the MERGED_FILE, or, if the
+/* Run an external editor, passing it the MERGED_ABSPATH, or, if the
* 'merged' file is null, return an error. The tool to use is determined by
* B->editor_cmd, B->config and environment variables; see
* svn_cl__edit_file_externally() for details.
@@ -338,15 +332,15 @@ show_prop_conflict(const svn_wc_conflict
* return that error. */
static svn_error_t *
open_editor(svn_boolean_t *performed_edit,
- const char *merged_file,
+ const char *merged_abspath,
svn_cl__interactive_conflict_baton_t *b,
apr_pool_t *pool)
{
svn_error_t *err;
- if (merged_file)
+ if (merged_abspath)
{
- err = svn_cmdline__edit_file_externally(merged_file, b->editor_cmd,
+ err = svn_cmdline__edit_file_externally(merged_abspath, b->editor_cmd,
b->config, pool);
if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR ||
err->apr_err == SVN_ERR_EXTERNAL_PROGRAM))
@@ -371,12 +365,16 @@ open_editor(svn_boolean_t *performed_edi
return SVN_NO_ERROR;
}
-/* Run an external editor, passing it the 'merged' property in DESC.
+/* Run an external editor on the merged property value with conflict markers.
+ * Return the edited result in *MERGED_PROPVAL.
+ * If the edit is aborted, set *MERGED_ABSPATH and *MERGED_PROPVAL to NULL.
* The tool to use is determined by B->editor_cmd, B->config and
* environment variables; see svn_cl__edit_file_externally() for details. */
static svn_error_t *
-edit_prop_conflict(const char **merged_file_path,
- const svn_wc_conflict_description2_t *desc,
+edit_prop_conflict(const svn_string_t **merged_propval,
+ const svn_string_t *base_propval,
+ const svn_string_t *my_propval,
+ const svn_string_t *their_propval,
svn_cl__interactive_conflict_baton_t *b,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
@@ -391,14 +389,23 @@ edit_prop_conflict(const char **merged_f
result_pool, scratch_pool));
merged_prop = svn_stream_from_aprfile2(file, TRUE /* disown */,
scratch_pool);
- SVN_ERR(merge_prop_conflict(merged_prop, desc, NULL,
+ SVN_ERR(merge_prop_conflict(merged_prop, base_propval, my_propval,
+ their_propval, NULL,
b->pb->cancel_func,
b->pb->cancel_baton,
scratch_pool));
SVN_ERR(svn_stream_close(merged_prop));
SVN_ERR(svn_io_file_flush(file, scratch_pool));
SVN_ERR(open_editor(&performed_edit, file_path, b, scratch_pool));
- *merged_file_path = (performed_edit ? file_path : NULL);
+ if (performed_edit)
+ {
+ svn_stringbuf_t *buf;
+
+ SVN_ERR(svn_stringbuf_from_file2(&buf, file_path, scratch_pool));
+ *merged_propval = svn_string_create_from_buf(buf, result_pool);
+ }
+ else
+ *merged_propval = NULL;
return SVN_NO_ERROR;
}
@@ -695,13 +702,13 @@ prompt_user(const resolver_option_t **op
return SVN_NO_ERROR;
}
-/* Ask the user what to do about the text conflict described by DESC.
+/* Ask the user what to do about the text conflict described by CONFLICT.
* Return the answer in RESULT. B is the conflict baton for this
* conflict resolution session.
* SCRATCH_POOL is used for temporary allocations. */
static svn_error_t *
handle_text_conflict(svn_wc_conflict_result_t *result,
- const svn_wc_conflict_description2_t *desc,
+ const svn_client_conflict_t *conflict,
svn_cl__interactive_conflict_baton_t *b,
apr_pool_t *scratch_pool)
{
@@ -715,15 +722,19 @@ handle_text_conflict(svn_wc_conflict_res
give them a rational basis for choosing (r)esolved? */
svn_boolean_t knows_something = FALSE;
const char *local_relpath;
- const char *local_abspath = svn_client_conflict_get_local_abspath(desc);
- svn_boolean_t is_binary = svn_client_conflict_get_is_binary(desc);
- const char *base_abspath = svn_client_conflict_get_base_abspath(desc);
- const char *my_abspath = svn_client_conflict_get_my_abspath(desc);
- const char *their_abspath = svn_client_conflict_get_their_abspath(desc);
- const char *merged_file = svn_client_conflict_get_merged_file(desc);
-
- SVN_ERR_ASSERT(svn_client_conflict_get_kind(desc) ==
- svn_wc_conflict_kind_text);
+ const char *local_abspath = svn_client_conflict_get_local_abspath(conflict);
+ const char *mime_type = svn_client_conflict_text_get_mime_type(conflict);
+ svn_boolean_t is_binary = mime_type ? svn_mime_type_is_binary(mime_type)
+ : FALSE;
+ const char *base_abspath;
+ const char *my_abspath;
+ const char *their_abspath;
+ const char *merged_abspath = svn_client_conflict_get_local_abspath(conflict);
+
+ SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
+ &base_abspath, &their_abspath,
+ conflict, scratch_pool,
+ scratch_pool));
local_relpath = svn_cl__local_style_skip_ancestor(b->path_prefix,
local_abspath,
@@ -747,7 +758,7 @@ handle_text_conflict(svn_wc_conflict_res
scenario), or if no base is available, we can show a diff
between mine and theirs. */
if (!is_binary &&
- ((merged_file && base_abspath)
+ ((merged_abspath && base_abspath)
|| (!base_abspath && my_abspath && their_abspath)))
diff_allowed = TRUE;
@@ -833,7 +844,7 @@ handle_text_conflict(svn_wc_conflict_res
"files not available.\n\n")));
continue;
}
- SVN_ERR(show_conflicts(desc,
+ SVN_ERR(show_conflicts(conflict,
b->pb->cancel_func,
b->pb->cancel_baton,
iterpool));
@@ -850,14 +861,14 @@ handle_text_conflict(svn_wc_conflict_res
continue;
}
- SVN_ERR(show_diff(desc, b->path_prefix,
+ SVN_ERR(show_diff(conflict, merged_abspath, b->path_prefix,
b->pb->cancel_func, b->pb->cancel_baton,
iterpool));
knows_something = TRUE;
}
else if (strcmp(opt->code, "e") == 0 || strcmp(opt->code, ":-E") == 0)
{
- SVN_ERR(open_editor(&performed_edit, merged_file, b, iterpool));
+ SVN_ERR(open_editor(&performed_edit, merged_abspath, b, iterpool));
if (performed_edit)
knows_something = TRUE;
}
@@ -878,7 +889,7 @@ handle_text_conflict(svn_wc_conflict_res
err = svn_cl__merge_file_externally(base_abspath,
their_abspath,
my_abspath,
- merged_file,
+ merged_abspath,
local_abspath, b->config,
NULL, iterpool);
if (err)
@@ -893,7 +904,7 @@ handle_text_conflict(svn_wc_conflict_res
base_abspath,
their_abspath,
my_abspath,
- merged_file,
+ merged_abspath,
local_abspath,
b->path_prefix,
b->editor_cmd,
@@ -931,9 +942,9 @@ handle_text_conflict(svn_wc_conflict_res
{
/* ### This check should be earlier as it's nasty to offer an option
* and then when the user chooses it say 'Invalid option'. */
- /* ### 'merged_file' shouldn't be necessary *before* we launch the
+ /* ### 'merged_abspath' shouldn't be necessary *before* we launch the
* resolver: it should be the *result* of doing so. */
- if (base_abspath && their_abspath && my_abspath && merged_file)
+ if (base_abspath && their_abspath && my_abspath && merged_abspath)
{
svn_error_t *err;
char buf[1024];
@@ -942,7 +953,7 @@ handle_text_conflict(svn_wc_conflict_res
err = svn_cl__merge_file_externally(base_abspath,
their_abspath,
my_abspath,
- merged_file,
+ merged_abspath,
local_abspath,
b->config, NULL, iterpool);
if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_MERGE_TOOL ||
@@ -973,7 +984,7 @@ handle_text_conflict(svn_wc_conflict_res
base_abspath,
their_abspath,
my_abspath,
- merged_file,
+ merged_abspath,
local_abspath,
b->path_prefix,
b->editor_cmd,
@@ -1022,41 +1033,40 @@ handle_text_conflict(svn_wc_conflict_res
return SVN_NO_ERROR;
}
-/* Ask the user what to do about the property conflict described by DESC.
+/* Ask the user what to do about the property conflict described by CONFLICT.
* Return the answer in RESULT. B is the conflict baton for this
* conflict resolution session.
* SCRATCH_POOL is used for temporary allocations. */
static svn_error_t *
handle_prop_conflict(svn_wc_conflict_result_t *result,
- const svn_wc_conflict_description2_t *desc,
+ const svn_client_conflict_t *conflict,
svn_cl__interactive_conflict_baton_t *b,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
apr_pool_t *iterpool;
const char *message;
- const char *merged_file_path = NULL;
+ const svn_string_t *merged_propval = NULL;
svn_boolean_t resolved_allowed = FALSE;
-
- /* ### Work around a historical bug in the provider: the path to the
- * conflict description file was put in the 'theirs' field, and
- * 'theirs' was put in the 'merged' field. */
- ((svn_wc_conflict_description2_t *)desc)->their_abspath = desc->merged_file;
- ((svn_wc_conflict_description2_t *)desc)->merged_file = NULL;
-
- SVN_ERR_ASSERT(svn_client_conflict_get_kind(desc) ==
- svn_wc_conflict_kind_property);
+ const svn_string_t *base_propval;
+ const svn_string_t *my_propval;
+ const svn_string_t *their_propval;
+
+ SVN_ERR(svn_client_conflict_prop_get_propvals(NULL, &my_propval,
+ &base_propval, &their_propval,
+ conflict, scratch_pool));
SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
_("Conflict for property '%s' discovered"
" on '%s'.\n"),
- svn_client_conflict_get_property_name(desc),
+ svn_client_conflict_prop_get_propname(conflict),
svn_cl__local_style_skip_ancestor(
b->path_prefix,
- svn_client_conflict_get_local_abspath(desc),
+ svn_client_conflict_get_local_abspath(conflict),
scratch_pool)));
- SVN_ERR(svn_cl__get_human_readable_prop_conflict_description(&message, desc,
+ SVN_ERR(svn_cl__get_human_readable_prop_conflict_description(&message,
+ conflict,
scratch_pool));
SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n", message));
@@ -1094,15 +1104,17 @@ handle_prop_conflict(svn_wc_conflict_res
}
else if (strcmp(opt->code, "dc") == 0)
{
- SVN_ERR(show_prop_conflict(desc, merged_file_path,
+ SVN_ERR(show_prop_conflict(base_propval, my_propval, their_propval,
+ merged_propval,
b->pb->cancel_func, b->pb->cancel_baton,
scratch_pool));
}
else if (strcmp(opt->code, "e") == 0)
{
- SVN_ERR(edit_prop_conflict(&merged_file_path, desc, b,
- result_pool, scratch_pool));
- resolved_allowed = (merged_file_path != NULL);
+ SVN_ERR(edit_prop_conflict(&merged_propval,
+ base_propval, my_propval, their_propval,
+ b, result_pool, scratch_pool));
+ resolved_allowed = (merged_propval != NULL);
}
else if (strcmp(opt->code, "r") == 0)
{
@@ -1114,7 +1126,7 @@ handle_prop_conflict(svn_wc_conflict_res
continue;
}
- result->merged_file = merged_file_path;
+ result->merged_value = merged_propval;
result->choice = svn_wc_conflict_choose_merged;
break;
}
@@ -1129,43 +1141,58 @@ handle_prop_conflict(svn_wc_conflict_res
return SVN_NO_ERROR;
}
-/* Ask the user what to do about the tree conflict described by DESC.
+/* Ask the user what to do about the tree conflict described by CONFLICT.
* Return the answer in RESULT. B is the conflict baton for this
* conflict resolution session.
* SCRATCH_POOL is used for temporary allocations. */
static svn_error_t *
handle_tree_conflict(svn_wc_conflict_result_t *result,
- const svn_wc_conflict_description2_t *desc,
+ const svn_client_conflict_t *conflict,
svn_cl__interactive_conflict_baton_t *b,
apr_pool_t *scratch_pool)
{
const char *readable_desc;
const char *src_left_version;
const char *src_right_version;
+ const char *repos_root_url;
+ const char *repos_relpath;
+ svn_revnum_t peg_rev;
+ svn_node_kind_t node_kind;
apr_pool_t *iterpool;
-
+
SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
- &readable_desc, desc, scratch_pool));
+ &readable_desc, conflict, scratch_pool));
SVN_ERR(svn_cmdline_fprintf(
stderr, scratch_pool,
_("Tree conflict on '%s'\n > %s\n"),
svn_cl__local_style_skip_ancestor(b->path_prefix,
- svn_client_conflict_get_local_abspath(desc), scratch_pool),
+ svn_client_conflict_get_local_abspath(conflict), scratch_pool),
readable_desc));
+ SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, NULL, conflict,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(&repos_relpath,
+ &peg_rev,
+ &node_kind,
+ conflict,
+ scratch_pool,
+ scratch_pool));
src_left_version =
- svn_cl__node_description(
- svn_client_conflict_get_src_left_version(desc),
- svn_client_conflict_get_src_left_version(desc)->repos_url,
- scratch_pool);
+ svn_cl__node_description(repos_root_url, repos_relpath, peg_rev,
+ node_kind, repos_root_url, scratch_pool);
if (src_left_version)
SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
_("Source left"), src_left_version));
+
+ SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(&repos_relpath,
+ &peg_rev,
+ &node_kind,
+ conflict,
+ scratch_pool,
+ scratch_pool));
src_right_version =
- svn_cl__node_description(
- svn_client_conflict_get_src_right_version(desc),
- svn_client_conflict_get_src_right_version(desc)->repos_url,
- scratch_pool);
+ svn_cl__node_description(repos_root_url, repos_relpath, peg_rev,
+ node_kind, repos_root_url, scratch_pool);
if (src_right_version)
SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
_("Source right"), src_right_version));
@@ -1180,12 +1207,14 @@ handle_tree_conflict(svn_wc_conflict_res
tc_opts = tree_conflict_options;
- if (svn_client_conflict_get_operation(desc) == svn_wc_operation_update ||
- svn_client_conflict_get_operation(desc) == svn_wc_operation_switch)
+ if (svn_client_conflict_get_operation(conflict) ==
+ svn_wc_operation_update ||
+ svn_client_conflict_get_operation(conflict) ==
+ svn_wc_operation_switch)
{
svn_wc_conflict_reason_t reason;
- reason = svn_client_conflict_get_local_change(desc);
+ reason = svn_client_conflict_get_local_change(conflict);
if (reason == svn_wc_conflict_reason_moved_away)
{
tc_opts = tree_conflict_options_update_moved_away;
@@ -1193,9 +1222,10 @@ handle_tree_conflict(svn_wc_conflict_res
else if (reason == svn_wc_conflict_reason_deleted ||
reason == svn_wc_conflict_reason_replaced)
{
- if (svn_client_conflict_get_incoming_change(desc) ==
+ if (svn_client_conflict_get_incoming_change(conflict) ==
svn_wc_conflict_action_edit &&
- svn_client_conflict_get_node_kind(desc) == svn_node_dir)
+ svn_client_conflict_tree_get_victim_node_kind(conflict) ==
+ svn_node_dir)
tc_opts = tree_conflict_options_update_edit_deleted_dir;
}
}
@@ -1225,17 +1255,24 @@ handle_tree_conflict(svn_wc_conflict_res
/* The body of svn_cl__conflict_func_interactive(). */
static svn_error_t *
conflict_func_interactive(svn_wc_conflict_result_t **result,
- const svn_wc_conflict_description2_t *desc,
+ const svn_client_conflict_t *conflict,
void *baton,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_cl__interactive_conflict_baton_t *b = baton;
svn_error_t *err;
- const char *base_abspath = svn_client_conflict_get_base_abspath(desc);
- const char *my_abspath = svn_client_conflict_get_my_abspath(desc);
- const char *their_abspath = svn_client_conflict_get_their_abspath(desc);
- const char *merged_file = svn_client_conflict_get_merged_file(desc);
+ const char *base_abspath = NULL;
+ const char *my_abspath = NULL;
+ const char *their_abspath = NULL;
+ const char *merged_abspath = svn_client_conflict_get_local_abspath(conflict);
+
+ if (svn_client_conflict_get_kind(conflict) == svn_wc_conflict_kind_text)
+ SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
+ &base_abspath,
+ &their_abspath,
+ conflict, scratch_pool,
+ scratch_pool));
/* Start out assuming we're going to postpone the conflict. */
*result = svn_wc_create_conflict_result(svn_wc_conflict_choose_postpone,
@@ -1254,10 +1291,6 @@ conflict_func_interactive(svn_wc_conflic
(*result)->choice = svn_wc_conflict_choose_base;
return SVN_NO_ERROR;
case svn_cl__accept_working:
- /* If the caller didn't merge the property values, then I guess
- * 'choose working' means 'choose mine'... */
- if (! merged_file)
- (*result)->merged_file = my_abspath;
(*result)->choice = svn_wc_conflict_choose_merged;
return SVN_NO_ERROR;
case svn_cl__accept_mine_conflict:
@@ -1273,7 +1306,7 @@ conflict_func_interactive(svn_wc_conflic
(*result)->choice = svn_wc_conflict_choose_theirs_full;
return SVN_NO_ERROR;
case svn_cl__accept_edit:
- if (merged_file)
+ if (merged_abspath)
{
if (b->external_failed)
{
@@ -1281,7 +1314,7 @@ conflict_func_interactive(svn_wc_conflic
return SVN_NO_ERROR;
}
- err = svn_cmdline__edit_file_externally(merged_file,
+ err = svn_cmdline__edit_file_externally(merged_abspath,
b->editor_cmd, b->config,
scratch_pool);
if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR ||
@@ -1304,7 +1337,7 @@ conflict_func_interactive(svn_wc_conflic
/* else, fall through to prompting. */
break;
case svn_cl__accept_launch:
- if (base_abspath && their_abspath && my_abspath && merged_file)
+ if (base_abspath && their_abspath && my_abspath && merged_abspath)
{
svn_boolean_t remains_in_conflict;
const char *local_abspath;
@@ -1315,11 +1348,11 @@ conflict_func_interactive(svn_wc_conflic
return SVN_NO_ERROR;
}
- local_abspath = svn_client_conflict_get_local_abspath(desc);
+ local_abspath = svn_client_conflict_get_local_abspath(conflict);
err = svn_cl__merge_file_externally(base_abspath,
their_abspath,
my_abspath,
- merged_file,
+ merged_abspath,
local_abspath,
b->config,
&remains_in_conflict,
@@ -1364,16 +1397,18 @@ conflict_func_interactive(svn_wc_conflic
Conflicting edits on a file's text, or
Conflicting edits on a property.
*/
- if (((svn_client_conflict_get_kind(desc) == svn_wc_conflict_kind_text)
- && (svn_client_conflict_get_incoming_change(desc) ==
+ if (((svn_client_conflict_get_kind(conflict) == svn_wc_conflict_kind_text)
+ && (svn_client_conflict_get_incoming_change(conflict) ==
svn_wc_conflict_action_edit)
- && (svn_client_conflict_get_local_change(desc) ==
+ && (svn_client_conflict_get_local_change(conflict) ==
svn_wc_conflict_reason_edited)))
- SVN_ERR(handle_text_conflict(*result, desc, b, scratch_pool));
- else if (svn_client_conflict_get_kind(desc) == svn_wc_conflict_kind_property)
- SVN_ERR(handle_prop_conflict(*result, desc, b, result_pool, scratch_pool));
- else if (svn_client_conflict_get_kind(desc) == svn_wc_conflict_kind_tree)
- SVN_ERR(handle_tree_conflict(*result, desc, b, scratch_pool));
+ SVN_ERR(handle_text_conflict(*result, conflict, b, scratch_pool));
+ else if (svn_client_conflict_get_kind(conflict) ==
+ svn_wc_conflict_kind_property)
+ SVN_ERR(handle_prop_conflict(*result, conflict, b, result_pool,
+ scratch_pool));
+ else if (svn_client_conflict_get_kind(conflict) == svn_wc_conflict_kind_tree)
+ SVN_ERR(handle_tree_conflict(*result, conflict, b, scratch_pool));
else /* other types of conflicts -- do nothing about them. */
{
@@ -1391,8 +1426,12 @@ svn_cl__conflict_func_interactive(svn_wc
apr_pool_t *scratch_pool)
{
svn_cl__interactive_conflict_baton_t *b = baton;
+ svn_client_conflict_t *conflict;
- SVN_ERR(conflict_func_interactive(result, desc, baton,
+ SVN_ERR(svn_client_conflict_from_wc_description2_t(&conflict, desc,
+ scratch_pool,
+ scratch_pool));
+ SVN_ERR(conflict_func_interactive(result, conflict, baton,
result_pool, scratch_pool));
/* If we are resolving a conflict, adjust the summary of conflicts. */
@@ -1400,11 +1439,11 @@ svn_cl__conflict_func_interactive(svn_wc
{
const char *local_path
= svn_cl__local_style_skip_ancestor(
- b->path_prefix, svn_client_conflict_get_local_abspath(desc),
+ b->path_prefix, svn_client_conflict_get_local_abspath(conflict),
scratch_pool);
svn_cl__conflict_stats_resolved(b->conflict_stats, local_path,
- svn_client_conflict_get_kind(desc));
+ svn_client_conflict_get_kind(conflict));
}
return SVN_NO_ERROR;
}
Modified: subversion/branches/reuse-ra-session/subversion/svn/help-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/help-cmd.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/help-cmd.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/help-cmd.c Fri Sep 11 15:51:30 2015
@@ -53,8 +53,9 @@ svn_cl__help(apr_getopt_t *os,
N_("usage: svn <subcommand> [options] [args]\n"
"Subversion command-line client.\n"
"Type 'svn help <subcommand>' for help on a specific subcommand.\n"
- "Type 'svn --version' to see the program version and RA modules\n"
- " or 'svn --version --quiet' to see just the version number.\n"
+ "Type 'svn --version' to see the program version and RA modules,\n"
+ " 'svn --version --verbose' to see dependency versions as well,\n"
+ " 'svn --version --quiet' to see just the version number.\n"
"\n"
"Most subcommands take file and/or directory arguments, recursing\n"
"on the directories. If no arguments are supplied to such a\n"
Modified: subversion/branches/reuse-ra-session/subversion/svn/info-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/info-cmd.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/info-cmd.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/info-cmd.c Fri Sep 11 15:51:30 2015
@@ -391,15 +391,24 @@ print_info_xml(void *baton,
if (info->wc_info && info->wc_info->conflicts)
{
int i;
+ apr_pool_t *iterpool;
+ iterpool = svn_pool_create(pool);
for (i = 0; i < info->wc_info->conflicts->nelts; i++)
{
- const svn_wc_conflict_description2_t *conflict =
+ const svn_wc_conflict_description2_t *desc =
APR_ARRAY_IDX(info->wc_info->conflicts, i,
const svn_wc_conflict_description2_t *);
+ svn_client_conflict_t *conflict;
- SVN_ERR(svn_cl__append_conflict_info_xml(sb, conflict, pool));
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_client_conflict_from_wc_description2_t(&conflict, desc,
+ iterpool,
+ iterpool));
+ SVN_ERR(svn_cl__append_conflict_info_xml(sb, conflict, iterpool));
}
+ svn_pool_destroy(iterpool);
}
if (info->lock)
@@ -581,27 +590,37 @@ print_info(void *baton,
if (info->wc_info->conflicts)
{
- svn_boolean_t printed_prop_conflict_file = FALSE;
svn_boolean_t printed_tc = FALSE;
+ svn_stringbuf_t *conflicted_props = NULL;
int i;
+ apr_pool_t *iterpool;
+ iterpool = svn_pool_create(pool);
for (i = 0; i < info->wc_info->conflicts->nelts; i++)
{
- const svn_wc_conflict_description2_t *conflict =
+ const svn_wc_conflict_description2_t *desc2 =
APR_ARRAY_IDX(info->wc_info->conflicts, i,
const svn_wc_conflict_description2_t *);
const char *desc;
- const char *base_abspath;
- const char *my_abspath;
- const char *their_abspath;
-
- base_abspath = svn_client_conflict_get_base_abspath(conflict);
- my_abspath = svn_client_conflict_get_my_abspath(conflict);
- their_abspath = svn_client_conflict_get_their_abspath(conflict);
-
+ const char *base_abspath = NULL;
+ const char *my_abspath = NULL;
+ const char *their_abspath = NULL;
+ svn_client_conflict_t *conflict;
+
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_client_conflict_from_wc_description2_t(&conflict,
+ desc2,
+ iterpool,
+ iterpool));
switch (svn_client_conflict_get_kind(conflict))
{
case svn_wc_conflict_kind_text:
+
+ SVN_ERR(svn_client_conflict_text_get_contents(
+ NULL, &my_abspath, &base_abspath, &their_abspath,
+ conflict, pool, pool));
+
if (base_abspath)
SVN_ERR(svn_cmdline_printf(pool,
_("Conflict Previous Base File: %s\n"),
@@ -628,15 +647,18 @@ print_info(void *baton,
break;
case svn_wc_conflict_kind_property:
- if (! printed_prop_conflict_file)
- SVN_ERR(svn_cmdline_printf(pool,
- _("Conflict Properties File: %s\n"),
- svn_cl__local_style_skip_ancestor(
- receiver_baton->path_prefix,
- svn_client_conflict_get_prop_reject_abspath(
- conflict),
- pool)));
- printed_prop_conflict_file = TRUE;
+ {
+ const char *name;
+
+ name = svn_client_conflict_prop_get_propname(conflict);
+ if (conflicted_props == NULL)
+ conflicted_props = svn_stringbuf_create(name, pool);
+ else
+ {
+ svn_stringbuf_appendbyte(conflicted_props, ' ');
+ svn_stringbuf_appendcstr(conflicted_props, name);
+ }
+ }
break;
case svn_wc_conflict_kind_tree:
@@ -650,6 +672,11 @@ print_info(void *baton,
break;
}
}
+ svn_pool_destroy(iterpool);
+
+ if (conflicted_props)
+ SVN_ERR(svn_cmdline_printf(pool, _("Conflicted Properties: %s\n"),
+ conflicted_props->data));
/* We only store one left and right version for all conflicts, which is
referenced from all conflicts.
@@ -658,10 +685,18 @@ print_info(void *baton,
{
const char *src_left_version;
const char *src_right_version;
- const svn_wc_conflict_description2_t *conflict =
+ const char *repos_root_url;
+ const char *repos_relpath;
+ svn_revnum_t peg_rev;
+ svn_node_kind_t node_kind;
+ const svn_wc_conflict_description2_t *desc2 =
APR_ARRAY_IDX(info->wc_info->conflicts, 0,
const svn_wc_conflict_description2_t *);
+ svn_client_conflict_t *conflict;
+
+ SVN_ERR(svn_client_conflict_from_wc_description2_t(&conflict, desc2,
+ pool, pool));
if (!printed_tc)
{
const char *desc;
@@ -669,21 +704,28 @@ print_info(void *baton,
SVN_ERR(svn_cl__get_human_readable_action_description(&desc,
svn_wc_conflict_action_edit,
svn_client_conflict_get_operation(conflict),
- svn_client_conflict_get_node_kind(conflict), pool));
+ info->kind,
+ pool));
SVN_ERR(svn_cmdline_printf(pool, "%s: %s\n",
_("Conflict Details"), desc));
}
+ SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, NULL,
+ conflict, pool, pool));
+ SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
+ &repos_relpath, &peg_rev, &node_kind, conflict,
+ pool, pool));
src_left_version =
- svn_cl__node_description(
- svn_client_conflict_get_src_left_version(conflict),
- info->repos_root_URL, pool);
+ svn_cl__node_description(repos_root_url, repos_relpath,
+ peg_rev, node_kind, info->repos_root_URL, pool);
+ SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
+ &repos_relpath, &peg_rev, &node_kind, conflict,
+ pool, pool));
src_right_version =
- svn_cl__node_description(
- svn_client_conflict_get_src_right_version(conflict),
- info->repos_root_URL, pool);
+ svn_cl__node_description(repos_root_url, repos_relpath,
+ peg_rev, node_kind, info->repos_root_URL, pool);
if (src_left_version)
SVN_ERR(svn_cmdline_printf(pool, " %s: %s\n",
Modified: subversion/branches/reuse-ra-session/subversion/svn/lock-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/lock-cmd.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/lock-cmd.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/lock-cmd.c Fri Sep 11 15:51:30 2015
@@ -80,6 +80,29 @@ get_comment(const char **comment, svn_cl
return SVN_NO_ERROR;
}
+/* Baton for notify_lock_handler */
+struct notify_lock_baton_t
+{
+ void *inner_baton;
+ svn_wc_notify_func2_t inner_notify;
+ svn_boolean_t had_failure;
+};
+
+/* Implements svn_wc_notify_func2_t for svn_cl__lock */
+static void
+notify_lock_handler(void *baton,
+ const svn_wc_notify_t *notify,
+ apr_pool_t *scratch_pool)
+{
+ struct notify_lock_baton_t *nlb = baton;
+
+ if (notify->action == svn_wc_notify_failed_lock)
+ nlb->had_failure = TRUE;
+
+ if (nlb->inner_notify)
+ nlb->inner_notify(nlb->inner_baton, notify, scratch_pool);
+}
+
/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
svn_cl__lock(apr_getopt_t *os,
@@ -90,6 +113,7 @@ svn_cl__lock(apr_getopt_t *os,
svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
apr_array_header_t *targets;
const char *comment;
+ struct notify_lock_baton_t nlb;
SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
opt_state->targets,
@@ -106,5 +130,18 @@ svn_cl__lock(apr_getopt_t *os,
SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, pool));
- return svn_client_lock(targets, comment, opt_state->force, ctx, pool);
+ nlb.inner_notify = ctx->notify_func2;
+ nlb.inner_baton = ctx->notify_baton2;
+ nlb.had_failure = FALSE;
+
+ ctx->notify_func2 = notify_lock_handler;
+ ctx->notify_baton2 = &nlb;
+
+ SVN_ERR(svn_client_lock(targets, comment, opt_state->force, ctx, pool));
+
+ if (nlb.had_failure)
+ return svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("One or more locks could not be obtained"));
+
+ return SVN_NO_ERROR;
}
Modified: subversion/branches/reuse-ra-session/subversion/svn/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/status.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/status.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/status.c Fri Sep 11 15:51:30 2015
@@ -282,11 +282,16 @@ print_status(const char *target_abspath,
if (tree_conflicted)
{
- const svn_wc_conflict_description2_t *tree_conflict;
- SVN_ERR(svn_wc__get_tree_conflict(&tree_conflict, ctx->wc_ctx,
+ const svn_wc_conflict_description2_t *desc2;
+ svn_client_conflict_t *tree_conflict;
+
+ SVN_ERR(svn_wc__get_tree_conflict(&desc2, ctx->wc_ctx,
local_abspath, pool, pool));
- SVN_ERR_ASSERT(tree_conflict != NULL);
+ SVN_ERR_ASSERT(desc2 != NULL);
+ SVN_ERR(svn_client_conflict_from_wc_description2_t(&tree_conflict,
+ desc2,
+ pool, pool));
tree_status_code = 'C';
SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
&desc, tree_conflict, pool));
Modified: subversion/branches/reuse-ra-session/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/svn.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/svn.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/svn.c Fri Sep 11 15:51:30 2015
@@ -415,7 +415,39 @@ const apr_getopt_option_t svn_cl__option
" "
"current revision (recommended when tagging)")},
{"show-item", opt_show_item, 1,
- N_("print only the item identified by ARG")},
+ N_("print only the item identified by ARG:\n"
+ " "
+ " 'kind' node kind of TARGET\n"
+ " "
+ " 'url' URL of TARGET in the repository\n"
+ " "
+ " 'relative-url'\n"
+ " "
+ " repository-relative URL of TARGET\n"
+ " "
+ " 'repos-root-url'\n"
+ " "
+ " root URL of repository\n"
+ " "
+ " 'repos-uuid' UUID of repository\n"
+ " "
+ " 'revision' specified or implied revision\n"
+ " "
+ " 'last-changed-revision'\n"
+ " "
+ " last change of TARGET at or before\n"
+ " "
+ " 'revision'\n"
+ " "
+ " 'last-changed-date'\n"
+ " "
+ " date of 'last-changed-revision'\n"
+ " "
+ " 'last-changed-author'\n"
+ " "
+ " author of 'last-changed-revision'\n"
+ " "
+ " 'wc-root' root of TARGET's working copy")},
/* Long-opt Aliases
*
@@ -726,23 +758,12 @@ const svn_opt_subcommand_desc2_t svn_cl_
"usage: info [TARGET[@REV]...]\n"
"\n"
" Print information about each TARGET (default: '.').\n"
- " TARGET may be either a working-copy path or URL. If specified, REV\n"
- " determines in which revision the target is first looked up.\n"
+ " TARGET may be either a working-copy path or a URL. If specified, REV\n"
+ " determines in which revision the target is first looked up; the default\n"
+ " is HEAD for a URL or BASE for a WC path.\n"
"\n"
" With --show-item, print only the value of one item of information\n"
- " about TARGET. One of the following items can be selected:\n"
- " kind the kind of TARGET\n"
- " url the URL of TARGET in the repository\n"
- " relative-url the repository-relative URL\n"
- " repos-root-url the repository root URL\n"
- " repos-uuid the repository UUID\n"
- " revision the revision of TARGET (defaults to BASE\n"
- " for working copy paths and HEAD for URLs)\n"
- " last-changed-revision the most recent revision in which TARGET\n"
- " was changed\n"
- " last-changed-date the date of the last-changed revision\n"
- " last-changed-author the author of the last-changed revision\n"
- " wc-root the root of TARGET's working copy"),
+ " about TARGET.\n"),
{'r', 'R', opt_depth, opt_targets, opt_incremental, opt_xml,
opt_changelist, opt_include_externals, opt_show_item, opt_no_newline}
},
Modified: subversion/branches/reuse-ra-session/subversion/svn/unlock-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/unlock-cmd.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/unlock-cmd.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/unlock-cmd.c Fri Sep 11 15:51:30 2015
@@ -39,6 +39,29 @@
/*** Code. ***/
+/* Baton for notify_unlock_handler */
+struct notify_unlock_baton_t
+{
+ void *inner_baton;
+ svn_wc_notify_func2_t inner_notify;
+ svn_boolean_t had_failure;
+};
+
+/* Implements svn_wc_notify_func2_t for svn_cl__unlock */
+static void
+notify_unlock_handler(void *baton,
+ const svn_wc_notify_t *notify,
+ apr_pool_t *scratch_pool)
+{
+ struct notify_unlock_baton_t *nub = baton;
+
+ if (notify->action == svn_wc_notify_failed_unlock)
+ nub->had_failure = TRUE;
+
+ if (nub->inner_notify)
+ nub->inner_notify(nub->inner_baton, notify, scratch_pool);
+}
+
/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
@@ -49,6 +72,7 @@ svn_cl__unlock(apr_getopt_t *os,
svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
apr_array_header_t *targets;
+ struct notify_unlock_baton_t nub;
SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
opt_state->targets,
@@ -63,6 +87,18 @@ svn_cl__unlock(apr_getopt_t *os,
SVN_ERR(svn_cl__assert_homogeneous_target_type(targets));
- return svn_error_trace(
- svn_client_unlock(targets, opt_state->force, ctx, scratch_pool));
+ nub.inner_notify = ctx->notify_func2;
+ nub.inner_baton = ctx->notify_baton2;
+ nub.had_failure = FALSE;
+
+ ctx->notify_func2 = notify_unlock_handler;
+ ctx->notify_baton2 = &nub;
+
+ SVN_ERR(svn_client_unlock(targets, opt_state->force, ctx, scratch_pool));
+
+ if (nub.had_failure)
+ return svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("One or more locks could not be released"));
+
+ return SVN_NO_ERROR;
}
Modified: subversion/branches/reuse-ra-session/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/util.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/util.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/util.c Fri Sep 11 15:51:30 2015
@@ -907,14 +907,17 @@ svn_cl__time_cstring_to_human_cstring(co
}
const char *
-svn_cl__node_description(const svn_wc_conflict_version_t *node,
+svn_cl__node_description(const char *repos_root_url,
+ const char *repos_relpath,
+ svn_revnum_t peg_rev,
+ svn_node_kind_t node_kind,
const char *wc_repos_root_URL,
apr_pool_t *pool)
{
const char *root_str = "^";
const char *path_str = "...";
- if (!node)
+ if (!repos_root_url || !repos_relpath || !SVN_IS_VALID_REVNUM(peg_rev))
/* Printing "(none)" the harder way to ensure conformity (mostly with
* translations). */
return apr_psprintf(pool, "(%s)",
@@ -923,18 +926,18 @@ svn_cl__node_description(const svn_wc_co
/* Construct a "caret notation" ^/URL if NODE matches WC_REPOS_ROOT_URL.
* Otherwise show the complete URL, and if we can't, show dots. */
- if (node->repos_url &&
+ if (repos_root_url &&
(wc_repos_root_URL == NULL ||
- strcmp(node->repos_url, wc_repos_root_URL) != 0))
- root_str = node->repos_url;
+ strcmp(repos_root_url, wc_repos_root_URL) != 0))
+ root_str = repos_root_url;
- if (node->path_in_repos)
- path_str = node->path_in_repos;
+ if (repos_relpath)
+ path_str = repos_relpath;
return apr_psprintf(pool, "(%s) %s@%ld",
- svn_cl__node_kind_str_human_readable(node->node_kind),
+ svn_cl__node_kind_str_human_readable(node_kind),
svn_path_url_add_component2(root_str, path_str, pool),
- node->peg_rev);
+ peg_rev);
}
svn_error_t *
Modified: subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c Fri Sep 11 15:51:30 2015
@@ -166,11 +166,13 @@ static svn_opt_subcommand_t
subcommand_delrevprop,
subcommand_deltify,
subcommand_dump,
+ subcommand_dump_revprops,
subcommand_freeze,
subcommand_help,
subcommand_hotcopy,
subcommand_info,
subcommand_load,
+ subcommand_load_revprops,
subcommand_list_dblogs,
subcommand_list_unused_dblogs,
subcommand_lock,
@@ -392,6 +394,15 @@ static const svn_opt_subcommand_desc2_t
"changed in those revisions.)\n"),
{'r', svnadmin__incremental, svnadmin__deltas, 'q', 'M'} },
+ {"dump-revprops", subcommand_dump_revprops, {0}, N_
+ ("usage: svnadmin dump-revprops REPOS_PATH [-r LOWER[:UPPER]]\n\n"
+ "Dump the revision properties of filesystem to stdout in a 'dumpfile'\n"
+ "portable format, sending feedback to stderr. Dump revisions\n"
+ "LOWER rev through UPPER rev. If no revisions are given, dump the\n"
+ "properties for all revisions. If only LOWER is given, dump the\n"
+ "properties for that one revision.\n"),
+ {'r', 'q'} },
+
{"freeze", subcommand_freeze, {0}, N_
("usage: 1. svnadmin freeze REPOS_PATH PROGRAM [ARG...]\n"
" 2. svnadmin freeze -F FILE PROGRAM [ARG...]\n\n"
@@ -444,6 +455,15 @@ static const svn_opt_subcommand_desc2_t
svnadmin__use_pre_commit_hook, svnadmin__use_post_commit_hook,
svnadmin__parent_dir, svnadmin__bypass_prop_validation, 'M'} },
+ {"load-revprops", subcommand_load_revprops, {0}, N_
+ ("usage: svnadmin load-revprops REPOS_PATH\n\n"
+ "Read a 'dumpfile'-formatted stream from stdin, setting the revision\n"
+ "properties in the repository's filesystem. Revisions not found in the\n"
+ "repository will cause an error. Progress feedback is sent to stdout.\n"
+ "If --revision is specified, limit the loaded revisions to only those\n"
+ "in the dump stream whose revision numbers match the specified range.\n"),
+ {'q', 'r', svnadmin__force_uuid, svnadmin__bypass_prop_validation} },
+
{"lock", subcommand_lock, {0}, N_
("usage: svnadmin lock REPOS_PATH PATH USERNAME COMMENT-FILE [TOKEN]\n\n"
"Lock PATH by USERNAME setting comments from COMMENT-FILE.\n"
@@ -864,25 +884,60 @@ err_cleanup(void *data)
return APR_SUCCESS;
}
-struct repos_notify_handler_baton {
- /* Stream to write progress and other non-error output to. */
- svn_stream_t *feedback_stream;
-
- /* Suppress notifications that are neither errors nor warnings. */
- svn_boolean_t silent_running;
-
- /* Whether errors contained in notifications should be printed along
- with the notification. If FALSE, any errors will only be
- summarized. */
- svn_boolean_t silent_errors;
+struct repos_verify_callback_baton
+{
+ /* Should we continue after receiving a first verification error? */
+ svn_boolean_t keep_going;
/* List of errors encountered during 'svnadmin verify --keep-going'. */
apr_array_header_t *error_summary;
- /* Pool for data collected during notifications. */
+ /* Pool for data collected during callback invocations. */
apr_pool_t *result_pool;
};
+/* Implementation of svn_repos_verify_callback_t to handle errors coming
+ from svn_repos_verify_fs3(). */
+static svn_error_t *
+repos_verify_callback(void *baton,
+ svn_revnum_t revision,
+ svn_error_t *verify_err,
+ apr_pool_t *scratch_pool)
+{
+ struct repos_verify_callback_baton *b = baton;
+
+ if (revision == SVN_INVALID_REVNUM)
+ {
+ SVN_ERR(svn_cmdline_fputs(_("* Error verifying repository metadata.\n"),
+ stderr, scratch_pool));
+ }
+ else
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("* Error verifying revision %ld.\n"),
+ revision));
+ }
+
+ if (b->keep_going)
+ {
+ struct verification_error *verr;
+
+ svn_handle_error2(verify_err, stderr, FALSE, "svnadmin: ");
+
+ /* Remember the error in B->ERROR_SUMMARY. */
+ verr = apr_palloc(b->result_pool, sizeof(*verr));
+ verr->rev = revision;
+ verr->err = svn_error_dup(verify_err);
+ apr_pool_cleanup_register(b->result_pool, verr->err, err_cleanup,
+ apr_pool_cleanup_null);
+ APR_ARRAY_PUSH(b->error_summary, struct verification_error *) = verr;
+
+ return SVN_NO_ERROR;
+ }
+ else
+ return svn_error_trace(svn_error_dup(verify_err));
+}
+
/* Implementation of svn_repos_notify_func_t to wrap the output to a
response stream for svn_repos_dump_fs2(), svn_repos_verify_fs(),
svn_repos_hotcopy3() and others. */
@@ -891,16 +946,7 @@ repos_notify_handler(void *baton,
const svn_repos_notify_t *notify,
apr_pool_t *scratch_pool)
{
- struct repos_notify_handler_baton *b = baton;
- svn_stream_t *feedback_stream = b->feedback_stream;
-
- /* Don't print anything if the feedback stream isn't provided.
- Only print errors and warnings in silent mode. */
- if (!feedback_stream
- || (b->silent_running
- && notify->action != svn_repos_notify_warning
- && notify->action != svn_repos_notify_failure))
- return;
+ svn_stream_t *feedback_stream = baton;
switch (notify->action)
{
@@ -910,32 +956,6 @@ repos_notify_handler(void *baton,
notify->warning_str));
return;
- case svn_repos_notify_failure:
- if (notify->revision != SVN_INVALID_REVNUM)
- svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
- _("* Error verifying revision %ld.\n"),
- notify->revision));
- if (notify->err)
- {
- if (!b->silent_errors)
- svn_handle_error2(notify->err, stderr, FALSE /* non-fatal */,
- "svnadmin: ");
-
- if (b->error_summary && notify->revision != SVN_INVALID_REVNUM)
- {
- struct verification_error *verr;
-
- verr = apr_palloc(b->result_pool, sizeof(*verr));
- verr->rev = notify->revision;
- verr->err = svn_error_dup(notify->err);
- apr_pool_cleanup_register(b->result_pool, verr->err, err_cleanup,
- apr_pool_cleanup_null);
- APR_ARRAY_PUSH(b->error_summary,
- struct verification_error *) = verr;
- }
- }
- return;
-
case svn_repos_notify_dump_rev_end:
svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
_("* Dumped revision %ld.\n"),
@@ -1126,6 +1146,24 @@ repos_notify_handler(void *baton,
_("* Copied revisions from %ld to %ld.\n"),
notify->start_revision, notify->end_revision));
}
+ return;
+
+ case svn_repos_notify_pack_noop:
+ /* For best backward compatibility, we keep silent if there were just
+ no more shards to pack. */
+ if (notify->shard == -1)
+ {
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _("svnadmin: Warning - this repository is not sharded."
+ " Packing has no effect.\n")));
+ }
+ return;
+
+ case svn_repos_notify_load_revprop_set:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _("Properties set on revision %ld.\n"),
+ notify->new_revision));
+ return;
default:
return;
@@ -1172,57 +1210,106 @@ recode_stream_create(FILE *std_stream, a
return rw_stream;
}
-
-/* This implements `svn_opt_subcommand_t'. */
-static svn_error_t *
-subcommand_dump(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+/* Read the min / max revision from the OPT_STATE, verify them against REPOS
+ and return them in *LOWER and *UPPER, respectively. Use SCRATCH_POOL
+ for temporary allocations. */
+static svn_error_t *
+get_dump_range(svn_revnum_t *lower,
+ svn_revnum_t *upper,
+ svn_repos_t *repos,
+ struct svnadmin_opt_state *opt_state,
+ apr_pool_t *scratch_pool)
{
- struct svnadmin_opt_state *opt_state = baton;
- svn_repos_t *repos;
svn_fs_t *fs;
- svn_stream_t *stdout_stream;
- svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
svn_revnum_t youngest;
- struct repos_notify_handler_baton notify_baton = { 0 };
- /* Expect no more arguments. */
- SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+ *lower = SVN_INVALID_REVNUM;
+ *upper = SVN_INVALID_REVNUM;
- SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
fs = svn_repos_fs(repos);
- SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));
+ SVN_ERR(svn_fs_youngest_rev(&youngest, fs, scratch_pool));
/* Find the revision numbers at which to start and end. */
- SVN_ERR(get_revnum(&lower, &opt_state->start_revision,
- youngest, repos, pool));
- SVN_ERR(get_revnum(&upper, &opt_state->end_revision,
- youngest, repos, pool));
+ SVN_ERR(get_revnum(lower, &opt_state->start_revision,
+ youngest, repos, scratch_pool));
+ SVN_ERR(get_revnum(upper, &opt_state->end_revision,
+ youngest, repos, scratch_pool));
/* Fill in implied revisions if necessary. */
- if (lower == SVN_INVALID_REVNUM)
+ if (*lower == SVN_INVALID_REVNUM)
{
- lower = 0;
- upper = youngest;
+ *lower = 0;
+ *upper = youngest;
}
- else if (upper == SVN_INVALID_REVNUM)
+ else if (*upper == SVN_INVALID_REVNUM)
{
- upper = lower;
+ *upper = *lower;
}
- if (lower > upper)
+ if (*lower > *upper)
return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("First revision cannot be higher than second"));
+ return SVN_NO_ERROR;
+}
+
+/* This implements `svn_opt_subcommand_t'. */
+static svn_error_t *
+subcommand_dump(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+ struct svnadmin_opt_state *opt_state = baton;
+ svn_repos_t *repos;
+ svn_stream_t *stdout_stream;
+ svn_revnum_t lower, upper;
+ svn_stream_t *feedback_stream = NULL;
+
+ /* Expect no more arguments. */
+ SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+
+ SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
+ SVN_ERR(get_dump_range(&lower, &upper, repos, opt_state, pool));
+
SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
/* Progress feedback goes to STDERR, unless they asked to suppress it. */
if (! opt_state->quiet)
- notify_baton.feedback_stream = recode_stream_create(stderr, pool);
+ feedback_stream = recode_stream_create(stderr, pool);
- SVN_ERR(svn_repos_dump_fs3(repos, stdout_stream, lower, upper,
+ SVN_ERR(svn_repos_dump_fs4(repos, stdout_stream, lower, upper,
opt_state->incremental, opt_state->use_deltas,
+ TRUE, TRUE,
+ !opt_state->quiet ? repos_notify_handler : NULL,
+ feedback_stream, check_cancel, NULL, pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* This implements `svn_opt_subcommand_t'. */
+static svn_error_t *
+subcommand_dump_revprops(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+ struct svnadmin_opt_state *opt_state = baton;
+ svn_repos_t *repos;
+ svn_stream_t *stdout_stream;
+ svn_revnum_t lower, upper;
+ svn_stream_t *feedback_stream = NULL;
+
+ /* Expect no more arguments. */
+ SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+
+ SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
+ SVN_ERR(get_dump_range(&lower, &upper, repos, opt_state, pool));
+
+ SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
+
+ /* Progress feedback goes to STDERR, unless they asked to suppress it. */
+ if (! opt_state->quiet)
+ feedback_stream = recode_stream_create(stderr, pool);
+
+ SVN_ERR(svn_repos_dump_fs4(repos, stdout_stream, lower, upper,
+ FALSE, FALSE, TRUE, FALSE,
!opt_state->quiet ? repos_notify_handler : NULL,
- ¬ify_baton, check_cancel, NULL, pool));
+ feedback_stream, check_cancel, NULL, pool));
return SVN_NO_ERROR;
}
@@ -1362,43 +1449,57 @@ optrev_to_revnum(svn_revnum_t *revnum, c
return SVN_NO_ERROR;
}
-
-/* This implements `svn_opt_subcommand_t'. */
+/* Read the min / max revision from the OPT_STATE, verify them and return
+ them in *LOWER and *UPPER, respectively. */
static svn_error_t *
-subcommand_load(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+get_load_range(svn_revnum_t *lower,
+ svn_revnum_t *upper,
+ struct svnadmin_opt_state *opt_state)
{
- svn_error_t *err;
- struct svnadmin_opt_state *opt_state = baton;
- svn_repos_t *repos;
- svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
- svn_stream_t *stdin_stream;
- struct repos_notify_handler_baton notify_baton = { 0 };
-
- /* Expect no more arguments. */
- SVN_ERR(parse_args(NULL, os, 0, 0, pool));
-
/* Find the revision numbers at which to start and end. We only
support a limited set of revision kinds: number and unspecified. */
- SVN_ERR(optrev_to_revnum(&lower, &opt_state->start_revision));
- SVN_ERR(optrev_to_revnum(&upper, &opt_state->end_revision));
+ SVN_ERR(optrev_to_revnum(lower, &opt_state->start_revision));
+ SVN_ERR(optrev_to_revnum(upper, &opt_state->end_revision));
/* Fill in implied revisions if necessary. */
- if ((upper == SVN_INVALID_REVNUM) && (lower != SVN_INVALID_REVNUM))
+ if ((*upper == SVN_INVALID_REVNUM) && (*lower != SVN_INVALID_REVNUM))
{
- upper = lower;
+ *upper = *lower;
}
- else if ((upper != SVN_INVALID_REVNUM) && (lower == SVN_INVALID_REVNUM))
+ else if ((*upper != SVN_INVALID_REVNUM) && (*lower == SVN_INVALID_REVNUM))
{
- lower = upper;
+ *lower = *upper;
}
/* Ensure correct range ordering. */
- if (lower > upper)
+ if (*lower > *upper)
{
return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("First revision cannot be higher than second"));
}
+ return SVN_NO_ERROR;
+}
+
+
+/* This implements `svn_opt_subcommand_t'. */
+static svn_error_t *
+subcommand_load(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+ svn_error_t *err;
+ struct svnadmin_opt_state *opt_state = baton;
+ svn_repos_t *repos;
+ svn_revnum_t lower, upper;
+ svn_stream_t *stdin_stream;
+ svn_stream_t *feedback_stream = NULL;
+
+ /* Expect no more arguments. */
+ SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+
+ /* Find the revision numbers at which to start and end. We only
+ support a limited set of revision kinds: number and unspecified. */
+ SVN_ERR(get_load_range(&lower, &upper, opt_state));
+
SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
/* Read the stream from STDIN. Users can redirect a file. */
@@ -1406,7 +1507,7 @@ subcommand_load(apr_getopt_t *os, void *
/* Progress feedback goes to STDOUT, unless they asked to suppress it. */
if (! opt_state->quiet)
- notify_baton.feedback_stream = recode_stream_create(stdout, pool);
+ feedback_stream = recode_stream_create(stdout, pool);
err = svn_repos_load_fs5(repos, stdin_stream, lower, upper,
opt_state->uuid_action, opt_state->parent_dir,
@@ -1415,7 +1516,7 @@ subcommand_load(apr_getopt_t *os, void *
!opt_state->bypass_prop_validation,
opt_state->ignore_dates,
opt_state->quiet ? NULL : repos_notify_handler,
- ¬ify_baton, check_cancel, NULL, pool);
+ feedback_stream, check_cancel, NULL, pool);
if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE)
return svn_error_quick_wrap(err,
_("Invalid property value found in "
@@ -1425,6 +1526,48 @@ subcommand_load(apr_getopt_t *os, void *
return err;
}
+static svn_error_t *
+subcommand_load_revprops(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+ svn_error_t *err;
+ struct svnadmin_opt_state *opt_state = baton;
+ svn_repos_t *repos;
+ svn_revnum_t lower, upper;
+ svn_stream_t *stdin_stream;
+
+ svn_stream_t *feedback_stream = NULL;
+
+ /* Expect no more arguments. */
+ SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+
+ /* Find the revision numbers at which to start and end. We only
+ support a limited set of revision kinds: number and unspecified. */
+ SVN_ERR(get_load_range(&lower, &upper, opt_state));
+
+ SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
+
+ /* Read the stream from STDIN. Users can redirect a file. */
+ SVN_ERR(svn_stream_for_stdin(&stdin_stream, pool));
+ stdin_stream = svn_stream_wrap_buffered_read(stdin_stream, pool);
+
+ /* Progress feedback goes to STDOUT, unless they asked to suppress it. */
+ if (! opt_state->quiet)
+ feedback_stream = recode_stream_create(stdout, pool);
+
+ err = svn_repos_load_fs_revprops(repos, stdin_stream, lower, upper,
+ !opt_state->bypass_prop_validation,
+ opt_state->ignore_dates,
+ opt_state->quiet ? NULL
+ : repos_notify_handler,
+ feedback_stream, check_cancel, NULL, pool);
+ if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE)
+ return svn_error_quick_wrap(err,
+ _("Invalid property value found in "
+ "dumpstream; consider repairing the source "
+ "or using --bypass-prop-validation while "
+ "loading."));
+ return err;
+}
/* This implements `svn_opt_subcommand_t'. */
static svn_error_t *
@@ -1462,12 +1605,12 @@ subcommand_recover(apr_getopt_t *os, voi
svn_repos_t *repos;
svn_error_t *err;
struct svnadmin_opt_state *opt_state = baton;
- struct repos_notify_handler_baton notify_baton = { 0 };
+ svn_stream_t *feedback_stream = NULL;
/* Expect no more arguments. */
SVN_ERR(parse_args(NULL, os, 0, 0, pool));
- SVN_ERR(svn_stream_for_stdout(¬ify_baton.feedback_stream, pool));
+ SVN_ERR(svn_stream_for_stdout(&feedback_stream, pool));
/* Restore default signal handlers until after we have acquired the
* exclusive lock so that the user interrupt before we actually
@@ -1475,7 +1618,7 @@ subcommand_recover(apr_getopt_t *os, voi
setup_cancellation_signals(SIG_DFL);
err = svn_repos_recover4(opt_state->repository_path, TRUE,
- repos_notify_handler, ¬ify_baton,
+ repos_notify_handler, feedback_stream,
check_cancel, NULL, pool);
if (err)
{
@@ -1493,7 +1636,7 @@ subcommand_recover(apr_getopt_t *os, voi
" another process has it open?\n")));
SVN_ERR(svn_cmdline_fflush(stdout));
SVN_ERR(svn_repos_recover4(opt_state->repository_path, FALSE,
- repos_notify_handler, ¬ify_baton,
+ repos_notify_handler, feedback_stream,
check_cancel, NULL, pool));
}
@@ -1779,7 +1922,7 @@ subcommand_pack(apr_getopt_t *os, void *
{
struct svnadmin_opt_state *opt_state = baton;
svn_repos_t *repos;
- struct repos_notify_handler_baton notify_baton = { 0 };
+ svn_stream_t *feedback_stream = NULL;
/* Expect no more arguments. */
SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1788,11 +1931,11 @@ subcommand_pack(apr_getopt_t *os, void *
/* Progress feedback goes to STDOUT, unless they asked to suppress it. */
if (! opt_state->quiet)
- notify_baton.feedback_stream = recode_stream_create(stdout, pool);
+ feedback_stream = recode_stream_create(stdout, pool);
return svn_error_trace(
svn_repos_fs_pack2(repos, !opt_state->quiet ? repos_notify_handler : NULL,
- ¬ify_baton, check_cancel, NULL, pool));
+ feedback_stream, check_cancel, NULL, pool));
}
@@ -1804,10 +1947,8 @@ subcommand_verify(apr_getopt_t *os, void
svn_repos_t *repos;
svn_fs_t *fs;
svn_revnum_t youngest, lower, upper;
- struct repos_notify_handler_baton notify_baton = { 0 };
- struct repos_notify_handler_baton *notify_baton_p = ¬ify_baton;
- svn_repos_notify_func_t notify_func = repos_notify_handler;
- svn_error_t *verify_err;
+ svn_stream_t *feedback_stream = NULL;
+ struct repos_verify_callback_baton verify_baton = { 0 };
/* Expect no more arguments. */
SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1851,42 +1992,27 @@ subcommand_verify(apr_getopt_t *os, void
upper = lower;
}
- /* Set up the notification handler. */
- if (!opt_state->quiet || opt_state->keep_going)
- {
- if (opt_state->quiet)
- {
- notify_baton.silent_running = TRUE;
- notify_baton.feedback_stream = recode_stream_create(stderr, pool);
- }
- else
- notify_baton.feedback_stream = recode_stream_create(stdout, pool);
-
- if (opt_state->keep_going)
- notify_baton.error_summary =
- apr_array_make(pool, 0, sizeof(struct verification_error *));
- else
- notify_baton.silent_errors = TRUE;
-
- notify_baton.result_pool = pool;
- }
- else
- {
- notify_func = NULL;
- notify_baton_p = NULL;
- }
+ if (!opt_state->quiet)
+ feedback_stream = recode_stream_create(stdout, pool);
- verify_err = svn_repos_verify_fs3(repos, lower, upper,
- opt_state->keep_going,
- opt_state->check_normalization,
- opt_state->metadata_only,
- notify_func, notify_baton_p,
- check_cancel, NULL, pool);
+ verify_baton.keep_going = opt_state->keep_going;
+ verify_baton.error_summary =
+ apr_array_make(pool, 0, sizeof(struct verification_error *));
+ verify_baton.result_pool = pool;
+
+ SVN_ERR(svn_repos_verify_fs3(repos, lower, upper,
+ opt_state->check_normalization,
+ opt_state->metadata_only,
+ !opt_state->quiet
+ ? repos_notify_handler : NULL,
+ feedback_stream,
+ repos_verify_callback, &verify_baton,
+ check_cancel, NULL, pool));
/* Show the --keep-going error summary. */
if (!opt_state->quiet
&& opt_state->keep_going
- && notify_baton.error_summary->nelts > 0)
+ && verify_baton.error_summary->nelts > 0)
{
int rev_maxlength;
svn_revnum_t end_revnum;
@@ -1894,15 +2020,15 @@ subcommand_verify(apr_getopt_t *os, void
int i;
svn_error_clear(
- svn_stream_puts(notify_baton.feedback_stream,
+ svn_stream_puts(feedback_stream,
_("\n-----Summary of corrupt revisions-----\n")));
/* The standard column width for the revision number is 6 characters.
If the revision number can potentially be larger (i.e. if end_revnum
is larger than 1000000), we increase the column width as needed. */
rev_maxlength = 6;
- end_revnum = APR_ARRAY_IDX(notify_baton.error_summary,
- notify_baton.error_summary->nelts - 1,
+ end_revnum = APR_ARRAY_IDX(verify_baton.error_summary,
+ verify_baton.error_summary->nelts - 1,
struct verification_error *)->rev;
while (end_revnum >= 1000000)
{
@@ -1911,7 +2037,7 @@ subcommand_verify(apr_getopt_t *os, void
}
iterpool = svn_pool_create(pool);
- for (i = 0; i < notify_baton.error_summary->nelts; i++)
+ for (i = 0; i < verify_baton.error_summary->nelts; i++)
{
struct verification_error *verr;
svn_error_t *err;
@@ -1919,29 +2045,40 @@ subcommand_verify(apr_getopt_t *os, void
svn_pool_clear(iterpool);
- verr = APR_ARRAY_IDX(notify_baton.error_summary, i,
+ verr = APR_ARRAY_IDX(verify_baton.error_summary, i,
struct verification_error *);
- rev_str = apr_psprintf(iterpool, "r%ld", verr->rev);
- rev_str = apr_psprintf(iterpool, "%*s", rev_maxlength, rev_str);
- for (err = svn_error_purge_tracing(verr->err);
- err != SVN_NO_ERROR; err = err->child)
- {
- char buf[512];
- const char *message;
- message = svn_err_best_message(err, buf, sizeof(buf));
- svn_error_clear(svn_stream_printf(notify_baton.feedback_stream,
- iterpool,
- "%s: E%06d: %s\n",
- rev_str, err->apr_err,
- message));
+ if (verr->rev != SVN_INVALID_REVNUM)
+ {
+ rev_str = apr_psprintf(iterpool, "r%ld", verr->rev);
+ rev_str = apr_psprintf(iterpool, "%*s", rev_maxlength, rev_str);
+ for (err = svn_error_purge_tracing(verr->err);
+ err != SVN_NO_ERROR; err = err->child)
+ {
+ char buf[512];
+ const char *message;
+
+ message = svn_err_best_message(err, buf, sizeof(buf));
+ svn_error_clear(svn_stream_printf(feedback_stream, iterpool,
+ "%s: E%06d: %s\n",
+ rev_str, err->apr_err,
+ message));
+ }
}
}
svn_pool_destroy(iterpool);
}
- return svn_error_trace(verify_err);
+ if (verify_baton.error_summary->nelts > 0)
+ {
+ return svn_error_createf(SVN_ERR_CL_REPOS_VERIFY_FAILED, NULL,
+ _("Failed to verify repository '%s'"),
+ svn_dirent_local_style(
+ opt_state->repository_path, pool));
+ }
+
+ return SVN_NO_ERROR;
}
/* This implements `svn_opt_subcommand_t'. */
@@ -1949,7 +2086,7 @@ svn_error_t *
subcommand_hotcopy(apr_getopt_t *os, void *baton, apr_pool_t *pool)
{
struct svnadmin_opt_state *opt_state = baton;
- struct repos_notify_handler_baton notify_baton = { 0 };
+ svn_stream_t *feedback_stream = NULL;
apr_array_header_t *targets;
const char *new_repos_path;
@@ -1960,12 +2097,12 @@ subcommand_hotcopy(apr_getopt_t *os, voi
/* Progress feedback goes to STDOUT, unless they asked to suppress it. */
if (! opt_state->quiet)
- notify_baton.feedback_stream = recode_stream_create(stdout, pool);
+ feedback_stream = recode_stream_create(stdout, pool);
return svn_repos_hotcopy3(opt_state->repository_path, new_repos_path,
opt_state->clean_logs, opt_state->incremental,
!opt_state->quiet ? repos_notify_handler : NULL,
- ¬ify_baton, check_cancel, NULL, pool);
+ feedback_stream, check_cancel, NULL, pool);
}
svn_error_t *
@@ -1976,6 +2113,7 @@ subcommand_info(apr_getopt_t *os, void *
svn_fs_t *fs;
int fs_format;
const char *uuid;
+ svn_revnum_t head_rev;
/* Expect no more arguments. */
SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1988,6 +2126,9 @@ subcommand_info(apr_getopt_t *os, void *
SVN_ERR(svn_fs_get_uuid(fs, &uuid, pool));
SVN_ERR(svn_cmdline_printf(pool, _("UUID: %s\n"), uuid));
+
+ SVN_ERR(svn_fs_youngest_rev(&head_rev, fs, pool));
+ SVN_ERR(svn_cmdline_printf(pool, _("Revisions: %ld\n"), head_rev));
{
int repos_format, minor;
svn_version_t *repos_version, *fs_version;
@@ -2349,18 +2490,18 @@ subcommand_upgrade(apr_getopt_t *os, voi
{
svn_error_t *err;
struct svnadmin_opt_state *opt_state = baton;
- struct repos_notify_handler_baton notify_baton = { 0 };
+ svn_stream_t *feedback_stream = NULL;
/* Expect no more arguments. */
SVN_ERR(parse_args(NULL, os, 0, 0, pool));
- SVN_ERR(svn_stream_for_stdout(¬ify_baton.feedback_stream, pool));
+ SVN_ERR(svn_stream_for_stdout(&feedback_stream, pool));
/* Restore default signal handlers. */
setup_cancellation_signals(SIG_DFL);
err = svn_repos_upgrade2(opt_state->repository_path, TRUE,
- repos_notify_handler, ¬ify_baton, pool);
+ repos_notify_handler, feedback_stream, pool);
if (err)
{
if (APR_STATUS_IS_EAGAIN(err->apr_err))
@@ -2378,7 +2519,7 @@ subcommand_upgrade(apr_getopt_t *os, voi
" another process has it open?\n")));
SVN_ERR(svn_cmdline_fflush(stdout));
SVN_ERR(svn_repos_upgrade2(opt_state->repository_path, FALSE,
- repos_notify_handler, ¬ify_baton,
+ repos_notify_handler, feedback_stream,
pool));
}
else if (err->apr_err == SVN_ERR_FS_UNSUPPORTED_UPGRADE)