subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bre...@apache.org
Subject svn commit: r1482138 - in /subversion/branches/1.8.x: ./ STATUS subversion/libsvn_wc/conflicts.c subversion/svn/conflict-callbacks.c
Date Mon, 13 May 2013 22:42:22 GMT
Author: breser
Date: Mon May 13 22:42:22 2013
New Revision: 1482138

URL: http://svn.apache.org/r1482138
Log:
Merge the r1477294 group from trunk:

 * r1477294, r1480616, r1480641, r1480642, r1480664, r1480669
   Further improvements for interactive resolution of property conflicts.
   Allow conflicted properties to be edited and resolved to the edited value.
   Justification:
     This is a usability enhancement we could make in 1.8.0.
     It also fixes a bug in libsvn_wc where it doesn't use results provided
     by the conflict callback (see r1480641), which might help API consumers.
   Notes:
     This group depends on r1470246.
     r1477294 and r1480616 are merged to avoid text conflicts from refactoring.
     r1480641 and r1480642 are the main changes.
     The other revisions are small follow-up fixes.
   Votes:
     +1: stsp (for 1.8.0, but not any 1.8.x since it changes the UI)
     +1: steveking
     +1: julianfoad
     -0: rhuijben (requires backport branch. I get a merge conflict using 1.7
                   <stsp> This is because this group requires r1470246 to
                          be merged first, as noted under Notes:)


Modified:
    subversion/branches/1.8.x/   (props changed)
    subversion/branches/1.8.x/STATUS
    subversion/branches/1.8.x/subversion/libsvn_wc/conflicts.c
    subversion/branches/1.8.x/subversion/svn/conflict-callbacks.c

Propchange: subversion/branches/1.8.x/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1477294,1480616,1480641-1480642,1480664,1480669

Modified: subversion/branches/1.8.x/STATUS
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x/STATUS?rev=1482138&r1=1482137&r2=1482138&view=diff
==============================================================================
--- subversion/branches/1.8.x/STATUS (original)
+++ subversion/branches/1.8.x/STATUS Mon May 13 22:42:22 2013
@@ -125,26 +125,6 @@ Approved changes:
 # blocking issues.  If in doubt see this link for details:
 # http://subversion.apache.org/docs/community-guide/releasing.html#release-stabilization
 
- * r1477294, r1480616, r1480641, r1480642, r1480664, r1480669
-   Further improvements for interactive resolution of property conflicts.
-   Allow conflicted properties to be edited and resolved to the edited value.
-   Justification:
-     This is a usability enhancement we could make in 1.8.0.
-     It also fixes a bug in libsvn_wc where it doesn't use results provided
-     by the conflict callback (see r1480641), which might help API consumers.
-   Notes:
-     This group depends on r1470246.
-     r1477294 and r1480616 are merged to avoid text conflicts from refactoring.
-     r1480641 and r1480642 are the main changes.
-     The other revisions are small follow-up fixes.
-   Votes:
-     +1: stsp (for 1.8.0, but not any 1.8.x since it changes the UI)
-     +1: steveking
-     +1: julianfoad
-     -0: rhuijben (requires backport branch. I get a merge conflict using 1.7
-                   <stsp> This is because this group requires r1470246 to
-                          be merged first, as noted under Notes:)
-
  * r1469363, r1469645, r1469674, r1470037, r1470537, r1478220, r1478221,
    r1478465, r1478998, r1480723
    Fix issue #4355 'svn_client_log5 broken with multiple revisions which

