[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [PATCH] Make --accept match conflict handling prompt

From: Eric Gillespie <epg_at_google.com>
Date: 2007-10-01 23:36:11 CEST

Daniel Rall <dlr@collab.net> writes:

> No, I did not apply your patch to my WC. All this trivial piggy-back
> patch does is change the names of enum -- and pseudo-enum -- elements,
> though. I can always redo it after you commit, if that's more
> comfortable for ya.

Eh, I've said that many times and then managed to screw up
anyway. I'll include it, though, and point people to you in the
unlikely event it blows up.

> > > > +svn_cl__conflict_baton_new(svn_cl__accept_t accept_which,
> > > > + apr_hash_t *config,
> > > > + const char *editor_cmd,
> > > > + apr_pool_t *pool);
> > >=20
> > > Subversion uses the verbs "create" or "make" more often than the word
> > > "new" in constructor function names.
> >=20
> > Ah, OK. I'll look around to see which is more common.
>
> We use all three, but "create" outnumbers "make" by like 3-1, and
> "new" is hardly used at all.

Yep, renamed to "make".

> > > > +/* Return svn_cl__accept_t value corresponding to @ word.
> > > > + * @since New in 1.5.
> > > > + */
> > > > +svn_cl__accept_t
> > > > +svn_cl__accept_from_word(const char *word);
> > >=20
> > > While I see value in having the "since what version" info in the doc
> > > strings, these particular doc strings don't need to use Doxygen
> > > markup.
> >=20
> > Hm, do we actively discourage it? It seems like a good habit to
> > stay in, and harmless enough.
>
> We've made an effort to avoid the use Doxygen markup in internal
> header files that don't have Doxygen run against them. That said, it
> communicates the point pretty well. *shrug*

They're all gone now.

> > > > +svn_cl__conflict_handler(svn_wc_conflict_result_t *result,
> > > > + const svn_wc_conflict_description_t *desc,
> > > > + void *baton,
> > > > + apr_pool_t *pool)
> > > > {
> > >=20
> > > The changes to this routine are probably going to hork Augie F's patch.
> >=20
> > Oh, somehow I overlooked that. I'll take a look at it; let's see
> > if we can get it committed first.
>
> sussman reviewed Augie's patch, and I saw Augie mention on IRC that
> he'd work on revising it based on Ben's comments.

It's pretty much ready to go. I'll go ahead and handle the merge
now, before that goes in. Here's my new patch, without Augie's
changes, for the record:

Index: subversion/include/svn_types.h
===================================================================
--- subversion/include/svn_types.h (revision 26821)
+++ subversion/include/svn_types.h (working copy)
@@ -221,37 +221,6 @@
   svn_recursive
 };
 
-/** The concept of automatic conflict resolution.
- *
- * @since New in 1.5.
- */
-typedef enum
-{
- /* Invalid accept flag */
- svn_accept_invalid = -1,
-
- /* Resolve the conflict as usual */
- svn_accept_none,
-
- /* Resolve the conflict with the pre-conflict base file */
- svn_accept_left,
-
- /* Resolve the conflict with the pre-conflict working copy file */
- svn_accept_working,
-
- /* Resolve the conflict with the post-conflict base file */
- svn_accept_right,
-
-} svn_accept_t;
-
-/** Return the appropriate accept for @a accept_str. @a word is as
- * returned from svn_accept_to_word().
- *
- * @since New in 1.5.
- */
-svn_accept_t
-svn_accept_from_word(const char *word);
-
 /** The concept of depth for directories.
  *
  * @note This is similar to, but not exactly the same as, the WebDAV
Index: subversion/include/svn_wc.h
===================================================================
--- subversion/include/svn_wc.h (revision 26821)
+++ subversion/include/svn_wc.h (working copy)
@@ -1007,8 +1007,8 @@
    * they default to NULL.) */
 
   const char *base_file; /* common ancestor of the two files being merged */
- const char *repos_file; /* repository's version of the file */
- const char *user_file; /* user's locally-edited version of the file */
+ const char *their_file; /* their version of the file */
+ const char *my_file; /* my locally-edited version of the file */
   const char *merged_file; /* merged version of file; has conflict markers */
 
 } svn_wc_conflict_description_t;
@@ -1036,8 +1036,8 @@
      "installing" the chosen file as the final version of the file.*/
 
   svn_wc_conflict_result_choose_base, /* user chooses the base file */
- svn_wc_conflict_result_choose_repos, /* user chooses the repository file */
- svn_wc_conflict_result_choose_user, /* user chooses own version of file */
+ svn_wc_conflict_result_choose_theirs, /* user chooses their file */
+ svn_wc_conflict_result_choose_mine, /* user chooses own version of file */
   svn_wc_conflict_result_choose_merged /* user chooses the merged-file
                                            (which she may have
                                            manually edited) */
@@ -2662,15 +2662,12 @@
  * if any); if @c svn_depth_infinity, resolve @a path and every
  * conflicted file or directory anywhere beneath it.
  *
- * @a accept_ is the argument used to facilitate automatic conflict resolution.
- * If @a accept_ is svn_accept_left, the contents of the conflicted file will
- * be replaced with the prestine contents of the pre-modification base file
- * contents. If @a accept_ is svn_accept_right, the contents of the conflicted
- * file will be replaced with the post-conflict base file contents. If @a
- * accept_ is svn_accept_working, the contents of the conflicted file will be
- * the content of the pre-conflict working copy file. If @a accept_ is
- * svn_accept_default, conflict resolution will be handled just like before
- * automatic conflict resolution was availble.
+ * If @a conflict_result is svn_wc_conflict_result_choose_base, resolve the
+ * conflict with the old file contents; if
+ * svn_wc_conflict_result_choose_user, use the original working contents;
+ * if svn_wc_conflict_result_choose_theirs, the new contents; and if
+ * svn_wc_conflict_result_choose_merged, don't change the contents at all,
+ * just remove the conflict status (i.e. pre-1.5 behavior).
  *
  * @a adm_access is an access baton, with a write lock, for @a path.
  *
@@ -2700,7 +2697,7 @@
                                        svn_boolean_t resolve_text,
                                        svn_boolean_t resolve_props,
                                        svn_depth_t depth,
- svn_accept_t accept_,
+ svn_wc_conflict_result_t conflict_result,
                                        svn_wc_notify_func2_t notify_func,
                                        void *notify_baton,
                                        svn_cancel_func_t cancel_func,
Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h (revision 26821)
+++ subversion/include/svn_client.h (working copy)
@@ -2705,17 +2705,12 @@
  * if any); if @c svn_depth_infinity, resolve @a path and every
  * conflicted file or directory anywhere beneath it.
  *
- * @a accept_which is the argument used to facilitate automatic
- * conflict resolution. If @a accept_which is svn_accept_left, the
- * contents of the conflicted file will be replaced with the prestine
- * contents of the pre-modification base file contents. If @a
- * accept_which is svn_accept_right, the contents of the conflicted
- * file will be replaced with the post-conflict base file contents. If @a
- * accept_which is svn_accept_working, the contents of the conflicted
- * file will be the content of the pre-conflict working copy file. If
- * @a accept_which is svn_accept_default, conflict resolution will
- * be handled just like before automatic conflict resolution was
- * availble.
+ * If @a conflict_result is svn_wc_conflict_result_choose_base, resolve the
+ * conflict with the old file contents; if
+ * svn_wc_conflict_result_choose_user, use the original working contents;
+ * if svn_wc_conflict_result_choose_theirs, the new contents; and if
+ * svn_wc_conflict_result_choose_merged, don't change the contents at all,
+ * just remove the conflict status (i.e. pre-1.5 behavior).
  *
  * If @a path is not in a state of conflict to begin with, do nothing.
  * If @a path's conflict state is removed and @a ctx->notify_func2 is non-null,
@@ -2726,7 +2721,7 @@
 svn_error_t *
 svn_client_resolved2(const char *path,
                      svn_depth_t depth,
- svn_accept_t accept_which,
+ svn_wc_conflict_result_t conflict_result,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *pool);
 
Index: subversion/libsvn_wc/merge.c
===================================================================
--- subversion/libsvn_wc/merge.c (revision 26821)
+++ subversion/libsvn_wc/merge.c (working copy)
@@ -416,8 +416,8 @@
               cdesc.action = svn_wc_conflict_action_edit;
               cdesc.reason = svn_wc_conflict_reason_edited;
               cdesc.base_file = left;
- cdesc.repos_file = right;
- cdesc.user_file = tmp_target;
+ cdesc.their_file = right;
+ cdesc.my_file = tmp_target;
               cdesc.merged_file = result_target;
 
               SVN_ERR(conflict_func(&result, &cdesc, conflict_baton, pool));
@@ -436,7 +436,7 @@
                       contains_conflicts = FALSE;
                       goto merge_complete;
                     }
