# # # patch "cmd_ws_commit.cc" # from [42bb3c5d7f960a344b04e043805cca2b17752f51] # to [edbf7e543d9a4dc31a3f4815acd1a9c2a83ee651] # # patch "merge_content.cc" # from [06f264a5ff0b3b6360efdb930d91f0a1f0b5af76] # to [b7b36faae51fad93a1b7ba37c17eee7bb20dd5a9] # # patch "merge_content.hh" # from [c3dc50ac9bad4488b4583c84551f3c6302763a64] # to [119dac7660310c581b280923d4c5000266f0e54f] # # patch "tests/attr_set_drop/__driver__.lua" # from [81b453444a735d9074b44b1581452535f914b3ca] # to [b37ecf5a73caaa196d084da7c9bdfa0fedab9aa3] # # patch "tests/attr_set_get_commands/__driver__.lua" # from [d95e515541285d3a2e72d5408aa0a40cd875f55f] # to [389bd92411944c03f1e3aaac5d9dd12bc3052c08] # # patch "tests/clobbered_attrs/__driver__.lua" # from [bfb5a45667663a0f57d8bc580619aeed33640862] # to [13108b8034266888fb78ad445ee78847efcdf635] # # patch "work.cc" # from [b5811c6d3cc22d001ab1673b1c828a0e2683a73c] # to [ce1864612e74d782bca6371960bd9ac9608c039d] # ============================================================ --- cmd_ws_commit.cc 42bb3c5d7f960a344b04e043805cca2b17752f51 +++ cmd_ws_commit.cc edbf7e543d9a4dc31a3f4815acd1a9c2a83ee651 @@ -714,27 +714,26 @@ CMD_GROUP(attr, "attr", "", CMD_REF(work N_("Manages file attributes"), N_("This command is used to set, get or drop file attributes.")); -CMD(attr_drop, "drop", "", CMD_REF(attr), N_("PATH [ATTR]"), - N_("Removes attributes from a file"), - N_("If no attribute is specified, this command removes all attributes " - "attached to the file given in PATH. Otherwise only removes the " - "attribute specified in ATTR."), - options::opts::none) +// WARNING: this function is used by both attr_drop and AUTOMATE drop_attribute +// don't change anything that affects the automate interface contract + +static void +drop_attr(app_state & app, args_vector const & args) { - E(args.size() > 0 && args.size() < 3, origin::user, - F("wrong argument count")); + database db(app); + workspace work(app); - roster_t new_roster; + roster_t old_roster; temp_node_id_source nis; - database db(app); - workspace work(app); - work.get_current_roster_shape(db, nis, new_roster); + work.get_current_roster_shape(db, nis, old_roster); file_path path = file_path_external(idx(args, 0)); - E(new_roster.has_node(path), origin::user, + E(old_roster.has_node(path), origin::user, F("Unknown path '%s'") % path); + + roster_t new_roster = old_roster; node_t node = new_roster.get_node(path); // Clear all attrs (or a specific attr). @@ -754,15 +753,33 @@ CMD(attr_drop, "drop", "", CMD_REF(attr) node->attrs[a_key] = make_pair(false, ""); } + cset cs; + make_cset(old_roster, new_roster, cs); + + content_merge_empty_adaptor empty; + work.perform_content_update(db, cs, empty); + parent_map parents; work.get_parent_rosters(db, parents); revision_t new_work; make_revision_for_workspace(parents, new_roster, new_work); work.put_work_rev(new_work); - work.update_any_attrs(db); } +CMD(attr_drop, "drop", "", CMD_REF(attr), N_("PATH [ATTR]"), + N_("Removes attributes from a file"), + N_("If no attribute is specified, this command removes all attributes " + "attached to the file given in PATH. Otherwise only removes the " + "attribute specified in ATTR."), + options::opts::none) +{ + if (args.size() != 1 && args.size() != 2) + throw usage(execid); + + drop_attr(app, args); +} + CMD(attr_get, "get", "", CMD_REF(attr), N_("PATH [ATTR]"), N_("Gets the values of a file's attributes"), N_("If no attribute is specified, this command prints all attributes " @@ -770,8 +787,8 @@ CMD(attr_get, "get", "", CMD_REF(attr), "attribute specified in ATTR."), options::opts::none) { - E(args.size() > 0 && args.size() < 3, origin::user, - F("wrong argument count")); + if (args.size() != 1 && args.size() != 2) + throw usage(execid); roster_t new_roster; temp_node_id_source nis; @@ -815,26 +832,26 @@ CMD(attr_get, "get", "", CMD_REF(attr), } } -CMD(attr_set, "set", "", CMD_REF(attr), N_("PATH ATTR VALUE"), - N_("Sets an attribute on a file"), - N_("Sets the attribute given on ATTR to the value specified in VALUE " - "for the file mentioned in PATH."), - options::opts::none) +// WARNING: this function is used by both attr_set and AUTOMATE set_attribute +// don't change anything that affects the automate interface contract + +static void +set_attr(app_state & app, args_vector const & args) { - E(args.size() == 3, origin::user, - F("wrong argument count")); + database db(app); + workspace work(app); - roster_t new_roster; + roster_t old_roster; temp_node_id_source nis; - database db(app); - workspace work(app); - work.get_current_roster_shape(db, nis, new_roster); + work.get_current_roster_shape(db, nis, old_roster); file_path path = file_path_external(idx(args, 0)); - E(new_roster.has_node(path), origin::user, + E(old_roster.has_node(path), origin::user, F("Unknown path '%s'") % path); + + roster_t new_roster = old_roster; node_t node = new_roster.get_node(path); attr_key a_key = typecast_vocab(idx(args, 1)); @@ -842,15 +859,32 @@ CMD(attr_set, "set", "", CMD_REF(attr), node->attrs[a_key] = make_pair(true, a_value); + cset cs; + make_cset(old_roster, new_roster, cs); + + content_merge_empty_adaptor empty; + work.perform_content_update(db, cs, empty); + parent_map parents; work.get_parent_rosters(db, parents); revision_t new_work; make_revision_for_workspace(parents, new_roster, new_work); work.put_work_rev(new_work); - work.update_any_attrs(db); } +CMD(attr_set, "set", "", CMD_REF(attr), N_("PATH ATTR VALUE"), + N_("Sets an attribute on a file"), + N_("Sets the attribute given on ATTR to the value specified in VALUE " + "for the file mentioned in PATH."), + options::opts::none) +{ + if (args.size() != 3) + throw usage(execid); + + set_attr(app, args); +} + // Name: get_attributes // Arguments: // 1: file / directory name @@ -997,32 +1031,7 @@ CMD_AUTOMATE(set_attribute, N_("PATH KEY E(args.size() == 3, origin::user, F("wrong argument count")); - database db(app); - workspace work(app); - - roster_t new_roster; - temp_node_id_source nis; - - work.get_current_roster_shape(db, nis, new_roster); - - file_path path = file_path_external(idx(args,0)); - - E(new_roster.has_node(path), origin::user, - F("Unknown path '%s'") % path); - node_t node = new_roster.get_node(path); - - attr_key a_key = typecast_vocab(idx(args,1)); - attr_value a_value = typecast_vocab(idx(args,2)); - - node->attrs[a_key] = make_pair(true, a_value); - - parent_map parents; - work.get_parent_rosters(db, parents); - - revision_t new_work; - make_revision_for_workspace(parents, new_roster, new_work); - work.put_work_rev(new_work); - work.update_any_attrs(db); + set_attr(app, args); } // Name: drop_attribute @@ -1044,42 +1053,7 @@ CMD_AUTOMATE(drop_attribute, N_("PATH [K E(args.size() ==1 || args.size() == 2, origin::user, F("wrong argument count")); - database db(app); - workspace work(app); - - roster_t new_roster; - temp_node_id_source nis; - - work.get_current_roster_shape(db, nis, new_roster); - - file_path path = file_path_external(idx(args,0)); - - E(new_roster.has_node(path), origin::user, F("Unknown path '%s'") % path); - node_t node = new_roster.get_node(path); - - // Clear all attrs (or a specific attr). - if (args.size() == 1) - { - for (attr_map_t::iterator i = node->attrs.begin(); - i != node->attrs.end(); ++i) - i->second = make_pair(false, ""); - } - else - { - attr_key a_key = typecast_vocab(idx(args,1)); - E(node->attrs.find(a_key) != node->attrs.end(), origin::user, - F("Path '%s' does not have attribute '%s'") - % path % a_key); - node->attrs[a_key] = make_pair(false, ""); - } - - parent_map parents; - work.get_parent_rosters(db, parents); - - revision_t new_work; - make_revision_for_workspace(parents, new_roster, new_work); - work.put_work_rev(new_work); - work.update_any_attrs(db); + drop_attr(app, args); } CMD(commit, "commit", "ci", CMD_REF(workspace), N_("[PATH]..."), ============================================================ --- merge_content.cc 06f264a5ff0b3b6360efdb930d91f0a1f0b5af76 +++ merge_content.cc b7b36faae51fad93a1b7ba37c17eee7bb20dd5a9 @@ -333,7 +333,45 @@ content_merge_checkout_adaptor::get_vers db.get_file_version(ident, dat); } +/////////////////////////////////////////////////////////////////////////// +// content_merge_empty_adaptor +/////////////////////////////////////////////////////////////////////////// +void +content_merge_empty_adaptor::record_merge(file_id const & left_ident, + file_id const & right_ident, + file_id const & merged_ident, + file_data const & left_data, + file_data const & right_data, + file_data const & merged_data) +{ + I(false); +} + +void +content_merge_empty_adaptor::record_file(file_id const & parent_ident, + file_id const & merged_ident, + file_data const & parent_data, + file_data const & merged_data) +{ + I(false); +} + +void +content_merge_empty_adaptor::get_ancestral_roster(node_id nid, + revision_id & rid, + shared_ptr & anc) +{ + I(false); +} + +void +content_merge_empty_adaptor::get_version(file_id const & ident, + file_data & dat) const +{ + I(false); +} + /////////////////////////////////////////////////////////////////////////// // content_merger /////////////////////////////////////////////////////////////////////////// ============================================================ --- merge_content.hh c3dc50ac9bad4488b4583c84551f3c6302763a64 +++ merge_content.hh 119dac7660310c581b280923d4c5000266f0e54f @@ -160,6 +160,30 @@ content_merge_checkout_adaptor }; +struct +content_merge_empty_adaptor + : public content_merge_adaptor +{ + void record_merge(file_id const & left_ident, + file_id const & right_ident, + file_id const & merged_ident, + file_data const & left_data, + file_data const & right_data, + file_data const & merged_data); + + void record_file(file_id const & parent_ident, + file_id const & merged_ident, + file_data const & parent_data, + file_data const & merged_data); + + void get_ancestral_roster(node_id nid, + revision_id & rid, + boost::shared_ptr & anc); + + void get_version(file_id const & ident, + file_data & dat) const; +}; + struct content_merger { lua_hooks & lua; ============================================================ --- tests/attr_set_drop/__driver__.lua 81b453444a735d9074b44b1581452535f914b3ca +++ tests/attr_set_drop/__driver__.lua b37ecf5a73caaa196d084da7c9bdfa0fedab9aa3 @@ -10,14 +10,10 @@ check({"test", "!", "-x","foo"}, 0, fals -- check that no execute bits are set check({"test", "!", "-x","foo"}, 0, false, false) --- setting mtn:execute does set the file's execute bits +-- setting mtn:execute sets the file's execute bits check(mtn("attr", "set", "foo", "mtn:execute", "true"), 0, false, false) check({"test", "-x","foo"}, 0, false, false) --- dropping mtn:execute does NOT clear the file's execute bits --- this is a minor bug/inconsistency since set does set the execute bits --- it's caused by the fact that both attr_set and attr_drop call --- updade_any_attrs which only sets currently existing attrs and doesn't clear --- them +-- dropping mtn:execute clears the file's execute bits check(mtn("attr", "drop", "foo", "mtn:execute"), 0, false, false) -xfail({"test", "!", "-x","foo"}, 0, false, false) +check({"test", "!", "-x","foo"}, 0, false, false) ============================================================ --- tests/attr_set_get_commands/__driver__.lua d95e515541285d3a2e72d5408aa0a40cd875f55f +++ tests/attr_set_get_commands/__driver__.lua 389bd92411944c03f1e3aaac5d9dd12bc3052c08 @@ -30,4 +30,4 @@ check(qgrep("test:test_attr:a:2", "stdou check(qgrep("test:test_attr:a:2", "stdout")) -- check that files must exist to have attributes set -check(mtn("attr", "set", "missing", "mtn:execute"), 1, false, false) +check(mtn("attr", "set", "missing", "mtn:execute", "true"), 1, false, false) ============================================================ --- tests/clobbered_attrs/__driver__.lua bfb5a45667663a0f57d8bc580619aeed33640862 +++ tests/clobbered_attrs/__driver__.lua 13108b8034266888fb78ad445ee78847efcdf635 @@ -27,7 +27,7 @@ check(mtn("attr", "set", "bar", "mtn:exe -- now tell monotone to set the execute bits on bar -- this should not touch foo check(mtn("attr", "set", "bar", "mtn:execute", "true"), 0, false, false) -xfail({"test", "!", "-x","foo"}, 0, false, false) +check({"test", "!", "-x","foo"}, 0, false, false) check({"test", "-x","bar"}, 0, false, false) -- manually clear the execute bits from foo and bar ============================================================ --- work.cc b5811c6d3cc22d001ab1673b1c828a0e2683a73c +++ work.cc ce1864612e74d782bca6371960bd9ac9608c039d @@ -1010,24 +1010,6 @@ struct simulated_working_tree : public e }; -struct content_merge_empty_adaptor : public content_merge_adaptor -{ - virtual void get_version(file_id const &, file_data &) const - { I(false); } - virtual void record_merge(file_id const &, file_id const &, - file_id const &, - file_data const &, file_data const &, - file_data const &) - { I(false); } - virtual void record_file(file_id const &, - file_id const &, - file_data const &, - file_data const &) - { I(false); } - virtual void get_ancestral_roster(node_id, revision_id &, boost::shared_ptr &) - { I(false); } -}; - // editable_working_tree implementation static inline bookkeeping_path