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


From: code
Subject: [Monotone-commits-diffs] net.venge.monotone.issue-209: e46f9aa2c96785da56a6ae6a13197ee7f3ad7b8c
Date: Sat, 9 Jun 2012 17:32:35 +0200 (CEST)

revision:            e46f9aa2c96785da56a6ae6a13197ee7f3ad7b8c
date:                2012-06-08T16:09:05
author:              address@hidden
branch:              net.venge.monotone.issue-209
changelog:
handle dropped then re-added file in dropped/modified conflict

* doc/monotone.texi: discuss dropped then re-added file in dropped/modified 
conflict

* src/merge_roster.cc:
* src/merge_conflict.cc:
* src/cmd_conflicts.cc: handle dropped then re-added file in dropped/modified 
conflict

* src/merge_roster.hh (dropped_modified_conflict): add recreated, change rename 
to non-pointer.

* src/roster.cc (check_sane): add MM

* test/func/resolve_conflicts_dropped_modified/show_conflicts-orphaned:
* test/func/resolve_conflicts_dropped_modified/conflicts-orphaned-resolved:
* test/func/resolve_conflicts_dropped_modified/conflicts-orphaned:
* test/func/resolve_conflicts_dropped_modified/__driver__.lua: fix revisions in 
orphaned files test. add test of dropped then re-added file (passes).

* test/func/resolve_conflicts_dropped_modified/conflicts-recreated: New file.

* test/func/resolve_conflicts_dropped_modified/conflicts-recreated-resolved: 
New file.


manifest:
format_version "1"

new_manifest [b7ec1d733e4a57d07338279919d7dfd171f1fcd3]

old_revision [f33065689b915304ecbc095df537751e12ebd3dd]

add_file "test/func/resolve_conflicts_dropped_modified/conflicts-recreated"
 content [84f2b46cd09c045eae6a8ad386f1337623db33a9]

add_file 
"test/func/resolve_conflicts_dropped_modified/conflicts-recreated-resolved"
 content [eda35ed4d0fd88adf5e07b52005d56aacd05bd8a]

patch "doc/monotone.texi"
 from [f22f349d0207a09ae6806f8a57c86991a4143028]
   to [9bb8f851cd652361bf4b4d0c0f645a7dd9659ccb]

patch "src/cmd_conflicts.cc"
 from [a4ebd8012db61009bdc9b24fc677c489b9812661]
   to [e1b7feca5acd314d85498cabedf888f5293bf30e]

patch "src/merge_conflict.cc"
 from [b2d9fd8f7f7614af23106048c8810ae7e3c2ec60]
   to [4269fe13d0992982ea99d03c27383830f2e8e381]

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

patch "src/merge_roster.hh"
 from [4bd3be5251736b3b0987a2179c6defbcd7d0b188]
   to [919a6e38017219453de30c8e6a8a03dfc8b32821]

patch "src/roster.cc"
 from [b4cec49faa1928388c7ab0ae1e2f389b202270b0]
   to [3f81121ce80b42565e6e5e4bbe3e6186b85e9b10]

patch "test/func/resolve_conflicts_dropped_modified/__driver__.lua"
 from [bcfc3ea32eb2bc76edc978567c24731402967120]
   to [9653bbfed7d26f56e0313979a069a3ab139d1666]

patch "test/func/resolve_conflicts_dropped_modified/conflicts-orphaned"
 from [1d2aa9cc3444a9002bca7ba6d74335e943fbed3c]
   to [8fb06d4519659f162e902ee36fa0bd5346242435]

patch "test/func/resolve_conflicts_dropped_modified/conflicts-orphaned-resolved"
 from [203dc22e1122af927193f34e7186bb650b77302f]
   to [a0f4f2e8e55ec599e3e3b810ffde282aac49196c]

patch "test/func/resolve_conflicts_dropped_modified/show_conflicts-orphaned"
 from [3fd23fd24470d5755be8e083666afadf9f9aad58]
   to [c72fc91818bad393cb71a003450a7ae8cc7a959f]
