# # patch "ChangeLog" # from [9df88607ee3b9fde1203282405f9fee132ba61d3] # to [9c1933d220ac12975bfac1c54c39fbbd218419b3] # # patch "change_set.cc" # from [8c37c6f09b401fcf164561e83f7c0f6e04d6358d] # to [2c23e02d428444eb487bbb1d81dd71d8b1e8947e] # # patch "change_set.hh" # from [07b4b1de8d6ab268425d121270a8f08f38fa29ca] # to [aee5ff6b0ed2f320c451e25a118aba890bd6f89e] # # patch "pcdv.cc" # from [109b9384a6d250b492e7704aa2e3a9e1b2be001f] # to [141ba3bc8d108539e711c63ccf0c2faf05cf04f7] # # patch "tests/t_merge_add_rename_add.at" # from [65aee8363a38ca7e1ba54d2d691725867c0e46e4] # to [3ace704eea4bdc0441cc2966efe2954425fe193f] # ======================================================================== --- ChangeLog 9df88607ee3b9fde1203282405f9fee132ba61d3 +++ ChangeLog 9c1933d220ac12975bfac1c54c39fbbd218419b3 @@ -1,3 +1,12 @@ +2005-08-24 Timothy Brownawell + + * tests/t_merge_add_rename_add.at: remove XFAIL + The result of this merge (, ) are now defined: call + the resolve_path_conflicts hook with a "collision" type conflict. + Not resolving the conflict (in this case) leads to a warning, + followed by a crash. The warning should be an error, but is triggered + by the monotone db. + 2005-08-22 Timothy Brownawell * tree merger: Allow tree conflicts to be resolved by the user. ======================================================================== --- change_set.cc 8c37c6f09b401fcf164561e83f7c0f6e04d6358d +++ change_set.cc 2c23e02d428444eb487bbb1d81dd71d8b1e8947e @@ -1789,6 +1789,7 @@ std::vector & paths, interner & itx) { + MM(paths); std::map ip; std::vector > ps; std::map > sm; @@ -1909,6 +1910,7 @@ std::vector conf(l.conflict(r)); MM(conf); std::set res; + MM(res); if (!conf.empty()) { data c, r; ======================================================================== --- change_set.hh 07b4b1de8d6ab268425d121270a8f08f38fa29ca +++ change_set.hh aee5ff6b0ed2f320c451e25a118aba890bd6f89e @@ -237,5 +237,6 @@ // debugging void dump(change_set const & cs, std::string & out); +void dump(change_set::path_rearrangement const & pr, std::string & out); #endif // __CHANGE_SET_HH__ ======================================================================== --- pcdv.cc 109b9384a6d250b492e7704aa2e3a9e1b2be001f +++ pcdv.cc 141ba3bc8d108539e711c63ccf0c2faf05cf04f7 @@ -926,6 +926,7 @@ if (!(m->second.first == o->second.first)) { W(F("Sutured items previously had different values in the same revision.")); + W(F("This may cause crashes.")); L(F("This was in revision #%1%") % o->first); } std::set s; @@ -955,7 +956,14 @@ suture_maps(versions->second, other.versions->second); item_status myother(other); myother.versions = versions; - return merge(myother); + item_status out = merge(myother); + if (out.current_names().size() > 1) + { + W(F("Sutured items previously had different values in the same revision.")); + W(F("This may cause crashes.")); + L(F("This was in revision #%1%") % *leaves->first.begin()); + } + return out; } template @@ -1659,43 +1667,12 @@ return out; } -std::vector > -tree_state::current() const -{ - apply_sutures(); - std::vector > out; - for (std::map::const_iterator i = states->begin(); - i != states->end(); ++i) - { - if (i->second.is_dir) - continue; - file_path fp = get_full_name(i->second); - if (!(fp == file_path())) - out.push_back(make_pair(i->first, fp)); - } - return out; -} - -std::vector > -tree_state::current_with_dirs() const -{ - apply_sutures(); - std::vector > out; - for (std::map::const_iterator i = states->begin(); - i != states->end(); ++i) - { - file_path fp = get_full_name(i->second); - if (!(fp == file_path())) - out.push_back(make_pair(i->first, fp)); - } - return out; -} - void tree_state::get_changes_for_merge(tree_state const & merged, change_set::path_rearrangement & changes) const { + MM(changes); this->apply_sutures(); merged.apply_sutures(); changes.deleted_dirs.clear(); @@ -1944,6 +1921,38 @@ return merged; } +std::vector > +tree_state::current() const +{ + apply_sutures(); + std::vector > out; + for (std::map::const_iterator i = states->begin(); + i != states->end(); ++i) + { + if (i->second.is_dir) + continue; + file_path fp = get_full_name(i->second); + if (!(fp == file_path())) + out.push_back(make_pair(i->first, fp)); + } + return out; +} + +std::vector > +tree_state::current_with_dirs() const +{ + apply_sutures(); + std::vector > out; + for (std::map::const_iterator i = states->begin(); + i != states->end(); ++i) + { + file_path fp = get_full_name(i->second); + if (!(fp == file_path())) + out.push_back(make_pair(i->first, fp)); + } + return out; +} + file_path tree_state::get_full_name(item_status x) const { @@ -1980,6 +1989,11 @@ return file_path(); } x = *y.begin(); + if (null_name(x.second)) + {// a parent dir was deleted + d = 0; + return file_path(); + } names.push_back(x.second); } reverse(names.begin(), names.end()); @@ -2008,6 +2022,8 @@ break; } x = *y.begin(); + if (null_name(x.second)) + return std::string(); names.push_back(x.second); } reverse(names.begin(), names.end()); ======================================================================== --- tests/t_merge_add_rename_add.at 65aee8363a38ca7e1ba54d2d691725867c0e46e4 +++ tests/t_merge_add_rename_add.at 3ace704eea4bdc0441cc2966efe2954425fe193f @@ -1,9 +1,7 @@ # -*- Autoconf -*- AT_SETUP([merging with ]) -# This test is a bug report. -AT_XFAIL_IF(true) MONOTONE_SETUP @@ -14,13 +12,24 @@ # D # # A is the common ancestor, containing 'add foo'. B contains 'rename foo -# bar'. C contains 'add bar'. D is the final state after a merge--we -# currently don't have a definition for what this final state is. +# bar'. C contains 'add bar'. +# Merging B and C gives a tree conflict. If this isn't resolved, it leads +# to a suture. But since both files being sutured exist in C, the suture will +# trigger an I . +# Expect the merge to fail, but check that the tree resolution hook is told +# about the conflict. AT_DATA(foo, [extra blah blah foo ]) AT_DATA(bar, [extra blah blah bar ]) +AT_DATA(dumpconf.lua, [function resolve_path_conflicts(conflicts) +local x = io.open("conf", "w") +x:write(conflicts) +io.close(x) +return nil +end +]) # produce state A AT_CHECK(MONOTONE add foo, [], [ignore], [ignore]) @@ -40,9 +49,10 @@ C_REVISION_SHA=`BASE_REVISION` # merge heads to make D -AT_CHECK(MONOTONE --branch=branch.main merge, [], [ignore], [ignore]) +AT_CHECK(MONOTONE --branch=branch.main --rcfile=dumpconf.lua merge, [3], [ignore], [stderr]) -# XXX: once the final state has a real definition inside monotone, we need -# to add checks here to ensure that state has been reached. +AT_CHECK(grep "This may cause crashes." stderr, [], [ignore], [ignore]) +AT_CHECK(grep "Type: Collision" conf, [], [ignore], [ignore]) + AT_CLEANUP