# # # patch "cmd.hh" # from [368ffa6d9febc8720994b25d238c80eda21968fb] # to [644db6cc97abb6bb3b3d4941f23ebb6c4ea3c7b4] # # patch "file_io.cc" # from [719b28300650ccd464ec25254a4999f979fa593f] # to [299b167760e61ae5e53fab22001f9c0fbf4af1cb] # # patch "paths.cc" # from [5ecb3102980dd8fc2a6966a5dffc61ba3dd0760f] # to [355b9e0c8b86963f7783b5e798803bcf29d3ea32] # # patch "paths.hh" # from [6b435d71c4ffd44102ce968f714fde870b4fad55] # to [88bab6e0937c669fd1f37c3b3963a0079514cf34] # # patch "work.cc" # from [0db4f196f31d8c2262a68b0985a1487f48cba55a] # to [4970cd18c393af339bc306f5d364bd5f8299c8eb] # ============================================================ --- cmd.hh 368ffa6d9febc8720994b25d238c80eda21968fb +++ cmd.hh 644db6cc97abb6bb3b3d4941f23ebb6c4ea3c7b4 @@ -57,11 +57,18 @@ args_to_paths(std::vector const & std::vector paths; for (std::vector::const_iterator i = args.begin(); i != args.end(); ++i) { - if (bookkeeping_path::is_bookkeeping_path((*i)())) + if (bookkeeping_path::external_string_is_bookkeeping_path(*i)) W(F("ignored bookkeeping path '%s'") % *i); else paths.push_back(file_path_external(*i)); } + // "it should not be the case that args were passed, but our paths set + // ended up empty". This test is because some commands have default + // behavior for empty path sets -- in particular, it is the same as having + // no restriction at all. "mtn revert _MTN" turning into "mtn revert" + // would be bad. (Or substitute diff, etc.) + N(!(!args.empty() && paths.empty()), + F("all arguments given were bookkeeping paths; aborting")); return paths; } ============================================================ --- file_io.cc 719b28300650ccd464ec25254a4999f979fa593f +++ file_io.cc 299b167760e61ae5e53fab22001f9c0fbf4af1cb @@ -503,7 +503,8 @@ walk_tree_recursive(fs::path const & abs entry.normalize(); rel_entry.normalize(); - if (bookkeeping_path::is_bookkeeping_path(rel_entry.string())) + // FIXME BUG: this utf8() cast is a total lie + if (bookkeeping_path::internal_string_is_bookkeeping_path(utf8(rel_entry.string()))) { L(FL("ignoring book keeping entry %s") % rel_entry.string()); continue; ============================================================ --- paths.cc 5ecb3102980dd8fc2a6966a5dffc61ba3dd0760f +++ paths.cc 355b9e0c8b86963f7783b5e798803bcf29d3ea32 @@ -316,12 +316,17 @@ bool } bool -bookkeeping_path::is_bookkeeping_path(string const & path) +bookkeeping_path::external_string_is_bookkeeping_path(utf8 const & path) { + // FIXME: this charset casting everywhere is ridiculous string normalized; - normalize_external_path(path, normalized); - return in_bookkeeping_dir(normalized); + normalize_external_path(path(), normalized); + return internal_string_is_bookkeeping_path(utf8(normalized)); } +bool bookkeeping_path::internal_string_is_bookkeeping_path(utf8 const & path) +{ + return in_bookkeeping_dir(path()); +} /////////////////////////////////////////////////////////////////////////// // splitting/joining ============================================================ --- paths.hh 6b435d71c4ffd44102ce968f714fde870b4fad55 +++ paths.hh 88bab6e0937c669fd1f37c3b3963a0079514cf34 @@ -209,8 +209,9 @@ public: // usually you should just use the / operator as a constructor! bookkeeping_path(std::string const & path); bookkeeping_path operator /(std::string const & to_append) const; - // exposed for the use of walk_tree - static bool is_bookkeeping_path(std::string const & path); + // exposed for the use of walk_tree and friends + static bool internal_string_is_bookkeeping_path(utf8 const & path); + static bool external_string_is_bookkeeping_path(utf8 const & path); bool operator ==(const bookkeeping_path & other) const { return data == other.data; } ============================================================ --- work.cc 0db4f196f31d8c2262a68b0985a1487f48cba55a +++ work.cc 4970cd18c393af339bc306f5d364bd5f8299c8eb @@ -661,7 +661,7 @@ editable_working_tree::detach_node(split for (vector::const_iterator i = files.begin(); i != files.end(); ++i) move_file(src_pth / (*i)(), dst_pth / (*i)()); for (vector::const_iterator i = dirs.begin(); i != dirs.end(); ++i) - if (!bookkeeping_path::is_bookkeeping_path((*i)())) + if (!bookkeeping_path::internal_string_is_bookkeeping_path(*i)) move_dir(src_pth / (*i)(), dst_pth / (*i)()); root_dir_attached = false; } @@ -762,12 +762,12 @@ editable_working_tree::attach_node(node_ read_directory(src_pth, files, dirs); for (vector::const_iterator i = files.begin(); i != files.end(); ++i) { - I(!bookkeeping_path::is_bookkeeping_path((*i)())); + I(!bookkeeping_path::internal_string_is_bookkeeping_path(*i)); move_file(src_pth / (*i)(), dst_pth / (*i)()); } for (vector::const_iterator i = dirs.begin(); i != dirs.end(); ++i) { - I(!bookkeeping_path::is_bookkeeping_path((*i)())); + I(!bookkeeping_path::internal_string_is_bookkeeping_path(*i)); move_dir(src_pth / (*i)(), dst_pth / (*i)()); } delete_dir_shallow(src_pth);