============================================================
--- doc/monotone.texi	f22f349d0207a09ae6806f8a57c86991a4143028
+++ doc/monotone.texi	9bb8f851cd652361bf4b4d0c0f645a7dd9659ccb
@@ -3503,6 +3503,12 @@ @subheading Dropped/Modified file Confli
 still there; the user can see it by starting @command{mtn log} again
 for the same file but in the parent of the merge.
 
+A special case occurs when the user re-adds the file after dropping
+it, then attempts to merge. In this case, the possible resolutions are
+to keep the re-added version, or keep a user modified version,
+replacing the re-added version (drop is
+not a valid resolution).
+
 There is no such thing as a dropped/modified directory; if the
 directory is empty, the only possible change is rename, which is
 ignored.
@@ -10452,6 +10458,19 @@ @section Automation
 possible resolutions are different; orphaned requires a rename if the
 file is kept.
 
+File dropped and recreated on one side; modified on the other (and possibly renamed):
address@hidden
+        conflict dropped_modified
+   ancestor_name "foo"
+ancestor_file_id [e80910e54d0bdea1b6d295ada320b87aaf9fdc23]
+       left_type "recreated file"
+       left_name "foo"
+    left_file_id [e80910e54d0bdea1b6d295ada320b87aaf9fdc23]
+      right_type "modified file"
+      right_name "baz"
+   right_file_id [fe6d523f607e2f2fc0f0defad3bda0351a95a337]
address@hidden verbatim
+
 Invalid file name (@file{_MTN} in root directory):
 @verbatim
      conflict invalid_name
============================================================
--- src/cmd_conflicts.cc	a4ebd8012db61009bdc9b24fc677c489b9812661
+++ src/cmd_conflicts.cc	e1b7feca5acd314d85498cabedf888f5293bf30e
@@ -126,31 +126,40 @@ show_conflicts(database & db, conflicts_
             {
               if (conflict.left_nid == the_null_node)
                 {
-                  P(F("dropped on the left"));
+                  if (conflict.recreated == the_null_node)
+                    P(F("dropped on the left"));
+                  else
+                    P(F("dropped and recreated on the left"));
+
                   P(F("modified on the right"));
                 }
               else
                 {
                   P(F("modified on the left"));
-                  P(F("dropped on the right"));
+
+                  if (conflict.recreated == the_null_node)
+                    P(F("dropped on the right"));
+                  else
+                    P(F("dropped and recreated on the right"));
                 }
             }
 
           switch (show_case)
             {
             case first:
+              P(F("possible resolutions:"));
+
+              if (conflict.recreated == the_null_node)
+                P(F("resolve_first drop"));
+
               if (conflict.orphaned)
                 {
-                  P(F("possible resolutions:"));
-                  P(F("resolve_first drop"));
                   P(F("resolve_first rename"));
                   P(F("resolve_first user_rename \"new_content_name\" \"new_file_name\""));
                   return;
                 }
               else
                 {
-                  P(F("possible resolutions:"));
-                  P(F("resolve_first drop"));
                   P(F("resolve_first keep"));
                   P(F("resolve_first user \"name\""));
                   return;
@@ -448,6 +457,7 @@ set_first_conflict(database & db,
               if ("drop" == idx(args,0)())
                 {
                   E(args.size() == 1, origin::user, F("wrong number of arguments"));
+                  E(conflict.recreated == the_null_node, origin::user, F("recreated files may not be dropped"));
 
                   conflict.resolution.first  = resolve_conflicts::drop;
                 }
@@ -481,7 +491,7 @@ set_first_conflict(database & db,
 
                   conflict.resolution.first  = resolve_conflicts::content_user_rename;
                   conflict.resolution.second = new_optimal_path(idx(args,1)(), false);
-                  conflict.rename = resolve_conflicts::new_file_path(idx(args,2)());
+                  conflict.rename = file_path_external(utf8(idx(args,2)(), origin::user));
                 }
               else
                 {
============================================================
--- src/merge_conflict.cc	b2d9fd8f7f7614af23106048c8810ae7e3c2ec60
+++ src/merge_conflict.cc	4269fe13d0992982ea99d03c27383830f2e8e381
@@ -1124,7 +1124,17 @@ roster_merge_result::report_dropped_modi
                 }
               else
                 {
-                  st.push_str_pair(syms::left_type, "dropped file");
+                  if (conflict.recreated == the_null_node)
+                    {
+                      st.push_str_pair(syms::left_type, "dropped file");
+                    }
+                  else
+                    {
+                      st.push_str_pair(syms::left_type, "recreated file");
+                      st.push_str_pair(syms::left_name, modified_name.as_external());
+                      db_adaptor.db.get_file_content (db_adaptor.left_rid, conflict.recreated, fid);
+                      st.push_binary_pair(syms::left_file_id, fid.inner());
+                    }
                 }
             }
           else
@@ -1143,7 +1153,17 @@ roster_merge_result::report_dropped_modi
                 }
               else
                 {
-                  st.push_str_pair(syms::right_type, "dropped file");
+                  if (conflict.recreated == the_null_node)
+                    {
+                      st.push_str_pair(syms::right_type, "dropped file");
+                    }
+                  else
+                    {
+                      st.push_str_pair(syms::right_type, "recreated file");
+                      st.push_str_pair(syms::right_name, modified_name.as_external());
+                      db_adaptor.db.get_file_content (db_adaptor.right_rid, conflict.recreated, fid);
+                      st.push_binary_pair(syms::right_file_id, fid.inner());
+                    }
                 }
             }
           else
@@ -1165,12 +1185,10 @@ roster_merge_result::report_dropped_modi
                   break;
 
                 case resolve_conflicts::content_user_rename:
-                  st.push_str_pair(syms::resolved_rename_left, conflict.rename->as_external());
+                  st.push_str_pair(syms::resolved_rename_left, conflict.rename.as_external());
                   break;
 
                 default:
-                  // FIXME: debugging
-                  E(false, origin::user, F("conflict.resolution.first: %s") % conflict.resolution.first);
                   I(false);
                 }
             }
