# # # patch "commands.cc" # from [8f913fd56223d99d1788a09005e6e9882ea24f18] # to [aed0ffa2eb35ca26abc0c13343572a2ebe3a28d2] # # patch "restrictions.cc" # from [c5363980c5d8986822b60bee1a7165d88f6a8a40] # to [4407d30b1d57501662af09b8f5730ec8453c3146] # # patch "restrictions.hh" # from [bbce72d5483ff1f554f69fb41f6d3a6157d6037e] # to [f50acee89f65a083acc4a25a3e34b2ba611a7a6a] # # patch "roster.cc" # from [ba50d5cdfd2c149b6151036c8eb6d8f60c64f9c7] # to [186c5e741022599d1e1b4f21dfb53f1a346602bb] # ============================================================ --- commands.cc 8f913fd56223d99d1788a09005e6e9882ea24f18 +++ commands.cc aed0ffa2eb35ca26abc0c13343572a2ebe3a28d2 @@ -1287,7 +1287,6 @@ CMD(status, N_("informative"), N_("[PATH]..."), N_("show status of working copy"), OPT_DEPTH % OPT_BRIEF) { - path_set paths; roster_t old_roster, new_roster, restricted_roster; cset included, excluded; revision_id old_rev_id; @@ -1295,20 +1294,10 @@ data tmp; app.require_working_copy(); - get_base_and_current_roster_shape(old_roster, new_roster, app); - for (vector::const_iterator i = args.begin(); i != args.end(); ++i) - { - split_path sp; - file_path_external(*i).split(sp); - paths.insert(sp); - } + restriction mask(args, old_roster, new_roster); - restriction mask; - mask.add_nodes(old_roster, paths); - mask.add_nodes(new_roster, paths); - update_current_roster_from_filesystem(new_roster, mask, app); make_restricted_csets(old_roster, new_roster, included, excluded, mask); @@ -1662,25 +1651,13 @@ static void ls_known(app_state & app, vector const & args) { - path_set paths; roster_t old_roster, new_roster; - restriction mask; app.require_working_copy(); - get_base_and_current_roster_shape(old_roster, new_roster, app); - for (vector::const_iterator i = args.begin(); i != args.end(); ++i) - { - split_path sp; - file_path_external(*i).split(sp); - paths.insert(sp); - } + restriction mask(args, new_roster); - mask.add_nodes(new_roster, paths); - - // TODO: check for invalid paths that don't exist in either roster - node_map const & nodes = new_roster.all_nodes(); for (node_map::const_iterator i = nodes.begin(); i != nodes.end(); ++i) { @@ -1704,19 +1681,10 @@ revision_set rev; roster_t old_roster, new_roster; path_set known; - path_set paths; - restriction mask; get_base_and_current_roster_shape(old_roster, new_roster, app); - for (vector::const_iterator i = args.begin(); i != args.end(); ++i) - { - split_path sp; - file_path_external(*i).split(sp); - paths.insert(sp); - } - - mask.add_nodes(new_roster, paths); + restriction mask(args, new_roster); new_roster.extract_path_set(known); @@ -1746,23 +1714,12 @@ static void find_missing(app_state & app, vector const & args, path_set & missing) { - path_set paths; roster_t old_roster, new_roster; - restriction mask; get_base_and_current_roster_shape(old_roster, new_roster, app); - for (vector::const_iterator i = args.begin(); i != args.end(); ++i) - { - split_path sp; - file_path_external(*i).split(sp); - paths.insert(sp); - } + restriction mask(args, new_roster); - mask.add_nodes(new_roster, paths); - - // TODO: check for invalid paths that don't exist in either roster - node_map const & nodes = new_roster.all_nodes(); for (node_map::const_iterator i = nodes.begin(); i != nodes.end(); ++i) { @@ -2358,25 +2315,14 @@ revision_set restricted_rev; revision_id old_rev_id, restricted_rev_id; roster_t old_roster, new_roster, restricted_roster; - path_set paths; cset included, excluded; app.make_branch_sticky(); app.require_working_copy(); - get_base_and_current_roster_shape(old_roster, new_roster, app); - for (vector::const_iterator i = args.begin(); i != args.end(); ++i) - { - split_path sp; - file_path_external(*i).split(sp); - paths.insert(sp); - } + restriction mask(args, old_roster, new_roster); - restriction mask; - mask.add_nodes(old_roster, paths); - mask.add_nodes(new_roster, paths); - update_current_roster_from_filesystem(new_roster, mask, app); make_restricted_csets(old_roster, new_roster, included, excluded, mask); @@ -2741,7 +2687,6 @@ OPT_UNIFIED_DIFF % OPT_CONTEXT_DIFF % OPT_EXTERNAL_DIFF % OPT_EXTERNAL_DIFF_ARGS) { - path_set paths; bool new_is_archived; diff_type type = app.diff_format; ostringstream header; @@ -2760,28 +2705,17 @@ else if (app.revision_selectors.size() == 1) app.require_working_copy(); - for (vector::const_iterator i = args.begin(); i != args.end(); ++i) - { - split_path sp; - file_path_external(*i).split(sp); - paths.insert(sp); - } - if (app.revision_selectors.size() == 0) { roster_t new_roster, old_roster; revision_id old_rid; get_base_and_current_roster_shape(old_roster, new_roster, app); - get_revision_id(old_rid); - restriction mask; - mask.add_nodes(old_roster, paths); - mask.add_nodes(new_roster, paths); + restriction mask(args, old_roster, new_roster); update_current_roster_from_filesystem(new_roster, mask, app); - make_restricted_csets(old_roster, new_roster, included, excluded, mask); new_is_archived = false; @@ -2803,12 +2737,9 @@ // FIXME: handle no ancestor case // N(r_new.edges.size() == 1, F("current revision has no ancestor")); - restriction mask; - mask.add_nodes(old_roster, paths); - mask.add_nodes(new_roster, paths); + restriction mask(args, old_roster, new_roster); update_current_roster_from_filesystem(new_roster, mask, app); - make_restricted_csets(old_roster, new_roster, included, excluded, mask); new_is_archived = false; @@ -2830,9 +2761,7 @@ app.db.get_roster(r_old_id, old_roster); app.db.get_roster(r_new_id, new_roster); - restriction mask; - mask.add_nodes(old_roster, paths); - mask.add_nodes(new_roster, paths); + restriction mask(args, old_roster, new_roster); // FIXME: this is *possibly* a UI bug, insofar as we // look at the restriction name(s) you provided on the command @@ -3363,13 +3292,11 @@ N_("revert file(s), dir(s) or entire working copy"), OPT_DEPTH % OPT_EXCLUDE % OPT_MISSING) { - path_set paths; roster_t old_roster, new_roster; - restriction mask; cset included, excluded; app.require_working_copy(); - + vector args_copy(args); if (app.missing) { @@ -3391,20 +3318,10 @@ } get_base_and_current_roster_shape(old_roster, new_roster, app); + restriction mask(args_copy, old_roster, new_roster); - for (vector::const_iterator i = args_copy.begin(); i != args_copy.end(); ++i) - { - split_path sp; - file_path_external(*i).split(sp); - paths.insert(sp); - } - - mask.add_nodes(old_roster, paths); - mask.add_nodes(new_roster, paths); make_restricted_csets(old_roster, new_roster, included, excluded, mask); - // TODO: check for invalid paths that don't exist in either roster - node_map const & nodes = old_roster.all_nodes(); for (node_map::const_iterator i = nodes.begin(); i != nodes.end(); ++i) { @@ -3589,11 +3506,9 @@ if (app.revision_selectors.size() == 0) app.require_working_copy("try passing a --revision to start at"); - restriction mask; - set frontier; - revision_id first_rid; + if (app.revision_selectors.size() == 0) { get_revision_id(first_rid); @@ -3612,6 +3527,8 @@ } } + restriction mask; + if (args.size() > 0) { // User wants to trace only specific files @@ -3622,28 +3539,9 @@ else app.db.get_roster(first_rid, new_roster); - path_set paths; + // FIXME_RESTRICTIONS: should this add paths from the rosters of all selected revs? - for (vector::const_iterator i = args.begin(); i != args.end(); ++i) - { - split_path 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); - } - - // TODO: check for invalid paths that don't exist in either roster + mask = restriction(args, old_roster, new_roster); } cert_name author_name(author_cert_name); ============================================================ --- restrictions.cc c5363980c5d8986822b60bee1a7165d88f6a8a40 +++ restrictions.cc 4407d30b1d57501662af09b8f5730ec8453c3146 @@ -13,11 +13,41 @@ #include "safe_map.hh" #include "transforms.hh" -using std::vector; +restriction::restriction(vector const & args, + roster_t const & roster) +{ + set_paths(args); + add_nodes(roster); + check_paths(); +} +restriction::restriction(vector const & args, + roster_t const & roster1, + roster_t const & roster2) +{ + set_paths(args); + add_nodes(roster1); + add_nodes(roster2); + check_paths(); +} + void -restriction::add_nodes(roster_t const & roster, path_set const & paths) +restriction::set_paths(vector const & args) { + L(F("setting paths with %d args") % args.size()); + + for (vector::const_iterator i = args.begin(); i != args.end(); ++i) + { + split_path sp; + file_path_external(*i).split(sp); + paths.insert(sp); + L(F("added path '%s'") % *i); + } +} + +void +restriction::add_nodes(roster_t const & roster) +{ L(F("adding nodes\n")); for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i) @@ -32,6 +62,8 @@ bool recursive = is_dir_t(node); node_id nid = node->self; + valid_paths.insert(*i); + // TODO: proper wildcard paths like foo/... // for now we always add directories recursively and files exactly @@ -62,6 +94,10 @@ // for doing a set-difference against with the full list of paths to // find those that are not legal in any roster of this restriction } + else + { + L(F("missed path '%s'") % *i); + } } } @@ -120,6 +156,26 @@ restricted_node_map[nid] |= recursive; } +void +restriction::check_paths() +{ + int bad = 0; + for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i) + { + if (valid_paths.find(*i) == valid_paths.end()) + { + bad++; + W(F("unknown path %s") % *i); + } + } + + E(bad == 0, F("%d unknown paths") % bad); +} + + +// kill everything below this line // + + static void extract_rearranged_paths(cset const & cs, path_set & paths) { @@ -337,19 +393,8 @@ editable_roster_base er(new_roster, nis); cs->apply_to(er); - path_set paths; + restriction mask(args, old_roster, new_roster); - for (vector::const_iterator i = args.begin(); i != args.end(); ++i) - { - split_path sp; - file_path_external(*i).split(sp); - paths.insert(sp); - } - - restriction mask; - mask.add_nodes(old_roster, paths); - mask.add_nodes(new_roster, paths); - // Now update any idents in the new roster update_current_roster_from_filesystem(new_roster, mask, app); ============================================================ --- restrictions.hh bbce72d5483ff1f554f69fb41f6d3a6157d6037e +++ restrictions.hh f50acee89f65a083acc4a25a3e34b2ba611a7a6a @@ -12,6 +12,7 @@ #include "vocab.hh" using std::map; +using std::vector; // between any two related revisions, A and B, there is a set of changes (a // cset) that describes the operations required to get from A to B. for example: @@ -35,15 +36,29 @@ class restriction { public: - void add_nodes(roster_t const & roster, path_set const & paths); + restriction() {} + + restriction(vector const & args, + roster_t const & roster); + + restriction(vector const & args, + roster_t const & roster1, + roster_t const & roster2); + bool includes(roster_t const & roster, node_id nid) const; bool empty() const { return restricted_node_map.empty(); } - + private: typedef map restriction_map; restriction_map restricted_node_map; - + + path_set paths; + path_set valid_paths; + + void set_paths(vector const & args); + void add_nodes(roster_t const & roster); void insert(node_id nid, bool recursive); + void check_paths(); }; void ============================================================ --- roster.cc ba50d5cdfd2c149b6151036c8eb6d8f60c64f9c7 +++ roster.cc 186c5e741022599d1e1b4f21dfb53f1a346602bb @@ -1834,27 +1834,42 @@ I(false); case parallel::in_left: - L(F("in left %d\n") % i.left_key()); if (mask.includes(from, i.left_key())) + { delta_only_in_from(from, i.left_key(), i.left_data(), included); + L(F("included left %d\n") % i.left_key()); + } else + { delta_only_in_from(from, i.left_key(), i.left_data(), excluded); + L(F("excluded left %d\n") % i.left_key()); + } break; case parallel::in_right: - L(F("in right %d\n") % i.right_key()); if (mask.includes(to, i.right_key())) + { delta_only_in_to(to, i.right_key(), i.right_data(), included); + L(F("included right %d\n") % i.right_key()); + } else + { delta_only_in_to(to, i.right_key(), i.right_data(), excluded); + L(F("excluded right %d\n") % i.right_key()); + } break; case parallel::in_both: - L(F("in both %d %d\n") % i.left_key() % i.right_key()); if (mask.includes(from, i.left_key()) || mask.includes(to, i.right_key())) + { delta_in_both(i.left_key(), from, i.left_data(), to, i.right_data(), included); + L(F("in both %d %d\n") % i.left_key() % i.right_key()); + } else + { delta_in_both(i.left_key(), from, i.left_data(), to, i.right_data(), excluded); + L(F("in both %d %d\n") % i.left_key() % i.right_key()); + } break; } }