# # # add_dir "tests/resolve_conflicts_orphaned_file" # # add_file "tests/resolve_conflicts_orphaned_file/__driver__.lua" # content [c9a7317754a51e9586460e6f6b0c40087cba0195] # # patch "NEWS" # from [a552479773f4a0de26f6656074ba186228026bb3] # to [a5907378a44fd492ced099c2248511f3fcd8f04e] # # patch "cmd_conflicts.cc" # from [6bc6f92f1e233d26271ad61d32fa7d355d35a585] # to [ba7f076aeb967031dab8c0ff7487c7f61c8fb138] # # patch "merge_conflict.cc" # from [5a0307cd2d52e0fe6201428bda86121cdeea515a] # to [c76a564607a50a2c6b16b72f478f4346724638ed] # # patch "merge_content.cc" # from [758caf01d627a675e28dd169289c9f15fa69433e] # to [f7ab6793b8cf55a9b1774d8c94386b6df32c2b08] # # patch "merge_roster.cc" # from [0350ccbd3b9b7d79f93c7d8852b890ee4020e14c] # to [65fc3696459523e1a49b234c23760af3f6c361b1] # # patch "merge_roster.hh" # from [c721929e38b641375ea2b5ac1ae2fdd081e88882] # to [4624e3f09d3b3079bbce87d55b7449410cc65cc3] # # patch "monotone.texi" # from [74114cc5012ae25e3f1b7d523200f0b11fec78ec] # to [603105e645eac69b38e321cdc0daed4037708782] # # patch "tests/resolve_conflicts_all_resolutions/conflicts-resolved" # from [bbfb68dde1ac7c4394118c6efa86ef722167183b] # to [9bf71467379c69188e16ed3f0a1b9b2368c4dc8b] # # patch "tests/resolve_conflicts_content/conflicts-2" # from [257ff33f262f63e892785c5b98f5f998ca8e6adf] # to [43c4ca47a7c43059cb50aa4a3f91a878480f8955] # # patch "tests/resolve_conflicts_read_all/missing-root_left" # from [6fd2fb1fb92b77814c448d18b1f5ed64b3229ede] # to [09a9ca0a21242133b294121ed97973c4bbb20c49] # # patch "tests/resolve_conflicts_read_all/missing-root_right" # from [e09bcaac9f0d6f89f1b3bd1c043bb4688bf4e9f9] # to [8fac84c4bd01af269c29280eddbee8d70583e07f] # # patch "tests/resolve_conflicts_read_all/orphaned-add_left" # from [a068d1a4c11421001558744eaeb80b2e7f8ce681] # to [3b33412a97a5afe1e8b3156aea17e00ef0d0e919] # # patch "tests/resolve_conflicts_read_all/orphaned-add_right" # from [b9474d3cac17c784aa281da05e298484761450a5] # to [3b33412a97a5afe1e8b3156aea17e00ef0d0e919] # # patch "tests/resolve_conflicts_read_all/orphaned-rename_left" # from [194f30324d2357dde21f3c3d35be062cad06b886] # to [3b33412a97a5afe1e8b3156aea17e00ef0d0e919] # # patch "tests/resolve_conflicts_read_all/orphaned-rename_right" # from [2f23f8d495759525ba537e8b75f9f1d17b794042] # to [1417be342db3cf881af2b08633c0b40ae928ad07] # ============================================================ --- tests/resolve_conflicts_orphaned_file/__driver__.lua c9a7317754a51e9586460e6f6b0c40087cba0195 +++ tests/resolve_conflicts_orphaned_file/__driver__.lua c9a7317754a51e9586460e6f6b0c40087cba0195 @@ -0,0 +1,105 @@ +-- Test resolving orphaned_file and orphaned_directory conflicts + +mtn_setup() + +addfile("foo", "foo base") +mkdir("stuff") +addfile("stuff/file1", "file1 1") +commit("testbranch", "base") +base = base_revision() + +check(mtn("rm", "stuff/file1"), 0, false, false) +check(mtn("rm", "stuff"), 0, false, false) +commit("testbranch", "right 1") +right_1 = base_revision() + +revert_to(base) + +addfile("stuff/file2", "file2 1") +addfile("stuff/file3", "file3 1") +mkdir("stuff/dir1") +addfile("stuff/dir1/file4", "file4") +mkdir("stuff/dir2") +addfile("stuff/dir2/file5", "file5") +mkdir("stuff/dir3") +check(mtn("add", "stuff/dir3"), 0, nil, false) +commit("testbranch", "left 1") +left_1 = base_revision() + +check(mtn("conflicts", "store"), 0, nil, nil) + +-- Check suggested resolutions for orphaned directory +check(mtn("conflicts", "show_first"), 0, nil, true) +check( +"mtn: orphaned node stuff/dir1\n" .. +"mtn: possible resolutions:\n" .. +"mtn: resolve_first drop\n" .. +"mtn: resolve_first rename \"file_name\"\n" == readfile("stderr")) + +-- stuff/dir1 => dir1 +check(mtn("conflicts", "resolve_first", "rename", "dir1"), 0, nil, nil) + +-- stuff/dir2 => dropped (later gives error due to not empty) +check(mtn("conflicts", "show_first"), 0, nil, true) +check(qgrep("orphaned node stuff/dir2", "stderr")); +check(mtn("conflicts", "resolve_first", "drop"), 0, nil, nil) + +-- stuff/dir3 => dropped +check(mtn("conflicts", "show_first"), 0, nil, true) +check(qgrep("orphaned node stuff/dir3", "stderr")); +check(mtn("conflicts", "resolve_first", "drop"), 0, nil, nil) + +-- Check suggested resolutions for orphaned file +check(mtn("conflicts", "show_first"), 0, nil, true) +check( +"mtn: orphaned node stuff/file2\n" .. +"mtn: possible resolutions:\n" .. +"mtn: resolve_first drop\n" .. +"mtn: resolve_first rename \"file_name\"\n" == readfile("stderr")) + +-- stuff/file2 => file2 +check(mtn("conflicts", "resolve_first", "rename", "file2"), 0, nil, nil) + +-- stuff/file3 => dropped +check(mtn("conflicts", "show_first"), 0, nil, true) +check(qgrep("orphaned node stuff/file3", "stderr")); +check(mtn("conflicts", "resolve_first", "drop"), 0, nil, nil) + +check(mtn("merge", "--resolve-conflicts"), 1, nil, true) +check(qgrep("directory stuff/dir2; it is not empty", "stderr")); + +check(mtn("drop", "stuff/dir2/file5"), 0, nil, false) +commit("testbranch", "right 2") +right_2 = base_revision() + +-- and now we start the resolution process over again +check(mtn("conflicts", "store"), 0, nil, nil) +check(mtn("conflicts", "show_first"), 0, nil, true) +check(qgrep("orphaned node stuff/dir1", "stderr")); +check(mtn("conflicts", "resolve_first", "rename", "dir1"), 0, nil, nil) + +check(mtn("conflicts", "show_first"), 0, nil, true) +check(qgrep("orphaned node stuff/dir2", "stderr")); +check(mtn("conflicts", "resolve_first", "drop"), 0, nil, nil) + +check(mtn("conflicts", "show_first"), 0, nil, true) +check(qgrep("orphaned node stuff/dir3", "stderr")); +check(mtn("conflicts", "resolve_first", "drop"), 0, nil, nil) + +check(mtn("conflicts", "show_first"), 0, nil, true) +check(qgrep("orphaned node stuff/file2", "stderr")); +check(mtn("conflicts", "resolve_first", "rename", "file2"), 0, nil, nil) + +check(mtn("conflicts", "show_first"), 0, nil, true) +check(qgrep("orphaned node stuff/file3", "stderr")); +check(mtn("conflicts", "resolve_first", "drop"), 0, nil, nil) + +check(mtn("merge", "--resolve-conflicts"), 0, nil, true) +check(mtn("update"), 0, nil, true) +check(exists("file2")) +check(not exists("file3")) +check(exists("dir1")) +check(not exists("dir2")) +check(not exists("stuff")) + +-- end of file ============================================================ --- NEWS a552479773f4a0de26f6656074ba186228026bb3 +++ NEWS a5907378a44fd492ced099c2248511f3fcd8f04e @@ -29,6 +29,13 @@ _MTN/resolutions/, so the action can succeed, and the user can recover the files if necessary. + - Resolution of orphaned file conflicts is now supported by + 'merge --resolve-conflicts' and the 'conflicts' commands. + + - The 'resolved_user' conflict resolution is no longer + reported by 'automate show_conflicts' for file content + conflicts; 'resolved_user_left' is used instead. + Bugs fixed - Monotone now sanely skips paths with invalid characters ============================================================ --- cmd_conflicts.cc 6bc6f92f1e233d26271ad61d32fa7d355d35a585 +++ cmd_conflicts.cc ba7f076aeb967031dab8c0ff7487c7f61c8fb138 @@ -54,6 +54,36 @@ show_conflicts(database & db, conflicts_ { // Go thru the conflicts we know how to resolve in the same order // merge.cc resolve_merge_conflicts outputs them. + for (std::vector::iterator i = conflicts.result.orphaned_node_conflicts.begin(); + i != conflicts.result.orphaned_node_conflicts.end(); + ++i) + { + orphaned_node_conflict & conflict = *i; + + if (conflict.resolution.first == resolve_conflicts::none) + { + file_path name; + if (conflicts.left_roster->has_node(conflict.nid)) + conflicts.left_roster->get_name(conflict.nid, name); + else + conflicts.right_roster->get_name(conflict.nid, name); + + P(F("orphaned node %s") % name); + + switch (show_case) + { + case first: + P(F("possible resolutions:")); + P(F("resolve_first drop")); + P(F("resolve_first rename \"file_name\"")); + return; + + case remaining: + break; + } + } + } + for (std::vector::iterator i = conflicts.result.duplicate_name_conflicts.begin(); i != conflicts.result.duplicate_name_conflicts.end(); ++i) @@ -281,6 +311,36 @@ set_first_conflict(database & db, if (side == neither) { + for (std::vector::iterator i = conflicts.result.orphaned_node_conflicts.begin(); + i != conflicts.result.orphaned_node_conflicts.end(); + ++i) + { + orphaned_node_conflict & conflict = *i; + + if (conflict.resolution.first == resolve_conflicts::none) + { + if ("drop" == idx(args,0)()) + { + E(args.size() == 1, origin::user, F("wrong number of arguments")); + + conflict.resolution.first = resolve_conflicts::drop; + } + else if ("rename" == idx(args,0)()) + { + E(args.size() == 2, origin::user, F("wrong number of arguments")); + + conflict.resolution.first = resolve_conflicts::rename; + conflict.resolution.second = new_optimal_path(idx(args,1)(), false); + } + else + { + E(false, origin::user, + F(conflict_resolution_not_supported_msg) % idx(args,0) % "orphaned_node"); + } + return; + } + } + for (std::vector::iterator i = conflicts.result.file_content_conflicts.begin(); i != conflicts.result.file_content_conflicts.end(); ++i) ============================================================ --- merge_conflict.cc 5a0307cd2d52e0fe6201428bda86121cdeea515a +++ merge_conflict.cc c76a564607a50a2c6b16b72f478f4346724638ed @@ -68,7 +68,6 @@ namespace symbol const resolved_internal("resolved_internal"); symbol const resolved_rename_left("resolved_rename_left"); symbol const resolved_rename_right("resolved_rename_right"); - symbol const resolved_user("resolved_user"); symbol const resolved_user_left("resolved_user_left"); symbol const resolved_user_right("resolved_user_right"); symbol const right("right"); @@ -395,10 +394,15 @@ static void enum side_t {left_side, right_side}; static void -put_duplicate_name_resolution(basic_io::stanza & st, - side_t side, - resolve_conflicts::file_resolution_t const & resolution) +put_resolution(basic_io::stanza & st, + side_t side, + resolve_conflicts::file_resolution_t const & resolution) { + // We output any resolution for any conflict; only valid resolutions + // should get into the data structures. To enforce that, when reading + // resolutions from files we check that the resolution is valid for the + // conflict. Hence there is no read_resolution. + switch (resolution.first) { case resolve_conflicts::none: @@ -417,6 +421,10 @@ put_duplicate_name_resolution(basic_io:: } break; + case resolve_conflicts::content_internal: + st.push_symbol(syms::resolved_internal); + break; + case resolve_conflicts::rename: switch (side) { @@ -487,22 +495,6 @@ put_content_conflict (basic_io::stanza & file_id right_fid; db_adaptor.db.get_file_content (db_adaptor.right_rid, conflict.nid, right_fid); st.push_binary_pair(syms::right_file_id, right_fid.inner()); - switch (conflict.resolution.first) - { - case resolve_conflicts::none: - break; - - case resolve_conflicts::content_internal: - st.push_symbol(syms::resolved_internal); - break; - - case resolve_conflicts::content_user: - st.push_str_pair(syms::resolved_user, conflict.resolution.second->as_external()); - break; - - default: - I(false); - } } else { @@ -510,17 +502,8 @@ put_content_conflict (basic_io::stanza & st.push_str_pair(syms::ancestor_name, ancestor_name.as_external()); st.push_file_pair(syms::left_name, left_name); st.push_file_pair(syms::right_name, right_name); - - switch (conflict.resolution.first) - { - case resolve_conflicts::none: - break; - - default: - // not implemented yet - I(false); - } } + put_resolution (st, left_side, conflict.resolution); } static void @@ -985,7 +968,10 @@ roster_merge_result::report_orphaned_nod I(false); if (basic_io) - put_stanza (st, output); + { + put_resolution (st, left_side, conflict.resolution); + put_stanza (st, output); + } } } @@ -1220,8 +1206,8 @@ roster_merge_result::report_duplicate_na if (basic_io) { - put_duplicate_name_resolution (st, left_side, conflict.left_resolution); - put_duplicate_name_resolution (st, right_side, conflict.right_resolution); + put_resolution (st, left_side, conflict.left_resolution); + put_resolution (st, right_side, conflict.right_resolution); put_stanza(st, output); } } @@ -1634,6 +1620,27 @@ read_orphaned_node_conflict(basic_io::pa pars.esym(syms::ancestor_name); pars.str(); read_added_rename_conflict_left(pars, left_roster, conflict.nid, conflict.parent_name); } + + // check for a resolution + if ((!pars.symp (syms::conflict)) && pars.tok.in.lookahead != EOF) + { + if (pars.symp (syms::resolved_drop_left)) + { + conflict.resolution.first = resolve_conflicts::drop; + pars.sym(); + } + else if (pars.symp (syms::resolved_rename_left)) + { + conflict.resolution.first = resolve_conflicts::rename; + pars.sym(); + conflict.resolution.second = new_optimal_path(pars.token, true); + pars.str(); + } + else + E(false, origin::user, + F(conflict_resolution_not_supported_msg) % pars.token % "orphaned_node"); + } + } // read_orphaned_node_conflict static void @@ -1657,7 +1664,44 @@ read_orphaned_node_conflicts(basic_io::p } } // read_orphaned_node_conflicts +static void +validate_orphaned_node_conflicts(basic_io::parser & pars, + std::vector & conflicts, + roster_t const & left_roster, + roster_t const & right_roster) +{ + for (std::vector::iterator i = conflicts.begin(); + i != conflicts.end(); + ++i) + { + orphaned_node_conflict & merge_conflict = *i; + orphaned_node_conflict file_conflict; + if (pars.symp (syms::orphaned_directory) || pars.symp (syms::orphaned_file)) + { + pars.sym(); + read_orphaned_node_conflict(pars, file_conflict, left_roster, right_roster); + } + else + E(false, origin::user, F("expected orphaned_directory or orphaned_file, found %s") % pars.token); + + E(merge_conflict.nid == file_conflict.nid, origin::user, + F(conflicts_mismatch_msg)); + + merge_conflict.resolution = file_conflict.resolution; + + if (pars.tok.in.lookahead != EOF) + pars.esym (syms::conflict); + else + { + std::vector::iterator tmp = i; + E(++tmp == conflicts.end(), origin::user, + F("conflicts file does not match current conflicts")); + } + } +} // validate_orphaned_node_conflicts + + static void read_multiple_name_conflict(basic_io::parser & pars, multiple_name_conflict & conflict, @@ -1944,7 +1988,7 @@ read_file_content_conflict(basic_io::par conflict.resolution.first = resolve_conflicts::content_internal; pars.sym(); } - else if (pars.symp (syms::resolved_user)) + else if (pars.symp (syms::resolved_user_left)) { conflict.resolution.first = resolve_conflicts::content_user; pars.sym(); @@ -2024,7 +2068,7 @@ read_conflict_file_core(basic_io::parser // If we are validating, there must be one stanza in the file for each // conflict; otherwise something has changed since the file was // regenerated. So we go thru the conflicts in the same order they are - // generated; see merge.cc resolve_merge_conflicts. + // generated; see merge_content.cc resolve_merge_conflicts. if (validate) { @@ -2034,12 +2078,13 @@ read_conflict_file_core(basic_io::parser I(!result.missing_root_conflict); I(result.invalid_name_conflicts.size() == 0); I(result.directory_loop_conflicts.size() == 0); - I(result.orphaned_node_conflicts.size() == 0); I(result.multiple_name_conflicts.size() == 0); I(result.attribute_conflicts.size() == 0); - // These are the ones we know how to resolve. + // These are the ones we know how to resolve. They must be in the same + // order as non-validate, below. + validate_orphaned_node_conflicts(pars, result.orphaned_node_conflicts, left_roster, right_roster); validate_duplicate_name_conflicts(pars, result.duplicate_name_conflicts, left_roster, right_roster); validate_file_content_conflicts(pars, result.file_content_conflicts, left_roster, right_roster); } @@ -2224,6 +2269,71 @@ attach_node (lua_hooks & lua, } // attach_node +void +roster_merge_result::resolve_orphaned_node_conflicts(lua_hooks & lua, + roster_t const & left_roster, + roster_t const & right_roster, + content_merge_adaptor & adaptor) +{ + MM(left_roster); + MM(right_roster); + MM(this->roster); // New roster + + // Conflict nodes are present but detached (without filenames) in the new + // roster. The resolution is either to suture the two files together, or to + // rename one or both. + + for (std::vector::const_iterator i = orphaned_node_conflicts.begin(); + i != orphaned_node_conflicts.end(); + ++i) + { + orphaned_node_conflict const & conflict = *i; + MM(conflict); + + file_path name; + + if (left_roster.has_node(conflict.nid)) + { + left_roster.get_name(conflict.nid, name); + } + else + { + right_roster.get_name(conflict.nid, name); + } + + switch (conflict.resolution.first) + { + case resolve_conflicts::drop: + if (is_dir_t(roster.get_node(conflict.nid))) + { + E(downcast_to_dir_t(roster.get_node(conflict.nid))->children.empty(), origin::user, + F("can't drop directory %s; it is not empty") % name); + } + + P(F("dropping %s") % name); + roster.drop_detached_node(conflict.nid); + break; + + case resolve_conflicts::rename: + P(F("renaming %s to %s") % name % *conflict.resolution.second); + attach_node + (lua, roster, conflict.nid, file_path_internal (conflict.resolution.second->as_internal())); + break; + + case resolve_conflicts::none: + E(false, origin::user, + F("no resolution provided for orphaned_node %s") % name); + break; + + default: + E(false, origin::user, + F("invalid resolution for orphaned_node %s") % name); + } + } // end for + + orphaned_node_conflicts.clear(); +} + static void resolve_duplicate_name_one_side(lua_hooks & lua, resolve_conflicts::file_resolution_t const & resolution, ============================================================ --- merge_content.cc 758caf01d627a675e28dd169289c9f15fa69433e +++ merge_content.cc f7ab6793b8cf55a9b1774d8c94386b6df32c2b08 @@ -1,5 +1,5 @@ // Copyright (C) 2008 Nathaniel Smith -// 2008 Stephen Leake +// 2008, 2009 Stephen Leake // // This program is made available under the GNU GPL version 2.0 or // greater. See the accompanying file COPYING for details. @@ -670,14 +670,13 @@ resolve_merge_conflicts(lua_hooks & lua, F(msg) % "invalid_name_conflicts"); E(result.directory_loop_conflicts.size() == 0, origin::user, F(msg) % "directory_loop_conflicts"); - E(result.orphaned_node_conflicts.size() == 0, origin::user, - F(msg) % "orphaned_node_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. + result.resolve_orphaned_node_conflicts(lua, left_roster, right_roster, adaptor); result.resolve_duplicate_name_conflicts(lua, left_roster, right_roster, adaptor); result.resolve_file_content_conflicts(lua, left_roster, right_roster, adaptor); } ============================================================ --- merge_roster.cc 0350ccbd3b9b7d79f93c7d8852b890ee4020e14c +++ merge_roster.cc 65fc3696459523e1a49b234c23760af3f6c361b1 @@ -183,7 +183,6 @@ roster_merge_result::count_unsupported_r return (missing_root_conflict ? 1 : 0) + invalid_name_conflicts.size() + directory_loop_conflicts.size() - + orphaned_node_conflicts.size() + multiple_name_conflicts.size() + attribute_conflicts.size(); } ============================================================ --- merge_roster.hh c721929e38b641375ea2b5ac1ae2fdd081e88882 +++ merge_roster.hh 4624e3f09d3b3079bbce87d55b7449410cc65cc3 @@ -1,5 +1,5 @@ // Copyright (C) 2005 Nathaniel Smith -// 2008 Stephen Leake +// 2008, 2009 Stephen Leake // // This program is made available under the GNU GPL version 2.0 or // greater. See the accompanying file COPYING for details. @@ -68,6 +68,9 @@ struct orphaned_node_conflict // parent_name is the name of the orphaned node, in the parent revision // where it exists. parent_name.first is the directory containing // parent_name.second + + resolve_conflicts::file_resolution_t resolution; + }; // our general strategy is to return a (possibly insane) roster, and a list of @@ -208,6 +211,11 @@ struct roster_merge_result content_merge_adaptor & adaptor, bool const basic_io, std::ostream & output) const; + void resolve_orphaned_node_conflicts(lua_hooks & lua, + roster_t const & left_roster, + roster_t const & right_roster, + content_merge_adaptor & adaptor); + void report_multiple_name_conflicts(roster_t const & left, roster_t const & right, content_merge_adaptor & adaptor, ============================================================ --- monotone.texi 74114cc5012ae25e3f1b7d523200f0b11fec78ec +++ monotone.texi 603105e645eac69b38e321cdc0daed4037708782 @@ -3315,7 +3315,9 @@ @subheading Orphaned Node Conflict in both merge parents, or that has been added in the revision containing the orphaned files or directories. address@hidden does not yet support resolving this conflict. address@hidden supports resolving this conflict. However, if the +orphaned node is a directory that is not empty, the user must handle +the directory contents first, before invoking the conflicts commands. @subheading Multiple Name Conflict @@ -4858,7 +4860,7 @@ @subsection Conflicts convenient way to clean up. @end ftable -For single file conflicts, there are two possible resolutions: +For single file conflicts, there are several possible resolutions: @ftable @command @item interactive @var{file} @@ -4875,6 +4877,21 @@ @subsection Conflicts This inserts a @var{resolved_user file} conflict resolution in the conflicts file. + address@hidden drop +The file is dropped in the merge. This is useful for an orphaned file +conflict. + +This inserts a @var{resolved_drop_left} conflict resolution in the +conflicts file. + address@hidden rename @var{filename} +The file is renamed. This is useful for an orphaned file +conflict. + +This inserts a @var{resolved_rename_left filename} conflict resolution +in the conflicts file. + @end ftable For two file conflicts, the possible resolutions are: @@ -9041,6 +9058,10 @@ @section Automation @itemize @item +11.0 -- Add resolution for orphaned node conflicts. Deleted address@hidden conflict resolution; use @code{resolved_*_left} +for single file conflicts. address@hidden 9.0 -- Added default resolution for file content conflicts, user resolutions for others. @code{directory_loop_created} changed to @code{directory_loop}. @item @@ -9288,10 +9309,10 @@ @section Automation resolved_internal resolved_rename_left file resolved_rename_right file - resolved_user file resolved_user_left file resolved_user_right file @end verbatim +For single file conflicts, the @code{resolved_*_left} resolution name is used. @xref{Conflicts}, for more information on conflict resolutions. @@ -9489,8 +9510,7 @@ @section RCS @page address@hidden GIT, ,RCS, Command Reference - address@hidden GIT, , RCS, Command Reference @section GIT @ftable @command ============================================================ --- tests/resolve_conflicts_all_resolutions/conflicts-resolved bbfb68dde1ac7c4394118c6efa86ef722167183b +++ tests/resolve_conflicts_all_resolutions/conflicts-resolved 9bf71467379c69188e16ed3f0a1b9b2368c4dc8b @@ -32,15 +32,15 @@ resolved_rename_right "thermostat-honeyw resolved_rename_left "thermostat-westinghouse.c" resolved_rename_right "thermostat-honeywell.c" - conflict content - node_type "file" - ancestor_name "interactive_file" -ancestor_file_id [c0377dbf53083e56aec683b6f54790321963ac62] - left_name "interactive_file" - left_file_id [942f274ea0d3ef68b821d67f8b01f79d17cfbf8f] - right_name "interactive_file" - right_file_id [f5545d552609d36494a195deee7f9df617cb3443] - resolved_user "_MTN/resolutions/interactive_file" + conflict content + node_type "file" + ancestor_name "interactive_file" + ancestor_file_id [c0377dbf53083e56aec683b6f54790321963ac62] + left_name "interactive_file" + left_file_id [942f274ea0d3ef68b821d67f8b01f79d17cfbf8f] + right_name "interactive_file" + right_file_id [f5545d552609d36494a195deee7f9df617cb3443] +resolved_user_left "_MTN/resolutions/interactive_file" conflict content node_type "file" @@ -52,12 +52,12 @@ resolved_internal right_file_id [b70b9605783c1c4195f490dd0feafc743731478c] resolved_internal - conflict content - node_type "file" - ancestor_name "user_file" -ancestor_file_id [25ed8e31b995bb927966616df2a42b979a2717f0] - left_name "user_file" - left_file_id [5ce20f4b9a1da51992d03488cd0be4874324db75] - right_name "user_file" - right_file_id [faa330de9182327a12ef9c7e5eaa0bea7f74ecad] - resolved_user "resolutions/user_file" + conflict content + node_type "file" + ancestor_name "user_file" + ancestor_file_id [25ed8e31b995bb927966616df2a42b979a2717f0] + left_name "user_file" + left_file_id [5ce20f4b9a1da51992d03488cd0be4874324db75] + right_name "user_file" + right_file_id [faa330de9182327a12ef9c7e5eaa0bea7f74ecad] +resolved_user_left "resolutions/user_file" ============================================================ --- tests/resolve_conflicts_content/conflicts-2 257ff33f262f63e892785c5b98f5f998ca8e6adf +++ tests/resolve_conflicts_content/conflicts-2 43c4ca47a7c43059cb50aa4a3f91a878480f8955 @@ -1,4 +1,5 @@ - left [36cfb5960784df07636cc9d119617326fe87c3f6] + +left [36cfb5960784df07636cc9d119617326fe87c3f6] right [be155249f011e658f913c109bafd743b1bfea0fe] ancestor [574e08409c35c5c0eb6e929bf1e3abf49a8bacd4] @@ -12,22 +13,22 @@ resolved_internal right_file_id [5fd4e3cf64e24e969cfcd2380cf244aee9e52d5d] resolved_internal - conflict content - node_type "file" - ancestor_name "files/baz" -ancestor_file_id [ae708173915e11248629c18d16c96c3a34f87d16] - left_name "files/baz" - left_file_id [c438704db55b0d6f819e7e79c1622e5d757b926b] - right_name "files/baz" - right_file_id [b87f48c43f61d258cc0b12d07bd53a7ddde357a9] - resolved_user "_MTN/result/baz" + conflict content + node_type "file" + ancestor_name "files/baz" + ancestor_file_id [ae708173915e11248629c18d16c96c3a34f87d16] + left_name "files/baz" + left_file_id [c438704db55b0d6f819e7e79c1622e5d757b926b] + right_name "files/baz" + right_file_id [b87f48c43f61d258cc0b12d07bd53a7ddde357a9] +resolved_user_left "_MTN/result/baz" - conflict content - node_type "file" - ancestor_name "files/foo" -ancestor_file_id [0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33] - left_name "files/foo" - left_file_id [841e3d2ada1a56123f9efe9db0d0c045ff9e6d8f] - right_name "files/foo" - right_file_id [3506995775abf41d3cdeb1e0417bdd3bcf059395] - resolved_user "files/foo" + conflict content + node_type "file" + ancestor_name "files/foo" + ancestor_file_id [0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33] + left_name "files/foo" + left_file_id [841e3d2ada1a56123f9efe9db0d0c045ff9e6d8f] + right_name "files/foo" + right_file_id [3506995775abf41d3cdeb1e0417bdd3bcf059395] +resolved_user_left "files/foo" ============================================================ --- tests/resolve_conflicts_read_all/missing-root_left 6fd2fb1fb92b77814c448d18b1f5ed64b3229ede +++ tests/resolve_conflicts_read_all/missing-root_left 09a9ca0a21242133b294121ed97973c4bbb20c49 @@ -1,4 +1,5 @@ -mtn: warning: 2 conflicts with no supported resolutions. +mtn: orphaned node bar +mtn: warning: 1 conflict with no supported resolutions. mtn: conflict: missing root directory mtn: directory 'foo' pivoted to root on the left mtn: directory 'foo' deleted on the right ============================================================ --- tests/resolve_conflicts_read_all/missing-root_right e09bcaac9f0d6f89f1b3bd1c043bb4688bf4e9f9 +++ tests/resolve_conflicts_read_all/missing-root_right 8fac84c4bd01af269c29280eddbee8d70583e07f @@ -1,4 +1,5 @@ -mtn: warning: 2 conflicts with no supported resolutions. +mtn: orphaned node +mtn: warning: 1 conflict with no supported resolutions. mtn: conflict: missing root directory mtn: directory 'foo' deleted on the left mtn: directory 'foo' pivoted to root on the right ============================================================ --- tests/resolve_conflicts_read_all/orphaned-add_left a068d1a4c11421001558744eaeb80b2e7f8ce681 +++ tests/resolve_conflicts_read_all/orphaned-add_left 3b33412a97a5afe1e8b3156aea17e00ef0d0e919 @@ -1,4 +1 @@ -mtn: warning: 1 conflict with no supported resolutions. -mtn: conflict: orphaned file 'foo/bar' from revision efb0fbbaad55564248c9aa2d7b8154d7aa02031a -mtn: parent directory 'foo' was deleted on the right -mtn: file 'foo/baz' was added on the left +mtn: orphaned node foo/baz ============================================================ --- tests/resolve_conflicts_read_all/orphaned-add_right b9474d3cac17c784aa281da05e298484761450a5 +++ tests/resolve_conflicts_read_all/orphaned-add_right 3b33412a97a5afe1e8b3156aea17e00ef0d0e919 @@ -1,4 +1 @@ -mtn: warning: 1 conflict with no supported resolutions. -mtn: conflict: orphaned file 'foo/bar' from revision efb0fbbaad55564248c9aa2d7b8154d7aa02031a -mtn: parent directory 'foo' was deleted on the left -mtn: file 'foo/baz' was added on the right +mtn: orphaned node foo/baz ============================================================ --- tests/resolve_conflicts_read_all/orphaned-rename_left 194f30324d2357dde21f3c3d35be062cad06b886 +++ tests/resolve_conflicts_read_all/orphaned-rename_left 3b33412a97a5afe1e8b3156aea17e00ef0d0e919 @@ -1,4 +1 @@ -mtn: warning: 1 conflict with no supported resolutions. -mtn: conflict: orphaned file 'bar' from revision b5f52dbc0dc530adffbdd140a7de5b129cf74f29 -mtn: parent directory 'foo' was deleted on the right -mtn: file 'foo/baz' was renamed from 'bar' on the left +mtn: orphaned node foo/baz ============================================================ --- tests/resolve_conflicts_read_all/orphaned-rename_right 2f23f8d495759525ba537e8b75f9f1d17b794042 +++ tests/resolve_conflicts_read_all/orphaned-rename_right 1417be342db3cf881af2b08633c0b40ae928ad07 @@ -1,4 +1 @@ -mtn: warning: 1 conflict with no supported resolutions. -mtn: conflict: orphaned file 'bar' from revision b5f52dbc0dc530adffbdd140a7de5b129cf74f29 -mtn: parent directory 'foo' was deleted on the left -mtn: file 'foo/baz' was renamed from 'bar' on the right +mtn: orphaned node bar