# # # patch "cmd_merging.cc" # from [c00d7dd2a1dd4dda7da812ae6216b6ee391238b9] # to [47e0b9aed399b96cb0c35f9cd2617d67f95f3e21] # # patch "merge.cc" # from [9059000487b5a7e6e6390175c376b45ca4f251f0] # to [261329782b6722da16fcafd9ad02a411e38c57f4] # # patch "roster.cc" # from [a787c8b26da6821124f4501337e49493b42e367f] # to [29314247d94e318e37023a900f3d1b0da1117e49] # # patch "roster_merge.cc" # from [5463b7ef47e81e7c564215345bf33ceea7001621] # to [7029afe0cbca494809037d3981cdf052b99d0d65] # # patch "roster_merge.hh" # from [48d9aa743811732826e3f855a5759c1d61416984] # to [742f61535acecd23a75df6133af2eda7f5d766e5] # ============================================================ --- cmd_merging.cc c00d7dd2a1dd4dda7da812ae6216b6ee391238b9 +++ cmd_merging.cc 47e0b9aed399b96cb0c35f9cd2617d67f95f3e21 @@ -903,6 +903,7 @@ show_conflicts_core (database & db, revi result.report_directory_loop_conflicts(*l_roster, *r_roster, adaptor, basic_io, output); result.report_orphaned_node_conflicts(*l_roster, *r_roster, adaptor, basic_io, output); + result.report_node_existance_conflicts(*l_roster, *r_roster, adaptor, basic_io, output); result.report_multiple_name_conflicts(*l_roster, *r_roster, adaptor, basic_io, output); result.report_duplicate_name_conflicts(*l_roster, *r_roster, adaptor, basic_io, output); ============================================================ --- merge.cc 9059000487b5a7e6e6390175c376b45ca4f251f0 +++ merge.cc 261329782b6722da16fcafd9ad02a411e38c57f4 @@ -148,6 +148,7 @@ resolve_merge_conflicts(lua_hooks & lua, result.report_directory_loop_conflicts(left_roster, right_roster, adaptor, false, std::cout); result.report_orphaned_node_conflicts(left_roster, right_roster, adaptor, false, std::cout); + result.report_node_existance_conflicts(left_roster, right_roster, adaptor, false, std::cout); result.report_multiple_name_conflicts(left_roster, right_roster, adaptor, false, std::cout); result.report_duplicate_name_conflicts(left_roster, right_roster, adaptor, false, std::cout); ============================================================ --- roster.cc a787c8b26da6821124f4501337e49493b42e367f +++ roster.cc 29314247d94e318e37023a900f3d1b0da1117e49 @@ -1509,8 +1509,8 @@ namespace } void - mark_unmerged_node(marking_t const & parent_marking, bool parent_existence, node_t parent_n, - revision_id const & new_rid, node_t n, bool & n_existence, + mark_unmerged_node(marking_t const & parent_marking, node_t parent_n, + revision_id const & new_rid, node_t n, marking_t & new_marking) { // SPEEDUP?: the common case here is that the parent and child nodes are @@ -1530,9 +1530,9 @@ namespace new_marking.parent_name); mark_unmerged_scalar(parent_marking.existence, - parent_existence, + true, new_rid, - n_existence, + true, new_marking.existence); if (is_file_t(n)) @@ -1559,16 +1559,13 @@ namespace void mark_merged_node(marking_t const & left_marking, - bool left_existence, set const & left_uncommon_ancestors, node_t ln, marking_t const & right_marking, - bool right_existence, set const & right_uncommon_ancestors, node_t rn, revision_id const & new_rid, node_t n, - bool & n_existence, marking_t & new_marking) { I(same_type(ln, n) && same_type(rn, n)); @@ -1585,11 +1582,11 @@ namespace new_marking.parent_name); // existence mark_merged_scalar(left_marking.existence, left_uncommon_ancestors, - left_existence, + true, right_marking.existence, right_uncommon_ancestors, - right_existence, + true, new_rid, - n_existence, + true, new_marking.existence); // content if (is_file_t(n)) @@ -1684,7 +1681,6 @@ mark_merge_roster(roster_t const & left_ bool exists_in_right = (rni != right_roster.all_nodes().end()); marking_t new_marking; - bool new_existence; if (!exists_in_left && !exists_in_right) mark_new_node(new_rid, n, new_marking); @@ -1696,8 +1692,8 @@ mark_merge_roster(roster_t const & left_ // must be unborn on the left (as opposed to dead) I(right_uncommon_ancestors.find(right_marking.birth_revision) != right_uncommon_ancestors.end()); - mark_unmerged_node(right_marking, exists_in_right, right_node, - new_rid, n, new_existence, new_marking); + mark_unmerged_node(right_marking, right_node, + new_rid, n, new_marking); } else if (exists_in_left && !exists_in_right) { @@ -1706,22 +1702,20 @@ mark_merge_roster(roster_t const & left_ // must be unborn on the right (as opposed to dead) I(left_uncommon_ancestors.find(left_marking.birth_revision) != left_uncommon_ancestors.end()); - mark_unmerged_node(left_marking, exists_in_left, left_node, - new_rid, n, new_existence, new_marking); + mark_unmerged_node(left_marking, left_node, + new_rid, n, new_marking); } else { node_t const & left_node = lni->second; node_t const & right_node = rni->second; - mark_merged_node(safe_get(left_markings, n->self), exists_in_left, + mark_merged_node(safe_get(left_markings, n->self), left_uncommon_ancestors, left_node, - safe_get(right_markings, n->self), exists_in_right, + safe_get(right_markings, n->self), right_uncommon_ancestors, right_node, - new_rid, n, new_existence, new_marking); + new_rid, n, new_marking); } - I(new_existence); - safe_insert(new_markings, make_pair(i->first, new_marking)); } } @@ -2004,14 +1998,12 @@ mark_roster_with_one_parent(roster_t con i != child.all_nodes().end(); ++i) { marking_t new_marking; - bool n_existence = true; if (parent.has_node(i->first)) - mark_unmerged_node(safe_get(parent_markings, i->first), true, + mark_unmerged_node(safe_get(parent_markings, i->first), parent.get_node(i->first), - child_rid, i->second, n_existence, new_marking); + child_rid, i->second, new_marking); else mark_new_node(child_rid, i->second, new_marking); - I(n_existence); safe_insert(child_markings, make_pair(i->first, new_marking)); } ============================================================ --- roster_merge.cc 5463b7ef47e81e7c564215345bf33ceea7001621 +++ roster_merge.cc 7029afe0cbca494809037d3981cdf052b99d0d65 @@ -59,6 +59,14 @@ template <> void } template <> void +dump(node_existance_conflict const & conflict, string & out) +{ + ostringstream oss; + oss << "node_existance_conflict on node: " << conflict.nid << "\n"; + out = oss.str(); +} + +template <> void dump(multiple_name_conflict const & conflict, string & out) { ostringstream oss; @@ -917,6 +925,55 @@ void } void +roster_merge_result::report_node_existance_conflicts(roster_t const & left_roster, + roster_t const & right_roster, + content_merge_adaptor & adaptor, + bool basic_io, + std::ostream & output) const +{ + MM(left_roster); + MM(right_roster); + +#warning FIXME!!! This function needs to be cleaned up! + + for (size_t i = 0; i < node_existance_conflicts.size(); ++i) + { + node_existance_conflict const & conflict = node_existance_conflicts[i]; + MM(conflict); + + shared_ptr lca_roster, parent_lca_roster; + revision_id lca_rid, parent_lca_rid; + file_path lca_name; + + adaptor.get_ancestral_roster(conflict.nid, lca_rid, lca_roster); + + lca_roster->get_name(conflict.nid, lca_name); + + node_type type = get_type(*lca_roster, conflict.nid); + + basic_io::stanza st; + + if (type == file_type) + if (basic_io) + st.push_str_pair(syms::conflict, "existance conflict"); + else + P(F("conflict: existance conflict on file '%s' from revision %s") + % lca_name % lca_rid); + else + { + if (basic_io) + st.push_str_pair(syms::conflict, "existance conflict"); + else + P(F("conflict: existance conflict on directory '%s' from revision %s") + % lca_name % lca_rid); + } + + if (basic_io) + put_stanza (st, output); + } +} + +void roster_merge_result::report_multiple_name_conflicts(roster_t const & left_roster, roster_t const & right_roster, content_merge_adaptor & adaptor, @@ -1616,7 +1673,6 @@ roster_merge(roster_t const & left_paren // First handle lifecycles, by die-die-die merge -- our result will contain // everything that is alive in both parents, or alive in one and unborn in // the other, exactly. - { parallel::iter i(left_parent.all_nodes(), right_parent.all_nodes()); while (i.next()) ============================================================ --- roster_merge.hh 48d9aa743811732826e3f855a5759c1d61416984 +++ roster_merge.hh 742f61535acecd23a75df6133af2eda7f5d766e5 @@ -51,6 +51,12 @@ struct orphaned_node_conflict std::pair parent_name; }; +// A node has been dropped on one side of a merge, and resurrected on the other. +struct node_existance_conflict +{ + node_id nid; +}; + // our general strategy is to return a (possibly insane) roster, and a list of // conflicts encountered in that roster. Each conflict encountered in merging // the roster creates an entry in this list. @@ -116,6 +122,7 @@ template <> void dump(orphaned_node_conf template <> void dump(directory_loop_conflict const & conflict, std::string & out); template <> void dump(orphaned_node_conflict const & conflict, std::string & out); +template <> void dump(node_existance_conflict const & conflict, std::string & out); template <> void dump(multiple_name_conflict const & conflict, std::string & out); template <> void dump(duplicate_name_conflict const & conflict, std::string & out); @@ -140,6 +147,7 @@ struct roster_merge_result std::vector directory_loop_conflicts; std::vector orphaned_node_conflicts; + std::vector node_existance_conflicts; std::vector multiple_name_conflicts; std::vector duplicate_name_conflicts; @@ -175,6 +183,11 @@ struct roster_merge_result content_merge_adaptor & adaptor, bool const basic_io, std::ostream & output) const; + void report_node_existance_conflicts(roster_t const & left, + roster_t const & right, + content_merge_adaptor & adaptor, + bool const basic_io, + std::ostream & output) const; void report_multiple_name_conflicts(roster_t const & left, roster_t const & right, content_merge_adaptor & adaptor,