# # # patch "app_state.cc" # from [3281ae9a7eb74b1cbfa4585514d735ef99f72406] # to [c360a84c19153585694de8a4f2e513a1c09c8f3a] # # patch "app_state.hh" # from [981c5dc2820c5e53e154c5c3411672bec5f99ef4] # to [c3bd73e2a38648b52f8317237902860e1f4fd754] # # patch "commands.cc" # from [97aed6eac0ce5d36656479a506aa6a1193f63aef] # to [29d646b50722a70124c3059897ecb3275f6b8a49] # # patch "restrictions.cc" # from [155a84dc00d2147928f473039efede4ad34b00b9] # to [b5729cdde64bdc8bba05b6285627e216b7ea9dc4] # # patch "work.cc" # from [78b5c36e59a153046fd843a3b848c0e6cd04786b] # to [ba756db00dcb9d22599f20c0c27c084c0f020925] # ============================================================ --- app_state.cc 3281ae9a7eb74b1cbfa4585514d735ef99f72406 +++ app_state.cc c360a84c19153585694de8a4f2e513a1c09c8f3a @@ -143,174 +143,6 @@ } void -app_state::set_restriction(path_set const & valid_paths, - vector const & paths, - bool respect_ignore) -{ - // FIXME: this was written before split_path, and only later kludged to - // work with it. Could be much tidier if written with knowledge of - // split_path. - - static file_path root = file_path_internal(""); - restrictions.clear(); - excludes.clear(); - for (vector::const_iterator i = paths.begin(); i != paths.end(); ++i) - { - file_path p = file_path_external(*i); - split_path sp; - p.split(sp); - - if (respect_ignore && lua.hook_ignore_file(p)) - { - L(F("'%s' ignored by restricted path set\n") % p); - continue; - } - - N(p == root || valid_paths.find(sp) != valid_paths.end(), - F("unknown path '%s'\n") % p); - - L(F("'%s' added to restricted path set\n") % p); - restrictions.insert(sp); - } - - for (std::set::const_iterator i = exclude_patterns.begin(); - i != exclude_patterns.end(); ++i) - { - file_path p = file_path_external(*i); - split_path sp; - p.split(sp); - - if (respect_ignore && lua.hook_ignore_file(p)) - { - L(F("'%s' ignored by excluded path set\n") % p); - continue; - } - - N(p == root || valid_paths.find(sp) != valid_paths.end(), - F("unknown path '%s'\n") % p); - - L(F("'%s' added to excluded path set\n") % p); - excludes.insert(sp); - } - - // if user supplied a depth but provided no paths - // assume current directory - if ((depth != -1) && restrictions.empty()) - { - file_path fp = file_path_external(utf8(".")); - split_path sp; - fp.split(sp); - restrictions.insert(sp); - } -} - -bool -app_state::restriction_requires_parent(split_path const & sp) -{ - file_path path(sp); - if (restrictions.empty()) - return false; - - for (path_set::const_iterator i = restrictions.begin(); - i != restrictions.end(); ++i) - { - // If sp is a parent of any member rs of the restriction, - // we want to return true. - split_path rs = *i; - if (rs.size() < sp.size()) - continue; - rs.resize(sp.size()); - if (rs == sp) - return true; - } - return false; -} - -bool -app_state::restriction_includes(split_path const & sp) -{ - // FIXME: this was written before split_path, and only later kludged to - // work with it. Could be much tidier if written with knowledge of - // split_path. - - file_path path(sp); - - static file_path root = file_path_internal(""); - split_path sp_root; - root.split(sp_root); - - if (restrictions.empty()) - { - if (!excludes.empty()) - { - if (excludes.find(sp_root) != excludes.end()) - return false; - - split_path test = sp; - - while (!test.empty()) - { - L(F("checking excluded path set for '%s'\n") % file_path(test)); - - path_set::const_iterator i = excludes.find(test); - - if (i != excludes.end()) - { - L(F("path '%s' found in excluded path set; '%s' excluded\n") - % file_path(test) % path); - return false; - } - - test.pop_back(); - } - } - return true; - } - - bool user_supplied_depth = (depth != -1); - - split_path test = sp; - long branch_depth = 0; - long max_depth = depth + 1; - - while (!test.empty()) - { - L(F("checking restricted path set for '%s'\n") % file_path(test)); - - path_set::const_iterator i = restrictions.find(test); - path_set::const_iterator j = excludes.find(test); - - if (i != restrictions.end()) - { - L(F("path '%s' found in restricted path set; '%s' included\n") - % file_path(test) % path); - return true; - } - else if (j != excludes.end()) - { - L(F("path '%s' found in excluded path set; '%s' excluded\n") - % file_path(test) % path); - return false; - } - - if (user_supplied_depth && (max_depth == branch_depth)) return false; - test.pop_back(); - ++branch_depth; - } - - // a path that normalizes to "." means that the restriction has been - // essentially cleared (all files are included). rather than be - // careful about what goes in to the restricted path set we just - // check for this special case here. - if (restrictions.find(sp_root) != restrictions.end()) - { - return (!user_supplied_depth) || (branch_depth <= max_depth); - } - - return false; -} - -void app_state::set_database(system_path const & filename) { if (!filename.empty()) db.set_filename(filename); ============================================================ --- app_state.hh 981c5dc2820c5e53e154c5c3411672bec5f99ef4 +++ app_state.hh c3bd73e2a38648b52f8317237902860e1f4fd754 @@ -53,7 +53,6 @@ std::vector revision_selectors; std::set exclude_patterns; std::vector extra_rcfiles; - path_set restrictions; path_set excludes; bool found_working_copy; long depth; @@ -90,12 +89,6 @@ void require_working_copy(std::string const & explanation = ""); void create_working_copy(system_path const & dir); - void set_restriction(path_set const & valid_paths, - std::vector const & paths, - bool respect_ignore = true); - bool restriction_requires_parent(split_path const & path); - bool restriction_includes(split_path const & path); - // Set the branch name. If you only invoke set_branch, the branch // name is not sticky (and won't be written to the working copy and // reused by subsequent monotone invocations). Commands which ============================================================ --- commands.cc 97aed6eac0ce5d36656479a506aa6a1193f63aef +++ commands.cc 29d646b50722a70124c3059897ecb3275f6b8a49 @@ -3575,6 +3575,9 @@ if (!mask.empty()) { + // TODO: stop if the restriction is pre-dated by the current roster + // i.e. the restriction's nodes are not born in the current roster + set nodes_modified; bool any_node_hit = false; select_nodes_modified_by_rev(rid, rev, roster, @@ -3604,11 +3607,6 @@ 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)); } ============================================================ --- restrictions.cc 155a84dc00d2147928f473039efede4ad34b00b9 +++ restrictions.cc b5729cdde64bdc8bba05b6285627e216b7ea9dc4 @@ -12,6 +12,14 @@ #include "safe_map.hh" #include "transforms.hh" +// TODO: add support for --depth (replace recursive boolean with depth value) +// TODO: add support for --exclude +// TODO: add check for relevant rosters to be used by log +// i.e. as log goes back through older and older rosters it may hit one that +// pre-dates any of the nodes in the restriction. the nodes that the restriction +// includes or excludes may not have been born in a sufficiently old roster. at +// this point log should stop because no earlier roster will include these nodes. + restriction::restriction(vector const & args, roster_t const & roster) { ============================================================ --- work.cc 78b5c36e59a153046fd843a3b848c0e6cd04786b +++ work.cc ba756db00dcb9d22599f20c0c27c084c0f020925 @@ -633,9 +633,11 @@ { split_path sp; new_roster.get_name(i->first, sp); - if (!app.restriction_includes(sp)) - continue; + // FIXME_RESTRICTIONS: do we need this check? + // if (!app.restriction_includes(sp)) + // continue; + node_t n = i->second; for (full_attr_map_t::const_iterator j = n->attrs.begin(); j != n->attrs.end(); ++j)