[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Monotone-commits-diffs] net.venge.monotone.issue-209.file_attribute: 6644cff8fa909e1b9d69554b60d473571f1ad135,
code <=