@@ -1187,7 +1205,10 @@ roster_merge_result::report_dropped_modi
                 }
               else
                 {
-                  P(F("dropped on the left"));
+                  if (conflict.recreated == the_null_node)
+                    P(F("dropped on the left"));
+                  else
+                    P(F("dropped and recreated on the left"));
                 }
               P(F("modified on the right, named %s") % modified_name);
             }
@@ -1200,7 +1221,10 @@ roster_merge_result::report_dropped_modi
                 }
               else
                 {
-                  P(F("dropped on the right"));
+                  if (conflict.recreated == the_null_node)
+                    P(F("dropped on the right"));
+                  else
+                    P(F("dropped and recreated on the right"));
                 }
             }
         }
@@ -1931,13 +1955,20 @@ read_dropped_modified_conflict(basic_io:
       // no more data for left
       conflict.orphaned = true;
     }
-  else
+  else if (tmp == "recreated file")
     {
-      // modified file
       pars.esym(syms::left_name); pars.str(tmp);
+      conflict.recreated = left_roster.get_node(file_path_external(utf8(tmp, origin::internal)))->self;
+      pars.esym(syms::left_file_id); pars.hex();
+    }
+  else if (tmp == "modified file")
+    {
+      pars.esym(syms::left_name); pars.str(tmp);
       conflict.left_nid = left_roster.get_node(file_path_external(utf8(tmp, origin::internal)))->self;
       pars.esym(syms::left_file_id); pars.hex();
     }
+  else
+    I(false);
 
   pars.esym(syms::right_type);
   pars.str(tmp);
@@ -1951,13 +1982,20 @@ read_dropped_modified_conflict(basic_io:
       // no more data for right
       conflict.orphaned = true;
     }
-  else
+  else if (tmp == "recreated file")
     {
-      // modified file
       pars.esym(syms::right_name); pars.str(tmp);
+      conflict.recreated = right_roster.get_node(file_path_external(utf8(tmp, origin::internal)))->self;
+      pars.esym(syms::right_file_id); pars.hex();
+    }
+  else if (tmp == "modified file")
+    {
+      pars.esym(syms::right_name); pars.str(tmp);
       conflict.right_nid = right_roster.get_node(file_path_external(utf8(tmp, origin::internal)))->self;
       pars.esym(syms::right_file_id); pars.hex();
     }