- case svn_wc_conflict_result_choose_repos:
+ case svn_wc_conflict_result_choose_theirs:
                     {
                       SVN_ERR(svn_wc__loggy_copy
                               (log_accum, NULL, adm_access,
@@ -447,7 +447,7 @@
                       contains_conflicts = FALSE;
                       goto merge_complete;
                     }
- case svn_wc_conflict_result_choose_user:
+ case svn_wc_conflict_result_choose_mine:
                     {
                       /* Do nothing to merge_target, let it live untouched! */
                       *merge_outcome = svn_wc_merge_merged;
@@ -648,8 +648,8 @@
           cdesc.action = svn_wc_conflict_action_edit;
           cdesc.reason = svn_wc_conflict_reason_edited;
           cdesc.base_file = left;
- cdesc.repos_file = right;
- cdesc.user_file = tmp_target;
+ cdesc.their_file = right;
+ cdesc.my_file = tmp_target;
           cdesc.merged_file = NULL; /* notice there is NO merged file! */
 
           SVN_ERR(conflict_func(&result, &cdesc, conflict_baton, pool));
@@ -669,7 +669,7 @@
                   contains_conflicts = FALSE;
                   goto merge_complete;
                 }
- case svn_wc_conflict_result_choose_repos:
+ case svn_wc_conflict_result_choose_theirs:
                 {
                   SVN_ERR(svn_wc__loggy_copy
                           (log_accum, NULL, adm_access,
@@ -685,7 +685,7 @@
                    the response claims to have already resolved the
                    problem.*/
               case svn_wc_conflict_result_resolved:
- case svn_wc_conflict_result_choose_user:
+ case svn_wc_conflict_result_choose_mine:
                 {
                   *merge_outcome = svn_wc_merge_merged;
                   contains_conflicts = FALSE;
Index: subversion/libsvn_wc/adm_crawler.c
===================================================================
--- subversion/libsvn_wc/adm_crawler.c (revision 26821)
+++ subversion/libsvn_wc/adm_crawler.c (working copy)
@@ -88,7 +88,8 @@
 
   /* Remove any text conflict */
   SVN_ERR(svn_wc_resolved_conflict3(file_path, adm_access, TRUE, FALSE,
- svn_depth_empty, svn_accept_left,
+ svn_depth_empty,
+ svn_wc_conflict_result_choose_merged,
                                     NULL, NULL, NULL, NULL, pool));
 
   if (use_commit_times)
Index: subversion/libsvn_wc/adm_ops.c
===================================================================
--- subversion/libsvn_wc/adm_ops.c (revision 26821)
+++ subversion/libsvn_wc/adm_ops.c (working copy)
@@ -2546,9 +2546,12 @@
 
 /* Conflict resolution involves removing the conflict files, if they exist,
    and clearing the conflict filenames from the entry. The latter needs to
- be done whether or not the conflict files exist. If @a accept is anything
- but svn_accept_default, automatically resolve the
- conflict with the respective temporary file contents.
+ be done whether or not the conflict files exist. If @a conflict_result
+ is svn_wc_conflict_result_choose_base, resolve the conflict with the old
+ file contents; if svn_wc_conflict_result_choose_user, use the original
+ working contents; if svn_wc_conflict_result_choose_theirs, the new
+ contents; and if svn_wc_conflict_result_choose_merged, don't change the
+ contents at all, just remove the conflict status (i.e. pre-1.5 behavior).
 
    @since 1.5 Automatic Conflict Resolution (Issue 2784)
 
@@ -2563,7 +2566,7 @@
                           const char *base_name,
                           svn_boolean_t resolve_text,
                           svn_boolean_t resolve_props,
- svn_accept_t accept_which,
+ svn_wc_conflict_result_t conflict_result,
                           svn_wc_notify_func2_t notify_func,
                           void *notify_baton,
                           apr_pool_t *pool)
@@ -2575,23 +2578,23 @@
 
   /* Handle automatic conflict resolution before the temporary files are
    * deleted, if necessary. */
- switch (accept_which)
+ switch (conflict_result)
     {
- case svn_accept_left:
- auto_resolve_src = entry->conflict_old;
- break;
- case svn_accept_working:
- auto_resolve_src = entry->conflict_wrk;
- break;
- case svn_accept_right:
- auto_resolve_src = entry->conflict_new;
- break;
- case svn_accept_none:
- auto_resolve_src = NULL;
- break;
- case svn_accept_invalid:
- return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
- _("Invalid 'accept' argument"));
+ case svn_wc_conflict_result_choose_base:
+ auto_resolve_src = entry->conflict_old;
+ break;
+ case svn_wc_conflict_result_choose_mine:
+ auto_resolve_src = entry->conflict_wrk;
+ break;
+ case svn_wc_conflict_result_choose_theirs:
+ auto_resolve_src = entry->conflict_new;
+ break;
+ case svn_wc_conflict_result_choose_merged:
+ auto_resolve_src = NULL;
+ break;
+ default:
+ return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+ _("Invalid 'conflict_result' argument"));
     }
 
     if (auto_resolve_src)
@@ -2675,7 +2678,7 @@
   /* TRUE if property conflicts are to be resolved. */
   svn_boolean_t resolve_props;
   /* The type of automatic conflict resolution to perform */
- svn_accept_t accept_;
+ svn_wc_conflict_result_t conflict_result;
   /* An access baton for the tree, with write access */
   svn_wc_adm_access_t *adm_access;
   /* Notification function and baton */
@@ -2710,7 +2713,7 @@
 
   return resolve_conflict_on_entry(path, entry, adm_access, base_name,
                                    baton->resolve_text, baton->resolve_props,
- baton->accept_, baton->notify_func,
+ baton->conflict_result, baton->notify_func,
                                    baton->notify_baton, pool);
 }
 
@@ -2758,7 +2761,8 @@
                           apr_pool_t *pool)
 {
   return svn_wc_resolved_conflict3(path, adm_access, resolve_text,
- resolve_props, recurse, svn_accept_none,
+ resolve_props, recurse,
+ svn_wc_conflict_result_choose_merged,
                                    notify_func, notify_baton, cancel_func,
                                    cancel_baton, pool);
 }
@@ -2769,7 +2773,7 @@
                           svn_boolean_t resolve_text,
                           svn_boolean_t resolve_props,
                           svn_depth_t depth,
- svn_accept_t accept_,
+ svn_wc_conflict_result_t conflict_result,
                           svn_wc_notify_func2_t notify_func,
                           void *notify_baton,
                           svn_cancel_func_t cancel_func,
@@ -2783,7 +2787,7 @@
   baton->adm_access = adm_access;
   baton->notify_func = notify_func;
   baton->notify_baton = notify_baton;
- baton->accept_ = accept_;
+ baton->conflict_result = conflict_result;
 
   if (depth == svn_depth_empty)
     {
Index: subversion/libsvn_subr/kitchensink.c
===================================================================
--- subversion/libsvn_subr/kitchensink.c (revision 26821)
+++ subversion/libsvn_subr/kitchensink.c (working copy)
@@ -68,20 +68,6 @@
   return uuid_str;
 }
 
-svn_accept_t
-svn_accept_from_word(const char *word)
-{
- if (strcmp(word, "left") == 0)
- return svn_accept_left;
- if (strcmp(word, "working") == 0)
- return svn_accept_working;
- if (strcmp(word, "right") == 0)
- return svn_accept_right;
- /* Return svn_accept_invalid which means that the passed string is not
- * a recognized accept option. */
- return svn_accept_invalid;
-}
-
 const char *
 svn_depth_to_word(svn_depth_t depth)
 {
Index: subversion/libsvn_client/resolved.c
===================================================================
--- subversion/libsvn_client/resolved.c (revision 26821)
+++ subversion/libsvn_client/resolved.c (working copy)
@@ -37,13 +37,14 @@
                     svn_client_ctx_t *ctx,
                     apr_pool_t *pool)
 {
- return svn_client_resolved2(path, recursive, svn_accept_none, ctx, pool);
+ return svn_client_resolved2(path, recursive,
+ svn_wc_conflict_result_choose_merged, ctx, pool);
 }
 
 svn_error_t *
 svn_client_resolved2(const char *path,
                      svn_depth_t depth,
- svn_accept_t accept_which,
+ svn_wc_conflict_result_t conflict_result,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *pool)
 {
@@ -59,7 +60,7 @@
                                  pool));
 
   SVN_ERR(svn_wc_resolved_conflict3(path, adm_access, TRUE, TRUE, depth,
- accept_which,
+ conflict_result,
                                     ctx->notify_func2, ctx->notify_baton2,
                                     ctx->cancel_func, ctx->cancel_baton,
                                     pool));
Index: subversion/bindings/javahl/native/ConflictResolverCallback.cpp
===================================================================
--- subversion/bindings/javahl/native/ConflictResolverCallback.cpp (revision 26821)
+++ subversion/bindings/javahl/native/ConflictResolverCallback.cpp (working copy)
@@ -210,10 +210,10 @@
       return svn_wc_conflict_result_resolved;
     case org_tigris_subversion_javahl_ConflictResolverCallback_Result_choose_base:
       return svn_wc_conflict_result_choose_base;
- case org_tigris_subversion_javahl_ConflictResolverCallback_Result_choose_repos:
- return svn_wc_conflict_result_choose_repos;
- case org_tigris_subversion_javahl_ConflictResolverCallback_Result_choose_user:
- return svn_wc_conflict_result_choose_user;
+ case org_tigris_subversion_javahl_ConflictResolverCallback_Result_choose_theirs:
+ return svn_wc_conflict_result_choose_theirs;
+ case org_tigris_subversion_javahl_ConflictResolverCallback_Result_choose_mine:
+ return svn_wc_conflict_result_choose_mine;
     case org_tigris_subversion_javahl_ConflictResolverCallback_Result_choose_merged:
       return svn_wc_conflict_result_choose_merged;
     }
