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: 22


From: code
Subject: [Monotone-commits-diffs] net.venge.monotone.issue-209.file_attribute: 22d58504a5b2f1ae30a72a8365b394b4f44c34cd
Date: Thu, 21 Jun 2012 14:29:30 +0200 (CEST)

revision:            22d58504a5b2f1ae30a72a8365b394b4f44c34cd
date:                2012-06-21T10:43:20
author:              address@hidden
branch:              net.venge.monotone.issue-209.file_attribute
changelog:
propagate from branch 'net.venge.monotone.issue-209' (head 
787ac8818c6d4fdadcc0f1257a849d46204a0250)
            to branch 'net.venge.monotone.issue-209.file_attribute' (head 
5f1a37961aa88c114e0ad40d8dd09a2d1b2e9f81)



manifest:
format_version "1"

new_manifest [81301c1d9b75318447b0fa49751378cdfff5734d]

old_revision [5f1a37961aa88c114e0ad40d8dd09a2d1b2e9f81]

patch "src/merge_conflict.cc"
 from [6fae4b5e0ab1c78bd6be557840d30f8c74d77be5]
   to [bfe541054099570c84dec211c6ed9980ec2bf43f]

patch "test/func/resolve_conflicts_dropped_modified/__driver__.lua"
 from [650ff8bc711de52a04b983c0bdd734ca14311506]
   to [e4f973e6cb8e3494c4b498f68f7cd4b2a6d20fa6]

patch "test/func/resolve_conflicts_dropped_modified_2/__driver__.lua"
 from [a477e8cd203c4b69b5662e36cfd32a24b57cb16f]
   to [6ac477e0740d4af2cae4bc7cb33099e98cd1fb45]

old_revision [787ac8818c6d4fdadcc0f1257a849d46204a0250]

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

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

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_conflict.cc	6fae4b5e0ab1c78bd6be557840d30f8c74d77be5
+++ src/merge_conflict.cc	bfe541054099570c84dec211c6ed9980ec2bf43f
@@ -2840,6 +2840,8 @@ roster_merge_result::resolve_dropped_mod
         case resolve_conflicts::content_user:
           P(F("replacing content of '%s' with '%s'") %
             modified_name % conflict.resolution.second->as_external());
