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 2012/05/11 00:28:14 UTC

svn commit: r1336929 - in /subversion/trunk/subversion: include/private/svn_wc_private.h include/svn_wc.h libsvn_client/resolved.c libsvn_wc/conflicts.c svn/conflict-callbacks.c svn/main.c svn/resolve-cmd.c

Author: stsp
Date: Thu May 10 22:28:13 2012
New Revision: 1336929

URL: http://svn.apache.org/viewvc?rev=1336929&view=rev
Log:
Make 'svn resolve' invoke the interactive conflict resolution callback
for all conflicted paths in the working copy. The --accept option is
no longer mandatory.

This is work in progress. Some interactive features don't work yet when
the resolver is invoked via 'svn resolve' (e.g. the diff-full option seems
to be broken.)

* subversion/include/private/svn_wc_private.h
  (svn_wc__resolve_conflicts): Declare.

* subversion/include/svn_wc.h
  (svn_wc_conflict_choice_t): Add new value svn_wc_conflict_choose_unspecified.

* subversion/libsvn_wc/conflicts.c
  (resolve_one_conflict): Accept conflict_func and conflict_baton parameters,
    and invoke the conflict function if the pre-defined conflict choice is
    'unspecified'.
  (recursive_resolve_conflict): Accept conflict_func and conflict_baton
   parameters, to be ultimately passed on to resolve_one_conflict().
  (svn_wc__resolve_conflicts): New API that allows higher layers to invoke
   conflict resolution on all items.
  (svn_wc_resolved_conflict5): Re-implement as wrapper around the new
   svn_wc__resolve_conflicts() function, passing NULL for the conflict callback.

* subversion/libsvn_client/resolved.c
  (svn_client_resolve): Call svn_wc__resolve_conflicts() instead of
   svn_wc_resolved_conflict5().

* subversion/svn/main.c
  (svn_cl__cmd_table): Update help text for 'svn resolve' to new semantics.

* subversion/svn/conflict-callbacks.c
  (svn_cl__conflict_handler): Provide a minimal prompt for tree-conflicts
   which allows users to either postpone resolution or accept the current
   working state. This allows tree-conflicts to be marked resolved to the
   working tree state during 'svn resolve'.

* subversion/svn/resolve-cmd.c
  (svn_cl__resolve): If no --accept option was specified, run the conflict
    callback for all conflicts in the working copy, with default depth of
    'infinity'. Else, behave as before, i.e. use the --accept argument
    as the resolution for the specified PATH, with default depth 'empty'.
    One slight difference in the --accept case is that the current directory
    is resolved if --accept is specified without a PATH argument (this was
    a valid invocation as per 'svn help resolve' but resulted in an error).

Modified:
    subversion/trunk/subversion/include/private/svn_wc_private.h
    subversion/trunk/subversion/include/svn_wc.h
    subversion/trunk/subversion/libsvn_client/resolved.c
    subversion/trunk/subversion/libsvn_wc/conflicts.c
    subversion/trunk/subversion/svn/conflict-callbacks.c
    subversion/trunk/subversion/svn/main.c
    subversion/trunk/subversion/svn/resolve-cmd.c

Modified: subversion/trunk/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_wc_private.h?rev=1336929&r1=1336928&r2=1336929&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_wc_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_wc_private.h Thu May 10 22:28:13 2012
@@ -1652,6 +1652,76 @@ svn_wc__get_diff_editor(const svn_delta_
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool);
 