Index: subversion/bindings/javahl/src/org/tigris/subversion/javahl/ConflictResolverCallback.java
===================================================================
--- subversion/bindings/javahl/src/org/tigris/subversion/javahl/ConflictResolverCallback.java (revision 26821)
+++ subversion/bindings/javahl/src/org/tigris/subversion/javahl/ConflictResolverCallback.java (working copy)
@@ -67,12 +67,12 @@
         /**
          * User chooses the repository file.
          */
- public static final int choose_repos = 3;
+ public static final int choose_theirs = 3;
 
         /**
          * User chooses own version of file.
          */
- public static final int choose_user = 4;
+ public static final int choose_mine = 4;
 
         /**
          * User chooses the merged-file (which she may have manually
Index: subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
===================================================================
--- subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (revision 26821)
+++ subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (working copy)
@@ -44,6 +44,12 @@
 #include "swig_python_external_runtime.swg"
 #include "swigutil_py.h"
 
+/* Define handy Python 2.4 macro if this is older Python. */
+#ifndef Py_RETURN_NONE
+#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
+#endif
+
+
 
 
 /*** Manage the Global Interpreter Lock ***/
Index: subversion/tests/cmdline/basic_tests.py
===================================================================
--- subversion/tests/cmdline/basic_tests.py (revision 26821)
+++ subversion/tests/cmdline/basic_tests.py (working copy)
@@ -2138,30 +2138,41 @@
   # So now lambda, mu and rho are all in a "conflicted" state. Run 'svn
   # resolved' with the respective "--accept[mine|orig|repo]" flag.
 
+ # But first, check --accept actions resolved does not accept.
+ svntest.actions.run_and_verify_svn(None,
+ # stdout, stderr
+ None,
+ ".*invalid 'accept' ARG",
+ 'resolved', '--accept=edit')
+ # TODO: when launch is implemented, this error message will match the rest.
+ svntest.actions.run_and_verify_svn(None,
+ # stdout, stderr
+ None,
+ '.*--accept=launch not yet implemented',
+ 'resolved', '--accept=launch')
+ svntest.actions.run_and_verify_svn(None,
+ # stdout, stderr
+ None,
+ ".*invalid 'accept' ARG",
+ 'resolved', '--accept=postpone')
   # Run 'svn resolved --accept=NOTVALID. Using omega for the test.
   svntest.actions.run_and_verify_svn("Resolved command", None,
- "svn: 'NOTVALID' is not a valid accept value; "
- "try 'left', 'right', or 'working'\n",
+ ".*NOTVALID' is not a valid accept value",
                                      'resolved',
                                      '--accept=NOTVALID',
                                      omega_path_backup)
 
- # Run 'svn resolved --accept=left. Using lambda for the test.
+ # Resolve lambda, mu, and rho with different --accept options.
   svntest.actions.run_and_verify_svn("Resolved command", None, [],
- 'resolved',
- '--accept=left',
+ 'resolved', '--accept=base',
                                      lambda_path_backup)
-
- # Run 'svn resolved --accept=working. Using mu for the test.
   svntest.actions.run_and_verify_svn("Resolved command", None, [],
                                      'resolved',
- '--accept=working',
+ '--accept=mine',
                                      mu_path_backup)
-
- # Run 'svn resolved --accept=right. Using rho for the test.
   svntest.actions.run_and_verify_svn("Resolved command", None, [],
                                      'resolved',
- '--accept=right',
+ '--accept=theirs',
                                      rho_path_backup)
 
   # Set the expected disk contents for the test
Index: subversion/tests/cmdline/update_tests.py
===================================================================
--- subversion/tests/cmdline/update_tests.py (revision 26821)
+++ subversion/tests/cmdline/update_tests.py (working copy)
@@ -3248,7 +3248,195 @@
                                         expected_disk,
                                         expected_status)
 
+#----------------------------------------------------------------------
 
