# # # patch "automate.cc" # from [497385b4a7d580444b7ad0755f629e0bb5316df6] # to [ebd25c3cd09ca4f3d6538de4dab1261d0aeb3486] # # patch "cmd_merging.cc" # from [65f25ddd571fda9bbab8938525cf817cc2a2b6ec] # to [05e6bf5e0085944554606888374a7f38c0e360ec] # # patch "cmd_ws_commit.cc" # from [dccf6cd4915b2d3d806c35124c82afcad4830d49] # to [62fbf1f8c008b60488a6c4f63fe990bb452d1fda] # # patch "commands.cc" # from [fa3aa8f033108be43ffb15c376b0f35484847b7e] # to [b511e36ce10116f262399abda75d41f2677dd26a] # # patch "database.cc" # from [764005eb7a22748052b1b2d2165963182dec9fa2] # to [f93a884890ae1d7eb7ee537ab815e556a1887e68] # # patch "project.cc" # from [7f1dc2c76c92b3e2ced9fa2d70dc24e014404604] # to [50538ea67357a522ab5a74bfcefebe2f842de40d] # # patch "project.hh" # from [d8d07d9efc0ae6e8ae723b3aab21370d85038d5c] # to [4370fd8dda1fcc27de319de6d53388c648dce201] # ============================================================ --- automate.cc 497385b4a7d580444b7ad0755f629e0bb5316df6 +++ automate.cc ebd25c3cd09ca4f3d6538de4dab1261d0aeb3486 @@ -71,7 +71,7 @@ AUTOMATE(heads, N_("[BRANCH]"), options: app.opts.branch_name = idx(args, 0); } set heads; - app.project.get_branch(app.opts.branch_name()).heads(heads); + app.project.get_branch_heads(app.opts.branch_name(), heads); for (set::const_iterator i = heads.begin(); i != heads.end(); ++i) output << (*i).inner()() << "\n"; } ============================================================ --- cmd_merging.cc 65f25ddd571fda9bbab8938525cf817cc2a2b6ec +++ cmd_merging.cc 05e6bf5e0085944554606888374a7f38c0e360ec @@ -320,7 +320,7 @@ CMD(merge, N_("tree"), "", N_("merge unm F("please specify a branch, with --branch=BRANCH")); set heads; - app.project.get_branch(app.opts.branch_name()).heads(heads); + app.project.get_branch_heads(app.opts.branch_name(), heads); N(heads.size() != 0, F("branch '%s' is empty") % app.opts.branch_name); if (heads.size() == 1) @@ -388,7 +388,7 @@ CMD(merge, N_("tree"), "", N_("merge unm ancestors.clear(); heads_for_ancestor.clear(); - app.project.get_branch(app.opts.branch_name()).heads(heads); + app.project.get_branch_heads(app.opts.branch_name(), heads); pass++; } @@ -453,8 +453,8 @@ CMD(merge_into_dir, N_("tree"), N_("SOUR if (args.size() != 3) throw usage(name); - app.project.get_branch(idx(args, 0)()).heads(src_heads); - app.project.get_branch(idx(args, 1)()).heads(dst_heads); + app.project.get_branch_heads(idx(args, 0)(), src_heads); + app.project.get_branch_heads(idx(args, 1)(), dst_heads); N(src_heads.size() != 0, F("branch '%s' is empty") % idx(args, 0)()); N(src_heads.size() == 1, F("branch '%s' is not merged") % idx(args, 0)()); @@ -818,7 +818,7 @@ CMD(heads, N_("tree"), "", N_("show unme N(app.opts.branch_name() != "", F("please specify a branch, with --branch=BRANCH")); - app.project.get_branch(app.opts.branch_name()).heads(heads); + app.project.get_branch_heads(app.opts.branch_name(), heads); if (heads.size() == 0) P(F("branch '%s' is empty") % app.opts.branch_name); ============================================================ --- cmd_ws_commit.cc dccf6cd4915b2d3d806c35124c82afcad4830d49 +++ cmd_ws_commit.cc 62fbf1f8c008b60488a6c4f63fe990bb452d1fda @@ -502,7 +502,7 @@ CMD(checkout, N_("tree"), N_("[DIRECTORY F("use --revision or --branch to specify what to checkout")); set heads; - app.project.get_branch(app.opts.branch_name).heads(heads); + app.project.get_branch_heads(app.opts.branch_name, heads); N(heads.size() > 0, F("branch '%s' is empty") % app.opts.branch_name); if (heads.size() > 1) @@ -748,7 +748,7 @@ CMD(commit, N_("workspace"), N_("[PATH]. I(restricted_rev.edges.size() == 1); set heads; - app.project.get_branch(app.opts.branch_name).heads(heads); + app.project.get_branch_heads(app.opts.branch_name, heads); unsigned int old_head_size = heads.size(); if (app.opts.branch_name() != "") @@ -921,7 +921,7 @@ CMD(commit, N_("workspace"), N_("[PATH]. app.work.blank_user_log(); - app.project.get_branch(app.opts.branch_name).heads(heads); + app.project.get_branch_heads(app.opts.branch_name, heads); if (heads.size() > old_head_size && old_head_size > 0) { P(F("note: this revision creates divergence\n" "note: you may (or may not) wish to run '%s merge'") @@ -1016,7 +1016,7 @@ CMD_NO_WORKSPACE(import, N_("tree"), N_( F("use --revision or --branch to specify what to checkout")); set heads; - app.project.get_branch(app.opts.branch_name).heads(heads); + app.project.get_branch_heads(app.opts.branch_name, heads); if (heads.size() > 1) { P(F("branch %s has multiple heads:") % app.opts.branch_name); ============================================================ --- commands.cc fa3aa8f033108be43ffb15c376b0f35484847b7e +++ commands.cc b511e36ce10116f262399abda75d41f2677dd26a @@ -460,7 +460,7 @@ notify_if_multiple_heads(app_state & app notify_if_multiple_heads(app_state & app) { set heads; - app.project.get_branch(app.opts.branch_name).heads(heads); + app.project.get_branch_heads(app.opts.branch_name, heads); if (heads.size() > 1) { string prefixedline; prefix_lines_with(_("note: "), ============================================================ --- database.cc 764005eb7a22748052b1b2d2165963182dec9fa2 +++ database.cc f93a884890ae1d7eb7ee537ab815e556a1887e68 @@ -2609,7 +2609,7 @@ void database::complete(selector_type ty bn != branch_names.end(); bn++) { set branch_heads; - __app->project.get_branch(*bn).heads(branch_heads); + __app->project.get_branch_heads(*bn, branch_heads); heads.insert(branch_heads.begin(), branch_heads.end()); L(FL("after get_branch_heads for %s, heads has %d entries") % (*bn) % heads.size()); } ============================================================ --- project.cc 7f1dc2c76c92b3e2ced9fa2d70dc24e014404604 +++ project.cc 50538ea67357a522ab5a74bfcefebe2f842de40d @@ -12,64 +12,7 @@ using std::vector; using std::set; using std::vector; -branch::branch(app_state & app, utf8 const & name) - : app(app), name(name) -{} -namespace -{ - struct not_in_branch : public is_failure - { - app_state & app; - base64 const & branch_encoded; - not_in_branch(app_state & app, - base64 const & branch_encoded) - : app(app), branch_encoded(branch_encoded) - {} - virtual bool operator()(revision_id const & rid) - { - vector< revision > certs; - app.db.get_revision_certs(rid, - cert_name(branch_cert_name), - branch_encoded, - certs); - erase_bogus_certs(certs, app); - return certs.empty(); - } - }; -} - -outdated_indicator -get_branch_heads(cert_value const & branchname, - app_state & app, - set & heads) -{ - L(FL("getting heads of branch %s") % branchname); - base64 branch_encoded; - encode_base64(branchname, branch_encoded); - - outdated_indicator stamp; - stamp = app.db.get_revisions_with_cert(cert_name(branch_cert_name), - branch_encoded, - heads); - - not_in_branch p(app, branch_encoded); - erase_ancestors_and_failures(heads, p, app); - L(FL("found heads of branch %s (%s heads)") % branchname % heads.size()); - return stamp; -} - -void -branch::heads(std::set & h) -{ - if (stamp.outdated()) - { - stamp = get_branch_heads(name(), app, _heads); - } - h = _heads; -} - - project_t::project_t(app_state & app) : app(app) {} @@ -81,15 +24,15 @@ project_t::get_branch_list(std::set got; indicator = app.db.get_branches(got); - actual_branches.clear(); + branches.clear(); for (std::vector::iterator i = got.begin(); i != got.end(); ++i) { - actual_branches.insert(*i); + branches.insert(*i); } } - names = actual_branches; + names = branches; } void @@ -106,14 +49,52 @@ project_t::get_branch_list(utf8 const & } } -branch & -project_t::get_branch(utf8 const & name) +namespace { - std::pair::iterator, bool> res; - res = known_branches.insert(std::make_pair(name, branch(app, name))); - return res.first->second; + struct not_in_branch : public is_failure + { + app_state & app; + base64 const & branch_encoded; + not_in_branch(app_state & app, + base64 const & branch_encoded) + : app(app), branch_encoded(branch_encoded) + {} + virtual bool operator()(revision_id const & rid) + { + vector< revision > certs; + app.db.get_revision_certs(rid, + cert_name(branch_cert_name), + branch_encoded, + certs); + erase_bogus_certs(certs, app); + return certs.empty(); + } + }; } +void +project_t::get_branch_heads(utf8 const & name, std::set & heads) +{ + std::pair > & branch = branch_heads[name]; + if (branch.first.outdated()) + { + L(FL("getting heads of branch %s") % name); + base64 branch_encoded; + encode_base64(cert_value(name()), branch_encoded); + + outdated_indicator stamp; + branch.first = app.db.get_revisions_with_cert(cert_name(branch_cert_name), + branch_encoded, + branch.second); + + not_in_branch p(app, branch_encoded); + erase_ancestors_and_failures(branch.second, p, app); + L(FL("found heads of branch %s (%s heads)") + % name % branch.second.size()); + } + heads = branch.second; +} + bool project_t::revision_is_in_branch(revision_id const & id, utf8 const & branch) ============================================================ --- project.hh d8d07d9efc0ae6e8ae723b3aab21370d85038d5c +++ project.hh 4370fd8dda1fcc27de319de6d53388c648dce201 @@ -1,8 +1,8 @@ // 2007 Timothy Brownawell // GNU GPL V2 or later -#ifndef __BRANCH_HH__ -#define __BRANCH_HH__ +#ifndef __PROJECT_HH__ +#define __PROJECT_HH__ #include #include @@ -13,18 +13,6 @@ class app_state; class app_state; -class branch -{ - app_state & app; - utf8 name; - outdated_indicator stamp; - std::set _heads; -public: - branch(app_state & app, utf8 const & name); - - void heads(std::set & h); -}; - class tag_t { public: @@ -38,8 +26,8 @@ class project_t class project_t { app_state & app; - std::map known_branches; - std::set actual_branches; + std::map > > branch_heads; + std::set branches; outdated_indicator indicator; public: @@ -47,7 +35,7 @@ public: void get_branch_list(std::set & names); void get_branch_list(utf8 const & glob, std::set & names); - branch & get_branch(utf8 const & name); + void get_branch_heads(utf8 const & name, std::set & heads); outdated_indicator get_tags(std::set & tags);