# # # patch "cmd_policy.cc" # from [94aaef4c6d5bffa4bdad8683a327fe6307324350] # to [06785d027f0bb7ee54b442713814be6f868c7429] # # patch "policies/delegation.cc" # from [9e22466ab58c50473fd6cdfa1bca95c1765999f2] # to [246a8cde7eea25378eeeed8902e3c03324f28e9f] # # patch "policies/policy.cc" # from [955c1314f33a8223a13fedfcdcc123b18b36fe38] # to [56c01f732a5be29d8584022a322b6516feb8d35d] # # patch "policies/policy.hh" # from [348069fc28357eacce1794788612981b04114fa3] # to [167080f8a791cd65a87a08fea69980e14787cae2] # # patch "policies/policy_branch.cc" # from [6d95a6cc71244cb0422646db3dc5781ecb97a947] # to [639f6bbf46119b2e3beaa759937141cb07fd0a3f] # # patch "policies/policy_branch.hh" # from [36a136a09c869d51293887a3ab8e223e40a51a46] # to [473e09b6b2700615b229a868eaa122cd48658947] # # patch "project.cc" # from [956426498a850ba2b0fc1624fbc05b9f434b0c63] # to [55176f0e44377a723384b2541f4d73527283e995] # ============================================================ --- cmd_policy.cc 94aaef4c6d5bffa4bdad8683a327fe6307324350 +++ cmd_policy.cc 06785d027f0bb7ee54b442713814be6f868c7429 @@ -105,7 +105,7 @@ CMD(create_subpolicy, "create_subpolicy" gov.back().policy, gov.back().delegation.get_branch_spec()); - policies::editable_policy parent(**parent_branch.begin()); + policies::editable_policy parent(*parent_branch.begin()->second); std::set admin_keys; { @@ -118,7 +118,8 @@ CMD(create_subpolicy, "create_subpolicy" del_name.strip_prefix(branch_name(gov.back().full_policy_name, origin::internal)); parent.set_delegation(del_name(), policies::delegation::create(app, admin_keys)); - parent_branch.commit(parent, utf8("Add delegation to new child policy")); + parent_branch.commit(project, keys, parent, + utf8("Add delegation to new child policy")); } CMD(create_branch, "create_branch", "", CMD_REF(policy), @@ -145,7 +146,7 @@ CMD(create_branch, "create_branch", "", policies::policy_branch parent(project, gov.back().policy, gov.back().delegation.get_branch_spec()); - policies::editable_policy ppol(**parent.begin()); + policies::editable_policy ppol(*parent.begin()->second); std::set admin_keys; { key_identity_info ident; @@ -158,7 +159,8 @@ CMD(create_branch, "create_branch", "", if (suffix().empty()) suffix = branch_name("__main__", origin::internal); ppol.set_branch(suffix(), policies::branch::create(app, admin_keys)); - parent.commit(ppol, utf8("Add branch.")); + parent.commit(project, keys, ppol, + utf8("Add branch.")); } CMD_FWD_DECL(list); ============================================================ --- policies/delegation.cc 9e22466ab58c50473fd6cdfa1bca95c1765999f2 +++ policies/delegation.cc 246a8cde7eea25378eeeed8902e3c03324f28e9f @@ -101,7 +101,7 @@ namespace policies { E(br.size() == 1, origin::no_fault, F("Policy branch '%s' has %d heads; need 1 head") % branch_desc.get_uid() % br.size()); - return *br.begin(); + return br.begin()->second; } break; } ============================================================ --- policies/policy.cc 955c1314f33a8223a13fedfcdcc123b18b36fe38 +++ policies/policy.cc 56c01f732a5be29d8584022a322b6516feb8d35d @@ -26,6 +26,11 @@ namespace policies { { } + policy::key_map const & policy::list_keys() const + { + return keys; + } + key_name policy::get_key_name(key_id const & ident) const { for (key_map::const_iterator k = keys.begin(); ============================================================ --- policies/policy.hh 348069fc28357eacce1794788612981b04114fa3 +++ policies/policy.hh 167080f8a791cd65a87a08fea69980e14787cae2 @@ -46,6 +46,7 @@ namespace policies { // a key could have several names, should // there be an invariant against that? // should this really be the full key_name, or just the final suffix? + key_map const & list_keys() const; key_name get_key_name(key_id const & ident) const; key_id get_key_id(key_name const & ident) const; @@ -63,7 +64,7 @@ namespace policies { virtual bool outdated() const { return false; } - policy_ptr get_parent() const; + //policy_ptr get_parent() const; }; } ============================================================ --- policies/policy_branch.cc 6d95a6cc71244cb0422646db3dc5781ecb97a947 +++ policies/policy_branch.cc 639f6bbf46119b2e3beaa759937141cb07fd0a3f @@ -12,13 +12,19 @@ #include "policies/policy_branch.hh" #include "database.hh" +#include "dates.hh" +#include "key_store.hh" #include "lexical_cast.hh" +#include "merge_roster.hh" #include "policies/editable_policy.hh" #include "project.hh" +#include "revision.hh" #include "roster.hh" #include "transforms.hh" #include "vocab_cast.hh" +using std::make_pair; +using std::map; using std::pair; using std::string; @@ -194,9 +200,119 @@ namespace policies { for (std::set::const_iterator i = heads.begin(); i != heads.end(); ++i) { - policies.insert(policy_from_revision(project, spec_owner, *i)); + policies.insert(make_pair(*i, policy_from_revision(project, + spec_owner, + *i))); } } + + void policy_branch::commit(project_t & project, + key_store & keys, + policy const & p, + utf8 const & changelog, + policy_branch::iterator parent_1, + policy_branch::iterator parent_2) + { + parent_map parents; + if (parent_1 != end()) + { + cached_roster cr; + project.db.get_roster(parent_1->first, cr); + parents.insert(make_pair(parent_1->first, cr)); + } + if (parent_2 != end()) + { + cached_roster cr; + project.db.get_roster(parent_2->first, cr); + parents.insert(make_pair(parent_2->first, cr)); + } + roster_t new_roster; + if (parents.empty()) + { + } + else if (parents.size() == 1) + { + new_roster = *parents.begin()->second.first; + } + else + { + parent_map::const_iterator left = parents.begin(); + parent_map::const_iterator right = left; ++right; + + + revision_id const & left_rid = left->first; + revision_id const & right_rid = right->first; + roster_t const & left_roster = *left->second.first; + roster_t const & right_roster = *right->second.first; + marking_map const & left_mm = *left->second.second; + marking_map const & right_mm = *right->second.second; + + std::set left_ancestors, right_ancestors; + project.db.get_uncommon_ancestors(left_rid, right_rid, + left_ancestors, + right_ancestors); + roster_merge_result merge_result; + roster_merge(left_roster, left_mm, left_ancestors, + right_roster, right_mm, right_ancestors, + merge_result); + // should really check this after applying our changes + // (or check that the only conflicts are contents conflicts + // on items that we'll be overwriting) + E(merge_result.is_clean(), origin::user, + F("Cannot automatically merge policy branch")); + new_roster = merge_result.roster; + } + + temp_node_id_source source; + + policy::del_map const & p_delegations = p.list_delegations(); + file_path delegation_path = file_path_internal("delegations"); + if (!new_roster.has_node(delegation_path)) + { + node_id n = new_roster.create_dir_node(source); + new_roster.attach_node(n, delegation_path); + } + for (policy::del_map::const_iterator i = p_delegations.begin(); + i != p_delegations.end(); ++i) + { + string x; + i->second.serialize(x); + file_data dat(x, origin::internal); + file_id contents; + calculate_ident(dat, contents); + path_component name(i->first, origin::internal); + if (new_roster.has_node(delegation_path / name)) + { + node_id n = new_roster.get_node(delegation_path / name)->self; + new_roster.set_content(n, contents); + } + else + { + node_id n = new_roster.create_file_node(contents, source); + new_roster.attach_node(n, delegation_path / name); + } + } + + policy::key_map const & p_keys = p.list_keys(); + map const & p_branches = p.list_branches(); + map const & p_tags = p.list_tags(); + + + revision_t rev; + make_revision(parents, new_roster, rev); + revision_id revid; + calculate_ident(rev, revid); + + string author = decode_hexenc(keys.signing_key.inner()(), origin::internal); + transaction_guard guard(project.db); + project.db.put_revision(revid, rev); + project.put_standard_certs(keys, revid, + spec.get_uid(), + changelog, + date_t::now(), + author); + guard.commit(); + } } ============================================================ --- policies/policy_branch.hh 36a136a09c869d51293887a3ab8e223e40a51a46 +++ policies/policy_branch.hh 473e09b6b2700615b229a868eaa122cd48658947 @@ -17,6 +17,7 @@ #include "policies/delegation.hh" #include "policies/policy.hh" +class key_store; class project_t; namespace policies { @@ -26,7 +27,7 @@ namespace policies { class policy_branch { public: - typedef std::set policy_set; + typedef std::set > policy_set; private: policy_ptr spec_owner; branch spec; @@ -48,16 +49,26 @@ namespace policies { iterator end() const; size_t size() const; - void commit(policy const & p, utf8 const & changelog, - iterator parent_1, iterator parent_2); - inline void commit(policy const & p, utf8 const & changelog, + void commit(project_t & project, + key_store & keys, + policy const & p, + utf8 const & changelog, + iterator parent_1, + iterator parent_2); + inline void commit(project_t & project, + key_store & keys, + policy const & p, + utf8 const & changelog, iterator parent) { - commit(p, changelog, parent, end()); + commit(project, keys, p, changelog, parent, end()); } - inline void commit(policy const & p, utf8 const & changelog) + inline void commit(project_t & project, + key_store & keys, + policy const & p, + utf8 const & changelog) { - commit(p, changelog, end()); + commit(project, keys, p, changelog, end()); } }; } ============================================================ --- project.cc 956426498a850ba2b0fc1624fbc05b9f434b0c63 +++ project.cc 55176f0e44377a723384b2541f4d73527283e995 @@ -987,12 +987,13 @@ project_t::put_tag(key_store & keys, info.back().delegation.get_branch_spec()); I(br.begin() != br.end()); - policies::editable_policy ep(**br.begin()); + policies::editable_policy ep(*br.begin()->second); ep.set_tag(name.substr(info.back().full_policy_name.size() + 1), id); - br.commit(ep, utf8((F("Set tag %s") % name).str(), - origin::internal)); + br.commit(*this, keys, ep, + utf8((F("Set tag %s") % name).str(), + origin::internal)); } }