+def update_accept_conflicts(sbox):
+ "update --accept automatic conflict resolution"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # Make a backup copy of the working copy
+ wc_backup = sbox.add_wc_path('backup')
+ svntest.actions.duplicate_dir(wc_dir, wc_backup)
+
+ # Make a few local mods to files which will be committed
+ iota_path = os.path.join(wc_dir, 'iota')
+ lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
+ mu_path = os.path.join(wc_dir, 'A', 'mu')
+ alpha_path = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha')
+ beta_path = os.path.join(wc_dir, 'A', 'B', 'E', 'beta')
+ rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
+ svntest.main.file_append(lambda_path, 'Their appended text for lambda\n')
+ svntest.main.file_append(iota_path, 'Their appended text for iota\n')
+ svntest.main.file_append(mu_path, 'Their appended text for mu\n')
+ svntest.main.file_append(alpha_path, 'Their appended text for alpha\n')
+ svntest.main.file_append(beta_path, 'Their appended text for beta\n')
+ svntest.main.file_append(rho_path, 'Their appended text for rho\n')
+
+ # Make a few local mods to files which will be conflicted
+ iota_path_backup = os.path.join(wc_backup, 'iota')
+ lambda_path_backup = os.path.join(wc_backup, 'A', 'B', 'lambda')
+ mu_path_backup = os.path.join(wc_backup, 'A', 'mu')
+ alpha_path_backup = os.path.join(wc_backup, 'A', 'B', 'E', 'alpha')
+ beta_path_backup = os.path.join(wc_backup, 'A', 'B', 'E', 'beta')
+ rho_path_backup = os.path.join(wc_backup, 'A', 'D', 'G', 'rho')
+ svntest.main.file_append(iota_path_backup,
+ 'My appended text for iota\n')
+ svntest.main.file_append(lambda_path_backup,
+ 'My appended text for lambda\n')
+ svntest.main.file_append(mu_path_backup,
+ 'My appended text for mu\n')
+ svntest.main.file_append(alpha_path_backup,
+ 'My appended text for alpha\n')
+ svntest.main.file_append(beta_path_backup,
+ 'My appended text for beta\n')
+ svntest.main.file_append(rho_path_backup,
+ 'My appended text for rho\n')
+
+ # Created expected output tree for 'svn ci'
+ expected_output = svntest.wc.State(wc_dir, {
+ 'iota' : Item(verb='Sending'),
+ 'A/B/lambda' : Item(verb='Sending'),
+ 'A/mu' : Item(verb='Sending'),
+ 'A/B/E/alpha': Item(verb='Sending'),
+ 'A/B/E/beta': Item(verb='Sending'),
+ 'A/D/G/rho' : Item(verb='Sending'),
+ })
+
+ # Create expected status tree; all local revisions should be at 1,
+ # but mu and rho should be at revision 2.
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('iota', wc_rev=2)
+ expected_status.tweak('A/B/lambda', wc_rev=2)
+ expected_status.tweak('A/mu', wc_rev=2)
+ expected_status.tweak('A/B/E/alpha', wc_rev=2)
+ expected_status.tweak('A/B/E/beta', wc_rev=2)
+ expected_status.tweak('A/D/G/rho', wc_rev=2)
+
+ # Commit.
+ svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+ expected_status, None,
+ None, None, None, None, wc_dir)
+
+ # Now we'll update each of our 5 files in wc_backup; each one will get
+ # conflicts, and we'll handle each with a different --accept option.
+
+# os.chdir(wc_backup)
+# os.system('zsh')
+
+ # iota: no accept option
+ # Just leave the conflicts alone, since run_and_verify_svn already uses
+ # the --non-interactive option.
+ svntest.actions.run_and_verify_svn(None,
+ ['C %s\n' % (iota_path_backup,),
+ 'Updated to revision 2.\n'],
+ [],
+ 'update', iota_path_backup)
+
+ # lambda: --accept=postpone
+ # Just leave the conflicts alone.
+ svntest.actions.run_and_verify_svn(None,
+ ['C %s\n' % (lambda_path_backup,),
+ 'Updated to revision 2.\n'],
+ [],
+ 'update', '--accept=postpone',
+ lambda_path_backup)
+
+ # mu: --accept=base
+ # Accept the pre-update base file.
+ svntest.actions.run_and_verify_svn(None,
+ ['G %s\n' % (mu_path_backup,),
+ 'Updated to revision 2.\n'],
+ [],
+ 'update', '--accept=base',
+ mu_path_backup)
+
+ # alpha: --accept=mine
+ # Accept the user's working file.
+ svntest.actions.run_and_verify_svn(None,
+ ['G %s\n' % (alpha_path_backup,),
+ 'Updated to revision 2.\n'],
+ [],
+ 'update', '--accept=mine',
+ alpha_path_backup)
+
+ # beta: --accept=theirs
+ # Accept their file.
+ svntest.actions.run_and_verify_svn(None,
+ ['G %s\n' % (beta_path_backup,),
+ 'Updated to revision 2.\n'],
+ [],
+ 'update', '--accept=theirs',
+ beta_path_backup)
+
+ # rho: --accept=edit
+ # Run editor and accept the edited file.
+ svntest.main.use_editor('append_foo')
+ svntest.actions.run_and_verify_svn(None,
+ ['G %s\n' % (rho_path_backup,),
+ 'Updated to revision 2.\n'],
+ [],
+ 'update', '--accept=edit',
+ rho_path_backup)
+
+ # Set the expected disk contents for the test
+ expected_disk = svntest.main.greek_state.copy()
+
+ expected_disk.tweak('iota', contents=("This is the file 'iota'.\n"
+ '<<<<<<< .mine\n'
+ 'My appended text for iota\n'
+ '=======\n'
+ 'Their appended text for iota\n'
+ '>>>>>>> .r2\n'))
+ expected_disk.tweak('A/B/lambda', contents=("This is the file 'lambda'.\n"
+ '<<<<<<< .mine\n'
+ 'My appended text for lambda\n'
+ '=======\n'
+ 'Their appended text for lambda\n'
+ '>>>>>>> .r2\n'))
+ expected_disk.tweak('A/mu', contents="This is the file 'mu'.\n")
+ expected_disk.tweak('A/B/E/alpha', contents=("This is the file 'alpha'.\n"
+ 'My appended text for alpha\n'))
+ expected_disk.tweak('A/B/E/beta', contents=("This is the file 'beta'.\n"
+ 'Their appended text for beta\n'))
+ expected_disk.tweak('A/D/G/rho', contents=("This is the file 'rho'.\n"
+ '<<<<<<< .mine\n'
+ 'My appended text for rho\n'
+ '=======\n'
+ 'Their appended text for rho\n'
+ '>>>>>>> .r2\n'
+ 'foo\n'))
+
+ # Set the expected extra files for the test
+ extra_files = ['iota.*\.r1', 'iota.*\.r2', 'iota.*\.mine',
+ 'lambda.*\.r1', 'lambda.*\.r2', 'lambda.*\.mine']
+
+ # Set the expected status for the test
+ expected_status = svntest.actions.get_virginal_state(wc_backup, 2)
+ expected_status.tweak('iota', 'A/B/lambda', 'A/mu',
+ 'A/B/E/alpha', 'A/B/E/beta',
+ 'A/D/G/rho', wc_rev=2)
+ expected_status.tweak('iota', status='C ')
+ expected_status.tweak('A/B/lambda', status='C ')
+ expected_status.tweak('A/mu', status='M ')
+ expected_status.tweak('A/B/E/alpha', status='M ')
+ expected_status.tweak('A/B/E/beta', status=' ')
+ expected_status.tweak('A/D/G/rho', status='M ')
+
+ # Set the expected output for the test
+ expected_output = wc.State(wc_backup, {})
+
+ # Do the update and check the results in three ways.
+ svntest.actions.run_and_verify_update(wc_backup,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None,
+ svntest.tree.detect_conflict_files,
+ extra_files)
+
+
 #######################################################################
 # Run the tests
 
@@ -3292,6 +3480,7 @@
               update_conflicted,
               mergeinfo_update_elision,
               XFail(update_handles_copyfrom),
+ update_accept_conflicts,
              ]
 
 if __name__ == '__main__':
Index: subversion/svn/cl.h
===================================================================
--- subversion/svn/cl.h (revision 26821)
+++ subversion/svn/cl.h (working copy)
@@ -90,6 +90,44 @@
 } svn_cl__longopt_t;
 
 
