# # # patch "cmd_policy.cc" # from [12ab8bee009b15977984a06d63f9b875a5b10b66] # to [cee1c5271c91317816f2d55239085838faaa5506] # # patch "editable_policy.cc" # from [d1fb22b9a7f5f1a637a4e15b99c21599524479aa] # to [e62f5bbe20a1b69aea2221104f294d67f9e80e0a] # # patch "editable_policy.hh" # from [fd828eb31b270be2506394bebf8d64baa65f5a30] # to [e1404607b8e485f7e422e68f0d20e51df7d56d44] # # patch "policy.cc" # from [dee33538419609912f1d564b9c820b5e46e9cee3] # to [056b625808613b0938e13b1cb6e7f8069d6d8aac] # # patch "tests/policy-basic/__driver__.lua" # from [8255551f13efd5e894e099b42b73a7b96a845a40] # to [81d1af4034c099f12f995ee128e750ba0d5b5ab9] # # patch "tests/policy-netsync/__driver__.lua" # from [a8653926b753e196251a30a66817cad3f063b16a] # to [e7f90e5aefdca02e8103bf1daf06269f90995f40] # ============================================================ --- cmd_policy.cc 12ab8bee009b15977984a06d63f9b875a5b10b66 +++ cmd_policy.cc cee1c5271c91317816f2d55239085838faaa5506 @@ -147,6 +147,7 @@ CMD(create_branch, "create_branch", "", N(!br, F("A branch %s already exists under policy %s") % relative_name % parent_prefix); br = parent.get_branch(relative_name, true); + br->committers = admin_keys; parent.commit(keys, utf8(N_("Declare new branch"))); } ============================================================ --- editable_policy.cc d1fb22b9a7f5f1a637a4e15b99c21599524479aa +++ editable_policy.cc e62f5bbe20a1b69aea2221104f294d67f9e80e0a @@ -49,6 +49,15 @@ namespace basic_io } } +bool +operator == (editable_policy::delegation const & lhs, + editable_policy::delegation const & rhs) +{ + return lhs.rev == rhs.rev + && lhs.uid == rhs.uid + && lhs.committers == rhs.committers; +} + namespace { branch_uid generate_uid() @@ -103,12 +112,16 @@ namespace { typedef thing_holder tag_holder; typedef thing_holder branch_holder; typedef thing_holder delegation_holder; + + + outdated_indicator_factory never_outdated; } class editable_policy_impl { public: database & db; + outdated_indicator indicator; editable_policy_impl(database & db) : db(db) {} @@ -162,6 +175,7 @@ editable_policy::editable_policy(databas self.new_value->uid = uid; self.new_value->committers = admins; impl->branches.insert(self); + impl->indicator = never_outdated.get_indicator(); } namespace { @@ -249,6 +263,12 @@ editable_policy::operator = (editable_po return *this; } +bool +editable_policy::outdated() const +{ + return impl->indicator.outdated(); +} + void editable_policy::init(revision_id const & rev) { @@ -263,6 +283,7 @@ editable_policy::init(revision_id const impl->old_rev_id = rev; impl->db.get_roster(rev, impl->old_roster); load_policy(impl); + impl->indicator = never_outdated.get_indicator(); } void @@ -270,7 +291,7 @@ editable_policy::init(editable_policy::b { uid = br.uid; set heads; - get_branch_heads(br, false, impl->db, heads, NULL); + impl->indicator = get_branch_heads(br, false, impl->db, heads, NULL); E(heads.size() <= 1, F("Policy branch %s has too many heads") % uid); if (heads.empty()) @@ -663,6 +684,7 @@ editable_policy::get_branch(string const branch_holder::info_type item; item.new_name = name; item.new_value.reset(new branch()); + item.new_value->uid = generate_uid(); impl->branches.insert(item); return item.new_value; } ============================================================ --- editable_policy.hh fd828eb31b270be2506394bebf8d64baa65f5a30 +++ editable_policy.hh e1404607b8e485f7e422e68f0d20e51df7d56d44 @@ -25,6 +25,7 @@ public: boost::shared_ptr impl; public: branch_uid uid; + bool outdated() const; class tag { @@ -114,5 +115,8 @@ public: tag_map get_all_tags(); const_tag_map get_all_tags() const; }; +bool +operator == (editable_policy::delegation const & lhs, + editable_policy::delegation const & rhs); #endif ============================================================ --- policy.cc dee33538419609912f1d564b9c820b5e46e9cee3 +++ policy.cc 056b625808613b0938e13b1cb6e7f8069d6d8aac @@ -72,25 +72,50 @@ policy_branch::init() bool policy_branch::init() { - if (policy) + if (policy && !policy->outdated()) return true; if (!delayed) return false; policy.reset(new editable_policy(db, *delayed)); - delayed.reset(); init_lower(); return true; } + void policy_branch::init_lower() { + delegation_map old_delegations = delegations; + delegations.clear(); + editable_policy::const_delegation_map dels = policy->get_all_delegations(); for (editable_policy::const_delegation_map::const_iterator i = dels.begin(); i != dels.end(); ++i) { - delegations.insert(make_pair(i->first, create(*i->second, db))); + delegation_map::iterator j = old_delegations.find(i->first); + if (j != old_delegations.end()) + { // Is this delegation unchanged? + if (j->second->delayed && *j->second->delayed == *i->second) + { + delegations.insert(*j); + continue; + } + } + bool found = false; + for (j = old_delegations.begin(); j != old_delegations.end(); ++j) + { // Does it exist somewhere else (renamed)? + if (j->second->delayed && *j->second->delayed == *i->second) + { + delegations.insert(*j); + found = true; + continue; + } + } + if (!found) + { + delegations.insert(make_pair(i->first, create(*i->second, db))); + } } } ============================================================ --- tests/policy-basic/__driver__.lua 8255551f13efd5e894e099b42b73a7b96a845a40 +++ tests/policy-basic/__driver__.lua 81d1af4034c099f12f995ee128e750ba0d5b5ab9 @@ -29,7 +29,11 @@ addfile("file3", "data3") check(mtn("update", "-r", base), 0, false, false) addfile("file3", "data3") -check(mtn("ci", "-mtwogood", "--branch=test_project.__policy__"), 0, false, false) +-- This will actually fail after the commit proper if --policy-revision +-- isn't given, because you can't get the new head count because the +-- policy is suddenly invalid... +check(mtn("ci", "-mtwogood", "--branch=test_project.__policy__", + "--policy-revision=test_project@" .. base), 0, false, false) -- Can't do stuff now, because the policy branch has two heads. check(mtn("heads", "--branch=test_project.__policy__"), 1, false, false) ============================================================ --- tests/policy-netsync/__driver__.lua a8653926b753e196251a30a66817cad3f063b16a +++ tests/policy-netsync/__driver__.lua e7f90e5aefdca02e8103bf1daf06269f90995f40 @@ -22,3 +22,21 @@ check(mtn("ls", "certs", rev2), 0, false netsync.push("test_project.*") check(mtn("ls", "certs", rev2), 0, false) + +srv = netsync.start({"--debug"}) + +-- send an update to the policy branch +check(mtn2("create_branch", "test_project.otherbranch"), 0, false, false) +srv:push("test_project.*", 2) +-- send a revision on the new branch +writefile("testfile", "third contents") +check(mtn2("commit", "-mx", "-b", "test_project.otherbranch"), 0, false, false) +other_rev = base_revision() +srv:push("test_project.*", 2) +-- see if the server recognized the new branch +-- if the policy info is stale, it won't recognize it for the +-- globish expansion +srv:pull("test_project.*", 3) +check(mtn3("ls", "certs", other_rev), 0, false) + +srv:stop()