# # # patch "commands.cc" # from [a94b5769c05c44cef8f86ddff5cf4e18c3c21938] # to [52977ffa0b3d2e9519214050ed4ce7c0648e9ac3] # # patch "database.hh" # from [a2cdd91a834be480b4567a0c713f8e88a6f8a788] # to [86b313c82724c67e30549e212cbbcd3d14a35125] # # patch "restrictions.cc" # from [16bada07dd71f3f2e1479b5365d638acda1da9b0] # to [99587c2d19e7554350c96be42ae45cb87f2943e8] # # patch "restrictions.hh" # from [85100c84ee4c672e33910afbba2d0c4558759cb7] # to [4bb92e680ba4588a887cdaaf91f392767d924ecd] # # patch "revision.cc" # from [15ae85321c01342ff77f2891a6a435b2997c650e] # to [669f88c9c229096148f67046db9b629b5f63409f] # # patch "revision.hh" # from [8863b12618d9ec380c9cea7d6f7bfa8c4ad8ad0d] # to [5fd4815970a65584ed67b234be808652f65d59c7] # # patch "roster.cc" # from [9a4c19826701e0ad7c72d317550b56cd2bd9242f] # to [4bec0e6ca6cc5cb0f64abf3a8385fb02070ff17b] # # patch "roster.hh" # from [5162a38542d92b1a6b619a4f20e3f83c10b0506c] # to [a044f3d270422283c51b933cf62a15ee01bd629b] # ============================================================ --- commands.cc a94b5769c05c44cef8f86ddff5cf4e18c3c21938 +++ commands.cc 52977ffa0b3d2e9519214050ed4ce7c0648e9ac3 @@ -3504,7 +3504,7 @@ if (app.revision_selectors.size() == 0) app.require_working_copy("try passing a --revision to start at"); - set nodes; + restriction mask; set frontier; @@ -3531,24 +3531,36 @@ { // User wants to trace only specific files roster_t old_roster, new_roster; - revision_set rev; + temp_node_id_source nis; if (app.revision_selectors.size() == 0) - get_unrestricted_working_revision_and_rosters(app, rev, old_roster, new_roster); + get_base_and_current_roster_shape(old_roster, new_roster, nis, app); else app.db.get_roster(first_rid, new_roster); - for (size_t i = 0; i < args.size(); ++i) + path_set paths; + + for (vector::const_iterator i = args.begin(); i != args.end(); ++i) { - file_path fp = file_path_external(idx(args, i)); split_path sp; - fp.split(sp); - N(new_roster.has_node(sp), + file_path_external(*i).split(sp); + paths.insert(sp); + } + + // FIXME: should this add paths from the roster all selected revs? + + mask.add_nodes(old_roster, paths); + mask.add_nodes(new_roster, paths); + + for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i) + { + file_path fp(*i); + N(old_roster.has_node(*i) || new_roster.has_node(*i), F("Unknown file '%s' for log command") % fp); - nodes.insert(new_roster.get_node(sp)->self); } - } + // TODO: check for invalid paths that don't exist in either roster + } cert_name author_name(author_cert_name); cert_name date_name(date_cert_name); @@ -3561,6 +3573,8 @@ long last = app.last; revision_set rev; + roster_t roster; + while(! frontier.empty() && (last == -1 || last > 0)) { set next_frontier; @@ -3570,7 +3584,7 @@ { revision_id rid = *i; - bool print_this = nodes.empty(); + bool print_this = mask.empty(); set< revision > parents; vector< revision > tmp; @@ -3585,31 +3599,26 @@ seen.insert(rid); app.db.get_revision(rid, rev); + app.db.get_roster(rid, roster); - if (!nodes.empty()) + if (!mask.empty()) { - set nodes_changed; - set nodes_born; + set nodes_modified; bool any_node_hit = false; - select_nodes_modified_by_rev(rid, rev, - nodes_changed, - nodes_born, + select_nodes_modified_by_rev(rid, rev, roster, + nodes_modified, app); - - // FIXME_RESTRICTIONS: this looks ok for roster restriction - - for (set::const_iterator n = nodes.begin(); n != nodes.end(); ++n) + + for (set::const_iterator n = nodes_modified.begin(); + n != nodes_modified.end(); ++n) { - if (nodes_changed.find(*n) != nodes_changed.end() - || nodes_born.find(*n) != nodes_born.end()) + // the current roster won't have deleted nodes + if (!roster.has_node(*n) || mask.includes(roster, *n)) { any_node_hit = true; break; } } - for (set::const_iterator n = nodes_born.begin(); n != nodes_born.end(); - ++n) - nodes.erase(*n); if (any_node_hit) print_this = true; @@ -3623,6 +3632,11 @@ e != rev.edges.end(); ++e) { ancestors.insert(edge_old_revision(e)); + + // TODO: limit the frontier to revisions that still contain nodes + // in the current restriction so this stops when none of the + // specified files have been born + next_frontier.insert(edge_old_revision(e)); csum.add_change_set(edge_changes(e)); } ============================================================ --- database.hh a2cdd91a834be480b4567a0c713f8e88a6f8a788 +++ database.hh 86b313c82724c67e30549e212cbbcd3d14a35125 @@ -282,10 +282,10 @@ void deltify_revision(revision_id const & rid); void get_revision(revision_id const & id, - revision_set & cs); + revision_set & cs); void get_revision(revision_id const & id, - revision_data & dat); + revision_data & dat); void put_revision(revision_id const & new_id, revision_set const & rev); ============================================================ --- restrictions.cc 16bada07dd71f3f2e1479b5365d638acda1da9b0 +++ restrictions.cc 99587c2d19e7554350c96be42ae45cb87f2943e8 @@ -73,6 +73,10 @@ node_id current = nid; + MM(roster); + + I(roster.has_node(nid)); + while (!null_node(current)) { split_path sp; ============================================================ --- restrictions.hh 85100c84ee4c672e33910afbba2d0c4558759cb7 +++ restrictions.hh 4bb92e680ba4588a887cdaaf91f392767d924ecd @@ -37,6 +37,7 @@ public: void add_nodes(roster_t const & roster, path_set const & paths); bool includes(roster_t const & roster, node_id nid) const; + bool empty() const { return restricted_node_map.empty(); } private: typedef map restriction_map; ============================================================ --- revision.cc 15ae85321c01342ff77f2891a6a435b2997c650e +++ revision.cc 669f88c9c229096148f67046db9b629b5f63409f @@ -516,32 +516,25 @@ void select_nodes_modified_by_rev(revision_id const & rid, revision_set const & rev, - std::set & nodes_changed, - std::set & nodes_born, + roster_t const new_roster, + std::set & nodes_modified, app_state & app) { - roster_t new_roster; - marking_map mm; - nodes_changed.clear(); - nodes_born.clear(); - app.db.get_roster(rid, new_roster, mm); + nodes_modified.clear(); for (edge_map::const_iterator i = rev.edges.begin(); i != rev.edges.end(); ++i) { - std::set edge_nodes_changed, edge_nodes_born; + std::set edge_nodes_modified; roster_t old_roster; - marking_map mm2; - app.db.get_roster(edge_old_revision(i), old_roster, mm2); + app.db.get_roster(edge_old_revision(i), old_roster); select_nodes_modified_by_cset(edge_changes(i), old_roster, new_roster, - edge_nodes_changed, - edge_nodes_born); - std::copy(edge_nodes_changed.begin(), edge_nodes_changed.end(), - inserter(nodes_changed, nodes_changed.begin())); - std::copy(edge_nodes_born.begin(), edge_nodes_born.end(), - inserter(nodes_born, nodes_born.begin())); + edge_nodes_modified); + + std::copy(edge_nodes_modified.begin(), edge_nodes_modified.end(), + inserter(nodes_modified, nodes_modified.begin())); } } ============================================================ --- revision.hh 8863b12618d9ec380c9cea7d6f7bfa8c4ad8ad0d +++ revision.hh 5fd4815970a65584ed67b234be808652f65d59c7 @@ -153,8 +153,8 @@ void select_nodes_modified_by_rev(revision_id const & rid, revision_set const & rev, - std::set & nodes_changed, - std::set & nodes_born, + roster_t const roster, + std::set & nodes_modified, app_state & app); /* ============================================================ --- roster.cc 9a4c19826701e0ad7c72d317550b56cd2bd9242f +++ roster.cc 4bec0e6ca6cc5cb0f64abf3a8385fb02070ff17b @@ -1747,11 +1747,9 @@ select_nodes_modified_by_cset(cset const & cs, roster_t const & old_roster, roster_t const & new_roster, - std::set & nodes_changed, - std::set & nodes_born) + std::set & nodes_modified) { - nodes_changed.clear(); - nodes_born.clear(); + nodes_modified.clear(); path_set modified_prestate_nodes; path_set modified_poststate_nodes; @@ -1796,29 +1794,16 @@ i != modified_prestate_nodes.end(); ++i) { I(old_roster.has_node(*i)); - nodes_changed.insert(old_roster.get_node(*i)->self); + nodes_modified.insert(old_roster.get_node(*i)->self); } for (path_set::const_iterator i = modified_poststate_nodes.begin(); i != modified_poststate_nodes.end(); ++i) { I(new_roster.has_node(*i)); - nodes_changed.insert(new_roster.get_node(*i)->self); + nodes_modified.insert(new_roster.get_node(*i)->self); } - for (path_set::const_iterator i = cs.dirs_added.begin(); - i != cs.dirs_added.end(); ++i) - { - I(new_roster.has_node(*i)); - nodes_born.insert(new_roster.get_node(*i)->self); - } - - for (std::map::const_iterator i = cs.files_added.begin(); - i != cs.files_added.end(); ++i) - { - I(new_roster.has_node(i->first)); - nodes_born.insert(new_roster.get_node(i->first)->self); - } } //////////////////////////////////////////////////////////////////// ============================================================ --- roster.hh 5162a38542d92b1a6b619a4f20e3f83c10b0506c +++ roster.hh a044f3d270422283c51b933cf62a15ee01bd629b @@ -303,8 +303,7 @@ select_nodes_modified_by_cset(cset const & cs, roster_t const & old_roster, roster_t const & new_roster, - std::set & nodes_changed, - std::set & nodes_born); + std::set & nodes_modified); void classify_roster_paths(roster_t const & ros,