+          P(F("history for '%s' will be lost; see user manual Merge Conflicts section") %
+            modified_name);
 
           if (conflict.recreated == the_null_node)
             {
@@ -2872,6 +2874,8 @@ roster_merge_result::resolve_dropped_mod
           I(conflict.rename.as_external().length() != 0);
           P(F("replacing content of '%s' (renamed to '%s') with '%s'") %
             modified_name % conflict.rename.as_external() % conflict.resolution.second->as_external());
+          P(F("history for '%s' will be lost; see user manual Merge Conflicts section") %
+            modified_name);
 
           resolve_dropped_modified_user(roster, nid, modified_fid, conflict, adaptor, nis);
           attach_node(lua, roster, nid, file_path_internal (conflict.rename.as_internal()));
@@ -2885,6 +2889,8 @@ roster_merge_result::resolve_dropped_mod
 
         case resolve_conflicts::rename:
           P(F("renaming '%s' to '%s'") % modified_name % conflict.resolution.second->as_external());
+          P(F("history for '%s' will be lost; see user manual Merge Conflicts section") %
+            modified_name);
 
           // See comment in keep below on why we drop first.
           roster.drop_detached_node(nid);
@@ -2896,6 +2902,8 @@ roster_merge_result::resolve_dropped_mod
           if (conflict.recreated == the_null_node)
             {
               P(F("keeping '%s'") % modified_name);
+              P(F("history for '%s' will be lost; see user manual Merge Conflicts section") %
+                modified_name);
 
               // We'd like to just attach_node here, but that violates a
               // fundamental design principle of mtn; nodes are born once,
@@ -2913,6 +2921,8 @@ roster_merge_result::resolve_dropped_mod
           else
             {
               P(F("keeping '%s' from %s") % modified_name % ((conflict.left_nid == the_null_node) ? "right" : "left"));
+              P(F("history for '%s' will be lost; see user manual Merge Conflicts section") %
+                modified_name);
 
               roster.drop_detached_node(nid);
 
============================================================
--- test/func/resolve_conflicts_dropped_modified/__driver__.lua	650ff8bc711de52a04b983c0bdd734ca14311506
+++ test/func/resolve_conflicts_dropped_modified/__driver__.lua	e4f973e6cb8e3494c4b498f68f7cd4b2a6d20fa6
@@ -271,8 +271,10 @@ check(samelines("stderr",
 {"mtn: [left]  4228fbd8003cdd89e7eea51fcef10c3f91d78f69",
  "mtn: [right] 6cb6438a490a1ad4c69ff6cac23c75a903cd9cfd",
  "mtn: replacing content of 'dir2/file_10' (renamed to 'file_10') with '_MTN/resolutions/file_10'",
+ "mtn: history for 'dir2/file_10' will be lost; see user manual Merge Conflicts section",
  "mtn: dropping 'dir2/file_11'",
  "mtn: renaming 'dir2/file_9' to 'file_9'",
+ "mtn: history for 'dir2/file_9' will be lost; see user manual Merge Conflicts section",
  "mtn: [merged] 5cafe5405ed31c81f9061be62e38f25aeaaea9c5"}))
  
 -- A special case; drop then re-add vs modify. This used to be the test
@@ -353,7 +355,9 @@ check(samelines("stderr",
 {"mtn: [left]  9485fe891d5e23d6dc30140228cd02840ee719e9",
  "mtn: [right] 9a8192d3bf263cbd5782791e823b837d42af6902",
  "mtn: keeping 'file_10' from left",
+ "mtn: history for 'file_10' will be lost; see user manual Merge Conflicts section",
  "mtn: replacing content of 'file_11' with '_MTN/resolutions/file_11'",
+ "mtn: history for 'file_11' will be lost; see user manual Merge Conflicts section",
  "mtn: [merged] 306eb31064512a8a2f4d316ff7a7ec32a1f64f4c"}))
 
 check(mtn("update"), 0, nil, true)
============================================================
--- test/func/resolve_conflicts_dropped_modified_2/__driver__.lua	a477e8cd203c4b69b5662e36cfd32a24b57cb16f
+++ test/func/resolve_conflicts_dropped_modified_2/__driver__.lua	6ac477e0740d4af2cae4bc7cb33099e98cd1fb45
@@ -50,6 +50,7 @@ check(samelines
  {"mtn: [left]  506d8ed51b06c0080e8bb307155a88637045b532",
   "mtn: [right] a2889488ed1801a904d0219ec9939dfc2e9be033",
   "mtn: keeping 'file_2'",
+  "mtn: history for 'file_2' will be lost; see user manual Merge Conflicts section",
   "mtn: [merged] 3df3126220588440def7b08f488ca35eaa94f1b6"}))
 
 check(mtn("update"), 0, nil, true)
============================================================
--- src/merge_content.cc	57645741618933e4443f1051f348fc140d861550
+++ src/merge_content.cc	3cc3b3f391b7ac369cd6f9ef7afb364178b4fe35
@@ -739,12 +739,21 @@ resolve_merge_conflicts(lua_hooks & lua,
           E(result.attribute_conflicts.size() == 0, origin::user,
             F(msg) % "attribute_conflicts");
 
-          // resolve the ones we can, if they have resolutions specified
+          // 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);
+
+          result.resolve_file_content_conflicts (lua, left_roster, right_roster, adaptor);
         }
+      else
+        {
+          // The user did not specify --resolve_conflicts, but there may
+          // still be some specified by attr mtn:resolve_conflict. Only
+          // these conflicts support that so far.
+          result.resolve_dropped_modified_conflicts(lua, left_roster, right_roster, adaptor, nis);
+        }
     }
 
   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]