monotone-commits-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Monotone-commits-diffs] net.venge.monotone.issue-209.file_attribute: 66


From: code
Subject: [Monotone-commits-diffs] net.venge.monotone.issue-209.file_attribute: 6644cff8fa909e1b9d69554b60d473571f1ad135
Date: Tue, 19 Jun 2012 13:44:28 +0200 (CEST)

revision:            6644cff8fa909e1b9d69554b60d473571f1ad135
date:                2012-06-19T11:21:15
author:              address@hidden
branch:              net.venge.monotone.issue-209.file_attribute
changelog:
add attr mtn:resolve_conflict, use in 
resolve_conflicts_dropped_modified_upstream_vs_local. Works, but breaks other 
tests in a minor way.

* src/merge_content.cc (resolve_merge_conflicts): don't require 
--resolve_conflicts, so attr mtn:resolve_conflict is more transparent

* src/merge_roster.cc (insert_if_unborn): add dropped_modified resolution from 
mtn:resolve_conflict

* src/merge_roster.hh (dropped_modified_conflict): add null constructor

* 
test/func/resolve_conflicts_dropped_modified_upstream_vs_local/__driver__.lua: 
use mtn:resolve_conflict

* test/func/resolve_conflicts_dropped_modified_upstream_vs_local/conflicts: New 
file.

manifest:
format_version "1"

new_manifest [58e2f5e7a7e10fd96c8dc06af271d72af73147ac]

old_revision [2c0f9103d5356726f5ff0abf8d3546cc5d22b144]

add_file 
"test/func/resolve_conflicts_dropped_modified_upstream_vs_local/conflicts"
 content [0ab94901aaab08fbed7c8a74c8dd4e44dcd85f46]

patch "src/merge_content.cc"
 from [57645741618933e4443f1051f348fc140d861550]
   to [acce6123a6becddeb69fd81221d85be2b372252d]

patch "src/merge_roster.cc"
 from [e94fdfa49616a796084a2f066beb39b4c225d0b8]
   to [5fbc50c114df22f4753f444aa137c06ea0f06195]

patch "src/merge_roster.hh"
 from [919a6e38017219453de30c8e6a8a03dfc8b32821]
   to [34d382b0ad333fa0f052e8640a88c1ece03caaa9]

patch 
"test/func/resolve_conflicts_dropped_modified_upstream_vs_local/__driver__.lua"
 from [138b0260d623eca6964febdda7d8c2bd7dccf544]
   to [7c8b929f332343bb26a5fb489727ec53e5bd60bc]