+/* --accept actions */
+typedef enum
+{
+ /* invalid or unspecified accept action */
+ svn_cl__accept_invalid = -1,
+
+ /* Leave conflicts alone, for later resolution. */
+ svn_cl__accept_postpone,
+
+ /* Resolve the conflict with the pre-conflict base file. */
+ svn_cl__accept_base,
+
+ /* Resolve the conflict with the pre-conflict working copy file. */
+ svn_cl__accept_mine,
+
+ /* Resolve the conflict with the post-conflict base file. */
+ svn_cl__accept_theirs,
+
+ /* Launch user's editor and resolve conflict with edited file. */
+ svn_cl__accept_edit,
+
+ /* Launch user's resolver and resolve conflict with edited file. */
+ svn_cl__accept_launch,
+} svn_cl__accept_t;
+
+/* --accept action user input words */
+#define SVN_CL__ACCEPT_POSTPONE "postpone"
+#define SVN_CL__ACCEPT_BASE "base"
+#define SVN_CL__ACCEPT_MINE "mine"
+#define SVN_CL__ACCEPT_THEIRS "theirs"
+#define SVN_CL__ACCEPT_EDIT "edit"
+#define SVN_CL__ACCEPT_LAUNCH "launch"
+
+/* Return svn_cl__accept_t value corresponding to word. */
+svn_cl__accept_t
+svn_cl__accept_from_word(const char *word);
+
+
 
 /*** Command dispatch. ***/
 
@@ -161,7 +199,7 @@
   apr_hash_t *revprop_table; /* table of revision properties to get/set */
   svn_boolean_t parents; /* create intermediate directories */
   svn_boolean_t use_merge_history; /* use/display extra merge information */
- svn_accept_t accept_which; /* automatically resolve conflict */
+ svn_cl__accept_t accept_which; /* how to handle conflicts */
 
 } svn_cl__opt_state_t;
 
@@ -248,6 +286,22 @@
 
 /* Various conflict-resolution callbacks. */
 
+typedef struct {
+ svn_cl__accept_t accept_which;
+ apr_hash_t *config;
+ const char *editor_cmd;
+ svn_boolean_t external_failed;
+ svn_boolean_t interactive;
+} svn_cl__conflict_baton_t;
+
+/* Return address of newly allocated and initialized
+ svn_cl__conflict_baton_t. */
+svn_cl__conflict_baton_t *
+svn_cl__conflict_baton_make(svn_cl__accept_t accept_which,
+ apr_hash_t *config,
+ const char *editor_cmd,
+ apr_pool_t *pool);
+
 /* A mindless implementation of svn_wc_conflict_resolver_func_t that
  * does absolutely nothing to resolve conflicts. */
 svn_error_t *
@@ -260,10 +314,10 @@
    one of the 3 fulltexts, edit the merged file on the spot, or just
    skip the conflict (to be resolved later). */
 svn_error_t *
-svn_cl__interactive_conflict_handler(svn_wc_conflict_result_t *result,
- const svn_wc_conflict_description_t *desc,
- void *baton,
- apr_pool_t *pool);
+svn_cl__conflict_handler(svn_wc_conflict_result_t *result,
+ const svn_wc_conflict_description_t *desc,
+ void *baton,
+ apr_pool_t *pool);
 
 
 
Index: subversion/svn/resolved-cmd.c
===================================================================
--- subversion/svn/resolved-cmd.c (revision 26821)
+++ subversion/svn/resolved-cmd.c (working copy)
@@ -29,7 +29,9 @@
 #include "svn_pools.h"
 #include "cl.h"
 
+#include "svn_private_config.h"
 
+
 
 /*** Code. ***/
 
@@ -41,11 +43,31 @@
 {
   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;
+ svn_wc_conflict_result_t conflict_result;
   svn_error_t *err;
   apr_array_header_t *targets;
   int i;
   apr_pool_t *subpool;
 
+ switch (opt_state->accept_which)
+ {
+ case svn_cl__accept_invalid:
+ conflict_result = svn_wc_conflict_result_choose_merged;
+ break;
+ case svn_cl__accept_base:
+ conflict_result = svn_wc_conflict_result_choose_base;
+ break;
+ case svn_cl__accept_theirs:
+ conflict_result = svn_wc_conflict_result_choose_theirs;
+ break;
+ case svn_cl__accept_mine:
+ conflict_result = svn_wc_conflict_result_choose_mine;
+ break;
+ default:
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("invalid 'accept' ARG"));
+ }
+
   SVN_ERR(svn_opt_args_to_target_array2(&targets, os,
                                         opt_state->targets, pool));
   if (! targets->nelts)
@@ -65,8 +87,7 @@
       svn_pool_clear(subpool);
       SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
       err = svn_client_resolved2(target,
- opt_state->depth,
- opt_state->accept_which,
+ opt_state->depth, conflict_result,
                                  ctx,
                                  subpool);
       if (err)
Index: subversion/svn/conflict-callbacks.c
===================================================================
--- subversion/svn/conflict-callbacks.c (revision 26821)
+++ subversion/svn/conflict-callbacks.c (working copy)
@@ -38,6 +38,40 @@
 
 
 
+svn_cl__conflict_baton_t *
+svn_cl__conflict_baton_make(svn_cl__accept_t accept_which,
+ apr_hash_t *config,
+ const char *editor_cmd,
+ apr_pool_t *pool)
+{
+ svn_cl__conflict_baton_t *b = apr_palloc(pool, sizeof(*b));
+ b->accept_which = accept_which;
+ b->config = config;
+ b->editor_cmd = editor_cmd;
+ b->external_failed = FALSE;
+ return b;
+}
+
+svn_cl__accept_t
+svn_cl__accept_from_word(const char *word)
+{
+ if (strcmp(word, SVN_CL__ACCEPT_POSTPONE) == 0)
+ return svn_cl__accept_postpone;
+ if (strcmp(word, SVN_CL__ACCEPT_BASE) == 0)
+ return svn_cl__accept_base;
+ if (strcmp(word, SVN_CL__ACCEPT_MINE) == 0)
+ return svn_cl__accept_mine;
+ if (strcmp(word, SVN_CL__ACCEPT_THEIRS) == 0)
+ return svn_cl__accept_theirs;
+ if (strcmp(word, SVN_CL__ACCEPT_EDIT) == 0)
+ return svn_cl__accept_edit;
+ if (strcmp(word, SVN_CL__ACCEPT_LAUNCH) == 0)
+ return svn_cl__accept_launch;
+ /* word is an invalid action. */
+ return svn_cl__accept_invalid;
+}
+
+
 /* Utility to print a full description of the conflict. */
 static svn_error_t *
 print_conflict_description(const svn_wc_conflict_description_t *desc,
@@ -102,14 +136,14 @@
   }
 
   if (desc->base_file)
