# # # add_dir "tests/w_selector" # # add_file "tests/w_selector/__driver__.lua" # content [75b6c0ec3c3b50dc651acbc938e08778cc166c32] # # patch "NEWS" # from [4185f5904848634aafa6d7b3340df73533bc305c] # to [4fb3a20cd2d273bd91109e1937a104f8a1e856c7] # # patch "monotone.texi" # from [e3ee512383c619b773f1c7d24acd74ce6b6ad7b1] # to [b1ea779ac43cdb91cb9d2423910233493a612453] # # patch "selectors.cc" # from [91d924b52e55b60329cba63adac1af6d874014d0] # to [9d5b40b5b6930b793c110d0950076556ff182782] # ============================================================ --- tests/w_selector/__driver__.lua 75b6c0ec3c3b50dc651acbc938e08778cc166c32 +++ tests/w_selector/__driver__.lua 75b6c0ec3c3b50dc651acbc938e08778cc166c32 @@ -0,0 +1,22 @@ + +include("common/selectors.lua") + +mtn_setup() + +-- empty revision +selmap("w:", {""}) + +-- clean ws +addfile("testfile", "blah blah") +commit() +r=base_revision() +selmap("w:", {r}) + +-- ws with changes +writefile("testfile", "stuff stuff") +selmap("w:", {r}) +commit() + +-- back to parent +check(mtn("update", "-rp:"), 0, false, false) +selmap("w:", {r}) ============================================================ --- NEWS 4185f5904848634aafa6d7b3340df73533bc305c +++ NEWS 4fb3a20cd2d273bd91109e1937a104f8a1e856c7 @@ -14,6 +14,9 @@ xxx xxx xx xx:xx:xx UTC 2009 New features + - New 'w:' selector type for selecting the revision the workspace + is based on. + Bugs fixed Internal ============================================================ --- monotone.texi e3ee512383c619b773f1c7d24acd74ce6b6ad7b1 +++ monotone.texi b1ea779ac43cdb91cb9d2423910233493a612453 @@ -2811,6 +2811,10 @@ @heading Selectors in detail Uses selector type @code{t}. For example, @code{t:monotone-0.11} matches @code{tag} certs where the cert value begins with @code{monotone-0.11}. Values to match for can have shell wildcards. address@hidden Workspace base revision +Uses selector type @code{w}. This selector must be used from within a +workspace and must not have any associated value. It matches the base +revision ID(s) this workspace is based on. @end table Further selector types may be added in the future. ============================================================ --- selectors.cc 91d924b52e55b60329cba63adac1af6d874014d0 +++ selectors.cc 9d5b40b5b6930b793c110d0950076556ff182782 @@ -45,15 +45,15 @@ enum selector_type sel_message, sel_parent, sel_update, + sel_base, sel_unknown }; typedef vector > selector_list; static void -decode_selector(project_t & project, - options const & opts, - lua_hooks & lua, +decode_selector(options const & opts, lua_hooks & lua, + project_t & project, string const & orig_sel, selector_type & type, string & sel) @@ -116,6 +116,9 @@ decode_selector(project_t & project, case 'u': type = sel_update; break; + case 'w': + type = sel_base; + break; default: W(F("unknown selector type: %c") % sel[0]); break; @@ -214,6 +217,10 @@ decode_selector(project_t & project, sel = encode_hexenc(update_id.inner()(), origin::internal); } break; + case sel_base: + E(sel.empty(), origin::user, + F("no value is allowed with the base revision selector w:")); + break; default: break; } @@ -221,9 +228,8 @@ static void } static void -parse_selector(project_t & project, - options const & opts, - lua_hooks & lua, +parse_selector(options const & opts, lua_hooks & lua, + project_t & project, string const & str, selector_list & sels) { sels.clear(); @@ -250,14 +256,15 @@ parse_selector(project_t & project, string sel; selector_type type = sel_unknown; - decode_selector(project, opts, lua, *i, type, sel); + decode_selector(opts, lua, project, *i, type, sel); sels.push_back(make_pair(type, sel)); } } } static void -complete_one_selector(project_t & project, +complete_one_selector(options const & opts, lua_hooks & lua, + project_t & project, selector_type ty, string const & value, set & completions) { @@ -358,11 +365,27 @@ complete_one_selector(project_t & projec } } break; + + case sel_base: + { + workspace work(opts, lua, F("the selector w: returns the " + "base revision(s) of the workspace")); + parent_map parents; + work.get_parent_rosters(project.db, parents); + + for (parent_map::const_iterator i = parents.begin(); + i != parents.end(); ++i) + { + completions.insert(i->first); + } + } + break; } } static void -complete_selector(project_t & project, +complete_selector(options const & opts, lua_hooks & lua, + project_t & project, selector_list const & limit, set & completions) { @@ -373,14 +396,14 @@ complete_selector(project_t & project, } selector_list::const_iterator i = limit.begin(); - complete_one_selector(project, i->first, i->second, completions); + complete_one_selector(opts, lua, project, i->first, i->second, completions); i++; while (i != limit.end()) { set candidates; set intersection; - complete_one_selector(project, i->first, i->second, candidates); + complete_one_selector(opts, lua, project, i->first, i->second, candidates); intersection.clear(); set_intersection(completions.begin(), completions.end(), @@ -399,7 +422,7 @@ complete(options const & opts, lua_hooks set & completions) { selector_list sels; - parse_selector(project, opts, lua, str, sels); + parse_selector(opts, lua, project, str, sels); // avoid logging if there's no expansion to be done if (sels.size() == 1 @@ -413,7 +436,7 @@ complete(options const & opts, lua_hooks } P(F("expanding selection '%s'") % str); - complete_selector(project, sels, completions); + complete_selector(opts, lua, project, sels, completions); E(!completions.empty(), origin::user, F("no match for selection '%s'") % str); @@ -454,7 +477,7 @@ expand_selector(options const & opts, lu set & completions) { selector_list sels; - parse_selector(project, opts, lua, str, sels); + parse_selector(opts, lua, project, str, sels); // avoid logging if there's no expansion to be done if (sels.size() == 1 @@ -466,7 +489,7 @@ expand_selector(options const & opts, lu return; } - complete_selector(project, sels, completions); + complete_selector(opts, lua, project, sels, completions); } void