#
#
# patch "ChangeLog"
# from [88305775462778aa644f720ff94a615642a917cf]
# to [d7dae52d540e0a14c5efa3f2623a69e762545c5a]
#
# patch "automate.cc"
# from [e94d9b21f86d943fdeed0688b5d151be135454a3]
# to [6111b76b19325f315e922506ba45effb8bb67745]
#
# patch "inodeprint.hh"
# from [5038b686d11482660c2f1e2f8d485acdda145670]
# to [9b599b89eb011fb1f9b0fc43d095cfe7e5a6a7f7]
#
# patch "roster.hh"
# from [d35f5991b7dbd6741d2281fa0397d9b2136d2288]
# to [9865c34aef469e1b07951875a72dcdfa1b117bb9]
#
# patch "work.cc"
# from [95c5685d05ca64884882a7653f75a0bbff65f587]
# to [b481a3be180c44adb5868753e2ff121deef7fe2c]
#
# patch "work.hh"
# from [f75890d7970c1c6f41d9956f19d0b22d8882d2e1]
# to [6d5b779aa179042965356dfa2b75d8271e9d771a]
#
============================================================
--- ChangeLog 88305775462778aa644f720ff94a615642a917cf
+++ ChangeLog d7dae52d540e0a14c5efa3f2623a69e762545c5a
@@ -1,3 +1,19 @@
+2006-11-18 Derek Scherger
+
+ * automate.cc (struct inventory_itemizer): account for inodeprints
+ code moving into struct workspace; merge fixups
+ * inodeprint.hh (inodeprint_file): move declaration above
+ inodeprint_unchanged which seems to need it
+ * roster.cc (update_current_roster_from_filesystem):
+ * work.{cc,hh} (in_inodeprints_mode):
+ (read_inodeprints):
+ (write_inodeprints): make these available in struct workspace so
+ that inventory can use them
+ (inodeprint_unchanged): removed again; previously moved to
+ inodeprint.hh; merges seem to keep resurrecting this
+ (classify_roster_paths): removed again; merges seem to keep
+ resurrecting this
+
2006-11-13 Thomas Moschny
* cmd_diff_log.cc (CMD(log)): Fix-ups from last propagate nvm ->
============================================================
--- automate.cc e94d9b21f86d943fdeed0688b5d151be135454a3
+++ automate.cc 6111b76b19325f315e922506ba45effb8bb67745
@@ -620,10 +620,10 @@ struct inventory_itemizer : public tree_
inventory_itemizer(app_state & a, inventory_map & i) :
app(a), inventory(i)
{
- if (in_inodeprints_mode())
+ if (app.work.in_inodeprints_mode())
{
data dat;
- read_inodeprints(dat);
+ app.work.read_inodeprints(dat);
read_inodeprint_map(dat, ipm);
}
}
@@ -722,120 +722,133 @@ AUTOMATE(inventory, "", options::opts::n
app.require_workspace();
temp_node_id_source nis;
- roster_t base, curr;
- inventory_map inventory;
- cset cs; MM(cs);
- path_set unchanged, changed, missing, unknown, ignored;
+ roster_t old_roster, new_roster;
- app.work.get_base_and_current_roster_shape(base, curr, nis);
- make_cset(base, curr, cs);
+ app.work.get_base_and_current_roster_shape(old_roster, new_roster, nis);
- // The current roster (curr) has the complete set of registered nodes
- // conveniently with unchanged sha1 hash values.
+ inventory_map inventory;
- // The cset (cs) has the list of drops/renames/adds that have
- // occurred between the two rosters along with an empty list of
- // deltas. this list is empty only because the current roster used
- // to generate the cset does not have current hash values as
- // recorded on the filesystem (because get_..._shape was used to
- // build it).
+ inventory_rosters(old_roster, new_roster, inventory);
+ inventory_filesystem(app, inventory);
- path_set nodes_added(cs.dirs_added);
- extract_added_file_paths(cs.files_added, nodes_added);
+ basic_io::printer pr;
- inventory_pre_state(inventory, cs.nodes_deleted,
- inventory_item::DROPPED_PATH, 0);
- inventory_renames(inventory, cs.nodes_renamed);
- inventory_post_state(inventory, nodes_added,
- inventory_item::ADDED_PATH, 0);
-
- path_restriction mask;
- vector roots;
- roots.push_back(file_path());
-
- app.work.classify_roster_paths(curr, unchanged, changed, missing);
- app.work.find_unknown_and_ignored(mask, roots, unknown, ignored);
-
- inventory_node_state(inventory, unchanged,
- inventory_item::UNCHANGED_NODE);
-
- inventory_node_state(inventory, changed,
- inventory_item::PATCHED_NODE);
-
- inventory_node_state(inventory, missing,
- inventory_item::MISSING_NODE);
-
- inventory_node_state(inventory, unknown,
- inventory_item::UNKNOWN_NODE);
-
- inventory_node_state(inventory, ignored,
- inventory_item::IGNORED_NODE);
-
- // FIXME: do we want to report on attribute changes here?!?
-
- for (inventory_map::const_iterator i = inventory.begin();
- i != inventory.end(); ++i)
+ for (inventory_map::const_iterator i = inventory.begin(); i != inventory.end();
+ ++i)
{
+ basic_io::stanza st;
+ inventory_item const & item = i->second;
- string path_suffix;
+ st.push_file_pair(syms::path, i->first);
- if (curr.has_node(i->first))
+ if (item.old_node.exists)
{
- // Explicitly skip the root dir for now. The trailing / dir
- // format isn't going to work here.
- node_t n = curr.get_node(i->first);
- if (is_root_dir_t(n)) continue;
- if (is_dir_t(n)) path_suffix = "/";
+ string id = lexical_cast(item.old_node.id);
+// st.push_str_pair("old_id", lexical_cast(item.old_node.id));
+ switch (item.old_node.type)
+ {
+ case path::file: st.push_str_triple(syms::old_node, id, "file"); break;
+ case path::directory: st.push_str_triple(syms::old_node, id, "directory"); break;
+// case path::file: st.push_str_pair("old_type", "file"); break;
+// case path::directory: st.push_str_pair("old_type", "directory"); break;
+ case path::nonexistent: I(false);
+ }
}
- else if (directory_exists(file_path(i->first)))
+
+ if (item.new_node.exists)
{
- path_suffix = "/";
+ string id = lexical_cast(item.new_node.id);
+// st.push_str_pair("new_id", lexical_cast(item.new_node.id));
+ switch (item.new_node.type)
+ {
+ case path::file: st.push_str_triple(syms::new_node, id, "file"); break;
+ case path::directory: st.push_str_triple(syms::new_node, id, "directory"); break;
+// case path::file: st.push_str_pair("new_type", "file"); break;
+// case path::directory: st.push_str_pair("new_type", "directory"); break;
+ case path::nonexistent: I(false);
+ }
}
- switch (i->second.pre_state)
+ switch (item.fs_type)
{
- case inventory_item::UNCHANGED_PATH: output << " "; break;
- case inventory_item::DROPPED_PATH: output << "D"; break;
- case inventory_item::RENAMED_PATH: output << "R"; break;
- default: I(false); // invalid pre_state
+ case path::file: st.push_str_pair(syms::fs_type, "file"); break;
+ case path::directory: st.push_str_pair(syms::fs_type, "directory"); break;
+ case path::nonexistent: st.push_str_pair(syms::fs_type, "none"); break;
}
- switch (i->second.post_state)
+ if (item.fs_type == path::nonexistent)
{
- case inventory_item::UNCHANGED_PATH: output << " "; break;
- case inventory_item::RENAMED_PATH: output << "R"; break;
- case inventory_item::ADDED_PATH: output << "A"; break;
- default: I(false); // invalid post_state
+ if (item.new_node.exists)
+ st.push_str_pair(syms::status, "missing");
}
-
- switch (i->second.node_state)
+ else // exists on filesystem
{
- case inventory_item::UNCHANGED_NODE:
- if (i->second.post_state == inventory_item::ADDED_PATH)
- output << "P";
+ if (!item.new_node.exists)
+ {
+ if (app.lua.hook_ignore_file(i->first))
+ st.push_str_pair(syms::status, "ignored");
+ else
+ st.push_str_pair(syms::status, "unknown");
+ }
+ else if (item.new_node.type != item.fs_type)
+ st.push_str_pair(syms::status, "invalid");
+ // TODO: would an ls_invalid command be good for listing these paths?
else
- output << " ";
- break;
- case inventory_item::PATCHED_NODE: output << "P"; break;
- case inventory_item::UNKNOWN_NODE: output << "U"; break;
- case inventory_item::IGNORED_NODE: output << "I"; break;
- case inventory_item::MISSING_NODE: output << "M"; break;
- default: I(false); // invalid node_state
+ st.push_str_pair(syms::status, "known");
}
- output << " " << i->second.pre_id
- << " " << i->second.post_id
- << " " << i->first;
+ // note that we have three sources of information here
+ //
+ // the old roster
+ // the new roster
+ // the filesystem
+ //
+ // the new roster is synthesised from the old roster and the contents of
+ // _MTN/work and has *not* been updated with content hashes from the
+ // filesystem.
+ //
+ // one path can represent different nodes in the old and new rosters and
+ // the two different nodes can potentially be different types (file vs dir).
+ //
+ // we're interested in comparing the content and attributes of the current
+ // path in the new roster against their corresponding values in the old
+ // roster.
+ //
+ // the new content hash comes from the filesystem since the new roster has
+ // not been updated. the new attributes can come directly from the new
+ // roster.
+ //
+ // the old content hash and attributes both come from the old roster but
+ // we must use the node id of the path in the new roster to get the node
+ // from the old roster to compare against.
- // FIXME: it's possible that a directory was deleted and a file
- // was added in it's place (or vice-versa) so we need something
- // like pre/post node type indicators rather than a simple path
- // suffix! ugh.
+ if (item.new_node.exists)
+ {
+ std::vector changes;
- output << path_suffix;
+ if (item.new_node.type == path::file && old_roster.has_node(item.new_node.id))
+ {
+ file_t old_file = downcast_to_file_t(old_roster.get_node(item.new_node.id));
+ old_file->content;
+ if (item.fs_type == path::file && !(item.fs_ident == old_file->content))
+ changes.push_back("content");
+ }
- output << "\n";
+ if (old_roster.has_node(item.new_node.id))
+ {
+ node_t old_node = old_roster.get_node(item.new_node.id);
+ if (old_node->attrs != item.new_node.attrs)
+ changes.push_back("attrs");
+ }
+
+ if (!changes.empty())
+ st.push_str_multi(syms::changes, changes);
+ }
+
+ pr.print_stanza(st);
}
+
+ output.write(pr.buf.data(), pr.buf.size());
}
// Name: get_revision
============================================================
--- inodeprint.hh 5038b686d11482660c2f1e2f8d485acdda145670
+++ inodeprint.hh 9b599b89eb011fb1f9b0fc43d095cfe7e5a6a7f7
@@ -31,6 +31,8 @@ void write_inodeprint_map(inodeprint_map
void write_inodeprint_map(inodeprint_map const & ipm,
data & dat);
+bool inodeprint_file(file_path const & file, hexenc & ip);
+
inline bool
inodeprint_unchanged(inodeprint_map const & ipm, file_path const & path)
{
@@ -48,8 +50,6 @@ inodeprint_unchanged(inodeprint_map cons
}
-bool inodeprint_file(file_path const & file, hexenc & ip);
-
// Local Variables:
// mode: C++
// fill-column: 76
============================================================
--- roster.hh d35f5991b7dbd6741d2281fa0397d9b2136d2288
+++ roster.hh 9865c34aef469e1b07951875a72dcdfa1b117bb9
@@ -369,11 +369,6 @@ select_nodes_modified_by_cset(cset const
roster_t const & new_roster,
std::set & nodes_modified);
-void
-update_current_roster_from_filesystem(roster_t & ros,
-extract_roster_path_set(roster_t const & ros,
- path_set & paths);
-
// These two functions are for the use of things like 'update' or 'pluck',
// that need to construct fake rosters and/or markings in-memory, to achieve
// particular merge results.
============================================================
--- work.cc 95c5685d05ca64884882a7653f75a0bbff65f587
+++ work.cc b481a3be180c44adb5868753e2ff121deef7fe2c
@@ -351,16 +351,16 @@ workspace::get_local_dump_path(bookkeepi
// inodeprint file
-static bool
-in_inodeprints_mode()
+bool
+workspace::in_inodeprints_mode()
{
bookkeeping_path ip_path;
get_inodeprints_path(ip_path);
return file_exists(ip_path);
}
-static void
-read_inodeprints(data & dat)
+void
+workspace::read_inodeprints(data & dat)
{
I(in_inodeprints_mode());
bookkeeping_path ip_path;
@@ -368,8 +368,8 @@ read_inodeprints(data & dat)
read_data(ip_path, dat);
}
-static void
-write_inodeprints(data const & dat)
+void
+workspace::write_inodeprints(data const & dat)
{
I(in_inodeprints_mode());
bookkeeping_path ip_path;
@@ -841,88 +841,9 @@ add_parent_dirs(split_path const & dst,
build.visit_dir(dirname);
}
-inline static bool
-inodeprint_unchanged(inodeprint_map const & ipm, file_path const & path)
-{
- inodeprint_map::const_iterator old_ip = ipm.find(path);
- if (old_ip != ipm.end())
- {
- hexenc ip;
- if (inodeprint_file(path, ip) && ip == old_ip->second)
- return true; // unchanged
- else
- return false; // changed or unavailable
- }
- else
- return false; // unavailable
-}
-
// updating rosters from the workspace
-// TODO: unchanged, changed, missing might be better as set
-
-// note that this does not take a restriction because it is used only by
-// automate_inventory which operates on the entire, unrestricted, working
-// directory.
-
void
-workspace::classify_roster_paths(roster_t const & ros,
- path_set & unchanged,
- path_set & changed,
- path_set & missing)
-{
- temp_node_id_source nis;
- inodeprint_map ipm;
-
- if (in_inodeprints_mode())
- {
- data dat;
- read_inodeprints(dat);
- read_inodeprint_map(dat, ipm);
- }
-
- // this code is speed critical, hence the use of inode fingerprints so be
- // careful when making changes in here and preferably do some timing tests
-
- if (!ros.has_root())
- return;
-
- node_map const & nodes = ros.all_nodes();
- for (node_map::const_iterator i = nodes.begin(); i != nodes.end(); ++i)
- {
- node_id nid = i->first;
- node_t node = i->second;
-
- split_path sp;
- ros.get_name(nid, sp);
-
- file_path fp(sp);
-
- if (is_dir_t(node) || inodeprint_unchanged(ipm, fp))
- {
- // dirs don't have content changes
- unchanged.insert(sp);
- }
- else
- {
- file_t file = downcast_to_file_t(node);
- file_id fid;
- if (ident_existing_file(fp, fid, lua))
- {
- if (file->content == fid)
- unchanged.insert(sp);
- else
- changed.insert(sp);
- }
- else
- {
- missing.insert(sp);
- }
- }
- }
-}
-
-void
workspace::update_current_roster_from_filesystem(roster_t & ros)
{
update_current_roster_from_filesystem(ros, node_restriction());
============================================================
--- work.hh f75890d7970c1c6f41d9956f19d0b22d8882d2e1
+++ work.hh 6d5b779aa179042965356dfa2b75d8271e9d771a
@@ -193,6 +193,10 @@ struct workspace
// the 'inodeprints file' contains inode fingerprints
+ bool in_inodeprints_mode();
+ void read_inodeprints(data & dat);
+ void write_inodeprints(data const & dat);
+
void enable_inodeprints();
void maybe_update_inodeprints();