# # # patch "rcs_import.cc" # from [cc74b772a37ccffa216f3e7dee88df70d564d190] # to [82d53abdcb97d9ac0b49d25b95e814b92d1c8f50] # ============================================================ --- rcs_import.cc cc74b772a37ccffa216f3e7dee88df70d564d190 +++ rcs_import.cc 82d53abdcb97d9ac0b49d25b95e814b92d1c8f50 @@ -278,6 +278,11 @@ public: return events; } + void clear() + { + events.clear(); + } + blob_event_iter & begin() const { return *(new blob_event_iter(events.begin())); @@ -1460,59 +1465,43 @@ resolve_blob_dependencies(cvs_history &c cons->store_revisions(); } - void -import_cvs_repo(system_path const & cvsroot, - app_state & app) +move_symbol_events(cvs_history & cvs, const cvs_event_digest d, + shared_ptr< cvs_branch > from_branch, + shared_ptr< cvs_branch > to_branch) { - N(!directory_exists(cvsroot / "CVSROOT"), - F("%s appears to be a CVS repository root directory\n" - "try importing a module instead, with 'cvs_import %s/") - % cvsroot % cvsroot); + L(FL("moving symbol from branch %s to branch %s") + % cvs.branchname_interner.lookup(from_branch->branchname) + % cvs.branchname_interner.lookup(to_branch->branchname)); - { - // early short-circuit to avoid failure after lots of work - rsa_keypair_id key; - get_user_key(key, app); - require_password(key, app); - } + blob_index_iterator bi; - cvs_history cvs; - N(app.opts.branch_name() != "", F("need base --branch argument for importing")); - cvs.base_branch = app.opts.branch_name(); + bi = from_branch->get_blob(d, false); + cvs_blob & from_blob = from_branch->blobs[bi->second]; - // push the trunk - cvs_branchname bn = cvs.branchname_interner.intern(cvs.base_branch); - cvs.trunk = shared_ptr(new cvs_branch(bn)); - cvs.stk.push(cvs.trunk); - cvs.bstk.push(bn); + bi = to_branch->get_blob(d, false); + cvs_blob & to_blob = to_branch->blobs[bi->second]; - { - transaction_guard guard(app.db); - cvs_tree_walker walker(cvs, app.db); - require_path_is_directory(cvsroot, - F("path %s does not exist") % cvsroot, - F("'%s' is not a directory") % cvsroot); - app.db.ensure_open(); - change_current_working_dir(cvsroot); - walk_tree(file_path(), walker); - guard.commit(); - } + vector< cvs_event_ptr > & events = from_blob.get_events(); - // make sure all symbol blobs are only present in one branch - int unresolved_symbols = 99999998; - int prev_unresolved_symbols = 99999999; + for (blob_event_iter i = events.begin(); i != events.end(); ++i) + { + (*i)->dependencies.clear(); + to_blob.push_back(*i); + } - while ((unresolved_symbols > 0) && (unresolved_symbols < prev_unresolved_symbols)) - { - prev_unresolved_symbols = unresolved_symbols; - unresolved_symbols = 0; + from_blob.clear(); +} +void +mark_branch_ancestors(cvs_history & cvs) +{ map< cvs_event_digest, set< shared_ptr< cvs_branch > > >::iterator i; for (i = cvs.symbol_parents.begin(); i != cvs.symbol_parents.end(); ++i) { I(i->second.size() > 0); cvs_event_digest d = i->first; + I(!d.is_commit()); if (i->second.size() == 1) { @@ -1530,11 +1519,26 @@ import_cvs_repo(system_path const & cvsr be->branch->parent_branch = branch; } } - else if (i->second.size() > 1) - { + } +} - I(!d.is_commit()); +pair< int, int > +move_symbols(cvs_history & cvs) +{ + int unresolved_symbols = 0; + int symbols_moved = 0; + typedef vector< pair< cvs_event_digest, shared_ptr< cvs_branch > > > remp; + remp removable_parents; + + map< cvs_event_digest, set< shared_ptr< cvs_branch > > >::iterator i; + for (i = cvs.symbol_parents.begin(); i != cvs.symbol_parents.end(); ++i) + { + cvs_event_digest d = i->first; + I(!d.is_commit()); + + if (i->second.size() > 1) + { for (set< shared_ptr< cvs_branch > >::iterator j = i->second.begin(); j != i->second.end(); ++j) { @@ -1545,28 +1549,6 @@ import_cvs_repo(system_path const & cvsr shared_ptr< cvs_event > ev = *(blob.get_events().begin()); - if (d.is_branch()) - { - shared_ptr be = - boost::static_pointer_cast(ev); - - L(FL("XXXXX: Symbol (branch %s) is in branch %s") - % cvs.branchname_interner.lookup(be->branch->branchname) - % cvs.branchname_interner.lookup((*j)->branchname)); - } - else if (d.is_tag()) - { - shared_ptr te = - boost::static_pointer_cast(ev); - - L(FL("XXXXX: symbol tag %s is in branch %s") - % cvs.tag_interner.lookup(te->tag) - % cvs.branchname_interner.lookup((*j)->branchname)); - } - else - I(false); - for (set< shared_ptr< cvs_branch > >::iterator k = j; k != i->second.end(); ++k) { @@ -1576,7 +1558,9 @@ import_cvs_repo(system_path const & cvsr % cvs.branchname_interner.lookup((*j)->branchname) % cvs.branchname_interner.lookup((*k)->branchname)); - i->second.erase(*k); + move_symbol_events(cvs, d, *k, *j); + removable_parents.push_back(make_pair(d, *k)); + symbols_moved++; } else if ((*k)->parent_branch == (*j)) { @@ -1584,18 +1568,81 @@ import_cvs_repo(system_path const & cvsr % cvs.branchname_interner.lookup((*k)->branchname) % cvs.branchname_interner.lookup((*j)->branchname)); - i->second.erase(*j); + move_symbol_events(cvs, d, *j, *k); + removable_parents.push_back(make_pair(d, *j)); + symbols_moved++; } } } } } - L(FL("XXXX: still unresolved symbols: %d") % unresolved_symbols); + // remove the symbol parents of the blobs we have moved + for (remp::const_iterator w = removable_parents.begin(); + w != removable_parents.end(); ++w) + cvs.symbol_parents[w->first].erase(w->second); + + return make_pair(unresolved_symbols, symbols_moved); +} + +void +resolve_symbols(cvs_history & cvs) +{ + mark_branch_ancestors(cvs); + + pair< int, int > move_result = move_symbols(cvs); + L(FL("XXXX: unresolved symbols: %d, moved %d") % move_result.first % move_result.second); + while ((move_result.first > 0) && (move_result.second > 0)) + { + move_result = move_symbols(cvs); + L(FL("XXXX: unresolved symbols: %d, moved %d") % move_result.first % move_result.second); } + I(move_result.first == 0); +} + +void +import_cvs_repo(system_path const & cvsroot, + app_state & app) +{ + N(!directory_exists(cvsroot / "CVSROOT"), + F("%s appears to be a CVS repository root directory\n" + "try importing a module instead, with 'cvs_import %s/") + % cvsroot % cvsroot); + + { + // early short-circuit to avoid failure after lots of work + rsa_keypair_id key; + get_user_key(key, app); + require_password(key, app); + } + + cvs_history cvs; + N(app.opts.branch_name() != "", F("need base --branch argument for importing")); + cvs.base_branch = app.opts.branch_name(); + + // push the trunk + cvs_branchname bn = cvs.branchname_interner.intern(cvs.base_branch); + cvs.trunk = shared_ptr(new cvs_branch(bn)); + cvs.stk.push(cvs.trunk); + cvs.bstk.push(bn); + + { + transaction_guard guard(app.db); + cvs_tree_walker walker(cvs, app.db); + require_path_is_directory(cvsroot, + F("path %s does not exist") % cvsroot, + F("'%s' is not a directory") % cvsroot); + app.db.ensure_open(); + change_current_working_dir(cvsroot); + walk_tree(file_path(), walker); + guard.commit(); + } + I(cvs.stk.size() == 1); + resolve_symbols(cvs); + ticker n_revs(_("revisions"), "r", 1); { @@ -1604,14 +1651,28 @@ import_cvs_repo(system_path const & cvsr guard.commit(); } - for(map >::const_iterator i = - cvs.branches.begin(); i != cvs.branches.end(); ++i) + while (!cvs.branches.empty()) { - transaction_guard guard(app.db); - string branchname = cvs.branchname_interner.lookup(i->first); - shared_ptr branch = i->second; - resolve_blob_dependencies(cvs, app, branchname, branch, n_revs); - guard.commit(); + // import the first branch which has a parent_rid + map >::const_iterator i; + + for(i = cvs.branches.begin(); i != cvs.branches.end(); ++i) + { + shared_ptr branch = i->second; + if (!null_id(branch->parent_rid)) + { + transaction_guard guard(app.db); + string branchname = cvs.branchname_interner.lookup(i->first); + resolve_blob_dependencies(cvs, app, branchname, branch, n_revs); + guard.commit(); + + cvs.branches.erase(i->first); + break; + } + } + + // hopefully we found at least one branch with a parent_rid... + I(i != cvs.branches.end()); } return; @@ -1849,13 +1910,16 @@ cluster_consumer::consume_blob(const cvs shared_ptr cbe = boost::static_pointer_cast(*blob.begin()); - string child_rid_str; - dump(child_rid, child_rid_str); + if (!blob.empty()) + { + string child_rid_str; + dump(child_rid, child_rid_str); - L(FL("setting the parent revision id of branch %s to: %s") % - cvs.branchname_interner.lookup(cbe->branch->branchname) % child_rid_str); + L(FL("setting the parent revision id of branch %s to: %s") % + cvs.branchname_interner.lookup(cbe->branch->branchname) % child_rid_str); - cbe->branch->parent_rid = child_rid; + cbe->branch->parent_rid = child_rid; + } } else if (blob.get_digest().is_tag()) {