# # # patch "automate.cc" # from [373cfdd41349d7cbbdfebb4ab799240e70f7f0fc] # to [890d5b9b5d5929fac891089537877a2a83079467] # # patch "cmd_ws_commit.cc" # from [8321ee742a65e2ebaf58c328bdf6bdda11c8f21c] # to [ac1a5188bbc4545b8c1b17bebfada1e702349981] # # patch "lua_hooks.cc" # from [e61801cae30ad803e68f8419729619159719137a] # to [c0091bc965659efb797cf3a7b6ed508ffb8acc70] # # patch "lua_hooks.hh" # from [a03b6a9de65a23204776355184e50a093f65f649] # to [9837013e9c79ae73854ee1c6ec96c74ac787ecfe] # # patch "restrictions.cc" # from [9a37177b1a374c1973c01da3d4729e3a5d854453] # to [3d9ac89c1367e0d40b1c197f39b8df1c7af316d0] # # patch "work.cc" # from [04389e4274f38d0b2bc866c6938d53bbda5e8a2f] # to [0bc477ba2407659797f6ea6d907012686f2390ec] # # patch "work.hh" # from [8ba21b48a4ac6d7c479b6116f0da96dcbf902f66] # to [e42fa101dd8ccc458f2170ace6e04b40c8f0fffc] # ============================================================ --- automate.cc 373cfdd41349d7cbbdfebb4ab799240e70f7f0fc +++ automate.cc 890d5b9b5d5929fac891089537877a2a83079467 @@ -768,7 +768,7 @@ inventory_print_states(app_state & app, { if (!item.new_node.exists) { - if (app.lua.hook_ignore_file(fs_path)) + if (app.work.ignore_file(fs_path)) states.push_back("ignored"); else states.push_back("unknown"); ============================================================ --- cmd_ws_commit.cc 8321ee742a65e2ebaf58c328bdf6bdda11c8f21c +++ cmd_ws_commit.cc ac1a5188bbc4545b8c1b17bebfada1e702349981 @@ -353,7 +353,7 @@ CMD(mkdir, "mkdir", "", CMD_REF(workspac // we'll treat this as a user (fatal) error. it really wouldn't make // sense to add a dir to .mtn-ignore and then try to add it to the // project with a mkdir statement, but one never can tell... - N(app.opts.no_ignore || !app.lua.hook_ignore_file(fp), + N(app.opts.no_ignore || !app.work.ignore_file(fp), F("ignoring directory '%s' [see .mtn-ignore]") % fp); paths.insert(fp); ============================================================ --- lua_hooks.cc e61801cae30ad803e68f8419729619159719137a +++ lua_hooks.cc c0091bc965659efb797cf3a7b6ed508ffb8acc70 @@ -310,8 +310,17 @@ bool } bool -lua_hooks::hook_ignore_file(file_path const & p) +lua_hooks::obsolete_hook_ignore_file_defined() { + bool have_ignore_file = Lua(st) + .func("ignore_file") + .ok(); + return have_ignore_file; +} + +bool +lua_hooks::obsolete_hook_ignore_file(file_path const & p) +{ bool ignore_it = false; bool exec_ok = Lua(st) .func("ignore_file") ============================================================ --- lua_hooks.hh a03b6a9de65a23204776355184e50a093f65f649 +++ lua_hooks.hh 9837013e9c79ae73854ee1c6ec96c74ac787ecfe @@ -88,7 +88,13 @@ public: bool hook_get_netsync_write_permitted(rsa_keypair_id const & identity); // local repo hooks - bool hook_ignore_file(file_path const & p); + + // the ignore_file() hook is obsolete. if it's not defined we + // use faster code in work.cc. only work.cc should call either + // of these functions. + bool obsolete_hook_ignore_file_defined(); + bool obsolete_hook_ignore_file(file_path const & p); + bool hook_ignore_branch(branch_name const & branch); bool hook_merge3(file_path const & anc_path, file_path const & left_path, ============================================================ --- restrictions.cc 9a37177b1a374c1973c01da3d4729e3a5d854453 +++ restrictions.cc 3d9ac89c1367e0d40b1c197f39b8df1c7af316d0 @@ -87,7 +87,7 @@ validate_roster_paths(set con // rosters if (known_paths.find(*i) == known_paths.end()) { - if (!app.lua.hook_ignore_file(*i)) + if (!app.work.ignore_file(*i)) { bad++; W(F("restriction includes unknown path '%s'") % *i); @@ -124,7 +124,7 @@ validate_workspace_paths(set // ignored paths are allowed into the restriction but are not // considered invalid if they are found in none of the restriction's // rosters - if (!path_exists(*i) && !app.lua.hook_ignore_file(*i)) + if (!path_exists(*i) && !app.work.ignore_file(*i)) { bad++; W(F("restriction includes unknown path '%s'") % *i); ============================================================ --- work.cc 04389e4274f38d0b2bc866c6938d53bbda5e8a2f +++ work.cc 0bc477ba2407659797f6ea6d907012686f2390ec @@ -486,22 +486,47 @@ workspace::maybe_update_inodeprints() } // objects and routines for manipulating the workspace itself + +bool +workspace::ignore_file(file_path const & path) +{ + if (!know_ignore_hook) + { + have_ignore_hook = lua.obsolete_hook_ignore_file_defined(); + know_ignore_hook = true; + } + if (have_ignore_hook) + return lua.obsolete_hook_ignore_file(path); + return false; +} + +void +workspace::init_attributes(file_path const & path, editable_roster_base & er) +{ + map attrs; + lua.hook_init_attributes(path, attrs); + if (attrs.size() > 0) + for (map::const_iterator i = attrs.begin(); + i != attrs.end(); ++i) + er.set_attr(path, attr_key(i->first), attr_value(i->second)); +} + namespace { struct file_itemizer : public tree_walker { database & db; - lua_hooks & lua; + workspace & work; set & known; set & unknown; set & ignored; path_restriction const & mask; - file_itemizer(database & db, lua_hooks & lua, + file_itemizer(database & db, workspace & work, set & k, set & u, set & i, path_restriction const & r) - : db(db), lua(lua), known(k), unknown(u), ignored(i), mask(r) {} + : db(db), work(work), known(k), unknown(u), ignored(i), mask(r) {} virtual bool visit_dir(file_path const & path); virtual void visit_file(file_path const & path); }; @@ -519,7 +544,7 @@ file_itemizer::visit_file(file_path cons { if (mask.includes(path) && known.find(path) == known.end()) { - if (lua.hook_ignore_file(path) || db.is_dbfile(path)) + if (work.ignore_file(path) || db.is_dbfile(path)) ignored.insert(path); else unknown.insert(path); @@ -570,15 +595,15 @@ addition_builder : public tree_walker { database & db; - lua_hooks & lua; + workspace & work; roster_t & ros; editable_roster_base & er; bool respect_ignore; public: - addition_builder(database & db, lua_hooks & lua, + addition_builder(database & db, workspace & work, roster_t & r, editable_roster_base & e, bool i = true) - : db(db), lua(lua), ros(r), er(e), respect_ignore(i) + : db(db), work(work), ros(r), er(e), respect_ignore(i) {} virtual bool visit_dir(file_path const & path); virtual void visit_file(file_path const & path); @@ -622,15 +647,9 @@ addition_builder::add_nodes_for(file_pat I(nid != the_null_node); er.attach_node(nid, path); - map attrs; - lua.hook_init_attributes(path, attrs); - if (attrs.size() > 0) - for (map::const_iterator i = attrs.begin(); - i != attrs.end(); ++i) - er.set_attr(path, attr_key(i->first), attr_value(i->second)); + work.init_attributes(path, er); } - bool addition_builder::visit_dir(file_path const & path) { @@ -641,7 +660,7 @@ addition_builder::visit_file(file_path c void addition_builder::visit_file(file_path const & path) { - if ((respect_ignore && lua.hook_ignore_file(path)) || db.is_dbfile(path)) + if ((respect_ignore && work.ignore_file(path)) || db.is_dbfile(path)) { P(F("skipping ignorable file %s") % path); return; @@ -1037,10 +1056,10 @@ add_parent_dirs(file_path const & dst, r static void add_parent_dirs(file_path const & dst, roster_t & ros, node_id_source & nis, - database & db, lua_hooks & lua) + database & db, workspace & work) { editable_roster_base er(ros, nis); - addition_builder build(db, lua, ros, er); + addition_builder build(db, work, ros, er); // FIXME: this is a somewhat odd way to use the builder build.visit_dir(dst.dirname()); @@ -1174,7 +1193,7 @@ workspace::find_unknown_and_ignored(path get_current_roster_shape(new_roster, nis); new_roster.extract_path_set(known); - file_itemizer u(db, lua, known, unknown, ignored, mask); + file_itemizer u(db, *this, known, unknown, ignored, mask); for (vector::const_iterator i = roots.begin(); i != roots.end(); ++i) { @@ -1202,7 +1221,7 @@ workspace::perform_additions(set::const_iterator i = paths.begin(); i != paths.end(); ++i) { @@ -1391,7 +1410,7 @@ workspace::perform_rename(set } renames.insert(make_pair(src, dpath)); - add_parent_dirs(dpath, new_roster, nis, db, lua); + add_parent_dirs(dpath, new_roster, nis, db, *this); } else { @@ -1414,7 +1433,7 @@ workspace::perform_rename(set renames.insert(make_pair(*i, d)); - add_parent_dirs(d, new_roster, nis, db, lua); + add_parent_dirs(d, new_roster, nis, db, *this); } } ============================================================ --- work.hh 8ba21b48a4ac6d7c479b6116f0da96dcbf902f66 +++ work.hh e42fa101dd8ccc458f2170ace6e04b40c8f0fffc @@ -97,6 +97,7 @@ struct workspace bool messages = true); void update_any_attrs(); + void init_attributes(file_path const & path, editable_roster_base & er); bool has_changes(); @@ -195,12 +196,22 @@ struct workspace void enable_inodeprints(); void maybe_update_inodeprints(); + // the 'ignore file', .mtn-ignore in the root of the workspace, contains a + // set of regular expressions that match pathnames. any file or directory + // that exists, is unknown, and matches one of these regexps is treated as + // if it did not exist, instead of being an unknown file. + bool ignore_file(file_path const & path); + // constructor and locals. by caching pointers to the database and the // lua hooks, we don't have to know about app_state. - workspace(database & db, lua_hooks & lua) : db(db), lua(lua) {}; + workspace(database & db, lua_hooks & lua) + : db(db), lua(lua), have_ignore_hook(false), know_ignore_hook(false) + {}; private: database & db; lua_hooks & lua; + bool have_ignore_hook; + bool know_ignore_hook; }; // Local Variables: