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


From: code
Subject: [Monotone-commits-diffs] net.venge.monotone.issue-209: d6fdf316792e79267f9594e6761852b4ef6a9a6e
Date: Mon, 23 Jul 2012 11:01:13 +0200 (CEST)

revision:            d6fdf316792e79267f9594e6761852b4ef6a9a6e
date:                2012-07-21T13:23:31
author:              address@hidden
branch:              net.venge.monotone.issue-209
changelog:
resolve_conflicts_dropped_modified_upstream_vs_local_2: Now passing. Still more 
tests to add

* src/merge_conflict.cc (resolve_dropped_modified_one): factor out, improve
  (resolve_dropped_modified_conflicts): use it for left and right resolution

* src/merge_content.cc (resolve_merge_conflicts): resolve_dropped_modified now 
requires a db adaptor

* src/merge_roster.cc (resolve_conflicts::image(side_t)): new
  (dump dropped_modified): improve
  (dump duplicate_name): improve

* 
test/func/resolve_conflicts_dropped_modified_upstream_vs_local_2/__driver__.lua:
 add comment. Now passing.

manifest:
format_version "1"

new_manifest [bfcf68fecad2b6c9e9b5739468b99350bb37a754]

old_revision [48b14e6f132ad73fc3ed421bbf318c4ce6ec5b4e]

patch "src/merge_conflict.cc"
 from [ed311d6cdf1fa47f00a602e0db5b57f84be6a690]
   to [9b89912a0ccd71b9d77d5978ddf1b8bb89368b28]

patch "src/merge_content.cc"
 from [6a1d7ad7184f88674a585f5065e965f15294f7dc]
   to [095c2d20ac8d8d495806f6463c311d253cb6a686]

patch "src/merge_roster.cc"
 from [5d36f441612f9de68ce237b13226bdffd1e2c92a]
   to [a082529e5a0fced55068a65a67bc6f21074d6579]

patch "src/merge_roster.hh"
 from [b013f590a5c9e643afa06d41d3ed362f6c27d0e6]
   to [d214f006b7f4f1e3161313c39f3aac706372ccc5]

patch 
"test/func/resolve_conflicts_dropped_modified_upstream_vs_local_2/__driver__.lua"
 from [897b4a52ad2ebdb38453f98db1b4284da562a03c]
   to [b3dfb58300c6e9e6762b9132c33e910e05901c29]
============================================================
--- src/merge_conflict.cc	ed311d6cdf1fa47f00a602e0db5b57f84be6a690
+++ src/merge_conflict.cc	9b89912a0ccd71b9d77d5978ddf1b8bb89368b28
@@ -2915,36 +2915,147 @@ static void
 }
 
 static void
-error_extra_left(node_id left_nid, node_id right_nid, roster_t const & right_roster)
+resolve_dropped_modified_one(lua_hooks &                                  lua,
+                             string                                       side_image,
+                             bool                                         handling_dropped_side,
+                             resolve_conflicts::file_resolution_t const & resolution,
+                             resolve_conflicts::file_resolution_t const & other_resolution,
+                             roster_t const &                             side_roster,
+                             file_path const &                            name,
+                             file_id const &                              fid,
+                             node_id const                                nid,
+                             content_merge_database_adaptor &             adaptor,
+                             temp_node_id_source &                        nis,
+                             roster_t &                                   result_roster)
 {
-  if (left_nid == the_null_node)
+  if (nid == the_null_node)
     {
-      file_path right_name;
-      file_id   right_fid;
-      right_roster.get_file_details(right_nid, right_fid, right_name);
-      E(false, origin::user,
-        F("extra left_resolution provided for dropped_modifed '%s'") % right_name);
+      E(resolution.resolution == resolve_conflicts::none, origin::user,
+        F("extra %s_resolution provided for dropped_modified '%s'") % side_image % name);
+      return;
     }
-}
+  else
+    {
+      E(resolution.resolution != resolve_conflicts::none, origin::user,
+        F("no %s_resolution provided for dropped_modified '%s'") % side_image % name);
+    }
 
