# # # patch "ChangeLog" # from [77a2b221cedd0257b2ee2a51f00b0d4427c15762] # to [a80d1daa4cbca5505c6a5bd8385ce23460dc8d46] # # patch "commands.cc" # from [a1d92593724eaf181710c449c7c86237e0302902] # to [9b428678da5b09d7d6359bc189a9180c7022ea33] # # patch "restrictions.cc" # from [fc4fb9645fc05eaab15ef5b1f7c7711e66142877] # to [9f39723316d3ce099ed5bcf9b49ca7f255ebff82] # # patch "restrictions.hh" # from [54a5faec54b44ad6dec5ac9aa7854467331181e6] # to [d4f5430f74e4e2747729ddeeb8d77a79a3b98a2e] # # patch "roster.cc" # from [5df4ea90dbfb38554c8d54eaecfb2faa5c11b14b] # to [c068c4d2dc8f907ad3ca9515bdc5cab7067cefe5] # # patch "roster.hh" # from [bcbbee47f188d9fa7097f91c491045d97ddf1477] # to [4b88a215d13fd7c7a4d43560ab97bd96716ee18a] # # patch "tests/t_log_dir.at" # from [f965de2bd1db78e029424b04221edf6505862c0c] # to [2749d6ae52721e0a253d61fd845da46995daf97c] # ============================================================ --- ChangeLog 77a2b221cedd0257b2ee2a51f00b0d4427c15762 +++ ChangeLog a80d1daa4cbca5505c6a5bd8385ce23460dc8d46 @@ -1,3 +1,13 @@ +2006-03-30 Derek Scherger + + * commands.cc (status, ls_changed, commit, diff, revert): call + check_restricted_cset after make_restricted_csets + * restrictions.cc: remove implicit parents gunk and update + unit tests accordingly + * roster.{cc,hh} (check_restricted_cset): new function to issue a + nice message if required directories have been excluded + * tests/t_log_dir.at: un-XFAIL + 2006-03-03 Derek Scherger * restrictions.cc (check_for_missing_additions): new function ============================================================ --- commands.cc a1d92593724eaf181710c449c7c86237e0302902 +++ commands.cc 9b428678da5b09d7d6359bc189a9180c7022ea33 @@ -1346,6 +1346,7 @@ update_current_roster_from_filesystem(new_roster, mask, app); make_restricted_csets(old_roster, new_roster, included, excluded, mask); + check_restricted_cset(old_roster, included); restricted_roster = old_roster; temp_node_id_source nis; @@ -1814,6 +1815,7 @@ update_current_roster_from_filesystem(new_roster, mask, app); make_restricted_csets(old_roster, new_roster, included, excluded, mask); + check_restricted_cset(old_roster, included); // FIXME: this would probably be better as a function of roster.cc // set nodes; @@ -2342,6 +2344,7 @@ update_current_roster_from_filesystem(new_roster, mask, app); make_restricted_csets(old_roster, new_roster, included, excluded, mask); + check_restricted_cset(old_roster, included); restricted_roster = old_roster; temp_node_id_source nis; @@ -2745,6 +2748,7 @@ update_current_roster_from_filesystem(new_roster, mask, app); make_restricted_csets(old_roster, new_roster, included, excluded, mask); + check_restricted_cset(old_roster, included); new_is_archived = false; header << "# old_revision [" << old_rid << "]" << endl; @@ -2769,6 +2773,7 @@ update_current_roster_from_filesystem(new_roster, mask, app); make_restricted_csets(old_roster, new_roster, included, excluded, mask); + check_restricted_cset(old_roster, included); new_is_archived = false; header << "# old_revision [" << r_old_id << "]" << endl; @@ -2814,6 +2819,7 @@ // since versioned paths are required to be relative. make_restricted_csets(old_roster, new_roster, included, excluded, mask); + check_restricted_cset(old_roster, included); new_is_archived = true; } @@ -3432,6 +3438,9 @@ restriction mask(includes, excludes, old_roster, new_roster, app); make_restricted_csets(old_roster, new_roster, included, excluded, mask); + // the included cset will be thrown away (reverted) leaving the excluded + // cset pending in MTN/work which must be valid against the old roster + check_restricted_cset(old_roster, excluded); node_map const & nodes = old_roster.all_nodes(); for (node_map::const_iterator i = nodes.begin(); i != nodes.end(); ++i) ============================================================ --- restrictions.cc fc4fb9645fc05eaab15ef5b1f7c7711e66142877 +++ restrictions.cc 9f39723316d3ce099ed5bcf9b49ca7f255ebff82 @@ -15,10 +15,6 @@ using std::make_pair; using std::set; -// TODO: add support for --depth (replace recursive boolean with depth value) -// depth really only makes sense when one directory is specified however. it would -// be much better to support foo/... style recursive paths - // 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 @@ -37,23 +33,7 @@ } } -// FIXME: should we really be doing implicit includes of parents? static void -get_parent_paths(path_set const & paths, path_set & parents) -{ - for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i) - { - split_path sp(*i); - sp.pop_back(); - while (!sp.empty() && parents.find(sp) == parents.end()) - { - parents.insert(sp); - sp.pop_back(); - } - } -} - -static void get_nodes(path_set const & paths, roster_t const & roster, set & nodes, path_set & known_paths) @@ -69,24 +49,6 @@ } } -// FIXME: should we really be doing implicit includes of parents? -static void -get_parent_nodes(set const & nodes, - roster_t const & roster, - set & parents) -{ - for (set::const_iterator i = nodes.begin(); i != nodes.end(); ++i) - { - I(roster.has_node(*i)); - node_id nid = roster.get_node(*i)->parent; - while (!null_node(nid)) - { - parents.insert(nid); - nid = roster.get_node(nid)->parent; - } - } -} - static void merge_states(path_state const & old_state, path_state const & new_state, @@ -97,26 +59,6 @@ { merged_state = old_state; } - else if (old_state == explicit_include && new_state == implicit_include || - old_state == implicit_include && new_state == explicit_include) - { - merged_state = explicit_include; - } - else if (old_state == explicit_exclude && new_state == implicit_include || - old_state == implicit_include && new_state == explicit_exclude) - { - // FIXME: should we really be doing implicit includes of parents? - - // allowing a mix of explicit excludes and implicit includes on a path is - // rather questionable but is required by things like exclude x include - // x/y. (i.e. includes within excludes) these are also somewhat - // questionable themselves since they are equivalent to simply include - // x/y. - // - // this is also required more sensible things like include x exclude x/y - // include x/y/z. - merged_state = implicit_include; - } else { L(FL("path '%s' %d %d") % sp % old_state % new_state); @@ -182,35 +124,27 @@ make_path_set(include_args, included_paths); make_path_set(exclude_args, excluded_paths); - path_set parent_paths; - get_parent_paths(included_paths, parent_paths); + add_paths(path_map, included_paths, included); + add_paths(path_map, excluded_paths, excluded); - add_paths(path_map, included_paths, explicit_include); - add_paths(path_map, excluded_paths, explicit_exclude); - add_paths(path_map, parent_paths, implicit_include); - - L(FL("restriction paths: %d included; %d excluded; %d parents") + L(FL("restriction paths: %d included; %d excluded") % included_paths.size() - % excluded_paths.size() - % parent_paths.size()); + % excluded_paths.size()); } void restriction::map_nodes(roster_t const & roster) { - set included_nodes, excluded_nodes, parent_nodes; + set included_nodes, excluded_nodes; get_nodes(included_paths, roster, included_nodes, known_paths); get_nodes(excluded_paths, roster, excluded_nodes, known_paths); - get_parent_nodes(included_nodes, roster, parent_nodes); - add_nodes(node_map, roster, included_nodes, explicit_include); - add_nodes(node_map, roster, excluded_nodes, explicit_exclude); - add_nodes(node_map, roster, parent_nodes, implicit_include); + add_nodes(node_map, roster, included_nodes, included); + add_nodes(node_map, roster, excluded_nodes, excluded); - L(FL("restriction nodes: %d included; %d excluded; %d parents") + L(FL("restriction nodes: %d included; %d excluded") % included_nodes.size() - % excluded_nodes.size() - % parent_nodes.size()); + % excluded_nodes.size()); } void @@ -270,10 +204,11 @@ node_id current = nid; int depth = 0; - // use app.depth+1 here because the old semantics of depth=0 were something - // like "the current directory and its immediate children". it seems somewhat - // more reasonable here to use depth=0 to mean "exactly this directory" and - // depth=1 to mean "this directory and its immediate children" + // FIXME: this uses app.depth+1 because the old semantics of depth=0 were + // something like "the current directory and its immediate children". it seems + // somewhat more reasonable here to use depth=0 to mean "exactly this + // directory" and depth=1 to mean "this directory and its immediate children" + while (!null_node(current) && (app.depth == -1 || depth <= app.depth + 1)) { map::const_iterator r = node_map.find(current); @@ -282,21 +217,13 @@ { switch (r->second) { - case explicit_include: + case included: L(FL("explicit include of nid %d path '%s'") % current % file_path(sp)); return true; - case explicit_exclude: + case excluded: L(FL("explicit exclude of nid %d path '%s'") % current % file_path(sp)); return false; - - case implicit_include: - // this is non-recursive and requires an exact match - if (depth == 0) - { - L(FL("implicit include of nid %d path '%s'") % current % file_path(sp)); - return true; - } } } @@ -330,10 +257,11 @@ split_path current(sp); int depth = 0; - // use app.depth+1 here because the old semantics of depth=0 were something - // like "the current directory and its immediate children". it seems somewhat - // more reasonable here to use depth=0 to mean "exactly this directory" and - // depth=1 to mean "this directory and its immediate children" + // FIXME: this uses app.depth+1 because the old semantics of depth=0 were + // something like "the current directory and its immediate children". it seems + // somewhat more reasonable here to use depth=0 to mean "exactly this + // directory" and depth=1 to mean "this directory and its immediate children" + while (!current.empty() && (app.depth == -1 || depth <= app.depth + 1)) { map::const_iterator r = path_map.find(current); @@ -342,21 +270,13 @@ { switch (r->second) { - case explicit_include: + case included: L(FL("explicit include of path '%s'") % file_path(sp)); return true; - case explicit_exclude: + case excluded: L(FL("explicit exclude of path '%s'") % file_path(sp)); return false; - - case implicit_include: - // this is non-recursive and requires an exact match - if (depth == 0) - { - L(FL("implicit include of path '%s'") % file_path(sp)); - return true; - } } } @@ -612,11 +532,11 @@ BOOST_CHECK(!mask.empty()); // check restricted nodes - BOOST_CHECK( mask.includes(roster, nid_root)); + BOOST_CHECK(!mask.includes(roster, nid_root)); BOOST_CHECK(!mask.includes(roster, nid_f)); BOOST_CHECK(!mask.includes(roster, nid_g)); - BOOST_CHECK( mask.includes(roster, nid_x)); + BOOST_CHECK(!mask.includes(roster, nid_x)); BOOST_CHECK(!mask.includes(roster, nid_xf)); BOOST_CHECK(!mask.includes(roster, nid_xg)); BOOST_CHECK( mask.includes(roster, nid_xx)); @@ -626,7 +546,7 @@ BOOST_CHECK(!mask.includes(roster, nid_xyf)); BOOST_CHECK(!mask.includes(roster, nid_xyg)); - BOOST_CHECK( mask.includes(roster, nid_y)); + BOOST_CHECK(!mask.includes(roster, nid_y)); BOOST_CHECK(!mask.includes(roster, nid_yf)); BOOST_CHECK(!mask.includes(roster, nid_yg)); BOOST_CHECK(!mask.includes(roster, nid_yx)); @@ -637,11 +557,11 @@ BOOST_CHECK( mask.includes(roster, nid_yyg)); // check restricted paths - BOOST_CHECK( mask.includes(sp_root)); + BOOST_CHECK(!mask.includes(sp_root)); BOOST_CHECK(!mask.includes(sp_f)); BOOST_CHECK(!mask.includes(sp_g)); - BOOST_CHECK( mask.includes(sp_x)); + BOOST_CHECK(!mask.includes(sp_x)); BOOST_CHECK(!mask.includes(sp_xf)); BOOST_CHECK(!mask.includes(sp_xg)); BOOST_CHECK( mask.includes(sp_xx)); @@ -651,7 +571,7 @@ BOOST_CHECK(!mask.includes(sp_xyf)); BOOST_CHECK(!mask.includes(sp_xyg)); - BOOST_CHECK( mask.includes(sp_y)); + BOOST_CHECK(!mask.includes(sp_y)); BOOST_CHECK(!mask.includes(sp_yf)); BOOST_CHECK(!mask.includes(sp_yg)); BOOST_CHECK(!mask.includes(sp_yx)); @@ -746,7 +666,7 @@ BOOST_CHECK(!mask.empty()); // check restricted nodes - BOOST_CHECK( mask.includes(roster, nid_root)); + BOOST_CHECK(!mask.includes(roster, nid_root)); BOOST_CHECK(!mask.includes(roster, nid_f)); BOOST_CHECK(!mask.includes(roster, nid_g)); @@ -771,7 +691,7 @@ BOOST_CHECK(!mask.includes(roster, nid_yyg)); // check restricted paths - BOOST_CHECK( mask.includes(sp_root)); + BOOST_CHECK(!mask.includes(sp_root)); BOOST_CHECK(!mask.includes(sp_f)); BOOST_CHECK(!mask.includes(sp_g)); @@ -803,6 +723,9 @@ setup(roster); vector includes, excludes; + // note that excludes higher up the tree than the top + // include are rather pointless -- nothing above the + // top include is included anyway excludes.push_back(utf8(string("x"))); excludes.push_back(utf8(string("y"))); includes.push_back(utf8(string("x/x"))); @@ -814,11 +737,11 @@ BOOST_CHECK(!mask.empty()); // check restricted nodes - BOOST_CHECK( mask.includes(roster, nid_root)); + BOOST_CHECK(!mask.includes(roster, nid_root)); BOOST_CHECK(!mask.includes(roster, nid_f)); BOOST_CHECK(!mask.includes(roster, nid_g)); - BOOST_CHECK( mask.includes(roster, nid_x)); + BOOST_CHECK(!mask.includes(roster, nid_x)); BOOST_CHECK(!mask.includes(roster, nid_xf)); BOOST_CHECK(!mask.includes(roster, nid_xg)); BOOST_CHECK( mask.includes(roster, nid_xx)); @@ -828,7 +751,7 @@ BOOST_CHECK(!mask.includes(roster, nid_xyf)); BOOST_CHECK(!mask.includes(roster, nid_xyg)); - BOOST_CHECK( mask.includes(roster, nid_y)); + BOOST_CHECK(!mask.includes(roster, nid_y)); BOOST_CHECK(!mask.includes(roster, nid_yf)); BOOST_CHECK(!mask.includes(roster, nid_yg)); BOOST_CHECK(!mask.includes(roster, nid_yx)); @@ -839,11 +762,11 @@ BOOST_CHECK( mask.includes(roster, nid_yyg)); // check restricted paths - BOOST_CHECK( mask.includes(sp_root)); + BOOST_CHECK(!mask.includes(sp_root)); BOOST_CHECK(!mask.includes(sp_f)); BOOST_CHECK(!mask.includes(sp_g)); - BOOST_CHECK( mask.includes(sp_x)); + BOOST_CHECK(!mask.includes(sp_x)); BOOST_CHECK(!mask.includes(sp_xf)); BOOST_CHECK(!mask.includes(sp_xg)); BOOST_CHECK( mask.includes(sp_xx)); @@ -853,7 +776,7 @@ BOOST_CHECK(!mask.includes(sp_xyf)); BOOST_CHECK(!mask.includes(sp_xyg)); - BOOST_CHECK( mask.includes(sp_y)); + BOOST_CHECK(!mask.includes(sp_y)); BOOST_CHECK(!mask.includes(sp_yf)); BOOST_CHECK(!mask.includes(sp_yg)); BOOST_CHECK(!mask.includes(sp_yx)); @@ -879,24 +802,6 @@ } static void -test_get_parent_paths() -{ - path_set paths, parents; - split_path a, ab, abc; - - file_path_internal("a").split(a); - file_path_internal("a/b").split(ab); - file_path_internal("a/b/c").split(abc); - - paths.insert(abc); - get_parent_paths(paths, parents); - - BOOST_CHECK(parents.find(a) != parents.end()); - BOOST_CHECK(parents.find(ab) != parents.end()); - BOOST_CHECK(parents.find(abc) == parents.end()); -} - -static void test_include_depth_0() { roster_t roster; @@ -907,58 +812,61 @@ includes.push_back(utf8(string("y"))); app_state app; + // FIXME: depth == 0 currently means directory + immediate children + // this should be changed to mean just the named directory but for + // compatibility with old restrictions this behaviour has been preserved app.set_depth(0); restriction mask(includes, excludes, roster, app); BOOST_CHECK(!mask.empty()); // check restricted nodes - BOOST_CHECK( mask.includes(roster, nid_root)); + BOOST_CHECK(!mask.includes(roster, nid_root)); BOOST_CHECK(!mask.includes(roster, nid_f)); BOOST_CHECK(!mask.includes(roster, nid_g)); BOOST_CHECK( mask.includes(roster, nid_x)); - BOOST_CHECK(!mask.includes(roster, nid_xf)); - BOOST_CHECK(!mask.includes(roster, nid_xg)); - BOOST_CHECK(!mask.includes(roster, nid_xx)); + BOOST_CHECK( mask.includes(roster, nid_xf)); + BOOST_CHECK( mask.includes(roster, nid_xg)); + BOOST_CHECK( mask.includes(roster, nid_xx)); BOOST_CHECK(!mask.includes(roster, nid_xxf)); BOOST_CHECK(!mask.includes(roster, nid_xxg)); - BOOST_CHECK(!mask.includes(roster, nid_xy)); + BOOST_CHECK( mask.includes(roster, nid_xy)); BOOST_CHECK(!mask.includes(roster, nid_xyf)); BOOST_CHECK(!mask.includes(roster, nid_xyg)); BOOST_CHECK( mask.includes(roster, nid_y)); - BOOST_CHECK(!mask.includes(roster, nid_yf)); - BOOST_CHECK(!mask.includes(roster, nid_yg)); - BOOST_CHECK(!mask.includes(roster, nid_yx)); + BOOST_CHECK( mask.includes(roster, nid_yf)); + BOOST_CHECK( mask.includes(roster, nid_yg)); + BOOST_CHECK( mask.includes(roster, nid_yx)); BOOST_CHECK(!mask.includes(roster, nid_yxf)); BOOST_CHECK(!mask.includes(roster, nid_yxg)); - BOOST_CHECK(!mask.includes(roster, nid_yy)); + BOOST_CHECK( mask.includes(roster, nid_yy)); BOOST_CHECK(!mask.includes(roster, nid_yyf)); BOOST_CHECK(!mask.includes(roster, nid_yyg)); // check restricted paths - BOOST_CHECK( mask.includes(sp_root)); + BOOST_CHECK(!mask.includes(sp_root)); BOOST_CHECK(!mask.includes(sp_f)); BOOST_CHECK(!mask.includes(sp_g)); BOOST_CHECK( mask.includes(sp_x)); - BOOST_CHECK(!mask.includes(sp_xf)); - BOOST_CHECK(!mask.includes(sp_xg)); - BOOST_CHECK(!mask.includes(sp_xx)); + BOOST_CHECK( mask.includes(sp_xf)); + BOOST_CHECK( mask.includes(sp_xg)); + BOOST_CHECK( mask.includes(sp_xx)); BOOST_CHECK(!mask.includes(sp_xxf)); BOOST_CHECK(!mask.includes(sp_xxg)); - BOOST_CHECK(!mask.includes(sp_xy)); + BOOST_CHECK( mask.includes(sp_xy)); BOOST_CHECK(!mask.includes(sp_xyf)); BOOST_CHECK(!mask.includes(sp_xyg)); BOOST_CHECK( mask.includes(sp_y)); - BOOST_CHECK(!mask.includes(sp_yf)); - BOOST_CHECK(!mask.includes(sp_yg)); - BOOST_CHECK(!mask.includes(sp_yx)); + BOOST_CHECK( mask.includes(sp_yf)); + BOOST_CHECK( mask.includes(sp_yg)); + BOOST_CHECK( mask.includes(sp_yx)); BOOST_CHECK(!mask.includes(sp_yxf)); BOOST_CHECK(!mask.includes(sp_yxg)); - BOOST_CHECK(!mask.includes(sp_yy)); + BOOST_CHECK( mask.includes(sp_yy)); BOOST_CHECK(!mask.includes(sp_yyf)); BOOST_CHECK(!mask.includes(sp_yyg)); } @@ -974,13 +882,16 @@ includes.push_back(utf8(string("y"))); app_state app; + // FIXME: depth == 1 currently means directory + children + grand children + // this should be changed to mean directory + immediate children but for + // compatibility with old restrictions this behaviour has been preserved app.set_depth(1); restriction mask(includes, excludes, roster, app); BOOST_CHECK(!mask.empty()); // check restricted nodes - BOOST_CHECK( mask.includes(roster, nid_root)); + BOOST_CHECK(!mask.includes(roster, nid_root)); BOOST_CHECK(!mask.includes(roster, nid_f)); BOOST_CHECK(!mask.includes(roster, nid_g)); @@ -988,24 +899,24 @@ BOOST_CHECK( mask.includes(roster, nid_xf)); BOOST_CHECK( mask.includes(roster, nid_xg)); BOOST_CHECK( mask.includes(roster, nid_xx)); - BOOST_CHECK(!mask.includes(roster, nid_xxf)); - BOOST_CHECK(!mask.includes(roster, nid_xxg)); + BOOST_CHECK( mask.includes(roster, nid_xxf)); + BOOST_CHECK( mask.includes(roster, nid_xxg)); BOOST_CHECK( mask.includes(roster, nid_xy)); - BOOST_CHECK(!mask.includes(roster, nid_xyf)); - BOOST_CHECK(!mask.includes(roster, nid_xyg)); + BOOST_CHECK( mask.includes(roster, nid_xyf)); + BOOST_CHECK( mask.includes(roster, nid_xyg)); BOOST_CHECK( mask.includes(roster, nid_y)); BOOST_CHECK( mask.includes(roster, nid_yf)); BOOST_CHECK( mask.includes(roster, nid_yg)); BOOST_CHECK( mask.includes(roster, nid_yx)); - BOOST_CHECK(!mask.includes(roster, nid_yxf)); - BOOST_CHECK(!mask.includes(roster, nid_yxg)); + BOOST_CHECK( mask.includes(roster, nid_yxf)); + BOOST_CHECK( mask.includes(roster, nid_yxg)); BOOST_CHECK( mask.includes(roster, nid_yy)); - BOOST_CHECK(!mask.includes(roster, nid_yyf)); - BOOST_CHECK(!mask.includes(roster, nid_yyg)); + BOOST_CHECK( mask.includes(roster, nid_yyf)); + BOOST_CHECK( mask.includes(roster, nid_yyg)); // check restricted paths - BOOST_CHECK( mask.includes(sp_root)); + BOOST_CHECK(!mask.includes(sp_root)); BOOST_CHECK(!mask.includes(sp_f)); BOOST_CHECK(!mask.includes(sp_g)); @@ -1013,21 +924,21 @@ BOOST_CHECK( mask.includes(sp_xf)); BOOST_CHECK( mask.includes(sp_xg)); BOOST_CHECK( mask.includes(sp_xx)); - BOOST_CHECK(!mask.includes(sp_xxf)); - BOOST_CHECK(!mask.includes(sp_xxg)); + BOOST_CHECK( mask.includes(sp_xxf)); + BOOST_CHECK( mask.includes(sp_xxg)); BOOST_CHECK( mask.includes(sp_xy)); - BOOST_CHECK(!mask.includes(sp_xyf)); - BOOST_CHECK(!mask.includes(sp_xyg)); + BOOST_CHECK( mask.includes(sp_xyf)); + BOOST_CHECK( mask.includes(sp_xyg)); BOOST_CHECK( mask.includes(sp_y)); BOOST_CHECK( mask.includes(sp_yf)); BOOST_CHECK( mask.includes(sp_yg)); BOOST_CHECK( mask.includes(sp_yx)); - BOOST_CHECK(!mask.includes(sp_yxf)); - BOOST_CHECK(!mask.includes(sp_yxg)); + BOOST_CHECK( mask.includes(sp_yxf)); + BOOST_CHECK( mask.includes(sp_yxg)); BOOST_CHECK( mask.includes(sp_yy)); - BOOST_CHECK(!mask.includes(sp_yyf)); - BOOST_CHECK(!mask.includes(sp_yyg)); + BOOST_CHECK( mask.includes(sp_yyf)); + BOOST_CHECK( mask.includes(sp_yyg)); } void @@ -1040,7 +951,6 @@ suite->add(BOOST_TEST_CASE(&test_include_exclude)); suite->add(BOOST_TEST_CASE(&test_exclude_include)); suite->add(BOOST_TEST_CASE(&test_invalid_paths)); - suite->add(BOOST_TEST_CASE(&test_get_parent_paths)); suite->add(BOOST_TEST_CASE(&test_include_depth_0)); suite->add(BOOST_TEST_CASE(&test_include_depth_1)); ============================================================ --- restrictions.hh 54a5faec54b44ad6dec5ac9aa7854467331181e6 +++ restrictions.hh d4f5430f74e4e2747729ddeeb8d77a79a3b98a2e @@ -55,7 +55,7 @@ // FIXME: should we really be doing implicit includes of parents? // TODO: move these into the class below?!? -enum path_state { explicit_include, explicit_exclude, implicit_include }; +enum path_state { included, excluded }; class restriction { ============================================================ --- roster.cc 5df4ea90dbfb38554c8d54eaecfb2faa5c11b14b +++ roster.cc c068c4d2dc8f907ad3ca9515bdc5cab7067cefe5 @@ -1839,14 +1839,17 @@ I(false); case parallel::in_left: + // deleted delta_only_in_from(from, i.left_key(), i.left_data(), cs); break; case parallel::in_right: + // added delta_only_in_to(to, i.right_key(), i.right_data(), cs); break; case parallel::in_both: + // moved/renamed/patched/attribute changes delta_in_both(i.left_key(), from, i.left_data(), to, i.right_data(), cs); break; } @@ -1895,6 +1898,7 @@ { included.clear(); excluded.clear(); + L(FL("building restricted csets\n")); parallel::iter i(from.all_nodes(), to.all_nodes()); while (i.next()) @@ -1906,6 +1910,7 @@ I(false); case parallel::in_left: + // deleted if (mask.includes(from, i.left_key())) { delta_only_in_from(from, i.left_key(), i.left_data(), included); @@ -1919,6 +1924,7 @@ break; case parallel::in_right: + // added if (mask.includes(to, i.right_key())) { delta_only_in_to(to, i.right_key(), i.right_data(), included); @@ -1932,6 +1938,7 @@ break; case parallel::in_both: + // moved/renamed/patched/attribute changes 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); @@ -1945,9 +1952,52 @@ break; } } + } +void +check_restricted_cset(roster_t const & roster, cset const & cs) +{ + path_set added; + int missing = 0; + for (path_set::const_iterator i = cs.dirs_added.begin(); + i != cs.dirs_added.end(); ++i) + { + split_path dir(*i); + added.insert(dir); + + if (dir.size() > 1) + { + dir.pop_back(); + + if (!roster.has_node(dir) && added.find(dir) == added.end()) + { + missing++; + W(F("restriction excludes directory '%s'") % dir); + } + } + } + + for (std::map::const_iterator i = cs.files_added.begin(); + i != cs.files_added.end(); ++i) + { + split_path dir(i->first); + I(dir.size() > 1); + dir.pop_back(); + + if (!roster.has_node(dir) && added.find(dir) == added.end()) + { + missing++; + W(F("restriction excludes directory '%s'") % dir); + } + } + + N(missing == 0, F("invalid restriction excludes required directories")); + +} + + void select_nodes_modified_by_cset(cset const & cs, roster_t const & old_roster, ============================================================ --- roster.hh bcbbee47f188d9fa7097f91c491045d97ddf1477 +++ roster.hh 4b88a215d13fd7c7a4d43560ab97bd96716ee18a @@ -302,6 +302,9 @@ restriction const & mask); void +check_restricted_cset(roster_t const & roster, cset const & cs); + +void select_nodes_modified_by_cset(cset const & cs, roster_t const & old_roster, roster_t const & new_roster, ============================================================ --- tests/t_log_dir.at f965de2bd1db78e029424b04221edf6505862c0c +++ tests/t_log_dir.at 2749d6ae52721e0a253d61fd845da46995daf97c @@ -1,11 +1,6 @@ AT_SETUP([log dir]) MONOTONE_SETUP -# This test is a bug report -# log dir should only list revisions which change the things in or below dir - -AT_XFAIL_IF(true) - ADD_FILE(foo, [foo ]) ADD_FILE(bar, [bar