+/**
+ * Assuming @a local_abspath itself or any of its children are under version
+ * control or a tree conflict victim and in a state of conflict, take these
+ * nodes out of this state. 
+ *
+ * If @a resolve_text is TRUE then any text conflict is resolved,
+ * if @a resolve_tree is TRUE then any tree conflicts are resolved.
+ * If @a resolve_prop is set to "" all property conflicts are resolved,
+ * if it is set to any other string value, conflicts on that specific
+ * property are resolved and when resolve_prop is NULL, no property
+ * conflicts are resolved.
+ *
+ * If @a depth is #svn_depth_empty, act only on @a local_abspath; if
+ * #svn_depth_files, resolve @a local_abspath and its conflicted file
+ * children (if any); if #svn_depth_immediates, resolve @a local_abspath
+ * and all its immediate conflicted children (both files and directories,
+ * if any); if #svn_depth_infinity, resolve @a local_abspath and every
+ * conflicted file or directory anywhere beneath it.
+ *
+ * If @a conflict_choice is #svn_wc_conflict_choose_base, resolve the
+ * conflict with the old file contents; if
+ * #svn_wc_conflict_choose_mine_full, use the original working contents;
+ * if #svn_wc_conflict_choose_theirs_full, the new contents; and if
+ * #svn_wc_conflict_choose_merged, don't change the contents at all,
+ * just remove the conflict status, which is the pre-1.5 behavior.
+ *
+ * If @a conflict_choice is #svn_wc_conflict_choose_unspecified, invoke the
+ * @a conflict_func with the @a conflict_baton argument to obtain a
+ * resolution decision for each conflict.
+ *
+ * #svn_wc_conflict_choose_theirs_conflict and
+ * #svn_wc_conflict_choose_mine_conflict are not legal for binary
+ * files or properties.
+ *
+ * @a wc_ctx is a working copy context, with a write lock, for @a
+ * local_abspath.
+ *
+ * The implementation details are opaque, as our "conflicted" criteria
+ * might change over time.  (At the moment, this routine removes the
+ * three fulltext 'backup' files and any .prej file created in a conflict,
+ * and modifies @a local_abspath's entry.)
+ *
+ * If @a local_abspath is not under version control and not a tree
+ * conflict, return #SVN_ERR_ENTRY_NOT_FOUND. If @a path isn't in a
+ * state of conflict to begin with, do nothing, and return #SVN_NO_ERROR.
+ *
+ * If @c local_abspath was successfully taken out of a state of conflict,
+ * report this information to @c notify_func (if non-@c NULL.)  If only
+ * text, only property, or only tree conflict resolution was requested,
+ * and it was successful, then success gets reported.
+ *
+ * Temporary allocations will be performed in @a scratch_pool.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_wc__resolve_conflicts(svn_wc_context_t *wc_ctx,
+                          const char *local_abspath,
+                          svn_depth_t depth,
+                          svn_boolean_t resolve_text,
+                          const char *resolve_prop,
+                          svn_boolean_t resolve_tree,
+                          svn_wc_conflict_choice_t conflict_choice,
+                          svn_wc_conflict_resolver_func2_t conflict_func,
+                          void *conflict_baton,
+                          svn_cancel_func_t cancel_func,
+                          void *cancel_baton,
+                          svn_wc_notify_func2_t notify_func,
+                          void *notify_baton,
+                          apr_pool_t *scratch_pool);
 
 #ifdef __cplusplus
 }

Modified: subversion/trunk/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_wc.h?rev=1336929&r1=1336928&r2=1336929&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_wc.h (original)
+++ subversion/trunk/subversion/include/svn_wc.h Thu May 10 22:28:13 2012
@@ -2015,7 +2015,10 @@ typedef enum svn_wc_conflict_choice_t
   svn_wc_conflict_choose_mine_full,       /**< own version */
   svn_wc_conflict_choose_theirs_conflict, /**< incoming (for conflicted hunks) */
   svn_wc_conflict_choose_mine_conflict,   /**< own (for conflicted hunks) */
-  svn_wc_conflict_choose_merged           /**< merged version */
+  svn_wc_conflict_choose_merged,          /**< merged version */
+
+  /* @since New in 1.8. */
+  svn_wc_conflict_choose_unspecified      /**< undecided */
 
 } svn_wc_conflict_choice_t;
 

