# # # add_dir "tests/resolve_conflicts_duplicate_name_directory" # # add_file "tests/resolve_conflicts_duplicate_name_directory/__driver__.lua" # content [c99e91400983a126bcf49990f932bf6139b7a49a] # # patch "NEWS" # from [3d042bd138d50bd5a21bd0bb4d360ca5e5f9b2f6] # to [532b2a2716b1a9e9053948f21303acdcb6108f9e] # # patch "merge_conflict.cc" # from [c76a564607a50a2c6b16b72f478f4346724638ed] # to [759be69a7cc08e23e04cbfad88b6a7a523c02c81] # # patch "monotone.texi" # from [2b1ffb9d7e50c751d2d442853b99df18d0bdba9f] # to [6c1307b45f96e8fd7489fabf8c16ff4d3e83dffe] # # patch "tests/resolve_conflicts_content/conflicts-2" # from [43c4ca47a7c43059cb50aa4a3f91a878480f8955] # to [9dbe490ea9bae5cac631c4e445c84048a57ca89b] # ============================================================ --- tests/resolve_conflicts_duplicate_name_directory/__driver__.lua c99e91400983a126bcf49990f932bf6139b7a49a +++ tests/resolve_conflicts_duplicate_name_directory/__driver__.lua c99e91400983a126bcf49990f932bf6139b7a49a @@ -0,0 +1,58 @@ +-- Test/demonstrate handling of duplicate name directory conflicts. +-- +-- For a directory, we can't merge the contents; we can only +-- drop (if empty) or rename. + +mtn_setup() + +-- Get a non-empty base revision +addfile("randomfile", "blah blah blah") +commit() +base = base_revision() + +-- Abe adds conflict directory +mkdir("gui") +addfile("gui/gui.h", "gui.h abe") +commit("testbranch", "abe_1") +abe_1 = base_revision() + +revert_to(base) + +-- Beth adds directory +mkdir("gui") +addfile("gui/gui.h", "gui.h beth") +commit("testbranch", "beth_1") +beth_1 = base_revision() + +-- Resolve conflict +check(mtn("conflicts", "store"), 0, true, nil) + +check(mtn("conflicts", "show_first"), 0, nil, true) +check(qgrep("duplicate_name gui", "stderr")) + +-- Attempt to drop one side; fails at merge time, due to non-empty directory. +check(mtn("conflicts", "resolve_first_left", "drop"), 0, nil, nil) +check(mtn("conflicts", "resolve_first_right", "rename", "gui"), 0, nil, nil) + +check(mtn("merge", "--resolve-conflicts"), 1, nil, true) +check(qgrep("misuse: can't drop gui; not empty", "stderr")) + +-- Start again, use renames for both sides +check(mtn("conflicts", "clean"), 0, nil, true) + +check(mtn("conflicts", "store"), 0, true, nil) + +check(mtn("conflicts", "show_first"), 0, nil, true) +check(qgrep("duplicate_name gui", "stderr")) + +check(mtn("conflicts", "resolve_first_left", "rename", "gui_abe"), 0, nil, nil) +check(mtn("conflicts", "resolve_first_right", "rename", "gui_beth"), 0, nil, nil) + +check(mtn("merge", "--resolve-conflicts"), 0, nil, true) + +check(mtn("update"), 0, nil, false) +merged = base_revision() + +check("gui.h beth" == readfile("gui_beth/gui.h")) + +-- end of file ============================================================ --- NEWS 3d042bd138d50bd5a21bd0bb4d360ca5e5f9b2f6 +++ NEWS 532b2a2716b1a9e9053948f21303acdcb6108f9e @@ -36,17 +36,14 @@ reported by 'automate show_conflicts' for file content conflicts; 'resolved_user_left' is used instead. - - The 'conflict' commands can now handle duplicate name - conflicts for directories. - - - The 'conflict' resolution commands now take the 'keep' - resolution. - Bugs fixed - Monotone now sanely skips paths with invalid characters it encounters during 'add' or 'automate inventory'. + - The 'conflict' commands can now handle duplicate name + conflicts for directories. + Internal Tue May 12 20:44:00 UTC 2009 ============================================================ --- merge_conflict.cc c76a564607a50a2c6b16b72f478f4346724638ed +++ merge_conflict.cc 759be69a7cc08e23e04cbfad88b6a7a523c02c81 @@ -2376,6 +2376,12 @@ resolve_duplicate_name_one_side(lua_hook case resolve_conflicts::drop: P(F("dropping %s") % name); + + if (is_dir_t(result_roster.get_node(nid))) + { + dir_t n = downcast_to_dir_t(result_roster.get_node(nid)); + E(n->children.empty(), origin::user, F("can't drop %s; not empty") % name); + } result_roster.drop_detached_node(nid); break; @@ -2427,9 +2433,24 @@ roster_merge_result::resolve_duplicate_n file_path left_name, right_name; file_id left_fid, right_fid; - left_roster.get_file_details(left_nid, left_fid, left_name); - right_roster.get_file_details(right_nid, right_fid, right_name); + if (is_file_t(left_roster.get_node(left_nid))) + { + left_roster.get_file_details(left_nid, left_fid, left_name); + } + else + { + left_roster.get_name(left_nid, left_name); + } + if (is_file_t(right_roster.get_node(right_nid))) + { + right_roster.get_file_details(right_nid, right_fid, right_name); + } + else + { + right_roster.get_name(right_nid, right_name); + } + resolve_duplicate_name_one_side (lua, conflict.left_resolution, conflict.right_resolution, left_name, left_fid, left_nid, adaptor, roster); ============================================================ --- monotone.texi 2b1ffb9d7e50c751d2d442853b99df18d0bdba9f +++ monotone.texi 6c1307b45f96e8fd7489fabf8c16ff4d3e83dffe @@ -4911,12 +4911,6 @@ @subsection Conflicts For two file conflicts, the possible resolutions are: @ftable @command address@hidden keep -The file is kept in the merge. - -This inserts a @var{resolved_keep_left} or @var{resolved_keep_right} -conflict resolution in the conflicts file. - @item drop The file is dropped in the merge. @@ -9324,8 +9318,6 @@ @section Automation All possible conflict resolutions: @verbatim - resolved_keep_left - resolved_keep_right resolved_drop_left resolved_drop_right resolved_internal ============================================================ --- tests/resolve_conflicts_content/conflicts-2 43c4ca47a7c43059cb50aa4a3f91a878480f8955 +++ tests/resolve_conflicts_content/conflicts-2 9dbe490ea9bae5cac631c4e445c84048a57ca89b @@ -1,5 +1,4 @@ - -left [36cfb5960784df07636cc9d119617326fe87c3f6] + left [36cfb5960784df07636cc9d119617326fe87c3f6] right [be155249f011e658f913c109bafd743b1bfea0fe] ancestor [574e08409c35c5c0eb6e929bf1e3abf49a8bacd4]