-static void
-error_extra_right(node_id left_nid, node_id right_nid, roster_t const & left_roster)
-{
-  if (right_nid == the_null_node)
+  switch (resolution.resolution)
     {
-      file_path left_name;
-      file_id   left_fid;
-      left_roster.get_file_details(left_nid, left_fid, left_name);
-      E(false, origin::user,
-        F("extra right_resolution provided for dropped_modifed '%s'") % left_name);
+    case resolve_conflicts::none:
+      // handled above; can't get here
+      break;
+
+    case resolve_conflicts::content_user:
+      // FIXME: check other_resolution for consistency
+      if (handling_dropped_side)
+        {
+          // recreated; replace the contents of the recreated node
+          replace_content(side_roster, nid, result_roster, resolution.content, adaptor);
+        }
+      else
+        {
+          // modified; drop and create a new node
+          // See comments in keep below on why we drop first
+          result_roster.drop_detached_node(nid);
+
+          node_id new_nid = create_new_node (side_roster, nid, result_roster, resolution.content, adaptor, nis);
+
+          attach_node(lua, result_roster, new_nid, name);
+        }
+      break;
+
+    case resolve_conflicts::content_internal:
+      // not valid for dropped_modified
+      I(false);
+
+    case resolve_conflicts::drop:
+      // The node is either modified, recreated or duplicate name; in
+      // any case, it is present in the result roster, so drop it
+      P(F("dropping '%s'") % name);
+      result_roster.drop_detached_node(nid);
+      break;
+
+    case resolve_conflicts::keep:
+      if (handling_dropped_side)
+        {
+          // recreated; keep the recreated contents
+          P(F("keeping '%s'") % name);
+          attach_node(lua, result_roster, nid, name);
+        }
+      else
+        {
+          // modified; keep the modified contents
+
+          P(F("keeping '%s'") % name);
+          P(F("history for '%s' will be lost; see user manual Merge Conflicts section") %
+            name);
+
+          // We'd like to just attach_node here, but that violates a
+          // fundamental design principle of mtn; nodes are born once,
+          // and die once. If we attach here, the node is born, died,
+          // and then born again.
+          //
+          // So we have to drop the old node, and create a new node with
+          // the same contents. That loses history; 'mtn log <path>'
+          // will end here, not showing the history of the original
+          // node.
+          result_roster.drop_detached_node(nid);
+          node_id nid = result_roster.create_file_node(fid, nis);
+          attach_node (lua, result_roster, nid, name);
+        }
+      break;
+
+    case resolve_conflicts::rename:
+      if (handling_dropped_side)
+        {
+          // recreated; rename the recreated contents
+          P(F("renaming '%s' to '%s'") % name % resolution.rename.as_external());
+          attach_node(lua, result_roster, nid, resolution.rename);
+        }
+      else
+        {
+          // modified; drop, create new node with the modified contents, rename
+          // See comment in keep above on why we drop first.
+          result_roster.drop_detached_node(nid);
+
+          P(F("renaming '%s' to '%s'") % name % resolution.rename.as_external());
+          P(F("history for '%s' will be lost; see user manual Merge Conflicts section") % name);
+
+          node_id new_nid = result_roster.create_file_node(fid, nis);
+          attach_node (lua, result_roster, new_nid, resolution.rename);
+        }
+      break;
+
+    case resolve_conflicts::content_user_rename:
+      if (handling_dropped_side)
+        {
+          // recreated; rename and replace the recreated contents
+          replace_content(side_roster, nid, result_roster, resolution.content, adaptor);
+
+          P(F("renaming '%s' to '%s'") % name % resolution.rename.as_external());
+
+          attach_node (lua, result_roster, nid, resolution.rename);
+        }
+      else
+        {
+         // modified; drop, rename and replace the modified contents
+          node_id nid = create_new_node
+            (side_roster, nid, result_roster, resolution.content, adaptor, nis);
+
+          P(F("renaming '%s' to '%s'") % name % resolution.rename.as_external());
+
+          attach_node(lua, result_roster, nid, resolution.rename);
+        }
+      break;
     }
-}
+} // resolve_dropped_modified_one
 
 void
 roster_merge_result::resolve_dropped_modified_conflicts(lua_hooks & lua,
                                                         roster_t const & left_roster,
                                                         roster_t const & right_roster,
-                                                        content_merge_adaptor & adaptor,
+                                                        content_merge_database_adaptor & adaptor,
                                                         temp_node_id_source & nis)
 {
   MM(left_roster);
@@ -2963,164 +3074,56 @@ roster_merge_result::resolve_dropped_mod
       file_path right_name;
       file_id   right_fid;
 
-      switch (conflict.left_resolution.resolution)
+      if (null_id(conflict.left_rid))
         {
-        case resolve_conflicts::none:
           if (conflict.left_nid != the_null_node)
-            {
-              // FIXME: use left_name here if it's not too hard
-              right_roster.get_file_details(conflict.right_nid, right_fid, right_name);
-              E(false, origin::user,
-                F("no left_resolution provided for dropped_modifed '%s'") % right_name);
-            }
-          break;
+            left_roster.get_file_details(conflict.left_nid, left_fid, left_name);
+        }
+      else
+        {
+          roster_t tmp;
+          adaptor.db.get_roster(conflict.left_rid, tmp);
+          tmp.get_file_details(conflict.left_nid, left_fid, left_name);
+        }
 
-        case resolve_conflicts::content_user:
-          switch (conflict.dropped_side)
-            {
-            case resolve_conflicts::left_side:
-              error_extra_left(conflict.left_nid, conflict.right_nid, right_roster);
+      if (null_id (conflict.right_rid))
+        {
+          if (conflict.right_nid != the_null_node)
+            right_roster.get_file_details(conflict.right_nid, right_fid, right_name);
+        }
+      else
+        {
+          roster_t tmp;
+          adaptor.db.get_roster(conflict.right_rid, tmp);
+          tmp.get_file_details(conflict.right_nid, right_fid, right_name);
+        }
 
-              // recreated; replace the contents of the recreated node
-              replace_content(left_roster, conflict.left_nid, roster, conflict.left_resolution.content, adaptor);
-              break;
+      resolve_dropped_modified_one (lua,
+                                    string("left"),
+                                    conflict.dropped_side == resolve_conflicts::left_side,
+                                    conflict.left_resolution,
+                                    conflict.right_resolution,
+                                    left_roster,
+                                    left_name,
+                                    left_fid,
+                                    conflict.left_nid,
+                                    adaptor,
+                                    nis,
+                                    roster);
 
-            case resolve_conflicts::right_side:
-              error_extra_right(conflict.left_nid, conflict.right_nid, left_roster);
+      resolve_dropped_modified_one (lua,
+                                    string("right"),
+                                    conflict.dropped_side == resolve_conflicts::right_side,
+                                    conflict.right_resolution,
+                                    conflict.left_resolution,
+                                    right_roster,
+                                    right_name,
+                                    right_fid,
+                                    conflict.right_nid,
+                                    adaptor,
+                                    nis,
+                                    roster);
 
-              // modified; drop and create a new node
-              // See comments in keep below on why we drop first
-              roster.drop_detached_node(conflict.left_nid);
-
-              node_id new_nid = create_new_node
-                (left_roster, conflict.left_nid, roster, conflict.left_resolution.content, adaptor, nis);
-
-              attach_node(lua, roster, new_nid, left_name);
-
-              break;
-            }
-          break;
-
-        case resolve_conflicts::content_internal:
-          I(false);
-
-        case resolve_conflicts::drop:
-          switch (conflict.dropped_side)
-            {
-            case resolve_conflicts::left_side:
-              error_extra_left(conflict.left_nid, conflict.right_nid, right_roster);
-
-              left_roster.get_file_details(conflict.left_nid, left_fid, left_name);
-              P(F("dropping '%s'") % left_name);
-
-              roster.drop_detached_node(conflict.left_nid);
-              break;
-
-            case resolve_conflicts::right_side:
-              error_extra_right(conflict.left_nid, conflict.right_nid, left_roster);
-
-              right_roster.get_file_details(conflict.right_nid, right_fid, right_name);
-              P(F("dropping '%s'") % right_name);
-
-              roster.drop_detached_node(conflict.right_nid);
-              break;
-            }
-
-        case resolve_conflicts::keep:
-          switch (conflict.dropped_side)
-            {
-            case resolve_conflicts::left_side:
-              error_extra_left(conflict.left_nid, conflict.right_nid, right_roster);
-
-              // recreated; keep the recreated contents
-              left_roster.get_file_details(conflict.left_nid, left_fid, left_name);
-              P(F("keeping '%s'") % left_name);
-              attach_node(lua, roster, conflict.left_nid, left_name);
-              break;
-
-            case resolve_conflicts::right_side:
-              // modified; keep the modified contents
-
-              left_roster.get_file_details(conflict.left_nid, left_fid, left_name);
-              P(F("keeping '%s'") % left_name);
-              P(F("history for '%s' will be lost; see user manual Merge Conflicts section") %
-                left_name);
-
-              // We'd like to just attach_node here, but that violates a
-              // fundamental design principle of mtn; nodes are born once,
-              // and die once. If we attach here, the node is born, died,
-              // and then born again.
-              //
-              // So we have to drop the old node, and create a new node with
-              // the same contents. That loses history; 'mtn log <path>'
-              // will end here, not showing the history of the original
-              // node.
-              roster.drop_detached_node(conflict.left_nid);
-              node_id nid = roster.create_file_node(left_fid, nis);
-              attach_node (lua, roster, nid, left_name);
-              break;
-            }
-
-        case resolve_conflicts::rename:
-          switch (conflict.dropped_side)
-            {
-            case resolve_conflicts::left_side:
-              error_extra_left(conflict.left_nid, conflict.right_nid, right_roster);
-
-              // recreated; rename the recreated contents
-              left_roster.get_file_details(conflict.left_nid, left_fid, left_name);
-              P(F("renaming '%s' to '%s'") % left_name % conflict.left_resolution.rename.as_external());
-              attach_node(lua, roster, conflict.left_nid, conflict.left_resolution.rename);
-              break;
-
-            case resolve_conflicts::right_side:
-              error_extra_right(conflict.left_nid, conflict.right_nid, left_roster);
-
-              // modified; drop, create new node with the modified contents, rename
-              // See comment in keep above on why we drop first.
-              roster.drop_detached_node(conflict.left_nid);
-
-              left_roster.get_file_details(conflict.left_nid, left_fid, left_name);
-              P(F("renaming '%s' to '%s'") % left_name % conflict.left_resolution.rename.as_external());
-              P(F("history for '%s' will be lost; see user manual Merge Conflicts section") %
-                left_name);
-
-              node_id new_nid = roster.create_file_node(left_fid, nis);
-              attach_node (lua, roster, new_nid, conflict.left_resolution.rename);
-              break;
-            }
-
-        case resolve_conflicts::content_user_rename:
-          switch (conflict.dropped_side)
-            {
-            case resolve_conflicts::left_side:
-              error_extra_left(conflict.left_nid, conflict.right_nid, right_roster);
-
-              // recreated; rename and replace the recreated contents
-              replace_content(left_roster, conflict.left_nid, roster, conflict.left_resolution.content, adaptor);
-
-              left_roster.get_file_details(conflict.left_nid, left_fid, left_name);
-              P(F("renaming '%s' to '%s'") % left_name % conflict.left_resolution.rename.as_external());
-
-              attach_node (lua, roster, conflict.left_nid, conflict.left_resolution.rename);
-              break;
-
-            case resolve_conflicts::right_side:
-              // modified; drop, rename and replace the modified contents
-              node_id nid = create_new_node
-                (left_roster, conflict.left_nid, roster, conflict.left_resolution.content, adaptor, nis);
-
-              left_roster.get_file_details(conflict.left_nid, left_fid, left_name);
-              P(F("renaming '%s' to '%s'") % left_name % conflict.left_resolution.rename.as_external());
-
-              attach_node(lua, roster, conflict.left_nid, conflict.left_resolution.rename);
-              break;
-            }
-        }
-
-      // FIXME: handle right_resolution; factor out resolve_dropped_modified_one_side
-      // add inconsistent left/right resolution checks
-
     } // end for
 
   dropped_modified_conflicts.clear();