Modified: subversion/trunk/subversion/libsvn_client/resolved.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/resolved.c?rev=1336929&r1=1336928&r2=1336929&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/resolved.c (original)
+++ subversion/trunk/subversion/libsvn_client/resolved.c Thu May 10 22:28:13 2012
@@ -55,12 +55,14 @@ svn_client_resolve(const char *path,
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
 
-  SVN_ERR(svn_wc_resolved_conflict5(ctx->wc_ctx, local_abspath,
+  SVN_ERR(svn_wc__resolve_conflicts(ctx->wc_ctx, local_abspath,
                                     depth,
                                     TRUE /* resolve_text */,
                                     "" /* resolve_prop (ALL props) */,
                                     TRUE /* resolve_tree */,
                                     conflict_choice,
+                                    ctx->conflict_func2,
+                                    ctx->conflict_baton2,
                                     ctx->cancel_func, ctx->cancel_baton,
                                     ctx->notify_func2, ctx->notify_baton2,
                                     pool));

Modified: subversion/trunk/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/conflicts.c?rev=1336929&r1=1336928&r2=1336929&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_wc/conflicts.c Thu May 10 22:28:13 2012
@@ -345,6 +345,8 @@ resolve_one_conflict(svn_wc__db_t *db,
                      const char *resolve_prop,
                      svn_boolean_t resolve_tree,
                      svn_wc_conflict_choice_t conflict_choice,
+                     svn_wc_conflict_resolver_func2_t conflict_func,
+                     void *conflict_baton,
                      svn_wc_notify_func2_t notify_func,
                      void *notify_baton,
                      apr_pool_t *scratch_pool)
@@ -361,11 +363,31 @@ resolve_one_conflict(svn_wc__db_t *db,
     {
       const svn_wc_conflict_description2_t *cd;
       svn_boolean_t did_resolve;
+      svn_wc_conflict_choice_t my_choice = conflict_choice;
 
       cd = APR_ARRAY_IDX(conflicts, i, const svn_wc_conflict_description2_t *);
 
       svn_pool_clear(iterpool);
 
+      if (my_choice == svn_wc_conflict_choose_unspecified)
+        {
+          svn_wc_conflict_result_t *result;
+
+          if (conflict_func == NULL)
+            return svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                                    _("No conflict-callback and no "
+                                      "pre-defined conflict-choice provided"));
+                                    
+          SVN_ERR(conflict_func(&result, cd, conflict_baton, iterpool,
+                                iterpool));
+
+          my_choice = result->choice;
+        }
+
+
+      if (my_choice == svn_wc_conflict_choose_postpone)
+        continue;
+
       switch (cd->kind)
         {
           case svn_wc_conflict_kind_tree:
@@ -376,7 +398,7 @@ resolve_one_conflict(svn_wc__db_t *db,
              * to the working state. There is no way to pick theirs-full
              * or mine-full, etc. Throw an error if the user expects us
              * to be smarter than we really are. */
-            if (conflict_choice != svn_wc_conflict_choose_merged)
+            if (my_choice != svn_wc_conflict_choose_merged)
               {
                 return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
                                          NULL,
@@ -401,7 +423,7 @@ resolve_one_conflict(svn_wc__db_t *db,
                                              local_abspath,
                                              TRUE /* resolve_text */,
                                              FALSE /* resolve_props */,
-                                             conflict_choice,
+                                             my_choice,
                                              &did_resolve,
                                              iterpool));
 
@@ -427,7 +449,7 @@ resolve_one_conflict(svn_wc__db_t *db,
                                              local_abspath,
                                              FALSE /* resolve_text */,
                                              TRUE /* resolve_props */,
-                                             conflict_choice,
+                                             my_choice,
                                              &did_resolve,
                                              iterpool));
 
@@ -463,6 +485,8 @@ recursive_resolve_conflict(svn_wc__db_t 
                            const char *resolve_prop,
                            svn_boolean_t resolve_tree,
                            svn_wc_conflict_choice_t conflict_choice,
+                           svn_wc_conflict_resolver_func2_t conflict_func,
+                           void *conflict_baton,
                            svn_cancel_func_t cancel_func,
                            void *cancel_baton,
                            svn_wc_notify_func2_t notify_func,
@@ -486,6 +510,7 @@ recursive_resolve_conflict(svn_wc__db_t 
                                    resolve_prop,
                                    resolve_tree,
                                    conflict_choice,
+                                   conflict_func, conflict_baton,
                                    notify_func, notify_baton,
                                    iterpool));
     }
@@ -538,6 +563,7 @@ recursive_resolve_conflict(svn_wc__db_t 
                                            resolve_prop,
                                            resolve_tree,
                                            conflict_choice,
+                                           conflict_func, conflict_baton,
                                            cancel_func, cancel_baton,
                                            notify_func, notify_baton,
                                            iterpool));
@@ -548,6 +574,7 @@ recursive_resolve_conflict(svn_wc__db_t 
                                      resolve_prop,
                                      resolve_tree,
                                      conflict_choice,
+                                     conflict_func, conflict_baton,
                                      notify_func, notify_baton,
                                      iterpool));
     }
@@ -578,6 +605,7 @@ recursive_resolve_conflict(svn_wc__db_t 
                                    FALSE /*resolve_prop*/,
                                    resolve_tree,
                                    conflict_choice,
+                                   conflict_func, conflict_baton,
                                    notify_func, notify_baton,
                                    iterpool));
     }
