# # patch "commands.cc" # from [e786428e36bd7fc5df44bd4d98eb400e5dfc4239] # to [4a23bb5b1bf2813b1c2d6bd10821f8ee0bebc974] # # patch "database.cc" # from [375b41de0123b0e22c4e46b3c90d441fcf54cd01] # to [f98c41412a4707c6a310fd1e841523ad6f7f163e] # # patch "revision.cc" # from [a8dee743a7af7356d2a83a121c3210e8047fa797] # to [1f01aaf3b641cd4326c1dcefc12d5369d336dc35] # # patch "revision.hh" # from [fdad23c4f8f0c15ca9e9e9473e8f6b99d5b5259c] # to [6740497b6f3223f1cdd398e4bab8cd2e612d2fa4] # # patch "roster4.cc" # from [600f447ec1fac592432f0952b9b477c234d8881e] # to [00d25b977bb74b70ea97f126624e2216c6856aa2] # # patch "roster4.hh" # from [511de3285fb474b535d59d20c8268ad2288e2260] # to [9a8d95210af80e86f73c23d6d146032ea15fca5e] # ======================================================================== --- commands.cc e786428e36bd7fc5df44bd4d98eb400e5dfc4239 +++ commands.cc 4a23bb5b1bf2813b1c2d6bd10821f8ee0bebc974 @@ -2103,13 +2103,10 @@ app.db.migrate(); else if (idx(args, 0)() == "check") check_db(app); -/* -// FIXME_ROSTERS: disabled until rewritten to use rosters else if (idx(args, 0)() == "changesetify") build_changesets_from_manifest_ancestry(app); else if (idx(args, 0)() == "rebuild") build_changesets_from_existing_revs(app); -*/ else throw usage(name); } ======================================================================== --- database.cc 375b41de0123b0e22c4e46b3c90d441fcf54cd01 +++ database.cc f98c41412a4707c6a310fd1e841523ad6f7f163e @@ -1386,9 +1386,12 @@ roster_t parent_roster; marking_map ignored; manifest_id parent_mid; - get_roster(edge_old_revision(i), parent_roster, ignored); - calculate_ident(parent_roster, parent_mid); - I(edge_old_manifest(i) == parent_mid); + if (!edge_old_revision(i).inner()().empty()) + { + get_roster(edge_old_revision(i), parent_roster, ignored); + calculate_ident(parent_roster, parent_mid); + I(edge_old_manifest(i) == parent_mid); + } } } @@ -2483,6 +2486,12 @@ database::get_roster_id_for_revision(revision_id const & rev_id, hexenc & roster_id) { + if (rev_id.inner()().empty()) + { + roster_id = hexenc(); + return; + } + results res; string data_table = "rosters"; string delta_table = "roster_deltas"; @@ -2502,6 +2511,13 @@ roster_t & roster, marking_map & marks) { + if (rev_id.inner()().empty()) + { + roster = roster_t(); + marks = marking_map(); + return; + } + string data_table = "rosters"; string delta_table = "roster_deltas"; data dat; @@ -2540,7 +2556,7 @@ rev_id.inner()().c_str()); transaction_guard guard(*this); - if (res.size() != 0) + if (res.size() != 0 && !res[0][0].empty()) { // There's a parent revision; we are going to do delta // compression on the roster by using the roster associated with @@ -2573,7 +2589,7 @@ } // nb: rosters schema is (id, rev_id, data) - string query = "INSERT INTO " + data_table + " VALUES(?, ?, ?, ?)"; + string query = "INSERT INTO " + data_table + " VALUES(?, ?, ?)"; execute(query.c_str(), ident().c_str(), rev_id.inner()().c_str(), new_data_packed().c_str()); ======================================================================== --- revision.cc a8dee743a7af7356d2a83a121c3210e8047fa797 +++ revision.cc 1f01aaf3b641cd4326c1dcefc12d5369d336dc35 @@ -958,6 +958,11 @@ return node; } +static void +get_manifest_for_rev(app_state & app, + revision_id const & ident, + manifest_id & mid); + u64 anc_graph::add_node_for_old_revision(revision_id const & rev) { I(existing_graph); @@ -969,7 +974,7 @@ ++n_nodes; manifest_id man; - app.db.get_revision_manifest(rev, man); + get_manifest_for_rev(app, rev, man); L(F("node %d = revision %s = manifest %s\n") % node % rev % man); old_rev_to_node.insert(std::make_pair(rev, node)); @@ -1210,6 +1215,23 @@ } + // It is possible that we're at a "root" node here -- a node + // which had no parent in the old rev graph -- in which case we + // synthesize an edge from the empty revision to the current, + // containing a cset which adds all the files in the child. + + if (rev.edges.empty()) + { + revision_id parent_rid; + boost::shared_ptr parent_roster = boost::shared_ptr(new roster_t()); + boost::shared_ptr cs = boost::shared_ptr(new cset()); + make_cset(*parent_roster, child_roster, *cs); + manifest_id parent_manifest_id; + safe_insert (rev.edges, std::make_pair (parent_rid, + std::make_pair (parent_manifest_id, cs))); + + } + // Finally, put all this excitement into the database and save // the new_rid for use in the cert-writing pass. @@ -1217,6 +1239,9 @@ calculate_ident(rev, new_rid); node_to_new_rev.insert(std::make_pair(child, new_rid)); + L(F("made revision %s with %d edges, manifest id = %s\n") + % new_rid % rev.edges.size() % rev.new_manifest); + if (!app.db.revision_exists (new_rid)) { L(F("mapped node %d to revision %s\n") % child % new_rid); @@ -1317,6 +1342,41 @@ } +// HACK: this is a special reader which picks out the new_manifest field in +// a revision; it ignores all other symbols. This is because, in the +// pre-roster database, we have revisions holding change_sets, not +// csets. If we apply the cset reader to them, they fault. We need to +// *partially* read them, however, in order to get the manifest IDs out of +// the old revisions (before we delete the revs and rebuild them) + +static void +get_manifest_for_rev(app_state & app, + revision_id const & ident, + manifest_id & mid) +{ + revision_data dat; + app.db.get_revision(ident,dat); + std::istringstream iss(dat.inner()()); + basic_io::input_source src(iss, "revision"); + basic_io::tokenizer tok(src); + basic_io::parser pars(tok); + while (pars.symp()) + { + if (pars.symp(syms::new_manifest)) + { + std::string tmp; + pars.sym(); + pars.hex(tmp); + mid = manifest_id(tmp); + return; + } + else + pars.sym(); + } + I(false); +} + + void print_edge(basic_io::printer & printer, edge_entry const & e) ======================================================================== --- revision.hh fdad23c4f8f0c15ca9e9e9473e8f6b99d5b5259c +++ revision.hh 6740497b6f3223f1cdd398e4bab8cd2e612d2fa4 @@ -169,12 +169,13 @@ app_state & app, cset & composed); +*/ + void build_changesets_from_manifest_ancestry(app_state & app); void build_changesets_from_existing_revs(app_state & app); -*/ // basic_io access to printers and parsers ======================================================================== --- roster4.cc 600f447ec1fac592432f0952b9b477c234d8881e +++ roster4.cc 00d25b977bb74b70ea97f126624e2216c6856aa2 @@ -466,7 +466,10 @@ return has_root(); } - I(has_root()); + // If we have no root, we *definitely* don't have a non-root path + if (!has_root()) + return false; + dir_t d = root_dir; for (split_path::const_iterator i = dirname.begin()+1; i != dirname.end(); ++i) { @@ -743,7 +746,7 @@ } void -roster_t::check_sane() const +roster_t::check_sane(bool temp_nodes_ok) const { I(has_root()); node_map::const_iterator ri; @@ -753,7 +756,9 @@ ++ri) { node_id nid = ri->first; - I(!null_node(nid) && !temp_node(nid)); + I(!null_node(nid)); + if (!temp_nodes_ok) + I(!temp_node(nid)); node_t n = ri->second; I(n->self == nid); if (is_dir_t(n)) @@ -1964,7 +1969,7 @@ if (print_local_parts) ros.check_sane_against(mm); else - ros.check_sane(); + ros.check_sane(true); std::ostringstream oss; basic_io::printer pr(oss); ros.print_to(pr, mm, print_local_parts); ======================================================================== --- roster4.hh 511de3285fb474b535d59d20c8268ad2288e2260 +++ roster4.hh 9a8d95210af80e86f73c23d6d146032ea15fca5e @@ -199,7 +199,7 @@ bool operator==(roster_t const & other) const; - void check_sane() const; + void check_sane(bool temp_nodes_ok=false) const; // verify that this roster is sane, and corresponds to the given // marking map