- SVN_ERR(svn_cmdline_printf(pool, _(" Ancestor file: %s\n"),
+ SVN_ERR(svn_cmdline_printf(pool, _(" Base file: %s\n"),
                                desc->base_file));
- if (desc->repos_file)
- SVN_ERR(svn_cmdline_printf(pool, _(" Repository's file: %s\n"),
- desc->repos_file));
- if (desc->user_file)
- SVN_ERR(svn_cmdline_printf(pool, _(" User's file: %s\n"),
- desc->user_file));
+ if (desc->their_file)
+ SVN_ERR(svn_cmdline_printf(pool, _(" Their file: %s\n"),
+ desc->their_file));
+ if (desc->my_file)
+ SVN_ERR(svn_cmdline_printf(pool, _(" My file: %s\n"),
+ desc->my_file));
   if (desc->merged_file)
     SVN_ERR(svn_cmdline_printf(pool, _(" File with conflict markers: %s\n"),
                                desc->merged_file));
@@ -135,15 +169,92 @@
 }
 
 
-/* A conflict callback which does real user prompting. */
+/* Implement svn_wc_conflict_resolver_func_t; resolves based on
+ --accept option if given, else by prompting. */
 svn_error_t *
-svn_cl__interactive_conflict_handler(svn_wc_conflict_result_t *result,
- const svn_wc_conflict_description_t *desc,
- void *baton,
- apr_pool_t *pool)
+svn_cl__conflict_handler(svn_wc_conflict_result_t *result,
+ const svn_wc_conflict_description_t *desc,
+ void *baton,
+ apr_pool_t *pool)
 {
- apr_pool_t *subpool = svn_pool_create(pool);
+ svn_cl__conflict_baton_t *b = baton;
+ svn_error_t *err;
+ apr_pool_t *subpool;
 
+ switch (b->accept_which)
+ {
+ case svn_cl__accept_invalid:
+ /* No --accept option, fall through to prompting. */
+ break;
+ case svn_cl__accept_postpone:
+ *result = svn_wc_conflict_result_conflicted;
+ return SVN_NO_ERROR;
+ case svn_cl__accept_base:
+ *result = svn_wc_conflict_result_choose_base;
+ return SVN_NO_ERROR;
+ case svn_cl__accept_mine:
+ *result = svn_wc_conflict_result_choose_mine;
+ return SVN_NO_ERROR;
+ case svn_cl__accept_theirs:
+ *result = svn_wc_conflict_result_choose_theirs;
+ return SVN_NO_ERROR;
+ case svn_cl__accept_edit:
+ if (desc->merged_file)
+ {
+ if (b->external_failed)
+ {
+ *result = svn_wc_conflict_result_conflicted;
+ return SVN_NO_ERROR;
+ }
+
+ err = svn_cl__edit_file_externally(desc->merged_file,
+ b->editor_cmd, b->config, pool);
+ if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR))
+ {
+ SVN_ERR(svn_cmdline_printf(subpool,
+ err->message ? err->message :
+ _("No editor found,"
+ " leaving all conflicts.\n")));
+ svn_error_clear(err);
+ b->external_failed = TRUE;
+ }
+ else if (err && (err->apr_err == SVN_ERR_EXTERNAL_PROGRAM))
+ {
+ SVN_ERR(svn_cmdline_printf(subpool,
+ err->message ? err->message :
+ _("Error running editor,"
+ " leaving all conflicts.\n")));
+ svn_error_clear(err);
+ b->external_failed = TRUE;
+ }
+ else if (err)
+ return err;
+ *result = svn_wc_conflict_result_choose_merged;
+ return SVN_NO_ERROR;
+ }
+ /* else, fall through to prompting. */
+ break;
+ case svn_cl__accept_launch:
+ if (desc->base_file && desc->their_file && desc->my_file)
+ {
+ if (b->external_failed)
+ {
+ *result = svn_wc_conflict_result_conflicted;
+ return SVN_NO_ERROR;
+ }
+
+ /* ### TODO: launch $SVNMERGE tool here with 3 fulltexts; we
+ never get here, as this is blocked at --accept parsing in
+ main.c. */
+ }
+ /* else, fall through to prompting. */
+ break;
+ }
+
+ /* We're in interactive mode and either the user gave no --accept
+ option or the option did not apply; let's prompt. */
+ subpool = svn_pool_create(pool);
+
   /* Handle conflicting file contents, which is the most common case. */
   if ((desc->node_kind == svn_node_file)
       && (desc->action == svn_wc_conflict_action_edit)
@@ -190,12 +301,12 @@
             }
           if (strcmp(answer, "m") == 0)
             {
- *result = svn_wc_conflict_result_choose_user;
+ *result = svn_wc_conflict_result_choose_mine;
               break;
             }
           if (strcmp(answer, "t") == 0)
             {
- *result = svn_wc_conflict_result_choose_repos;
+ *result = svn_wc_conflict_result_choose_theirs;
               break;
             }
           if (strcmp(answer, "d") == 0)