============================================================
--- src/merge_content.cc	57645741618933e4443f1051f348fc140d861550
+++ src/merge_content.cc	acce6123a6becddeb69fd81221d85be2b372252d
@@ -722,29 +722,29 @@ resolve_merge_conflicts(lua_hooks & lua,
     {
       result.log_conflicts();
 
-      if (resolutions_given)
-        {
-          // If there are any conflicts for which we don't currently support
-          // resolutions, give a nice error message.
-          char const * const msg = "conflict resolution for %s not yet supported";
+      // Apply any conflict resolutions. If the user did not specify
+      // --resolve_conflicts, there may still be some specified by attr
+      // mtn:resolve_conflict.
 
-          E(!result.missing_root_conflict, origin::user,
-            F(msg) % "missing_root_dir");
-          E(result.invalid_name_conflicts.size() == 0, origin::user,
-            F(msg) % "invalid_name_conflicts");
-          E(result.directory_loop_conflicts.size() == 0, origin::user,
-            F(msg) % "directory_loop_conflicts");
-          E(result.multiple_name_conflicts.size() == 0, origin::user,
-            F(msg) % "multiple_name_conflicts");
-          E(result.attribute_conflicts.size() == 0, origin::user,
-            F(msg) % "attribute_conflicts");
+      char const * const msg = "conflict resolution for %s not yet supported";
 
-          // resolve the ones we can, if they have resolutions specified
-          result.resolve_orphaned_node_conflicts(lua, left_roster, right_roster, adaptor);
-          result.resolve_dropped_modified_conflicts(lua, left_roster, right_roster, adaptor, nis);
-          result.resolve_duplicate_name_conflicts(lua, left_roster, right_roster, adaptor);
-          result.resolve_file_content_conflicts(lua, left_roster, right_roster, adaptor);
-        }
+      E(!result.missing_root_conflict, origin::user,
+        F(msg) % "missing_root_dir");
+      E(result.invalid_name_conflicts.size() == 0, origin::user,
+        F(msg) % "invalid_name_conflicts");
+      E(result.directory_loop_conflicts.size() == 0, origin::user,
+        F(msg) % "directory_loop_conflicts");
+      E(result.multiple_name_conflicts.size() == 0, origin::user,
+        F(msg) % "multiple_name_conflicts");
+      E(result.attribute_conflicts.size() == 0, origin::user,
+        F(msg) % "attribute_conflicts");
+
+      // Resolve the ones we can, if they have resolutions specified. Each
+      // conflict list is deleted once all are resolved.
+      result.resolve_orphaned_node_conflicts(lua, left_roster, right_roster, adaptor);
+      result.resolve_dropped_modified_conflicts(lua, left_roster, right_roster, adaptor, nis);
+      result.resolve_duplicate_name_conflicts(lua, left_roster, right_roster, adaptor);
+      result.resolve_file_content_conflicts(lua, left_roster, right_roster, adaptor);
     }
 
   if (result.has_non_content_conflicts())
============================================================
--- src/merge_roster.cc	e94fdfa49616a796084a2f066beb39b4c225d0b8
+++ src/merge_roster.cc	5fbc50c114df22f4753f444aa137c06ea0f06195
@@ -14,6 +14,7 @@
 #include "sanity.hh"
 #include "safe_map.hh"
 #include "parallel_iter.hh"
+#include "vocab_cast.hh"
 
 #include <sstream>
 
@@ -364,18 +365,37 @@ namespace
           {
             if (uncommon_ancestors.find(*it) != uncommon_ancestors.end())
               {
+                dropped_modified_conflict conflict;
+                attr_key a_key = typecast_vocab<attr_key>(utf8("mtn:resolve_conflict"));
+                attr_map_t::const_iterator i = n->attrs.find(a_key);
+
                 create_node_for(n, result.roster);
+
                 switch (present_in)
                   {
                   case left_side:
-                    result.dropped_modified_conflicts.push_back
-                      (dropped_modified_conflict(n->self, the_null_node));
+                      conflict = dropped_modified_conflict(n->self, the_null_node);
                     break;
                   case right_side:
-                    result.dropped_modified_conflicts.push_back
-                      (dropped_modified_conflict(the_null_node, n->self));
+                    conflict = dropped_modified_conflict(the_null_node, n->self);
                     break;
                   }
+
+                if (i != n->attrs.end() && i->second.first)
+                  {
+                    if (i->second.second == typecast_vocab<attr_value>(utf8("drop")))
+                      {
+                        conflict.resolution.first = resolve_conflicts::drop;
+                      }
+                    else
+                      {
+                        E(false, origin::user,
+                          F("unsupported '%s' conflict resolution in mtn:resolve_conflict attribute") %
+                          i->second.first);
+                      }
+                  }
+
+                result.dropped_modified_conflicts.push_back(conflict);
                 return;
               }
           }
============================================================
--- src/merge_roster.hh	919a6e38017219453de30c8e6a8a03dfc8b32821
+++ src/merge_roster.hh	34d382b0ad333fa0f052e8640a88c1ece03caaa9
@@ -114,6 +114,14 @@ struct dropped_modified_conflict
     // rename is implicitly null
   {resolution.first = resolve_conflicts::none;}
 
+  dropped_modified_conflict() :
+    left_nid(the_null_node),
+    right_nid(the_null_node),
+    orphaned(false),
+    recreated(the_null_node)
+    // rename is implicitly null
+  {resolution.first = resolve_conflicts::none;}
+
   bool operator==(node_id n) {return left_nid == n || right_nid == n;}
 };
 
============================================================
--- test/func/resolve_conflicts_dropped_modified_upstream_vs_local/__driver__.lua	138b0260d623eca6964febdda7d8c2bd7dccf544
+++ test/func/resolve_conflicts_dropped_modified_upstream_vs_local/__driver__.lua	7c8b929f332343bb26a5fb489727ec53e5bd60bc
@@ -1,4 +1,6 @@
--- Show a problematic use case involving a dropped_modified conflict.
+-- Show a problematic use case involving a dropped_modified conflict,
+-- and how it can be resolved with the 'mtn:resolve_conflict'
+-- attribute.
 --
 -- There is an upstream branch, and a local branch. The local branch
 -- deletes a file that the upstream branch continues to modify. We
