You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/03/22 15:32:26 UTC
svn commit: r1736197 - in /subversion/trunk/subversion: include/svn_client.h
libsvn_client/conflicts.c svn/conflict-callbacks.c
Author: stsp
Date: Tue Mar 22 14:32:26 2016
New Revision: 1736197
URL: http://svn.apache.org/viewvc?rev=1736197&view=rev
Log:
At the API level, provide tree conflict descriptions in two parts: one part
describing the local change, and one part describing the incomcng change.
This will make it easier for client implementors to display conflict
descriptions in a useful way.
* subversion/include/svn_client.h
(svn_client_conflict_tree_get_description): Split the single 'description'
output parameter into two output parameters: 'local_change_description'
and 'incoming_change_description'. Document some syntactical properties
of descriptions which client implementors may rely on.
* subversion/libsvn_client/conflicts.c
(tree_conflict_get_description_func_t): Use two output params here as well.
(conflict_tree_get_description_generic
conflict_tree_get_description_incoming_delete,
conflict_tree_get_description_incoming_add,
conflict_tree_get_description_incoming_edit,
svn_client_conflict_tree_get_description): Update accordingly.
* subversion/svn/conflict-callbacks.c
(handle_tree_conflict): Update to use the changed API.
Modified:
subversion/trunk/subversion/include/svn_client.h
subversion/trunk/subversion/libsvn_client/conflicts.c
subversion/trunk/subversion/svn/conflict-callbacks.c
Modified: subversion/trunk/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1736197&r1=1736196&r2=1736197&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Tue Mar 22 14:32:26 2016
@@ -4495,18 +4495,40 @@ svn_client_conflict_prop_get_description
* Additionally, the description may be localized to the language used
* by the current locale.
*
+ * While client implementors are free to enhance descriptions by adding
+ * additional information to the text, or break up very long lines for
+ * formatting purposes, there is no syntax defined for descriptions, and
+ * implementors should not rely on any particular parts of descriptions
+ * to remain stable over time, apart from what is stated below.
+ * Descriptions may or may not form complete sentences. They may contain
+ * paths relative to the repository root; such paths always start with "^/",
+ * and end with either a peg revision (e.g. "@100") or a colon followed by
+ * a range of revisions (as in svn:mergeinfo, e.g. ":100-200").
+ * Paths may appear on a line of their own to avoid overlong lines.
+ * Any revision numbers mentioned elsewhere in the description are
+ * prefixed with the letter 'r' (e.g. "r99").
+ *
+ * The description has two parts: One describing the "local change" which
+ * occured in the working copy or perhaps a branch (the merge target).
+ * The other part describes the "incoming change" which conflicts with
+ * the local change. Both parts are provided independently to allow for
+ * some flexibility when displaying the description.
+ *
* By default, the description is based only on information available in
* the working copy. If svn_client_conflict_tree_get_details() was already
* called for @a conflict, the description might also contain useful
- * information obtained from the repository.
+ * information obtained from the repository and provide for a much better
+ * user experience.
*
* @since New in 1.10.
*/
svn_error_t *
-svn_client_conflict_tree_get_description(const char **description,
- svn_client_conflict_t *conflict,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
+svn_client_conflict_tree_get_description(
+ const char **local_change_description,
+ const char **incoming_change_description,
+ svn_client_conflict_t *conflict,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
/**
* Set @a *options to an array of pointers to svn_client_conflict_option_t
Modified: subversion/trunk/subversion/libsvn_client/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/conflicts.c?rev=1736197&r1=1736196&r2=1736197&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_client/conflicts.c Tue Mar 22 14:32:26 2016
@@ -51,7 +51,8 @@
/* Describe a tree conflict. */
typedef svn_error_t *(*tree_conflict_get_description_func_t)(
- const char **description,
+ const char **local_change_description,
+ const char **incoming_change_description,
svn_client_conflict_t *conflict,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
@@ -730,7 +731,8 @@ svn_client_conflict_prop_get_description
/* Implements tree_conflict_get_description_func_t. */
static svn_error_t *
-conflict_tree_get_description_generic(const char **description,
+conflict_tree_get_description_generic(const char **local_change_description,
+ const char **incoming_change_description,
svn_client_conflict_t *conflict,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
@@ -776,23 +778,24 @@ conflict_tree_get_description_generic(co
if (action && reason)
{
- *description = apr_psprintf(result_pool, _("%s, %s %s"),
- reason, action, operation);
+ *local_change_description = apr_pstrdup(result_pool, reason);
+ *incoming_change_description = apr_pstrdup(result_pool, action);
}
else
{
/* A catch-all message for very rare or nominally impossible cases.
It will not be pretty, but is closer to an internal error than
an ordinary user-facing string. */
- *description = apr_psprintf(result_pool,
- _("local: %s %s incoming: %s %s %s"),
- svn_node_kind_to_word(conflict_node_kind),
- svn_token__to_word(map_conflict_reason,
- conflict_reason),
- svn_node_kind_to_word(incoming_kind),
- svn_token__to_word(map_conflict_action,
- conflict_action),
- operation);
+ *local_change_description = apr_psprintf(result_pool,
+ _("local: %s %s"),
+ svn_node_kind_to_word(conflict_node_kind),
+ svn_token__to_word(map_conflict_reason,
+ conflict_reason));
+ *incoming_change_description = apr_psprintf(result_pool,
+ _("incoming: %s %s"),
+ svn_node_kind_to_word(incoming_kind),
+ svn_token__to_word(map_conflict_action,
+ conflict_action));
}
return SVN_NO_ERROR;
}
@@ -1344,10 +1347,12 @@ describe_incoming_reverse_addition_upon_
/* Implements tree_conflict_get_description_func_t. */
static svn_error_t *
-conflict_tree_get_description_incoming_delete(const char **description,
- svn_client_conflict_t *conflict,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+conflict_tree_get_description_incoming_delete(
+ const char **local_change_description,
+ const char **incoming_change_description,
+ svn_client_conflict_t *conflict,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
const char *action, *reason;
svn_node_kind_t victim_node_kind;
@@ -1360,20 +1365,20 @@ conflict_tree_get_description_incoming_d
struct conflict_tree_incoming_delete_details *details;
if (conflict->tree_conflict_details == NULL)
- return svn_error_trace(conflict_tree_get_description_generic(description,
- conflict,
- result_pool,
- scratch_pool));
+ return svn_error_trace(conflict_tree_get_description_generic(
+ local_change_description,
+ incoming_change_description,
+ conflict, result_pool, scratch_pool));
local_change = svn_client_conflict_get_local_change(conflict);
conflict_operation = svn_client_conflict_get_operation(conflict);
victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
SVN_ERR(describe_local_change(&reason, conflict, scratch_pool, scratch_pool));
if (reason == NULL)
- return svn_error_trace(conflict_tree_get_description_generic(description,
- conflict,
- result_pool,
- scratch_pool));
+ return svn_error_trace(conflict_tree_get_description_generic(
+ local_change_description,
+ incoming_change_description,
+ conflict, result_pool, scratch_pool));
SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
&old_repos_relpath, &old_rev, NULL, conflict, scratch_pool,
scratch_pool));
@@ -1442,7 +1447,9 @@ conflict_tree_get_description_incoming_d
}
}
- *description = apr_psprintf(result_pool, _("%s, %s"), reason, action);
+ *local_change_description = apr_pstrdup(result_pool, reason);
+ *incoming_change_description = apr_pstrdup(result_pool, action);
+
return SVN_NO_ERROR;
}
@@ -2293,10 +2300,12 @@ describe_incoming_reverse_deletion_upon_
/* Implements tree_conflict_get_description_func_t. */
static svn_error_t *
-conflict_tree_get_description_incoming_add(const char **description,
- svn_client_conflict_t *conflict,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+conflict_tree_get_description_incoming_add(
+ const char **local_change_description,
+ const char **incoming_change_description,
+ svn_client_conflict_t *conflict,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
const char *action, *reason;
svn_node_kind_t victim_node_kind;
@@ -2311,20 +2320,21 @@ conflict_tree_get_description_incoming_a
struct conflict_tree_incoming_add_details *details;
if (conflict->tree_conflict_details == NULL)
- return svn_error_trace(conflict_tree_get_description_generic(description,
- conflict,
- result_pool,
- scratch_pool));
+ return svn_error_trace(conflict_tree_get_description_generic(
+ local_change_description,
+ incoming_change_description,
+ conflict, result_pool, scratch_pool));
local_change = svn_client_conflict_get_local_change(conflict);
conflict_operation = svn_client_conflict_get_operation(conflict);
victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
SVN_ERR(describe_local_change(&reason, conflict, scratch_pool, scratch_pool));
if (reason == NULL)
- return svn_error_trace(conflict_tree_get_description_generic(description,
- conflict,
- result_pool,
- scratch_pool));
+ return svn_error_trace(conflict_tree_get_description_generic(
+ local_change_description,
+ incoming_change_description,
+ conflict, result_pool, scratch_pool));
+
SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
&old_repos_relpath, &old_rev, &old_node_kind, conflict,
scratch_pool, scratch_pool));
@@ -2364,7 +2374,9 @@ conflict_tree_get_description_incoming_a
old_rev, new_rev, result_pool);
}
- *description = apr_psprintf(result_pool, _("%s, %s"), reason, action);
+ *local_change_description = apr_pstrdup(result_pool, reason);
+ *incoming_change_description = apr_pstrdup(result_pool, action);
+
return SVN_NO_ERROR;
}
@@ -2708,10 +2720,12 @@ describe_incoming_edit_list_modified_rev
/* Implements tree_conflict_get_description_func_t. */
static svn_error_t *
-conflict_tree_get_description_incoming_edit(const char **description,
- svn_client_conflict_t *conflict,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+conflict_tree_get_description_incoming_edit(
+ const char **local_change_description,
+ const char **incoming_change_description,
+ svn_client_conflict_t *conflict,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
const char *action, *reason;
svn_node_kind_t victim_node_kind;
@@ -2726,10 +2740,10 @@ conflict_tree_get_description_incoming_e
apr_array_header_t *edits;
if (conflict->tree_conflict_details == NULL)
- return svn_error_trace(conflict_tree_get_description_generic(description,
- conflict,
- result_pool,
- scratch_pool));
+ return svn_error_trace(conflict_tree_get_description_generic(
+ local_change_description,
+ incoming_change_description,
+ conflict, result_pool, scratch_pool));
SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
&old_repos_relpath, &old_rev, &old_node_kind, conflict,
@@ -2743,10 +2757,10 @@ conflict_tree_get_description_incoming_e
victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
SVN_ERR(describe_local_change(&reason, conflict, scratch_pool, scratch_pool));
if (reason == NULL)
- return svn_error_trace(conflict_tree_get_description_generic(description,
- conflict,
- result_pool,
- scratch_pool));
+ return svn_error_trace(conflict_tree_get_description_generic(
+ local_change_description,
+ incoming_change_description,
+ conflict, result_pool, scratch_pool));
edits = conflict->tree_conflict_details;
@@ -2783,8 +2797,9 @@ conflict_tree_get_description_incoming_e
"^/%s:%ld"),
new_repos_relpath, new_rev);
- *description = apr_psprintf(result_pool, _("%s, %s"),
- reason, action);
+ *local_change_description = apr_pstrdup(result_pool, reason);
+ *incoming_change_description = apr_pstrdup(result_pool, action);
+
return SVN_NO_ERROR;
}
else
@@ -2833,8 +2848,9 @@ conflict_tree_get_description_incoming_e
"of ^/%s:%ld"),
new_repos_relpath, old_rev);
- *description = apr_psprintf(result_pool, _("%s, %s"),
- reason, action);
+ *local_change_description = apr_pstrdup(result_pool, reason);
+ *incoming_change_description = apr_pstrdup(result_pool, action);
+
return SVN_NO_ERROR;
}
else
@@ -2868,18 +2884,24 @@ conflict_tree_get_description_incoming_e
action = apr_psprintf(scratch_pool, "%s:%s", action,
describe_incoming_edit_list_modified_revs(
edits, scratch_pool));
- *description = apr_psprintf(result_pool, _("%s, %s"), reason, action);
+ *local_change_description = apr_pstrdup(result_pool, reason);
+ *incoming_change_description = apr_pstrdup(result_pool, action);
+
return SVN_NO_ERROR;
}
svn_error_t *
-svn_client_conflict_tree_get_description(const char **description,
- svn_client_conflict_t *conflict,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_client_conflict_tree_get_description(
+ const char **local_change_description,
+ const char **incoming_change_description,
+ svn_client_conflict_t *conflict,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
return svn_error_trace(conflict->tree_conflict_get_description_func(
- description, conflict, result_pool, scratch_pool));
+ local_change_description,
+ incoming_change_description,
+ conflict, result_pool, scratch_pool));
}
void
Modified: subversion/trunk/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/conflict-callbacks.c?rev=1736197&r1=1736196&r2=1736197&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/conflict-callbacks.c (original)
+++ subversion/trunk/subversion/svn/conflict-callbacks.c Tue Mar 22 14:32:26 2016
@@ -1419,7 +1419,8 @@ handle_tree_conflict(svn_boolean_t *reso
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
{
- const char *description;
+ const char *local_change_description;
+ const char *incoming_change_description;
const char *src_left_version;
const char *src_right_version;
const char *repos_root_url;
@@ -1436,13 +1437,14 @@ handle_tree_conflict(svn_boolean_t *reso
SVN_ERR(svn_client_conflict_tree_get_details(conflict, scratch_pool));
SVN_ERR(svn_client_conflict_tree_get_description(
- &description, conflict, scratch_pool, scratch_pool));
+ &local_change_description, &incoming_change_description,
+ conflict, scratch_pool, scratch_pool));
SVN_ERR(svn_cmdline_fprintf(
stderr, scratch_pool,
- _("Tree conflict on '%s'\n > %s\n"),
+ _("Tree conflict on '%s'\n > %s, %s\n"),
svn_cl__local_style_skip_ancestor(path_prefix,
svn_client_conflict_get_local_abspath(conflict), scratch_pool),
- description));
+ local_change_description, incoming_change_description));
SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, NULL, conflict,
scratch_pool, scratch_pool));