+  else
+    I(false);
 
   // check for a resolution
   if ((!pars.symp (syms::conflict)) && pars.tok.in.lookahead != EOF)
@@ -1986,7 +2024,7 @@ read_dropped_modified_conflict(basic_io:
               pars.esym (syms::resolved_rename_left);
               conflict.resolution.first = resolve_conflicts::content_user_rename;
               pars.str(tmp);
-              conflict.rename = new_optimal_path(tmp, false);
+              conflict.rename = file_path_external_ws(utf8(tmp, origin::user));
             }
         }
       else if (pars.symp (syms::resolved_rename_left))
@@ -2043,7 +2081,8 @@ validate_dropped_modified_conflicts(basi
 
       // Note that we do not confirm the file ids.
       E(merge_conflict.left_nid == file_conflict.left_nid &&
-        merge_conflict.right_nid == file_conflict.right_nid,
+        merge_conflict.right_nid == file_conflict.right_nid &&
+        merge_conflict.recreated == file_conflict.recreated,
         origin::user,
         F(conflicts_mismatch_msg));
 
@@ -2728,16 +2767,28 @@ roster_merge_result::resolve_dropped_mod
       node_id   nid;
       file_path modified_name;
       file_id   modified_fid;
+      file_path recreated_name;
+      file_id   recreated_fid;
 
       if (conflict.left_nid == the_null_node)
         {
           nid = conflict.right_nid;
           right_roster.get_file_details(nid, modified_fid, modified_name);
+
+          if (conflict.recreated != the_null_node)
+            {
+              roster.get_file_details(conflict.recreated, recreated_fid, recreated_name);
+            }
         }
       else
         {
           nid = conflict.left_nid;
           left_roster.get_file_details(nid, modified_fid, modified_name);
+
+          if (conflict.recreated != the_null_node)
+            {
+              roster.get_file_details(conflict.recreated, recreated_fid, recreated_name);
+            }
         }
 
       switch (conflict.resolution.first)
@@ -2751,17 +2802,40 @@ roster_merge_result::resolve_dropped_mod
           P(F("replacing content of '%s' with '%s'") %
             modified_name % conflict.resolution.second->as_external());
 
-          resolve_dropped_modified_user(roster, nid, modified_fid, conflict, adaptor, nis);
-          attach_node(lua, roster, nid, modified_name);
+          if (conflict.recreated == the_null_node)
+            {
+              resolve_dropped_modified_user(roster, nid, modified_fid, conflict, adaptor, nis);
+              attach_node(lua, roster, nid, modified_name);
+            }
+          else
+            {
+              // See comments in keep below on why we drop first
+              roster.drop_detached_node(nid);
+
+              file_id result_fid;
+              file_data parent_data, result_data;
+              data result_raw_data;
+              adaptor.get_version(recreated_fid, parent_data);
+
+              read_data(*conflict.resolution.second, result_raw_data);
+
+              result_data = file_data(result_raw_data);
+              calculate_ident(result_data, result_fid);
+
+              file_t result_node = downcast_to_file_t(roster.get_node_for_update(conflict.recreated));
+              result_node->content = result_fid;
+
+              adaptor.record_file(recreated_fid, result_fid, parent_data, result_data);
+            }
           break;
 
         case resolve_conflicts::content_user_rename:
-          I(conflict.rename != 0);
+          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());
+            modified_name % conflict.rename.as_external() % conflict.resolution.second->as_external());
 
           resolve_dropped_modified_user(roster, nid, modified_fid, conflict, adaptor, nis);
-          attach_node(lua, roster, nid, file_path_internal (conflict.rename->as_internal()));
+          attach_node(lua, roster, nid, file_path_internal (conflict.rename.as_internal()));
           break;
 
         case resolve_conflicts::drop:
@@ -2782,17 +2856,26 @@ roster_merge_result::resolve_dropped_mod
         case resolve_conflicts::keep:
           P(F("keeping '%s'") % modified_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(nid);
-          nid = roster.create_file_node(modified_fid, nis);
-          attach_node (lua, roster, nid, modified_name);
+          if (conflict.recreated == the_null_node)
+            {
+              // 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(nid);
+              nid = roster.create_file_node(modified_fid, nis);
+              attach_node (lua, roster, nid, modified_name);
+            }
+          else
+            {
+              roster.drop_detached_node(nid);
+              // Nothing else to do.
+            }
           break;
 
         default:
============================================================
--- src/merge_roster.cc	d68470addacbe005680b1f66a69f8a9edd4e6ea4
+++ src/merge_roster.cc	e94fdfa49616a796084a2f066beb39b4c225d0b8
@@ -351,8 +351,12 @@ namespace
         // The node has been deleted from the other side of the merge. If
         // there are changes to the file on this side of the merge, insert
         // it into the new roster, but leave it detached, so the conflict
-        // resolutions can deal with it easily. Note that attaching is done
-        // later; see roster_merge below.
+        // resolutions can deal with it easily. Note that attaching would be
+        // done later; see roster_merge below.
+        //
+        // We also need to look for another node with the same name; user
+        // may have already 'undeleted' the node. But we have to do that
+        // after all result nodes are created and attached.
         set<revision_id> const & content_marks = m->file_content;
         for (set<revision_id>::const_iterator it = content_marks.begin();
              it != content_marks.end();
@@ -767,6 +771,27 @@ roster_merge(roster_t const & left_paren
     I(new_i == result.roster.all_nodes().end());
   }
 
+  // now we can look for dropped_modified conflicts with recreated nodes
+  for (size_t i = 0; i < result.dropped_modified_conflicts.size(); ++i)
+    {
+      dropped_modified_conflict & conflict = result.dropped_modified_conflicts[i];
+
+      file_path modified_name;
+      if (conflict.left_nid == the_null_node)
+        {
+          right_parent.get_name(conflict.right_nid, modified_name);
+        }
+      else
+        {
+          left_parent.get_name(conflict.left_nid, modified_name);
+        }
+
+      if (result.roster.has_node(modified_name))
+        {
+          conflict.recreated = result.roster.get_node(modified_name)->self;
+        }
+    }
+
   // now check for the possible global problems
   if (!result.roster.has_root())
     result.missing_root_conflict = true;
============================================================
--- src/merge_roster.hh	4bd3be5251736b3b0987a2179c6defbcd7d0b188
+++ src/merge_roster.hh	919a6e38017219453de30c8e6a8a03dfc8b32821
@@ -98,8 +98,10 @@ struct dropped_modified_conflict
 
   bool orphaned; // if true, the dropped side is due to a dropped parent directory
 
+  node_id recreated; // by user, or in a previous drop/modified resolution
+
   resolve_conflicts::file_resolution_t resolution;
-  boost::shared_ptr<any_path> rename;
+  file_path rename;
   // if orphaned is true, the resolutions are 'drop' and 'user rename'; the
   // latter requires two paths; content in resolution->second, filename in
   // rename.
@@ -107,7 +109,9 @@ struct dropped_modified_conflict
   dropped_modified_conflict(node_id left_nid, node_id right_nid) :
     left_nid(left_nid),
     right_nid(right_nid),
-    orphaned(false)
+    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;}
============================================================
--- src/roster.cc	b4cec49faa1928388c7ab0ae1e2f389b202270b0
+++ src/roster.cc	3f81121ce80b42565e6e5e4bbe3e6186b85e9b10
@@ -1191,6 +1191,8 @@ roster_t::check_sane(bool temp_nodes_ok)
 void
 roster_t::check_sane(bool temp_nodes_ok) const
 {
+  MM(*this);
+
   node_id parent_id(the_null_node);
   const_dir_t parent_dir;
   I(old_locations.empty());
============================================================
--- test/func/resolve_conflicts_dropped_modified/__driver__.lua	bcfc3ea32eb2bc76edc978567c24731402967120
+++ test/func/resolve_conflicts_dropped_modified/__driver__.lua	9653bbfed7d26f56e0313979a069a3ab139d1666
@@ -257,27 +257,33 @@ check(samelines("stderr",
 
 check(mtn("explicit_merge", "--resolve-conflicts", left_3, right_3, "testbranch"), 0, nil, true)
 check(samelines("stderr",
-{"mtn: [left]  5ac4e947066417642f5404b9a54d4d8487bda002",
- "mtn: [right] d542a5d8e86dc29448a27449688d6f4fffcec72b",
+{"mtn: [left]  e6dba3377cbb926ae4e90642714daef18802b2ff",
+ "mtn: [right] 9549ab0f562b7a6d4597daa274892a922f38d45a",
  "mtn: replacing content of 'dir2/file_10' (renamed to 'file_10') with '_MTN/resolutions/file_10'",
  "mtn: dropping 'dir2/file_11'",
  "mtn: renaming 'dir2/file_9' to 'file_9'",
- "mtn: [merged] 202584446f5184430d1f8320eb702a5f81134505"}))
-
+ "mtn: [merged] 435d4d0197ba785b0360961debe3080f5704313e"}))
  
 -- A special case; drop then re-add vs modify. This used to be the test
 -- "merge((patch_a),_(drop_a,_add_a))"
-addfile("file_10", "file_10 base")
+addfile("file_10", "file_10 base") -- modify in left; drop, add in right
+addfile("file_11", "file_11 base") -- drop, add in left; modify in right
 commit("testbranch", "base 4")
 base_4 = base_revision()
 
 writefile("file_10", "file_10 left")
-commit("testbranch", "left 4")
+
+check(mtn("drop", "file_11"), 0, false, false)
+commit("testbranch", "left 4a")
+
+addfile("file_11", "file_11 left re-add")
+commit("testbranch", "left 4b")
 left_4 = base_revision()
 
 revert_to(base_4)
 
 check(mtn("drop", "file_10"), 0, false, false)
+writefile("file_11", "file_11 right")
 commit("testbranch", "right 4a")
 
 addfile("file_10", "file_10 right re-add")
@@ -285,26 +291,58 @@ check(mtn("show_conflicts", left_4, righ
 right_4 = base_revision()
 
 check(mtn("show_conflicts", left_4, right_4), 0, nil, true)
-check(qgrep("mtn: conflict: file 'file_10'", "stderr"))
-check(qgrep("mtn: modified on the left", "stderr"))
-check(qgrep("mtn: dropped on the right", "stderr"))
-check(qgrep("mtn: 1 conflict with supported resolutions.", "stderr"))
+check(samelines("stderr",
+{"mtn: [left]     fd12d8fb1973814d7756bae60c668b9c82364b59",
+ "mtn: [right]    74ded9748ae7ee457a83a8d8a7dd0ffac93b13af",
+ "mtn: [ancestor] 613d77ec3ea9e0cda71d1a9c8328d4965b5730bf",
+ "mtn: conflict: file 'file_10' from revision 613d77ec3ea9e0cda71d1a9c8328d4965b5730bf",
+ "mtn: modified on the left, named file_10",
+ "mtn: dropped and recreated on the right",
+ "mtn: conflict: file 'file_11' from revision 613d77ec3ea9e0cda71d1a9c8328d4965b5730bf",
+ "mtn: dropped and recreated on the left",
+ "mtn: modified on the right, named file_11",
+ "mtn: 2 conflicts with supported resolutions."}))
 
--- FIXME: Show this conflict can't be resolved by keep; two new nodes with same name
 check(mtn("conflicts", "store", left_4, right_4), 0, nil, true)
+check(samefilestd("conflicts-recreated", "_MTN/conflicts"))
 
+-- drop is not a valid resolution in this case
 check(mtn("conflicts", "show_first"), 0, nil, true)
 check(samelines("stderr",
 {"mtn: conflict: file 'file_10'",
  "mtn: modified on the left",
- "mtn: dropped on the right",
+ "mtn: dropped and recreated on the right",
  "mtn: possible resolutions:",
- "mtn: resolve_first drop",
  "mtn: resolve_first keep",
  "mtn: resolve_first user \"name\""}))
 
-check(mtn("conflicts", "resolve_first", "keep"), 0, nil, true)
+check(mtn("conflicts", "resolve_first", "drop"), 1, nil, true)
+check(samelines("stderr", {"mtn: misuse: recreated files may not be dropped"}))
 
-check(mtn("explicit_merge", "--resolve-conflicts", left_4, right_4, "testbranch"), 0, nil)
+check(mtn("conflicts", "resolve_first", "keep"), 0, nil, nil)
 
+check(mtn("conflicts", "show_first"), 0, nil, true)
+check(samelines("stderr",
+{"mtn: conflict: file 'file_11'",
+ "mtn: dropped and recreated on the left",
+ "mtn: modified on the right",
+ "mtn: possible resolutions:",
+ "mtn: resolve_first keep",
+ "mtn: resolve_first user \"name\""}))
+
+mkdir("_MTN")
+mkdir("_MTN/resolutions")
+writefile("_MTN/resolutions/file_11", "file_11 user")
+check(mtn("conflicts", "resolve_first", "user", "_MTN/resolutions/file_11"), 0, nil, nil)
+
+check(samefilestd("conflicts-recreated-resolved", "_MTN/conflicts"))
+
+check(mtn("explicit_merge", "--resolve-conflicts", left_4, right_4, "testbranch"), 0, nil, true)
+check(samelines("stderr",
+{"mtn: [left]  fd12d8fb1973814d7756bae60c668b9c82364b59",
+ "mtn: [right] 74ded9748ae7ee457a83a8d8a7dd0ffac93b13af",
+ "mtn: keeping 'file_10'",
+ "mtn: replacing content of 'file_11' with '_MTN/resolutions/file_11'",
+ "mtn: [merged] 4da275122e0592217634c4d23838284cc570681a"}))
+
 -- end of file
============================================================
--- test/func/resolve_conflicts_dropped_modified/conflicts-orphaned	1d2aa9cc3444a9002bca7ba6d74335e943fbed3c
+++ test/func/resolve_conflicts_dropped_modified/conflicts-orphaned	8fb06d4519659f162e902ee36fa0bd5346242435
@@ -1,6 +1,6 @@
-    left [5ac4e947066417642f5404b9a54d4d8487bda002]
-   right [d542a5d8e86dc29448a27449688d6f4fffcec72b]
-ancestor [70ef90574731a834d932669e77be7f89662e9097]
+    left [e6dba3377cbb926ae4e90642714daef18802b2ff]
+   right [9549ab0f562b7a6d4597daa274892a922f38d45a]
+ancestor [c55331b815b944b2fcde9b2ce42536dbda706a4c]
 
         conflict dropped_modified
    ancestor_name "dir2/file_10"
============================================================
--- test/func/resolve_conflicts_dropped_modified/conflicts-orphaned-resolved	203dc22e1122af927193f34e7186bb650b77302f
+++ test/func/resolve_conflicts_dropped_modified/conflicts-orphaned-resolved	a0f4f2e8e55ec599e3e3b810ffde282aac49196c
@@ -1,6 +1,6 @@
-    left [5ac4e947066417642f5404b9a54d4d8487bda002]
-   right [d542a5d8e86dc29448a27449688d6f4fffcec72b]
-ancestor [70ef90574731a834d932669e77be7f89662e9097]
+    left [e6dba3377cbb926ae4e90642714daef18802b2ff]
+   right [9549ab0f562b7a6d4597daa274892a922f38d45a]
+ancestor [c55331b815b944b2fcde9b2ce42536dbda706a4c]
 
             conflict dropped_modified
        ancestor_name "dir2/file_10"
============================================================
--- /dev/null	
+++ test/func/resolve_conflicts_dropped_modified/conflicts-recreated	84f2b46cd09c045eae6a8ad386f1337623db33a9
@@ -0,0 +1,23 @@
+    left [fd12d8fb1973814d7756bae60c668b9c82364b59]
+   right [74ded9748ae7ee457a83a8d8a7dd0ffac93b13af]
+ancestor [613d77ec3ea9e0cda71d1a9c8328d4965b5730bf]
+
+        conflict dropped_modified
+   ancestor_name "file_10"
+ancestor_file_id [7368a4340573dca149c05db6f49638fafee766d0]
+       left_type "modified file"
+       left_name "file_10"
+    left_file_id [080c590e6e671b1b9ca0e752e1bc468c5167e2a9]
+      right_type "recreated file"
+      right_name "file_10"
+   right_file_id [59db7ed2afabb782b5a0215d825a86271eb96b8d]
+
+        conflict dropped_modified
+   ancestor_name "file_11"
+ancestor_file_id [498b49fddbd0418f62eb19d2096de816f3e34116]
+       left_type "recreated file"
+       left_name "file_11"
+    left_file_id [bbf158a696465c2feb9ea22fac35ff7088f07ba0]
+      right_type "modified file"
+      right_name "file_11"
+   right_file_id [935f9a7af1da88e7fe541690076c48bac2108052]
============================================================
--- /dev/null	
+++ test/func/resolve_conflicts_dropped_modified/conflicts-recreated-resolved	eda35ed4d0fd88adf5e07b52005d56aacd05bd8a
@@ -0,0 +1,25 @@
+    left [fd12d8fb1973814d7756bae60c668b9c82364b59]
+   right [74ded9748ae7ee457a83a8d8a7dd0ffac93b13af]
+ancestor [613d77ec3ea9e0cda71d1a9c8328d4965b5730bf]
+
+          conflict dropped_modified
+     ancestor_name "file_10"
+  ancestor_file_id [7368a4340573dca149c05db6f49638fafee766d0]
+         left_type "modified file"
+         left_name "file_10"
+      left_file_id [080c590e6e671b1b9ca0e752e1bc468c5167e2a9]
+        right_type "recreated file"
+        right_name "file_10"
+     right_file_id [59db7ed2afabb782b5a0215d825a86271eb96b8d]
+resolved_keep_left 
+
+          conflict dropped_modified
+     ancestor_name "file_11"
+  ancestor_file_id [498b49fddbd0418f62eb19d2096de816f3e34116]
+         left_type "recreated file"
+         left_name "file_11"
+      left_file_id [bbf158a696465c2feb9ea22fac35ff7088f07ba0]
+        right_type "modified file"
+        right_name "file_11"
+     right_file_id [935f9a7af1da88e7fe541690076c48bac2108052]
+resolved_user_left "_MTN/resolutions/file_11"
============================================================
--- test/func/resolve_conflicts_dropped_modified/show_conflicts-orphaned	3fd23fd24470d5755be8e083666afadf9f9aad58
+++ test/func/resolve_conflicts_dropped_modified/show_conflicts-orphaned	c72fc91818bad393cb71a003450a7ae8cc7a959f
@@ -1,13 +1,13 @@
-mtn: [left]     5ac4e947066417642f5404b9a54d4d8487bda002
-mtn: [right]    d542a5d8e86dc29448a27449688d6f4fffcec72b
-mtn: [ancestor] 70ef90574731a834d932669e77be7f89662e9097
-mtn: conflict: file 'dir2/file_10' from revision 70ef90574731a834d932669e77be7f89662e9097
+mtn: [left]     e6dba3377cbb926ae4e90642714daef18802b2ff
+mtn: [right]    9549ab0f562b7a6d4597daa274892a922f38d45a
+mtn: [ancestor] c55331b815b944b2fcde9b2ce42536dbda706a4c
+mtn: conflict: file 'dir2/file_10' from revision c55331b815b944b2fcde9b2ce42536dbda706a4c
 mtn: modified on the left, named dir2/file_10
 mtn: orphaned on the right
-mtn: conflict: file 'dir2/file_11' from revision 70ef90574731a834d932669e77be7f89662e9097
+mtn: conflict: file 'dir2/file_11' from revision c55331b815b944b2fcde9b2ce42536dbda706a4c
 mtn: modified on the left, named dir2/file_11
 mtn: orphaned on the right
-mtn: conflict: file 'dir2/file_9' from revision 70ef90574731a834d932669e77be7f89662e9097
+mtn: conflict: file 'dir2/file_9' from revision c55331b815b944b2fcde9b2ce42536dbda706a4c
 mtn: modified on the left, named dir2/file_9
 mtn: orphaned on the right
 mtn: 3 conflicts with supported resolutions.

reply via email to

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