Modified: subversion/branches/1.8.x/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x/subversion/libsvn_wc/conflicts.c?rev=1482138&r1=1482137&r2=1482138&view=diff
==============================================================================
--- subversion/branches/1.8.x/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/1.8.x/subversion/libsvn_wc/conflicts.c Mon May 13 22:42:22 2013
@@ -2302,15 +2302,52 @@ svn_wc__read_conflicts(const apr_array_h
 
 /*** Resolving a conflict automatically ***/
 
-/*
- * Resolve the text conflict found in DB/LOCAL_ABSPATH/CONFLICTS
- * according to CONFLICT_CHOICE.  (Don't mark it as resolved.)
+/* Prepare to delete an artifact file at ARTIFACT_FILE_ABSPATH in the
+ * working copy at DB/WRI_ABSPATH.
+ *
+ * Set *WORK_ITEMS to a new work item that, when run, will delete the
+ * artifact file; or to NULL if there is no file to delete.
  *
- * If there were any marker files recorded and present on disk, append to
- * *WORK_ITEMS work items to remove them, and set *REMOVED_REJECT_FILES
- * to TRUE.  Otherwise, don't change *REMOVED_REJECT_FILES.
+ * Set *FILE_FOUND to TRUE if the artifact file is found on disk and its
+ * node kind is 'file'; otherwise do not change *FILE_FOUND.  FILE_FOUND
+ * may be NULL if not required.
+ */
+static svn_error_t *
+remove_artifact_file_if_exists(svn_skel_t **work_items,
+                               svn_boolean_t *file_found,
+                               svn_wc__db_t *db,
+                               const char *wri_abspath,
+                               const char *artifact_file_abspath,
+                               apr_pool_t *result_pool,
+                               apr_pool_t *scratch_pool)
+{
+  *work_items = NULL;
+  if (artifact_file_abspath)
+    {
+      svn_node_kind_t node_kind;
+
+      SVN_ERR(svn_io_check_path(artifact_file_abspath, &node_kind,
+                                scratch_pool));
+      if (node_kind == svn_node_file)
+        {
+          SVN_ERR(svn_wc__wq_build_file_remove(work_items,
+                                               db, wri_abspath,
+                                               artifact_file_abspath,
+                                               result_pool, scratch_pool));
+          if (file_found)
+            *file_found = TRUE;
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/*
+ * Resolve the text conflict found in DB/LOCAL_ABSPATH according
+ * to CONFLICT_CHOICE.
  *
- * It is an error if there is no text conflict.
+ * It is not an error if there is no text conflict. If a text conflict
+ * existed and was resolved, set *DID_RESOLVE to TRUE, else set it to FALSE.
  *
  * Note: When there are no conflict markers to remove there is no existing
  * text conflict; just a database containing old information, which we should
@@ -2319,21 +2356,37 @@ svn_wc__read_conflicts(const apr_array_h
  * Subversion 1.0.
  */
 static svn_error_t *
-resolve_text_conflict_on_node(svn_boolean_t *removed_reject_files,
-                              svn_skel_t **work_items,
+resolve_text_conflict_on_node(svn_boolean_t *did_resolve,
                               svn_wc__db_t *db,
                               const char *local_abspath,
-                              svn_wc_operation_t operation,
-                              svn_skel_t *conflicts,
                               svn_wc_conflict_choice_t conflict_choice,
+                              const char *merged_file,
+                              svn_cancel_func_t cancel_func,
+                              void *cancel_baton,
                               apr_pool_t *scratch_pool)
 {
   const char *conflict_old = NULL;
   const char *conflict_new = NULL;
   const char *conflict_working = NULL;
   const char *auto_resolve_src;
-  svn_node_kind_t node_kind;
   svn_skel_t *work_item;
+  svn_skel_t *work_items = NULL;
+  svn_skel_t *conflicts;
+  svn_wc_operation_t operation;
+  svn_boolean_t text_conflicted;
+
+  *did_resolve = FALSE;
+
+  SVN_ERR(svn_wc__db_read_conflict(&conflicts, db, local_abspath,
+                                   scratch_pool, scratch_pool));
+  if (!conflicts)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, &text_conflicted,
+                                     NULL, NULL, db, local_abspath, conflicts,
+                                     scratch_pool, scratch_pool));
+  if (!text_conflicted)
+    return SVN_NO_ERROR;
 
   SVN_ERR(svn_wc__conflict_read_text_conflict(&conflict_working,
                                               &conflict_old,
@@ -2355,7 +2408,7 @@ resolve_text_conflict_on_node(svn_boolea
       auto_resolve_src = conflict_new;
       break;
     case svn_wc_conflict_choose_merged:
-      auto_resolve_src = NULL;
+      auto_resolve_src = merged_file;
       break;
     case svn_wc_conflict_choose_theirs_conflict:
     case svn_wc_conflict_choose_mine_conflict:
@@ -2411,12 +2464,12 @@ resolve_text_conflict_on_node(svn_boolea
       SVN_ERR(svn_wc__wq_build_file_copy_translated(
                 &work_item, db, local_abspath,
                 auto_resolve_src, local_abspath, scratch_pool, scratch_pool));
-      *work_items = svn_wc__wq_merge(*work_items, work_item, scratch_pool);
+      work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
 
       SVN_ERR(svn_wc__wq_build_sync_file_flags(&work_item, db,
                                                local_abspath,
                                                scratch_pool, scratch_pool));
-      *work_items = svn_wc__wq_merge(*work_items, work_item, scratch_pool);
+      work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
     }
 
   /* Legacy behavior: Only report text conflicts as resolved when at least
@@ -2425,60 +2478,36 @@ resolve_text_conflict_on_node(svn_boolea
      If not the UI shows the conflict as already resolved
      (and in this case we just remove the in-db conflict) */
 
-  if (conflict_old)
-    {
-      SVN_ERR(svn_io_check_path(conflict_old, &node_kind, scratch_pool));
-      if (node_kind == svn_node_file)
-        {
-          SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db,
-                                               local_abspath,
-                                               conflict_old,
-                                               scratch_pool, scratch_pool));
-          *work_items = svn_wc__wq_merge(*work_items, work_item, scratch_pool);
-          *removed_reject_files = TRUE;
-        }
-    }
-
-  if (conflict_new)
-    {
-      SVN_ERR(svn_io_check_path(conflict_new, &node_kind, scratch_pool));
-      if (node_kind == svn_node_file)
-        {
-          SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db,
-                                               local_abspath,
-                                               conflict_new,
-                                               scratch_pool, scratch_pool));
-          *work_items = svn_wc__wq_merge(*work_items, work_item, scratch_pool);
-          *removed_reject_files = TRUE;
-        }
-    }
-
-  if (conflict_working)
-    {
-      SVN_ERR(svn_io_check_path(conflict_working, &node_kind, scratch_pool));
-      if (node_kind == svn_node_file)
-        {
-          SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db,
-                                               local_abspath,
-                                               conflict_working,
-                                               scratch_pool, scratch_pool));
-          *work_items = svn_wc__wq_merge(*work_items, work_item, scratch_pool);
-          *removed_reject_files = TRUE;
-        }
-    }
+  SVN_ERR(remove_artifact_file_if_exists(&work_item, did_resolve,
+                                         db, local_abspath, conflict_old,
+                                         scratch_pool, scratch_pool));
+  work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+
+  SVN_ERR(remove_artifact_file_if_exists(&work_item, did_resolve,
+                                         db, local_abspath, conflict_new,
+                                         scratch_pool, scratch_pool));
+  work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+
+  SVN_ERR(remove_artifact_file_if_exists(&work_item, did_resolve,
+                                         db, local_abspath, conflict_working,
+                                         scratch_pool, scratch_pool));
+  work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+
+  SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
+                                      TRUE, FALSE, FALSE,
+                                      work_items, scratch_pool));
+  SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
+                         scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
 /*
- * Resolve the property conflicts found in DB/LOCAL_ABSPATH/CONFLICTS
- * according to CONFLICT_CHOICE.  (Don't mark it as resolved.)
+ * Resolve the property conflicts found in DB/LOCAL_ABSPATH according
+ * to CONFLICT_CHOICE.
  *
- * If there was a reject file recorded and present on disk, append to
- * *WORK_ITEMS a work item to remove it, and set *REMOVED_REJECT_FILE
- * to TRUE.  Otherwise, don't change *REMOVED_REJECT_FILE.
- *
- * It is an error if there is no prop conflict.
+ * It is not an error if there is no prop conflict. If a prop conflict
+ * existed and was resolved, set *DID_RESOLVE to TRUE, else set it to FALSE.
  *
  * Note: When there are no conflict markers on-disk to remove there is
  * no existing text conflict (unless we are still in the process of
@@ -2509,16 +2538,16 @@ resolve_text_conflict_on_node(svn_boolea
  *
  */
 static svn_error_t *