@@ -6,8 +8,8 @@
 -- never merge in the other direction.
 --
 -- The dropped file causes new dropped_modified conflicts at each
--- propagate. We decided to always drop; we'd like to be able to tell
--- mtn that somehow.
+-- propagate. We decided to always drop, so we apply the
+-- 'mtn:resolve_conflict' attribute.
 
 mtn_setup()
 
@@ -55,18 +57,32 @@ local_2 = base_revision()
 
 local_2 = base_revision()
 
--- round 2; upstream modifies the file again
+-- round 2; upstream modifies the file again, and records the drop
+-- conflict resolution for future merges to downstream.
 revert_to(upstream_1)
 
 writefile("file_2", "file_2 upstream 2")
 
+check(mtn("attr", "set", "file_2", "mtn:resolve_conflict", "drop"), 0, nil, nil)
+
 commit("testbranch", "upstream 2")
 upstream_2 = base_revision()
 
+-- Since the attribute specifies the conflict resolution, we don't need to specify one ourselves
+
+-- We do not require --resolve-conflicts here; the attribute use makes
+-- the conflict transparent.
+check(mtn("merge"), 0, nil, true)
+check(qgrep("mtn: dropping 'file_2'", "stderr"))
+
+check(mtn("update"), 0, nil, true)
+check(not exists("file_2"))
+
+-- FIXME: show attribute here, report no unresolved conflicts, allow merge
 check(mtn("show_conflicts", upstream_2, local_2), 0, nil, true)
 check(samelines
 ("stderr",
- {"mtn: [left]     9bf6dcccb01b4566f2470acd0c6afa48f6eaef65",
+ {"mtn: [left]     c0ed8c29ffad149af1c948969e8e80d270999b13",
   "mtn: [right]    dd1ba606b52fddb4431da3760ff65b65f6509a48",
   "mtn: [ancestor] 1e700864de7a2cbb1cf85c26f5e1e4ca335d2bc2",
   "mtn: conflict: file 'file_2' from revision 1e700864de7a2cbb1cf85c26f5e1e4ca335d2bc2",
@@ -74,14 +90,9 @@ check(samelines
   "mtn: dropped on the right",
   "mtn: 1 conflict with supported resolutions."}))
 
+-- 'conflicts store' is not needed unless there are other conflicts,
+-- or the user wants to override the attribute.
 check(mtn("conflicts", "store", upstream_2, local_2), 0, nil, true)
+check(samefilestd("conflicts", "_MTN/conflicts"))
 
-check(mtn("conflicts", "resolve_first", "drop"), 0, nil, true)
-
-check(mtn("explicit_merge", "--resolve-conflicts", upstream_2, local_2, "testbranch"), 0, nil, true)
-check(qgrep("mtn: dropping 'file_2'", "stderr"))
-
-check(mtn("update"), 0, nil, true)
-check(not exists("file_2"))
-
 -- end of file
============================================================
--- /dev/null	
+++ test/func/resolve_conflicts_dropped_modified_upstream_vs_local/conflicts	0ab94901aaab08fbed7c8a74c8dd4e44dcd85f46
@@ -0,0 +1,15 @@
+    left [c0ed8c29ffad149af1c948969e8e80d270999b13]
+   right [dd1ba606b52fddb4431da3760ff65b65f6509a48]
+ancestor [1e700864de7a2cbb1cf85c26f5e1e4ca335d2bc2]
+
+          conflict dropped_modified
+     ancestor_name "file_2"
+  ancestor_file_id [7fc990de4797bd6534a5c1deb344e11964f6b353]
+         left_type "modified file"
+         left_name "file_2"
+      left_file_id [b7e3240a78dc6afce4507f5a18ab516963e72022]
+        right_type "dropped file"
+         right_rev [1e700864de7a2cbb1cf85c26f5e1e4ca335d2bc2]
+        right_name "file_2"
+     right_file_id [7fc990de4797bd6534a5c1deb344e11964f6b353]
+resolved_drop_left 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]