#
# add_file "tests/t_restriction_with_exclude.at"
#
# patch "ChangeLog"
# from [16768c3e61cd01848429d635a3cd40271fd353c3]
# to [746912cbb100ebc57364b0e9c8d3785cb3cc5f7d]
#
# patch "app_state.cc"
# from [913741f52364afa34c20540f2008ef88fc911f30]
# to [4c8ba6a5cdc3fa945a945e19ea63e1fc857d3ca1]
#
# patch "app_state.hh"
# from [6f4dfe92668723e2ca2eb8bb005ebab6c0d050c5]
# to [869c3e0393d765e37fc17ae117ccbbe69776b177]
#
# patch "commands.cc"
# from [59ff7fa5fa25b87fd469695fa7efa6cc197a23b0]
# to [61185ae5cc7cd776c25ca1655199a314bdd40378]
#
# patch "monotone.cc"
# from [21176c710f4d646215c27d82b55f182830d13268]
# to [21be582ccd322a35a5d1864ee1251e5773054619]
#
# patch "tests/t_restriction_with_exclude.at"
# from []
# to [bf85428b2d62062acb23d375b0b18a3706adc5dd]
#
# patch "testsuite.at"
# from [f37b217c9d261739b96a0f8ccdc61269f1c0ee67]
# to [9843a5c53ec471614fc6d5ef5dfcf16fc6995608]
#
========================================================================
--- ChangeLog 16768c3e61cd01848429d635a3cd40271fd353c3
+++ ChangeLog 746912cbb100ebc57364b0e9c8d3785cb3cc5f7d
@@ -1,3 +1,11 @@
+2005-09-15 Timothy Brownawell
+
+ * app_state.{cc,hh}: restrictions now understand --exclude
+ * commands.cc: commit and revert now take OPT_EXCLUDE
+ * monotone.cc: update description of --exclude
+ * tests/t_restriction_with_exclude.at: new test
+ * testsuite.at: add it
+
2005-09-14 Timothy Brownawell
* contrib/ciabot_monotone_hookversion.py: CIA bot client script
========================================================================
--- app_state.cc 913741f52364afa34c20540f2008ef88fc911f30
+++ app_state.cc 4c8ba6a5cdc3fa945a945e19ea63e1fc857d3ca1
@@ -123,6 +123,7 @@
{
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);
@@ -140,6 +141,24 @@
restrictions.insert(p);
}
+ for (std::set::const_iterator i = exclude_patterns.begin();
+ i != exclude_patterns.end(); ++i)
+ {
+ file_path p = file_path_external(*i);
+
+ 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(p) != valid_paths.end(),
+ F("unknown path '%s'\n") % p);
+
+ L(F("'%s' added to excluded path set\n") % p);
+ excludes.insert(p);
+ }
+
// if user supplied a depth but provided no paths
// assume current directory
if ((depth != -1) && restrictions.empty())
@@ -152,23 +171,37 @@
app_state::restriction_includes(file_path const & path)
{
static file_path root = file_path_internal("");
- if (restrictions.empty())
+
+ if (restrictions.empty())
{
- return true;
- }
+ if (!excludes.empty())
+ {
+ if (excludes.find(root) != excludes.end())
+ return false;
+ fs::path test = fs::path(path.as_external(), fs::native);
- bool user_supplied_depth = (depth != -1);
+ while (!test.empty())
+ {
+ L(F("checking excluded path set for '%s'\n") % test.string());
- // 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.
+ file_path p = file_path_internal(test.string());
+ path_set::const_iterator i = excludes.find(p);
- if ((!user_supplied_depth) && restrictions.find(root) != restrictions.end())
- {
+ if (i != excludes.end())
+ {
+ L(F("path '%s' found in excluded path set; '%s' excluded\n")
+ % test.string() % path);
+ return false;
+ }
+
+ test = test.branch_path();
+ }
+ }
return true;
}
+ bool user_supplied_depth = (depth != -1);
+
fs::path test = fs::path(path.as_external(), fs::native);
long branch_depth = 0;
long max_depth = depth + 1;
@@ -179,6 +212,7 @@
file_path p = file_path_internal(test.string());
path_set::const_iterator i = restrictions.find(p);
+ path_set::const_iterator j = excludes.find(p);
if (i != restrictions.end())
{
@@ -186,10 +220,11 @@
% test.string() % path);
return true;
}
- else
+ else if (j != excludes.end())
{
- L(F("path '%s' not found in restricted path set; '%s' excluded\n")
+ L(F("path '%s' found in excluded path set; '%s' excluded\n")
% test.string() % path);
+ return false;
}
if (user_supplied_depth && (max_depth == branch_depth)) return false;
@@ -197,9 +232,13 @@
++branch_depth;
}
- if (user_supplied_depth && (restrictions.find(root) != restrictions.end()))
+ // 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(root) != restrictions.end())
{
- return (branch_depth <= max_depth);
+ return (!user_supplied_depth) || (branch_depth <= max_depth);
}
return false;
========================================================================
--- app_state.hh 6f4dfe92668723e2ca2eb8bb005ebab6c0d050c5
+++ app_state.hh 869c3e0393d765e37fc17ae117ccbbe69776b177
@@ -50,6 +50,7 @@
std::set exclude_patterns;
std::vector extra_rcfiles;
path_set restrictions;
+ path_set excludes;
bool found_working_copy;
long depth;
long last;
========================================================================
--- commands.cc 59ff7fa5fa25b87fd469695fa7efa6cc197a23b0
+++ commands.cc 61185ae5cc7cd776c25ca1655199a314bdd40378
@@ -2214,7 +2214,7 @@
CMD(commit, N_("working copy"), N_("[PATH]..."),
N_("commit working copy to database"),
- OPT_BRANCH_NAME % OPT_MESSAGE % OPT_MSGFILE % OPT_DATE % OPT_AUTHOR % OPT_DEPTH)
+ OPT_BRANCH_NAME % OPT_MESSAGE % OPT_MSGFILE % OPT_DATE % OPT_AUTHOR % OPT_DEPTH % OPT_EXCLUDE)
{
string log_message("");
revision_set rs;
@@ -3304,7 +3304,7 @@
CMD(revert, N_("working copy"), N_("[PATH]..."),
- N_("revert file(s), dir(s) or entire working copy"), OPT_DEPTH)
+ N_("revert file(s), dir(s) or entire working copy"), OPT_DEPTH % OPT_EXCLUDE)
{
manifest_map m_old;
revision_id old_revision_id;
========================================================================
--- monotone.cc 21176c710f4d646215c27d82b55f182830d13268
+++ monotone.cc 21be582ccd322a35a5d1864ee1251e5773054619
@@ -61,7 +61,7 @@
{"diffs", 0, POPT_ARG_NONE, NULL, OPT_DIFFS, gettext_noop("print diffs along with logs"), NULL},
{"no-merges", 0, POPT_ARG_NONE, NULL, OPT_NO_MERGES, gettext_noop("skip merges when printing logs"), NULL},
{"set-default", 0, POPT_ARG_NONE, NULL, OPT_SET_DEFAULT, gettext_noop("use the current arguments as the future default"), NULL},
- {"exclude", 0, POPT_ARG_STRING, &argstr, OPT_EXCLUDE, gettext_noop("leave out branches matching a pattern"), NULL},
+ {"exclude", 0, POPT_ARG_STRING, &argstr, OPT_EXCLUDE, gettext_noop("leave out anything described by its argument"), NULL},
{"unified", 0, POPT_ARG_NONE, NULL, OPT_UNIFIED_DIFF, gettext_noop("use unified diff format"), NULL},
{"context", 0, POPT_ARG_NONE, NULL, OPT_CONTEXT_DIFF, gettext_noop("use context diff format"), NULL},
{"external", 0, POPT_ARG_NONE, NULL, OPT_EXTERNAL_DIFF, gettext_noop("use external diff hook for generating diffs"), NULL},
========================================================================
--- tests/t_restriction_with_exclude.at
+++ tests/t_restriction_with_exclude.at bf85428b2d62062acb23d375b0b18a3706adc5dd
@@ -0,0 +1,40 @@
+AT_SETUP([use restrictions with --exclude])
+MONOTONE_SETUP
+
+AT_CHECK(mkdir foo)
+AT_DATA(file1, [x
+])
+AT_DATA(foo/bar, [y
+])
+
+AT_CHECK(MONOTONE add file1, [], [ignore], [ignore])
+AT_CHECK(MONOTONE add foo/bar, [], [ignore], [ignore])
+
+AT_CHECK(MONOTONE ci --exclude . -m 'x', [1], [ignore], [ignore])
+
+AT_CHECK(MONOTONE ci --exclude . file1 -m 'x', [], [ignore], [ignore])
+AT_CHECK(MONOTONE status --brief | grep "foo/bar", [], [ignore], [ignore])
+AT_CHECK(MONOTONE status --brief | grep "file1", [1], [ignore], [ignore])
+AT_CHECK(echo a >>file1)
+
+AT_CHECK(MONOTONE ci --exclude foo -m 'x', [], [ignore], [ignore])
+AT_CHECK(MONOTONE status --brief | grep "foo/bar", [], [ignore], [ignore])
+AT_CHECK(MONOTONE status --brief | grep "file1", [1], [ignore], [ignore])
+AT_CHECK(echo a >>file1)
+
+AT_CHECK(MONOTONE ci . --exclude file1 -m 'x', [], [ignore], [ignore])
+AT_CHECK(MONOTONE status --brief | grep "foo/bar", [1], [ignore], [ignore])
+AT_CHECK(MONOTONE status --brief | grep "file1", [], [ignore], [ignore])
+AT_CHECK(echo b >>foo/bar)
+
+AT_CHECK(MONOTONE ci . --exclude foo foo/bar -m 'x', [], [ignore], [ignore])
+AT_CHECK(MONOTONE status --brief | grep "foo/bar", [1], [ignore], [ignore])
+AT_CHECK(MONOTONE status --brief | grep "file1", [1], [ignore], [ignore])
+AT_CHECK(echo a >>file1)
+AT_CHECK(echo b >>foo/bar)
+
+AT_CHECK(MONOTONE ci --exclude foo foo/bar -m 'x', [], [ignore], [ignore])
+AT_CHECK(MONOTONE status --brief | grep "foo/bar", [1], [ignore], [ignore])
+AT_CHECK(MONOTONE status --brief | grep "file1", [], [ignore], [ignore])
+
+AT_CLEANUP
========================================================================
--- testsuite.at f37b217c9d261739b96a0f8ccdc61269f1c0ee67
+++ testsuite.at 9843a5c53ec471614fc6d5ef5dfcf16fc6995608
@@ -704,3 +704,4 @@
m4_include(tests/t_automate_get_manifest.at)
m4_include(tests/t_automate_get_revision.at)
m4_include(tests/t_unreadable_db.at)
+m4_include(tests/t_restriction_with_exclude.at)