@@ -590,13 +618,15 @@ recursive_resolve_conflict(svn_wc__db_t 
 
 
 svn_error_t *
-svn_wc_resolved_conflict5(svn_wc_context_t *wc_ctx,
+svn_wc__resolve_conflicts(svn_wc_context_t *wc_ctx,
                           const char *local_abspath,
                           svn_depth_t depth,
                           svn_boolean_t resolve_text,
                           const char *resolve_prop,
                           svn_boolean_t resolve_tree,
                           svn_wc_conflict_choice_t conflict_choice,
+                          svn_wc_conflict_resolver_func2_t conflict_func,
+                          void *conflict_baton,
                           svn_cancel_func_t cancel_func,
                           void *cancel_baton,
                           svn_wc_notify_func2_t notify_func,
@@ -635,7 +665,33 @@ svn_wc_resolved_conflict5(svn_wc_context
                            resolve_prop,
                            resolve_tree,
                            conflict_choice,
+                           conflict_func, conflict_baton,
                            cancel_func, cancel_baton,
                            notify_func, notify_baton,
                            scratch_pool));
 }
+
+
+svn_error_t *
+svn_wc_resolved_conflict5(svn_wc_context_t *wc_ctx,
+                          const char *local_abspath,
+                          svn_depth_t depth,
+                          svn_boolean_t resolve_text,
+                          const char *resolve_prop,
+                          svn_boolean_t resolve_tree,
+                          svn_wc_conflict_choice_t conflict_choice,
+                          svn_cancel_func_t cancel_func,
+                          void *cancel_baton,
+                          svn_wc_notify_func2_t notify_func,
+                          void *notify_baton,
+                          apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(svn_wc__resolve_conflicts(wc_ctx, local_abspath,
+                                                   depth, resolve_text,
+                                                   resolve_prop, resolve_tree,
+                                                   conflict_choice,
+                                                   NULL, NULL,
+                                                   cancel_func, cancel_baton,
+                                                   notify_func, notify_baton,
+                                                   scratch_pool));
+}

Modified: subversion/trunk/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/conflict-callbacks.c?rev=1336929&r1=1336928&r2=1336929&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/conflict-callbacks.c (original)
+++ subversion/trunk/subversion/svn/conflict-callbacks.c Thu May 10 22:28:13 2012
@@ -35,6 +35,7 @@
 #include "svn_pools.h"
 
 #include "cl.h"
+#include "tree-conflicts.h"
 
 #include "svn_private_config.h"
 
@@ -758,6 +759,49 @@ svn_cl__conflict_handler(svn_wc_conflict
         }
     }
 
+  else if (desc->kind == svn_wc_conflict_kind_tree)
+    {
+      const char *answer;
+      const char *prompt;
+      const char *readable_desc;
+
+      SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
+               &readable_desc, desc, scratch_pool));
+      SVN_ERR(svn_cmdline_fprintf(
+                   stderr, subpool,
+                   _("Tree conflict on '%s'\n   > %s\n"),
+                   svn_cl__local_style_skip_ancestor(b->path_prefix,
+                                                     desc->local_abspath,
+                                                     scratch_pool),
+                   readable_desc));
+
+      prompt = _("Select: (p) postpone, (r) mark-resolved, (h) help: ");
+
+      while (1)
+        {
+          svn_pool_clear(subpool);
+
+          SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, b->pb, subpool));
+
+          if (strcmp(answer, "h") == 0 || strcmp(answer, "?") == 0)
+            {
+              SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
+              _("  (p) postpone      - resolve the conflict later\n"
+                "  (r) resolved      - accept current working tree\n")));
+            }
+          if (strcmp(answer, "p") == 0 || strcmp(answer, ":-p") == 0)
+            {
+              (*result)->choice = svn_wc_conflict_choose_postpone;
+              break;
+            }
+          else if (strcmp(answer, "r") == 0)
+            {
+              (*result)->choice = svn_wc_conflict_choose_merged;
+              break;
+            }
+        }
+    }
+
   else /* other types of conflicts -- do nothing about them. */
     {
       (*result)->choice = svn_wc_conflict_choose_postpone;

Modified: subversion/trunk/subversion/svn/main.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/main.c?rev=1336929&r1=1336928&r2=1336929&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/main.c (original)
+++ subversion/trunk/subversion/svn/main.c Thu May 10 22:28:13 2012
@@ -1278,9 +1278,12 @@ const svn_opt_subcommand_desc2_t svn_cl_
 
   { "resolve", svn_cl__resolve, {0}, N_
     ("Resolve conflicts on working copy files or directories.\n"
-     "usage: resolve --accept=ARG [PATH...]\n"
+     "usage: resolve [PATH...]\n"
      "\n"
-     "  Note:  the --accept option is currently required.\n"),
+     "  If no arguments are given, perform interactive conflict resolution for\n"
+     "  all conflicted paths in the working copy, with default depth 'infinity'.\n"
+     "  The --accept=ARG option prevents prompting and forces conflicts on PATH\n"
+     "  to resolved in the manner specified by ARG, with default depth 'empty'.\n"),
     {opt_targets, 'R', opt_depth, 'q', opt_accept},
     {{opt_accept, N_("specify automatic conflict resolution source\n"
                      "                             "

Modified: subversion/trunk/subversion/svn/resolve-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/resolve-cmd.c?rev=1336929&r1=1336928&r2=1336929&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/resolve-cmd.c (original)
+++ subversion/trunk/subversion/svn/resolve-cmd.c Thu May 10 22:28:13 2012
@@ -77,8 +77,11 @@ svn_cl__resolve(apr_getopt_t *os,
       conflict_choice = svn_wc_conflict_choose_mine_full;
       break;
     case svn_cl__accept_unspecified:
-      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                              _("missing --accept option"));
+      if (ctx->conflict_func2 == NULL)
+        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                _("missing --accept option"));
+      conflict_choice = svn_wc_conflict_choose_unspecified;
+      break;
     default:
       return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                               _("invalid 'accept' ARG"));
@@ -89,10 +92,15 @@ svn_cl__resolve(apr_getopt_t *os,
                                                       ctx, FALSE,
                                                       scratch_pool));
   if (! targets->nelts)
-    return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
+    svn_opt_push_implicit_dot_target(targets, scratch_pool);
 
   if (opt_state->depth == svn_depth_unknown)
-    opt_state->depth = svn_depth_empty;
+    {
+      if (opt_state->accept_which == svn_wc_conflict_choose_unspecified)
+        opt_state->depth = svn_depth_infinity;
+      else
+        opt_state->depth = svn_depth_empty;
+    }
 
   SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));
 