-resolve_prop_conflict_on_node(svn_boolean_t *removed_reject_file,
-                              svn_skel_t **work_items,
+resolve_prop_conflict_on_node(svn_boolean_t *did_resolve,
                               svn_wc__db_t *db,
                               const char *local_abspath,
-                              svn_wc_operation_t operation,
-                              svn_skel_t *conflicts,
+                              const char *conflicted_propname,
                               svn_wc_conflict_choice_t conflict_choice,
+                              const char *merged_file,
+                              svn_cancel_func_t cancel_func,
+                              void *cancel_baton,
                               apr_pool_t *scratch_pool)
 {
-  svn_node_kind_t node_kind;
   const char *prop_reject_file;
   apr_hash_t *mine_props;
   apr_hash_t *their_old_props;
@@ -2526,6 +2555,24 @@ resolve_prop_conflict_on_node(svn_boolea
   apr_hash_t *conflicted_props;
   apr_hash_t *old_props;
   apr_hash_t *resolve_from = NULL;
+  svn_skel_t *work_items = NULL;
+  svn_skel_t *conflicts;
+  svn_wc_operation_t operation;
+  svn_boolean_t prop_conflicted;
+
+  *did_resolve = FALSE;
+
+  SVN_ERR(svn_wc__db_read_conflict(&conflicts, db, local_abspath,
+                                   scratch_pool, scratch_pool));
+
+  if (!conflicts)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, &prop_conflicted,
+                                     NULL, db, local_abspath, conflicts,
+                                     scratch_pool, scratch_pool));
+  if (!prop_conflicted)
+    return SVN_NO_ERROR;
 
   SVN_ERR(svn_wc__conflict_read_prop_conflict(&prop_reject_file,
                                               &mine_props, &their_old_props,
@@ -2564,7 +2611,24 @@ resolve_prop_conflict_on_node(svn_boolea
       resolve_from = their_props;
       break;
     case svn_wc_conflict_choose_merged:
-      resolve_from = NULL;
+      if (merged_file && conflicted_propname[0] != '\0')
+        {
+          apr_hash_t *actual_props;
+          svn_stream_t *stream;
+          svn_string_t *merged_propval;
+
+          SVN_ERR(svn_wc__db_read_props(&actual_props, db, local_abspath,
+                                        scratch_pool, scratch_pool));
+          resolve_from = actual_props;
+
+          SVN_ERR(svn_stream_open_readonly(&stream, merged_file,
+                                           scratch_pool, scratch_pool));
+          SVN_ERR(svn_string_from_stream(&merged_propval, stream,
+                                         scratch_pool, scratch_pool));
+          svn_hash_sets(resolve_from, conflicted_propname, merged_propval);
+        }
+      else
+        resolve_from = NULL;
       break;
     default:
       return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
@@ -2601,39 +2665,36 @@ resolve_prop_conflict_on_node(svn_boolea
      If not the UI shows the conflict as already resolved
      (and in this case we just remove the in-db conflict) */
 
-  if (prop_reject_file)
-    {
-      SVN_ERR(svn_io_check_path(prop_reject_file, &node_kind, scratch_pool));
-      if (node_kind == svn_node_file)
-        {
-          svn_skel_t *work_item;
+  {
+    svn_skel_t *work_item;
 
-          SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db,
-                                               local_abspath,
-                                               prop_reject_file,
-                                               scratch_pool, scratch_pool));
-          *work_items = svn_wc__wq_merge(*work_items, work_item, scratch_pool);
-          *removed_reject_file = TRUE;
-        }
-    }
+    SVN_ERR(remove_artifact_file_if_exists(&work_item, did_resolve,
+                                           db, local_abspath, prop_reject_file,
+                                           scratch_pool, scratch_pool));
+    work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+  }
+
+  SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath, FALSE, TRUE, FALSE,
+                                      work_items, scratch_pool));
+  SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
+                         scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
 /*
- * Resolve the tree conflict found in DB/LOCAL_ABSPATH/CONFLICTS
- * according to CONFLICT_CHOICE.  (Don't mark it as resolved.)
+ * Resolve the tree conflict found in DB/LOCAL_ABSPATH according to
+ * CONFLICT_CHOICE.
  *
- * ### ... append to *WORK_ITEMS work items to ...?
+ * It is not an error if there is no tree conflict. If a tree conflict
+ * existed and was resolved, set *DID_RESOLVE to TRUE, else set it to FALSE.
  *
- * It is an error if there is no tree conflict.
+ * It is not an error if there is no tree conflict.
  */
 static svn_error_t *
-resolve_tree_conflict_on_node(svn_skel_t **work_items,
+resolve_tree_conflict_on_node(svn_boolean_t *did_resolve,
                               svn_wc__db_t *db,
                               const char *local_abspath,
-                              svn_wc_operation_t operation,
-                              svn_skel_t *conflicts,
                               svn_wc_conflict_choice_t conflict_choice,
                               svn_wc_notify_func2_t notify_func,
                               void *notify_baton,
@@ -2643,7 +2704,22 @@ resolve_tree_conflict_on_node(svn_skel_t
 {
   svn_wc_conflict_reason_t reason;
   svn_wc_conflict_action_t action;
-  svn_boolean_t did_resolve = FALSE;
+  svn_skel_t *conflicts;
+  svn_wc_operation_t operation;
+  svn_boolean_t tree_conflicted;
+
+  *did_resolve = FALSE;
+
+  SVN_ERR(svn_wc__db_read_conflict(&conflicts, db, local_abspath,
+                                   scratch_pool, scratch_pool));
+  if (!conflicts)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, NULL,
+                                     &tree_conflicted, db, local_abspath,
+                                     conflicts, scratch_pool, scratch_pool));
+  if (!tree_conflicted)
+    return SVN_NO_ERROR;
 
   SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, NULL,
                                               db, local_abspath,
@@ -2663,7 +2739,7 @@ resolve_tree_conflict_on_node(svn_skel_t
               SVN_ERR(svn_wc__db_resolve_break_moved_away_children(
                         db, local_abspath, notify_func, notify_baton,
                         scratch_pool));
-              did_resolve = TRUE;
+              *did_resolve = TRUE;
             }
           else if (conflict_choice == svn_wc_conflict_choose_mine_conflict)
             {
@@ -2674,7 +2750,7 @@ resolve_tree_conflict_on_node(svn_skel_t
               SVN_ERR(svn_wc__db_resolve_delete_raise_moved_away(
                         db, local_abspath, notify_func, notify_baton,
                         scratch_pool));
-              did_resolve = TRUE;
+              *did_resolve = TRUE;
             }
           else
             return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
@@ -2699,7 +2775,7 @@ resolve_tree_conflict_on_node(svn_skel_t
                         notify_func, notify_baton,
                         cancel_func, cancel_baton,
                         scratch_pool));
-              did_resolve = TRUE;
+              *did_resolve = TRUE;
             }
           else if (conflict_choice == svn_wc_conflict_choose_merged)
             {
@@ -2714,7 +2790,7 @@ resolve_tree_conflict_on_node(svn_skel_t
                                                           notify_func,
                                                           notify_baton,
                                                           scratch_pool));
-              did_resolve = TRUE;
+              *did_resolve = TRUE;
             }
           else
             return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
@@ -2727,7 +2803,7 @@ resolve_tree_conflict_on_node(svn_skel_t
         }
     }
 