============================================================
--- src/merge_content.cc	6a1d7ad7184f88674a585f5065e965f15294f7dc
+++ src/merge_content.cc	095c2d20ac8d8d495806f6463c311d253cb6a686
@@ -747,7 +747,8 @@ resolve_merge_conflicts(lua_hooks & lua,
           // 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_dropped_modified_conflicts(lua, left_roster, right_roster,
+                                                    dynamic_cast <content_merge_database_adaptor&>(adaptor), nis);
           result.resolve_duplicate_name_conflicts(lua, left_roster, right_roster, adaptor);
 
           result.resolve_file_content_conflicts (lua, left_roster, right_roster, adaptor);
============================================================
--- src/merge_roster.cc	5d36f441612f9de68ce237b13226bdffd1e2c92a
+++ src/merge_roster.cc	a082529e5a0fced55068a65a67bc6f21074d6579
@@ -29,6 +29,19 @@ namespace resolve_conflicts
 namespace resolve_conflicts
 {
   char const *
+  image(side_t item)
+  {
+    switch (item)
+      {
+      case resolve_conflicts::left_side:
+        return "left_side";
+      case resolve_conflicts::right_side:
+        return "right_side";
+      }
+    I(false); // keep compiler happy
+  }
+
+  char const *
   image(resolution_t resolution)
   {
     switch (resolution)
@@ -55,7 +68,7 @@ namespace resolve_conflicts
   image(file_resolution_t res)
   {
     if (res.resolution == resolve_conflicts::none)
-      return string("");
+      return string("\n");
     else
       {
         ostringstream oss;
@@ -116,12 +129,15 @@ dump(dropped_modified_conflict const & c
 dump(dropped_modified_conflict const & conflict, string & out)
 {
   ostringstream oss;
-  oss << "dropped_modified_conflict on node: " <<
-    conflict.left_nid == the_null_node ? conflict.right_nid : conflict.left_nid;
-  oss << " orphaned: " << conflict.orphaned;
-  oss << " left_resolution: " << image(conflict.left_resolution);
-  oss << " right_resolution: " << image(conflict.left_resolution);
-  oss << "\n";
+  oss << "dropped_modified_conflict -\n";
+  oss << " dropped_side    : " << image(conflict.dropped_side) << "\n";
+  oss << " left_nid        : " << conflict.left_nid << "\n";
+  oss << " right_nid       : " << conflict.right_nid << "\n";
+  oss << " orphaned        : " << conflict.orphaned << "\n";
+  oss << " left_rid        : " << conflict.left_rid << "\n";
+  oss << " right_rid       : " << conflict.right_rid << "\n";
+  oss << " left_resolution : " << image(conflict.left_resolution);
+  oss << " right_resolution: " << image(conflict.right_resolution);
   out = oss.str();
 }
 
@@ -133,8 +149,8 @@ dump(duplicate_name_conflict const & con
       << "and right node: " << conflict.right_nid << " "
       << "parent: " << conflict.parent_name.first << " "
       << "basename: " << conflict.parent_name.second << " "
-      << "left_resolution: " << " "
-      << "right_resolution: "
+      << "left_resolution: " << image(conflict.left_resolution)
+      << "right_resolution: " << image(conflict.right_resolution)
       << "\n";
   out = oss.str();
 }
============================================================
--- src/merge_roster.hh	b013f590a5c9e643afa06d41d3ed362f6c27d0e6
+++ src/merge_roster.hh	d214f006b7f4f1e3161313c39f3aac706372ccc5
@@ -35,6 +35,8 @@ namespace resolve_conflicts
 
   enum side_t {left_side, right_side};
 
+  char const * image(side_t item);
+
   struct file_resolution_t
   {
     resolution_t resolution;
@@ -137,7 +139,8 @@ struct dropped_modified_conflict
 
   bool orphaned; // if true, the dropped side is due to a dropped parent directory
 
-  // read_dropped_modified sets rid for dropped, non-recreated file FIXME: can we use this?
+  // read_dropped_modified sets rid when corresponding nid is non-null and
+  // not in the corresponding parent roster
   revision_id                          left_rid, right_rid;
   resolve_conflicts::file_resolution_t left_resolution, right_resolution;
 
@@ -313,7 +316,7 @@ struct roster_merge_result
   void resolve_dropped_modified_conflicts(lua_hooks & lua,
                                           roster_t const & left_roster,
                                           roster_t const & right_roster,
-                                          content_merge_adaptor & adaptor,
+                                          content_merge_database_adaptor & adaptor,
                                           temp_node_id_source & nis);
 
   void report_duplicate_name_conflicts(roster_t const & left,
============================================================
--- test/func/resolve_conflicts_dropped_modified_upstream_vs_local_2/__driver__.lua	897b4a52ad2ebdb38453f98db1b4284da562a03c
+++ test/func/resolve_conflicts_dropped_modified_upstream_vs_local_2/__driver__.lua	b3dfb58300c6e9e6762b9132c33e910e05901c29
@@ -87,6 +87,12 @@ check(samelines("stderr",
   "mtn: dropped and recreated on the right",
   "mtn: 1 conflict with supported resolutions."}))
 
+--  There are two nodes with filename 'file_2'; node 4 in upstream,
+--  node 3 in local. At this point, node 4 is modified in upstream and
+--  dropped in local; node 3 is unborn in upstream and modified in
+--  local. Therefore this is a combination of dropped_modified and
+--  duplicate_name conflicts, which we handle as a dropped_modified
+--  conflict.
 check(mtn("conflicts", "store", upstream_3, local_2), 0, nil, true)
 check(samefilestd("conflicts_3_2", "_MTN/conflicts"))
 

reply via email to

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