# # # patch "automate.cc" # from [52489d19dd4c75dae696c3e52859b480298d3900] # to [5f33581706b0cc4f67e4551580b12b505a4f625c] # # patch "tests/automate_inventory/__driver__.lua" # from [0f017c00f4db6c4a67af0805deffb207dc691b97] # to [16722b9eb51dbd60bfd1add6ac5850724b478215] # # patch "tests/automate_inventory_path/__driver__.lua" # from [f797cc043c33af87380b306cb7af71ad41756d81] # to [03a08e2c11507213d56341c3cee29cbdc50cf4da] # ============================================================ --- automate.cc 52489d19dd4c75dae696c3e52859b480298d3900 +++ automate.cc 5f33581706b0cc4f67e4551580b12b505a4f625c @@ -491,6 +491,9 @@ struct node_info struct node_info { bool exists; + // true if node_id is present in corresponding roster with the inventory map file_path + // false if not present, or present with a different file_path + // rest of data in this struct is invalid if false. node_id id; path::status type; file_id ident; @@ -500,28 +503,27 @@ static void }; static void -get_node_info(roster_t const & roster, file_path const & path, node_info & info) +get_node_info(node_t const & node, node_info & info) { - if (roster.has_node(path)) + info.exists = true; + info.id = node->self; + info.attrs = node->attrs; + if (is_file_t(node)) { - node_t node = roster.get_node(path); - info.exists = true; - info.id = node->self; - info.attrs = node->attrs; - if (is_file_t(node)) - { - info.type = path::file; - info.ident = downcast_to_file_t(node)->content; - } - else if (is_dir_t(node)) - info.type = path::directory; - else - I(false); + info.type = path::file; + info.ident = downcast_to_file_t(node)->content; } + else if (is_dir_t(node)) + info.type = path::directory; + else + I(false); } struct inventory_item { + // Records information about a pair of nodes with the same node_id in the + // old roster and new roster, and the corresponding path in the + // filesystem. node_info old_node; node_info new_node; file_path old_path; @@ -534,6 +536,10 @@ typedef std::map inventory_map; +// file_path will typically be an existing filesystem file, but in the case +// of a dropped or rename_source file it is only in the old roster, and in +// the case of a file added --bookkeep_only or rename_target +// --bookkeep_only, it is only in the new roster. static void inventory_rosters(roster_t const & old_roster, @@ -551,7 +557,7 @@ inventory_rosters(roster_t const & old_r { file_path fp; old_roster.get_name(i->first, fp); - get_node_info(old_roster, fp, inventory[fp].old_node); + get_node_info(old_roster.get_node(i->first), inventory[fp].old_node); old_paths[inventory[fp].old_node.id] = fp; } } @@ -563,7 +569,7 @@ inventory_rosters(roster_t const & old_r { file_path fp; new_roster.get_name(i->first, fp); - get_node_info(new_roster, fp, inventory[fp].new_node); + get_node_info(new_roster.get_node(i->first), inventory[fp].new_node); new_paths[inventory[fp].new_node.id] = fp; } } @@ -571,10 +577,22 @@ inventory_rosters(roster_t const & old_r std::map::iterator i; for (i = old_paths.begin(); i != old_paths.end(); ++i) { - // there is no new node available, i.e. this is a drop if (new_paths.find(i->first) == new_paths.end()) - continue; + { + // There is no new node available; this is either a drop or a + // rename to outside the current path restriction. + if (new_roster.has_node (i->first)) + { + // record rename outside restriction + new_roster.get_name (i->first, inventory[i->second].new_path); + continue; + } + else + // drop; no new path + continue; + } + file_path old_path(i->second); file_path new_path(new_paths[i->first]); @@ -582,6 +600,7 @@ inventory_rosters(roster_t const & old_r if (old_path == new_path) continue; + // record rename inventory[new_path].old_path = old_path; inventory[old_path].new_path = new_path; } @@ -740,6 +759,7 @@ CMD_AUTOMATE(inventory, N_("[PATH]...") } if (item.new_path.as_internal().length() > 0) + // new_path is only present if different from either inventory map path or old_path st.push_file_pair(syms::new_path, item.new_path); } @@ -801,7 +821,7 @@ CMD_AUTOMATE(inventory, N_("[PATH]...") states.push_back("dropped"); states.push_back("rename_target"); } - else + else { states.push_back("rename_source"); states.push_back("added"); ============================================================ --- tests/automate_inventory/__driver__.lua 0f017c00f4db6c4a67af0805deffb207dc691b97 +++ tests/automate_inventory/__driver__.lua 16722b9eb51dbd60bfd1add6ac5850724b478215 @@ -134,7 +134,7 @@ index = find_basic_io_line (parsed, {nam -- of the file are different between the filesystem and the new -- manifest (they are the same as the old manifest). -- --- If the user commits now, they probablyl get something other than +-- If the user commits now, they probably get something other than -- what they wanted; '--bookkeep-only' is dangerous. -- -- The 'changes' flag indicates that this was bookkeep-only. ============================================================ --- tests/automate_inventory_path/__driver__.lua f797cc043c33af87380b306cb7af71ad41756d81 +++ tests/automate_inventory_path/__driver__.lua 03a08e2c11507213d56341c3cee29cbdc50cf4da @@ -156,21 +156,14 @@ index = check_inventory (parsed, index, fs_type = "directory", status = {"known"}}) -index = fail_check_inventory (4, parsed, index, +index = check_inventory (parsed, index, { path = "dir_a/file_a", old_type = "file", - old_path = "dir_a/file_a", - new_type = "file", new_path = "dir_b/file_a", fs_type = "file", - status = {"known", "rename_source"}}) + status = {"rename_source", "unknown"}}) +-- "unknown" because of --bookkeep-only --- getting: --- path "dir_a/file_a" --- old_type "file" --- fs_type "file" --- status "dropped" "unknown" - checkexp ("checked all", #parsed, index-1) check(mtn("automate", "inventory", "dir_b"), 0, true, false) @@ -184,14 +177,13 @@ index = check_inventory (parsed, index, fs_type = "directory", status = {"known"}}) -index = fail_check_inventory (4, parsed, index, +index = check_inventory (parsed, index, { path = "dir_b/file_a", - old_type = "file", - old_path = "dir_a/file_a", new_type = "file", fs_type = "none", - status = {"renamed", "missing"}}) --- FIXME: not clear that "missing" is the right status here + status = {"added", "missing"}}) +-- _not_ "rename_target" because rename_source is outside restriction. +-- "missing" because of --bookkeep-only index = check_inventory (parsed, index, { path = "dir_b/file_b", @@ -217,13 +209,12 @@ index = check_inventory (parsed, index, fs_type = "directory", status = {"known"}}) -index = fail_check_inventory (4, parsed, index, +index = check_inventory (parsed, index, { path = "dir_a/file_a", old_type = "file", - old_path = "dir_a/file_a", - new_type = "file", new_path = "dir_b/file_a", - status = {"renamed"}}) + fs_type = "none", + status = {"rename_source"}}) checkexp ("checked all", #parsed, index-1) @@ -238,14 +229,11 @@ index = check_inventory (parsed, index, fs_type = "directory", status = {"known"}}) -index = fail_check_inventory (4, parsed, index, +index = check_inventory (parsed, index, { path = "dir_b/file_a", - old_type = "file", - old_path = "dir_a/file_a", new_type = "file", - fs_type = "none", - status = {"renamed", "missing"}}) --- FIXME: not clear that "missing" is the right status here + fs_type = "file", + status = {"added", "known"}}) index = check_inventory (parsed, index, { path = "dir_b/file_b", @@ -287,14 +275,13 @@ index = check_inventory (parsed, index, fs_type = "directory", status = {"known"}}) -index = fail_check_inventory (4, parsed, index, +index = check_inventory (parsed, index, { path = "file_0", old_type = "file", - old_name = "file_0", - new_type = "file", - new_name = "dir_a/file_0", + new_path = "dir_a/file_0", fs_type = "file", - status = {"renamed"}}) + status = {"rename_source", "unknown"}}) +-- unknown because of --bookkeep-only -- skip tester-generated files index = index + 3 * 10 @@ -332,14 +319,12 @@ index = check_inventory (parsed, index, fs_type = "directory", status = {"known"}}) -index = fail_check_inventory (4, parsed, index, -{ path = "dir_a/file_0", +index = check_inventory (parsed, index, +{ path = "file_0", old_type = "file", - old_name = "file_0", - new_type = "file", - new_name = "dir_a/file_0", - fs_type = "file", - status = {"renamed"}}) + new_path = "dir_a/file_0", + fs_type = "none", + status = {"rename_source"}}) -- skip tester-generated files index = index + 3 * 10