-  if (! did_resolve && conflict_choice != svn_wc_conflict_choose_merged)
+  if (! *did_resolve && conflict_choice != svn_wc_conflict_choose_merged)
     {
       /* For other tree conflicts, there is no way to pick
        * theirs-full or mine-full, etc. Throw an error if the
@@ -2741,110 +2817,13 @@ resolve_tree_conflict_on_node(svn_skel_t
                                                       scratch_pool));
     }
 
+  SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath, FALSE, FALSE, TRUE,
+                                      NULL, scratch_pool));
+  SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
+                         scratch_pool));
   return SVN_NO_ERROR;
 }
 
-/* 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.
-
-   ### This func combines *resolving* and *marking as resolved* -- seems poor.
-
-   LOCAL_ABSPATH in DB is the path to the item to be resolved.
-   RESOLVE_TEXT, RESOLVE_PROPS and RESOLVE_TREE are TRUE iff text, property
-   and tree conflicts respectively are to be resolved.
-
-   If this call marks any conflict as resolved, set *DID_RESOLVE to true,
-   else to false.
-   If asked to resolve a text or prop conflict, only set *DID_RESOLVE
-   to true if a conflict marker file was present, because if no marker
-   file was present then the conflict is considered to be marked as
-   resolved already.
-   ### If asked to resolve a tree conflict, always set *DID_RESOLVE to true.
-       This would make sense if 'resolve_tree' is only requested when
-       there is in fact a tree conflict to be resolved, but, for
-       consistency with text & prop conflicts, the code should probably
-       say "if (resolve_tree && tree_conflicted) *did_resolve = TRUE".
-
-   See svn_wc_resolved_conflict5() for how CONFLICT_CHOICE behaves.
-*/
-static svn_error_t *
-resolve_conflict_on_node(svn_boolean_t *did_resolve,
-                         svn_wc__db_t *db,
-                         const char *local_abspath,
-                         svn_boolean_t resolve_text,
-                         svn_boolean_t resolve_props,
-                         svn_boolean_t resolve_tree,
-                         svn_wc_conflict_choice_t conflict_choice,
-                         svn_wc_notify_func2_t notify_func,
-                         void *notify_baton,
-                         svn_cancel_func_t cancel_func,
-                         void *cancel_baton,
-                         apr_pool_t *scratch_pool)
-{
-  svn_skel_t *conflicts;
-  svn_wc_operation_t operation;
-  svn_boolean_t text_conflicted;
-  svn_boolean_t prop_conflicted;
-  svn_boolean_t tree_conflicted;
-  svn_skel_t *work_items = NULL;
-
-  *did_resolve = FALSE;
-
-  SVN_ERR(svn_wc__db_read_conflict(&conflicts, db, local_abspath,
-                                   scratch_pool, scratch_pool));
-
-  if (!conflicts)
-    return SVN_NO_ERROR;
-
-  SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, &text_conflicted,
-                                     &prop_conflicted, &tree_conflicted,
-                                     db, local_abspath, conflicts,
-                                     scratch_pool, scratch_pool));
-
-  if (resolve_text && text_conflicted)
-    SVN_ERR(resolve_text_conflict_on_node(did_resolve, &work_items,
-                                          db, local_abspath,
-                                          operation, conflicts,
-                                          conflict_choice,
-                                          scratch_pool));
-
-  if (resolve_props && prop_conflicted)
-    SVN_ERR(resolve_prop_conflict_on_node(did_resolve, &work_items,
-                                          db, local_abspath,
-                                          operation, conflicts,
-                                          conflict_choice,
-                                          scratch_pool));
-
-  if (resolve_tree)
-    {
-      SVN_ERR(resolve_tree_conflict_on_node(&work_items,
-                                            db, local_abspath,
-                                            operation, conflicts,
-                                            conflict_choice,
-                                            notify_func, notify_baton,
-                                            cancel_func, cancel_baton,
-                                            scratch_pool));
-      *did_resolve = TRUE;
-    }
-
-  if (resolve_text || resolve_props || resolve_tree)
-    {
-      SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
-                                          resolve_text, resolve_props,
-                                          resolve_tree, work_items,
-                                          scratch_pool));
-
-      /* Run the work queue to remove conflict marker files. */
-      SVN_ERR(svn_wc__wq_run(db, local_abspath,
-                             cancel_func, cancel_baton,
-                             scratch_pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
 svn_error_t *
 svn_wc__mark_resolved_text_conflict(svn_wc__db_t *db,
                                     const char *local_abspath,
@@ -2852,15 +2831,11 @@ svn_wc__mark_resolved_text_conflict(svn_
 {
   svn_boolean_t ignored_result;
 
-  return svn_error_trace(resolve_conflict_on_node(
+  return svn_error_trace(resolve_text_conflict_on_node(
                            &ignored_result,
                            db, local_abspath,
-                           TRUE /* resolve_text */,
-                           FALSE /* resolve_props */,
-                           FALSE /* resolve_tree */,
-                           svn_wc_conflict_choose_merged,
-                           NULL, NULL, /* notify_func */
-                           NULL, NULL, /* cancel_func */
+                           svn_wc_conflict_choose_merged, NULL,
+                           NULL, NULL,
                            scratch_pool));
 }
 
@@ -2871,15 +2846,11 @@ svn_wc__mark_resolved_prop_conflicts(svn
 {
   svn_boolean_t ignored_result;
 
-  return svn_error_trace(resolve_conflict_on_node(
+  return svn_error_trace(resolve_prop_conflict_on_node(
                            &ignored_result,
-                           db, local_abspath,
-                           FALSE /* resolve_text */,
-                           TRUE /* resolve_props */,
-                           FALSE /* resolve_tree */,
-                           svn_wc_conflict_choose_merged,
-                           NULL, NULL, /* notify_func */
-                           NULL, NULL, /* cancel_func */
+                           db, local_abspath, "",
+                           svn_wc_conflict_choose_merged, NULL,
+                           NULL, NULL,
                            scratch_pool));
 }
 
@@ -2901,8 +2872,6 @@ struct conflict_status_walker_baton
 };
 
 /* Implements svn_wc_status4_t to walk all conflicts to resolve.
- *
- * ### Bug: ignores the resolver callback's 'result->merged_file' output.
  */
 static svn_error_t *
 conflict_status_walker(void *baton,
@@ -2931,6 +2900,7 @@ conflict_status_walker(void *baton,
       const svn_wc_conflict_description2_t *cd;
       svn_boolean_t did_resolve;
       svn_wc_conflict_choice_t my_choice = cswb->conflict_choice;
+      const char *merged_file = NULL;
 
       cd = APR_ARRAY_IDX(conflicts, i, const svn_wc_conflict_description2_t *);
 
@@ -2949,7 +2919,8 @@ conflict_status_walker(void *baton,
                                       iterpool, iterpool));
 
           my_choice = result->choice;
-          /* ### Bug: ignores result->merged_file (and ->save_merged) */
+          merged_file = result->merged_file;
+          /* ### Bug: ignores result->save_merged */
         }
 
 
@@ -2961,18 +2932,15 @@ conflict_status_walker(void *baton,
           case svn_wc_conflict_kind_tree:
             if (!cswb->resolve_tree)
               break;
-            SVN_ERR(resolve_conflict_on_node(&did_resolve,
-                                             db,
-                                             local_abspath,
-                                             FALSE /* resolve_text */,
-                                             FALSE /* resolve_props */,
-                                             TRUE /* resolve_tree */,
-                                             my_choice,
-                                             cswb->notify_func,
-                                             cswb->notify_baton,
-                                             cswb->cancel_func,
-                                             cswb->cancel_baton,
-                                             iterpool));
+            SVN_ERR(resolve_tree_conflict_on_node(&did_resolve,
+                                                  db,
+                                                  local_abspath,
+                                                  my_choice,
+                                                  cswb->notify_func,
+                                                  cswb->notify_baton,
+                                                  cswb->cancel_func,
+                                                  cswb->cancel_baton,
+                                                  iterpool));
 
             resolved = TRUE;
             break;
@@ -2981,18 +2949,14 @@ conflict_status_walker(void *baton,
             if (!cswb->resolve_text)
               break;
 
-            SVN_ERR(resolve_conflict_on_node(&did_resolve,
-                                             db,
-                                             local_abspath,
-                                             TRUE /* resolve_text */,
-                                             FALSE /* resolve_props */,
-                                             FALSE /* resolve_tree */,
-                                             my_choice,
-                                             cswb->notify_func,
-                                             cswb->notify_baton,
-                                             cswb->cancel_func,
-                                             cswb->cancel_baton,
-                                             iterpool));
+            SVN_ERR(resolve_text_conflict_on_node(&did_resolve,
+                                                  db,
+                                                  local_abspath,
+                                                  my_choice,
+                                                  merged_file,
+                                                  cswb->cancel_func,
+                                                  cswb->cancel_baton,
+                                                  iterpool));
 
             if (did_resolve)
               resolved = TRUE;
@@ -3002,28 +2966,21 @@ conflict_status_walker(void *baton,
             if (!cswb->resolve_prop)
               break;
 
-            /* ### this is bogus. resolve_conflict_on_node() does not handle
-               ### individual property resolution.  */
             if (*cswb->resolve_prop != '\0' &&
                 strcmp(cswb->resolve_prop, cd->property_name) != 0)
               {
-                break; /* Skip this property conflict */
+                break; /* This is not the property we want to resolve. */
               }
 
-
-            /* We don't have property name handling here yet :( */
-            SVN_ERR(resolve_conflict_on_node(&did_resolve,
-                                             db,
-                                             local_abspath,
-                                             FALSE /* resolve_text */,
-                                             TRUE /* resolve_props */,
-                                             FALSE /* resolve_tree */,
-                                             my_choice,
-                                             cswb->notify_func,
-                                             cswb->notify_baton,
-                                             cswb->cancel_func,
-                                             cswb->cancel_baton,
-                                             iterpool));
+            SVN_ERR(resolve_prop_conflict_on_node(&did_resolve,
+                                                  db,
+                                                  local_abspath,
+                                                  cd->property_name,
+                                                  my_choice,
+                                                  merged_file,
+                                                  cswb->cancel_func,
+                                                  cswb->cancel_baton,
+                                                  iterpool));
 
             if (did_resolve)
               resolved = TRUE;

Modified: subversion/branches/1.8.x/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x/subversion/svn/conflict-callbacks.c?rev=1482138&r1=1482137&r2=1482138&view=diff
==============================================================================
--- subversion/branches/1.8.x/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/1.8.x/subversion/svn/conflict-callbacks.c Mon May 13 22:42:22 2013
@@ -225,20 +225,25 @@ show_conflicts(const svn_wc_conflict_des
                                      pool);
 }
 
-/* Display the conflicting values of a property as a 3-way diff.
+/* 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.
  *
  * Assume the values are printable UTF-8 text.
  */
 static svn_error_t *
-show_prop_conflict(const svn_wc_conflict_description2_t *desc,
-                   apr_pool_t *pool)
+merge_prop_conflict(svn_stream_t *output,
+                    const svn_wc_conflict_description2_t *desc,
+                    const char *merged_abspath,
+                    apr_pool_t *pool)
 {
   const char *base_abspath = desc->base_abspath;
   const char *my_abspath = desc->my_abspath;
   const char *their_abspath = desc->their_abspath;
   svn_diff_file_options_t *options = svn_diff_file_options_create(pool);
   svn_diff_t *diff;
-  svn_stream_t *output;
 
   /* If any of the property values is missing, use an empty file instead
    * for the purpose of showing a diff. */
@@ -258,13 +263,15 @@ show_prop_conflict(const svn_wc_conflict
     }
 
   options->ignore_eol_style = TRUE;
-  SVN_ERR(svn_stream_for_stdout(&output, pool));
   SVN_ERR(svn_diff_file_diff3_2(&diff,
-                                base_abspath, my_abspath, their_abspath,
+                                base_abspath,
+                                merged_abspath ? merged_abspath : my_abspath,
+                                their_abspath,
                                 options, pool));
   SVN_ERR(svn_diff_file_output_merge2(output, diff,
                                       base_abspath,
-                                      my_abspath,
+                                      merged_abspath ? merged_abspath
+                                                     : my_abspath,
                                       their_abspath,
                                       _("||||||| ORIGINAL"),
                                       _("<<<<<<< MINE"),
@@ -276,8 +283,27 @@ show_prop_conflict(const svn_wc_conflict
   return SVN_NO_ERROR;
 }
 
+/* Display the conflicting values of a property as a 3-way diff.
+ *
+ * If MERGED_ABSPATH is non-NULL, show it as 'my' version instead of
+ * DESC->MY_ABSPATH.
+ *
+ * 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,
+                   apr_pool_t *pool)
+{
+  svn_stream_t *output;
+
+  SVN_ERR(svn_stream_for_stdout(&output, pool));
+  SVN_ERR(merge_prop_conflict(output, desc, merged_abspath, pool));
 
-/* Run an external editor, passing it the 'merged' file in DESC, or, if the
+  return SVN_NO_ERROR;
+}
+
+/* Run an external editor, passing it the MERGED_FILE, 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.
@@ -288,15 +314,15 @@ show_prop_conflict(const svn_wc_conflict
  * return that error. */
 static svn_error_t *
 open_editor(svn_boolean_t *performed_edit,
-            const svn_wc_conflict_description2_t *desc,
+            const char *merged_file,
             svn_cl__interactive_conflict_baton_t *b,
             apr_pool_t *pool)
 {
   svn_error_t *err;
 
-  if (desc->merged_file)
+  if (merged_file)
     {
-      err = svn_cmdline__edit_file_externally(desc->merged_file, b->editor_cmd,
+      err = svn_cmdline__edit_file_externally(merged_file, b->editor_cmd,
                                               b->config, pool);
       if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR))
         {
@@ -329,6 +355,34 @@ open_editor(svn_boolean_t *performed_edi
   return SVN_NO_ERROR;
 }
 
+/* Run an external editor, passing it the 'merged' property in DESC.
+ * 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,
+                   svn_cl__interactive_conflict_baton_t *b,
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
+{
+  apr_file_t *file;
+  const char *file_path;
+  svn_boolean_t performed_edit = FALSE;
+  svn_stream_t *merged_prop;
+
+  SVN_ERR(svn_io_open_unique_file3(&file, &file_path, NULL,
+                                   svn_io_file_del_on_pool_cleanup,
+                                   result_pool, scratch_pool));
+  merged_prop = svn_stream_from_aprfile2(file, TRUE /* disown */,
+                                         scratch_pool);
+  SVN_ERR(merge_prop_conflict(merged_prop, desc, NULL, scratch_pool));
+  SVN_ERR(svn_stream_close(merged_prop));
+  SVN_ERR(svn_io_file_flush_to_disk(file, scratch_pool));
+  SVN_ERR(open_editor(&performed_edit, file_path, b, scratch_pool));
+  *merged_file_path = (performed_edit ? file_path : NULL);
+
+  return SVN_NO_ERROR;
+}
 
 /* Run an external merge tool, passing it the 'base', 'their', 'my' and
  * 'merged' files in DESC. The tool to use is determined by B->config and
@@ -445,6 +499,10 @@ static const resolver_option_t prop_conf
                                      "(same)  [theirs-full]"),
                                   svn_wc_conflict_choose_theirs_full },
   { "dc", N_("display conflict"), N_("show conflicts in this property"), -1 },
+  { "e",  N_("edit property"),    N_("change merged property value in an editor"
+                                     "  [edit]"), -1 },
+  { "r",  N_("resolved"),         N_("accept edited version of property"),
+                                  svn_wc_conflict_choose_merged },
   { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
                                   svn_wc_conflict_choose_postpone },
   { "h",  N_("help"),             N_("show this help (also '?')"), -1 },
@@ -790,7 +848,7 @@ handle_text_conflict(svn_wc_conflict_res
         }
       else if (strcmp(opt->code, "e") == 0 || strcmp(opt->code, ":-E") == 0)
         {
-          SVN_ERR(open_editor(&performed_edit, desc, b, iterpool));
+          SVN_ERR(open_editor(&performed_edit, desc->merged_file, b, iterpool));
           if (performed_edit)
             knows_something = TRUE;
         }
@@ -890,10 +948,13 @@ static svn_error_t *
 handle_prop_conflict(svn_wc_conflict_result_t *result,
                      const svn_wc_conflict_description2_t *desc,
                      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;
+  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
@@ -919,10 +980,23 @@ handle_prop_conflict(svn_wc_conflict_res
   while (TRUE)
     {
       const resolver_option_t *opt;
+      const char *options[ARRAY_LEN(prop_conflict_options)];
+      const char **next_option = options;
+
+      *next_option++ = "p";
+      *next_option++ = "mf";
+      *next_option++ = "tf";
+      *next_option++ = "dc";
+      *next_option++ = "e";
+      if (resolved_allowed)
+        *next_option++ = "r";
+      *next_option++ = "q";
+      *next_option++ = "h";
+      *next_option++ = NULL;
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(prompt_user(&opt, prop_conflict_options, NULL, b->pb,
+      SVN_ERR(prompt_user(&opt, prop_conflict_options, options, b->pb,
                           iterpool));
       if (! opt)
         continue;
@@ -936,7 +1010,27 @@ handle_prop_conflict(svn_wc_conflict_res
         }
       else if (strcmp(opt->code, "dc") == 0)
         {
-          SVN_ERR(show_prop_conflict(desc, scratch_pool));
+          SVN_ERR(show_prop_conflict(desc, merged_file_path, 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);
+        }
+      else if (strcmp(opt->code, "r") == 0)
+        {
+          if (! resolved_allowed)
+            {
+              SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
+                             _("Invalid option; please edit the property "
+                               "first.\n\n")));
+              continue;
+            }
+
+          result->merged_file = merged_file_path;
+          result->choice = svn_wc_conflict_choose_merged;
+          break;
         }
       else if (opt->choice != -1)
         {
@@ -1214,7 +1308,7 @@ conflict_func_interactive(svn_wc_conflic
        && (desc->reason == svn_wc_conflict_reason_edited)))
     SVN_ERR(handle_text_conflict(*result, desc, b, scratch_pool));
   else if (desc->kind == svn_wc_conflict_kind_property)
-    SVN_ERR(handle_prop_conflict(*result, desc, b, scratch_pool));
+    SVN_ERR(handle_prop_conflict(*result, desc, b, result_pool, scratch_pool));
 
   /*
     Dealing with obstruction of additions can be tricky.  The



Mime
View raw message