@@ -228,7 +339,8 @@
                 {
                   svn_error_t *eerr;
                   eerr = svn_cl__edit_file_externally(desc->merged_file,
- NULL, NULL, subpool);
+ b->editor_cmd,
+ b->config, subpool);
                   if (eerr && (eerr->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR))
                     {
                       SVN_ERR(svn_cmdline_printf(subpool,
@@ -253,7 +365,7 @@
             }
           if (strcmp(answer, "l") == 0)
             {
- if (desc->base_file && desc->repos_file && desc->user_file)
+ if (desc->base_file && desc->their_file && desc->my_file)
                 {
                   /* ### TODO: launch $SVNMERGE tool here with 3 fulltexts. */
                   SVN_ERR(svn_cmdline_printf(
@@ -289,7 +401,7 @@
       choose_user skip addition, skip addition skip addition
                         add existing item
 
- choose_repos destroy file, schedule-delete, revert add,
+ choose_theirs destroy file, schedule-delete, revert add,
                         add new item. add new item. rm file,
                                                             add new item
 
@@ -329,12 +441,12 @@
             }
           if (strcmp(answer, "m") == 0)
             {
- *result = svn_wc_conflict_result_choose_user;
+ *result = svn_wc_conflict_result_choose_mine;
               break;
             }
           if (strcmp(answer, "t") == 0)
             {
- *result = svn_wc_conflict_result_choose_repos;
+ *result = svn_wc_conflict_result_choose_theirs;
               break;
             }
         }
Index: subversion/svn/main.c
===================================================================
--- subversion/svn/main.c (revision 26821)
+++ subversion/svn/main.c (working copy)
@@ -211,9 +211,16 @@
                        " "
                        "history")},
   {"accept", svn_cl__accept_opt, 1,
- N_("specify automatic conflict resolution source\n"
+ N_("specify automatic conflict resolution action\n"
                        " "
- "('left', 'right', or 'working')")},
+ "('" SVN_CL__ACCEPT_POSTPONE "',"
+ " '" SVN_CL__ACCEPT_BASE "',"
+ " '" SVN_CL__ACCEPT_MINE "',"
+ " '" SVN_CL__ACCEPT_THEIRS "',"
+ " '" SVN_CL__ACCEPT_EDIT "')")},
+ /* TODO: 'launch' */
+/* " '" SVN_CL__ACCEPT_EDIT "'," */
+/* " '" SVN_CL__ACCEPT_LAUNCH "')")}, */
   {0, 0, 0, 0},
 };
 
@@ -715,7 +722,11 @@
      " remove conflict markers; it merely removes the conflict-related\n"
      " artifact files and allows PATH to be committed again.\n"),
     {svn_cl__targets_opt, 'R', svn_cl__depth_opt, 'q',
- svn_cl__config_dir_opt, svn_cl__accept_opt} },
+ svn_cl__config_dir_opt, svn_cl__accept_opt},
+ {{svn_cl__accept_opt, N_("specify automatic conflict resolution source\n"
+ " "
+ /* TODO: 'launch' */
+ "('SVN_CL__ACCEPT_BASE', 'SVN_CL__ACCEPT_MINE', 'SVN_CL__ACCEPT_THEIRS')")}} },
 
   { "revert", svn_cl__revert, {0}, N_
     ("Restore pristine working copy file (undo most local edits).\n"
@@ -874,7 +885,8 @@
      " in the first column with code 'E'.\n"),
     {'r', 'N', svn_cl__depth_opt, 'q', svn_cl__merge_cmd_opt,
      svn_cl__force_opt, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt,
- svn_cl__ignore_externals_opt, svn_cl__changelist_opt} },
+ svn_cl__ignore_externals_opt, svn_cl__changelist_opt,
+ svn_cl__editor_cmd_opt, svn_cl__accept_opt} },
 
   { NULL, NULL, {0}, NULL, {0} }
 };
@@ -1031,7 +1043,7 @@
   opt_state.start_revision.kind = svn_opt_revision_unspecified;
   opt_state.end_revision.kind = svn_opt_revision_unspecified;
   opt_state.depth = svn_depth_unknown;
- opt_state.accept_which = svn_accept_none;
+ opt_state.accept_which = svn_cl__accept_invalid;
 
   /* No args? Show usage. */
   if (argc <= 1)
@@ -1388,20 +1400,19 @@
         opt_state.use_merge_history = TRUE;
         break;
       case svn_cl__accept_opt:
- opt_state.accept_which = svn_accept_from_word(opt_arg);
-
- /* We need to make sure that the value passed to the accept flag
- * was one of the available options. Since svn_accept_invalid is what
- * gets set when one of the three expected are not passed, checking
- * for this as part of the command line parsing makes sense. */
- if (opt_state.accept_which == svn_accept_invalid)
- {
- return svn_cmdline_handle_exit_error
+ opt_state.accept_which = svn_cl__accept_from_word(opt_arg);
+ if (opt_state.accept_which == svn_cl__accept_invalid)
+ return svn_cmdline_handle_exit_error
             (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("'%s' is not a valid accept value; try "
- "'left', 'right', or 'working'"),
- opt_arg), pool, "svn: ");
- }
+ _("'%s' is not a valid accept value"), opt_arg),
+ pool, "svn: ");
+ /* TODO: launch */
+ if (opt_state.accept_which == svn_cl__accept_launch)
+ return svn_cmdline_handle_exit_error
+ (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("--accept=%s not yet implemented"),
+ SVN_CL__ACCEPT_LAUNCH),
+ pool, "svn: ");
       default:
         /* Hmmm. Perhaps this would be a good place to squirrel away
            opts that commands like svn diff might need. Hmmm indeed. */
@@ -1734,16 +1745,41 @@
                                                  we can change this. */
     svn_handle_error2(err, stderr, TRUE, "svn: ");
 
- if (interactive_conflicts
- && (! opt_state.non_interactive ))
+ if ((opt_state.accept_which == svn_cl__accept_invalid
+ && (!interactive_conflicts || opt_state.non_interactive))
+ || opt_state.accept_which == svn_cl__accept_postpone)
     {
- ctx->conflict_func = svn_cl__interactive_conflict_handler;
+ /* If no --accept option at all and we're non-interactive, we're
+ leaving the conflicts behind, so don't need the callback. Same if
+ the user said to postpone. */
+ ctx->conflict_func = NULL;
       ctx->conflict_baton = NULL;
     }
   else
     {
- ctx->conflict_func = NULL;
- ctx->conflict_baton = NULL;
+ if (opt_state.non_interactive)
+ {
+ if (opt_state.accept_which == svn_cl__accept_edit)
+ return svn_cmdline_handle_exit_error
+ (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("--accept=%s incompatible with"
+ " --non-interactive"), SVN_CL__ACCEPT_EDIT),
+ pool, "svn: ");
+ if (opt_state.accept_which == svn_cl__accept_launch)
+ return svn_cmdline_handle_exit_error
+ (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("--accept=%s incompatible with"
+ " --non-interactive"),
+ SVN_CL__ACCEPT_LAUNCH),
+ pool, "svn: ");
+ }
+
+ ctx->conflict_func = svn_cl__conflict_handler;
+ ctx->conflict_baton = svn_cl__conflict_baton_make(
+ opt_state.accept_which,
+ ctx->config,
+ opt_state.editor_cmd,
+ pool);
     }
 
   /* And now we finally run the subcommand. */

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Mon Oct 1 23:36:36 2007

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.