Re: svn commit: r1336929 - in /subversion/trunk/subversion: include/private/svn_wc_private.h include/svn_wc.h libsvn_client/resolved.c libsvn_wc/conflicts.c svn/conflict-callbacks.c svn/main.c svn/resolve-cmd.c

Posted by "C. Michael Pilato" <cm...@collab.net>.
On 05/10/2012 06:28 PM, stsp@apache.org wrote:
> Author: stsp
> Date: Thu May 10 22:28:13 2012
> New Revision: 1336929
> 
> URL: http://svn.apache.org/viewvc?rev=1336929&view=rev
> Log:
> Make 'svn resolve' invoke the interactive conflict resolution callback
> for all conflicted paths in the working copy. The --accept option is
> no longer mandatory.

Yay!  This is a good step in the right direction, Stefan.

-- 
C. Michael Pilato <cm...@collab.net>
CollabNet   <>   www.collab.net   <>   Enterprise Cloud Development


Re: svn commit: r1336929 - in /subversion/trunk/subversion: include/private/svn_wc_private.h include/svn_wc.h libsvn_client/resolved.c libsvn_wc/conflicts.c svn/conflict-callbacks.c svn/main.c svn/resolve-cmd.c

Posted by Greg Stein <gs...@gmail.com>.
Should
On May 10, 2012 12:28 PM, <st...@apache.org> wrote:
>
> Author: stsp
> Date: Thu May 10 22:28:13 2012
> New Revision: 1336929
>
> URL: http://svn.apache.org/viewvc?rev=1336929&view=rev
> Log:
> Make 'svn resolve' invoke the interactive conflict resolution callback
> for all conflicted paths in the working copy. The --accept option is
> no longer mandatory.
>
> This is work in progress. Some interactive features don't work yet when
> the resolver is invoked via 'svn resolve' (e.g. the diff-full option seems
> to be broken.)
>
> * subversion/include/private/svn_wc_private.h
>  (svn_wc__resolve_conflicts): Declare.
>
> * subversion/include/svn_wc.h
>  (svn_wc_conflict_choice_t): Add new value
svn_wc_conflict_choose_unspecified.
>
> * subversion/libsvn_wc/conflicts.c
>  (resolve_one_conflict): Accept conflict_func and conflict_baton
parameters,
>    and invoke the conflict function if the pre-defined conflict choice is
>    'unspecified'.
>  (recursive_resolve_conflict): Accept conflict_func and conflict_baton
>   parameters, to be ultimately passed on to resolve_one_conflict().
>  (svn_wc__resolve_conflicts): New API that allows higher layers to invoke
>   conflict resolution on all items.
>  (svn_wc_resolved_conflict5): Re-implement as wrapper around the new
>   svn_wc__resolve_conflicts() function, passing NULL for the conflict
callback.
>
> * subversion/libsvn_client/resolved.c
>  (svn_client_resolve): Call svn_wc__resolve_conflicts() instead of
>   svn_wc_resolved_conflict5().

Should svn_wc_resolved_conflict5 be deprecated? Seems like it.

("Use svn_client_FOO instead")

Cheers,
-g