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 2019/03/13 13:15:59 UTC

svn commit: r1855419 - /subversion/trunk/subversion/libsvn_client/conflicts.c

Author: stsp
Date: Wed Mar 13 13:15:59 2019
New Revision: 1855419

URL: http://svn.apache.org/viewvc?rev=1855419&view=rev
Log:
Fix conflict resolver bug where local and incoming edits got swapped.

When auto-resolving an incoming file move vs local file edit tree
conflict after an update or switch operation, text conflicts were
created with the incoming changes (theirs) and local changes (mine)
swapped within text conflict markers. When such a text conflict was
then resolved with the --accept mf/mc/tf/tc options the result was
the opposite of what it should have been.

Reported by: Jonathan Guy

* subversion/libsvn_client/conflicts.c
  (resolve_incoming_move_file_text_merge): After update/switch, run the
   text merge in a way that makes local and incoming changes properly
   land on their respective sides of a text conflict.

Modified:
    subversion/trunk/subversion/libsvn_client/conflicts.c

Modified: subversion/trunk/subversion/libsvn_client/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/conflicts.c?rev=1855419&r1=1855418&r2=1855419&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_client/conflicts.c Wed Mar 13 13:15:59 2019
@@ -8632,10 +8632,10 @@ resolve_incoming_move_file_text_merge(sv
   if (operation == svn_wc_operation_update ||
       operation == svn_wc_operation_switch)
     {
-      svn_stream_t *working_stream;
+      svn_stream_t *moved_to_stream;
       svn_stream_t *incoming_stream;
 
-      /* Create a temporary copy of the working file in repository-normal form.
+      /* Create a temporary copy of the moved file in repository-normal form.
        * Set up this temporary file to be automatically removed. */
       err = svn_stream_open_unique(&incoming_stream,
                                    &incoming_abspath, wc_tmpdir,
@@ -8644,19 +8644,31 @@ resolve_incoming_move_file_text_merge(sv
       if (err)
         goto unlock_wc;
 
-      err = svn_wc__translated_stream(&working_stream, ctx->wc_ctx,
-                                      merge_source_abspath,
-                                      merge_source_abspath,
+      err = svn_wc__translated_stream(&moved_to_stream, ctx->wc_ctx,
+                                      moved_to_abspath,
+                                      moved_to_abspath,
                                       SVN_WC_TRANSLATE_TO_NF,
                                       scratch_pool, scratch_pool);
       if (err)
         goto unlock_wc;
 
-      err = svn_stream_copy3(working_stream, incoming_stream,
+      err = svn_stream_copy3(moved_to_stream, incoming_stream,
                              NULL, NULL, /* no cancellation */
                              scratch_pool);
       if (err)
         goto unlock_wc;
+
+      /* Overwrite the moved file with the conflict victim's content.
+       * Incoming changes will be merged in from the temporary file created
+       * above. This is required to correctly make local changes show up as
+       * 'mine' during the three-way text merge between the ancestor file,
+       * the conflict victim ('mine'), and the moved file ('theirs') which
+       * was brought in by the update/switch operation and occupies the path
+       * of the merge target. */
+      err = svn_io_copy_file(merge_source_abspath, moved_to_abspath, FALSE,
+                             scratch_pool);
+      if (err)
+        goto unlock_wc;
     }
   else if (operation == svn_wc_operation_merge)
     {