# # patch "annotate.cc" # from [83bfd6473665ec34b1806987f08163e3df39b22f] # to [684fd4e9338f8c12aedce140f0840eb85cf49bdc] # # patch "annotate.hh" # from [c18c25ad6a2f8244aee67bb4948a8eadccafe7c4] # to [fa08bd0d934bb739c0ac61726c9c6b698605ad9f] # # patch "commands.cc" # from [5d703f0d21ba088792d9d367d6dc063761c9ac1f] # to [54c07a8e6bef36f960a7794e8a48830f8ad3477d] # ======================================================================== --- annotate.cc 83bfd6473665ec34b1806987f08163e3df39b22f +++ annotate.cc 684fd4e9338f8c12aedce140f0840eb85cf49bdc @@ -1,3 +1,4 @@ +// -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*- // copyright (C) 2005 emile snyder // all rights reserved. // licensed to the public under the terms of the GNU GPL (>= 2) @@ -118,26 +119,25 @@ struct annotate_node_work { annotate_node_work (boost::shared_ptr annotations_, boost::shared_ptr lineage_, - revision_id node_revision_, file_id node_fid_, file_path node_fpath_) + revision_id revision_, node_id fid_)//, file_path node_fpath_) : annotations(annotations_), lineage(lineage_), - node_revision(node_revision_), - node_fid(node_fid_), - node_fpath(node_fpath_) + revision(revision_), + fid(fid_)//, node_fpath(node_fpath_) {} annotate_node_work (const annotate_node_work &w) : annotations(w.annotations), lineage(w.lineage), - node_revision(w.node_revision), - node_fid(w.node_fid), - node_fpath(w.node_fpath) + revision(w.revision), + fid(w.fid) //, node_fpath(w.node_fpath) {} boost::shared_ptr annotations; boost::shared_ptr lineage; - revision_id node_revision; - file_id node_fid; - file_path node_fpath; + revision_id revision; + //file_id node_fid; + node_id fid; + //file_path node_fpath; }; @@ -502,41 +502,80 @@ const std::map &paths_to_nodes, std::map &pending_merge_nodes) { -/* -// FIXME_ROSTERS: disabled until rewritten to use rosters - L(F("do_annotate_node for node %s\n") % work_unit.node_revision); - I(nodes_complete.find(work_unit.node_revision) == nodes_complete.end()); - //nodes_seen.insert(std::make_pair(work_unit.node_revision, work_unit.lineage)); + L(F("do_annotate_node for node %s\n") % work_unit.revision); + I(nodes_complete.find(work_unit.revision) == nodes_complete.end()); + //nodes_seen.insert(std::make_pair(work_unit.revision, work_unit.lineage)); - revision_set rev; - app.db.get_revision(work_unit.node_revision, rev); + roster_t roster; + marking_map markmap; + app.db.get_roster(work_unit.revision, roster, markmap); + marking_t marks; + std::map::const_iterator mmi = markmap.find(work_unit.fid); + I(mmi != markmap.end()); + marks = mmi->second; - if (rev.edges.size() == 0) { - L(F("do_annotate_node credit_mapped_lines to revision %s\n") % work_unit.node_revision); - work_unit.lineage->credit_mapped_lines(work_unit.annotations); - work_unit.annotations->evaluate(work_unit.node_revision); - nodes_complete.insert(work_unit.node_revision); - return; - } + if (marks.file_content.size() == 0) + { + L(F("do_annotate_node credit_mapped_lines to revision %s\n") % work_unit.revision); + work_unit.lineage->credit_mapped_lines(work_unit.annotations); + work_unit.annotations->evaluate(work_unit.revision); + nodes_complete.insert(work_unit.revision); + return; + } - // if all deltas backwards have to add the file, then we credit any mapped but - // unassigned lines in our lineage to this revision. gotta count adds to compare to number - // of parent revs. + // if all edges from the parent revs to this (work_unit.revision) child have + // to add the file, then we credit any mapped but unassigned lines in our lineage + // to this revision. so we count adds to compare to number of parent revs. size_t added_in_parent_count = 0; + // iterate over set of content marks from the roster. each one represents + // a development history where a committer expressed an intention about a change + // in the content of the file we're interested in. + for (std::set::const_iterator i = marks.file_content.begin(); + i != marks.file_content.end(); + i++) + { + roster_t parent_roster; + marking_map parent_marks; + L(F("do_annotate_node processing edge from parent %s to child %s\n") % *i % work_unit.revision); + app.db.get_roster(*i, parent_roster, parent_marks); + + // determine if the file changed on this edge... + //node_t parent_node = parent_roster.get_node(work_unit.fid); + //if (null_node(parent_node)) + // { + // L(F("file added in %s, continuing\n") % work_unit.revision); + // added_in_parent++; + // continue; + // } + + // ok, wasn't added in this parent->child edge, but might have + // been renamed/moved. + + // I() that the file content is different, since that's what the + // mark that got us to the parent_revision was supposed to indicate + } + + I(added_in_parent_count <= marks.file_content.size()); + if (added_in_parent_count == marks.file_content.size()) + { + //L(F("added_in_parent_count == marks.file_content.size(), credit_mapped_lines to %s\n") % work_unit.revision); + work_unit.lineage->credit_mapped_lines(work_unit.annotations); + } + + work_unit.annotations->evaluate(work_unit.revision); + nodes_complete.insert(work_unit.revision); + +/* +// FIXME_ROSTERS: disabled until rewritten to use rosters + // edges are from parent -> child where child is our work_unit node for (edge_map::const_iterator i = rev.edges.begin(); i != rev.edges.end(); i++) { - revision_id parent_revision = edge_old_revision(i); - L(F("do_annotate_node processing edge from parent %s to child %s\n") % parent_revision % work_unit.node_revision); + ... snip change_set cs = edge_changes(i); - if (cs.rearrangement.added_files.find(work_unit.node_fpath) != cs.rearrangement.added_files.end()) - { - L(F("file %s added in %s, continuing\n") % work_unit.node_fpath % work_unit.node_revision); - added_in_parent_count++; - continue; - } + ... snip // even if the file was renamed in the parent, that's represented as 'rename oldname -> newname' // plus 'patch newname -> newname', so we don't have to find the oldname in the parent before @@ -594,9 +633,9 @@ { // already a pending node, so we just have to merge the lineage and decide whether to move it // over to the nodes_to_process queue - L(F("merging lineage from node %s to parent %s\n") % work_unit.node_revision % parent_revision); + L(F("merging lineage from node %s to parent %s\n") % work_unit.revision % parent_revision); lmn->second.merge(parent_lineage, work_unit.annotations); - //L(F("after merging from work revision %s to parent %s lineage_merge_node is:\n") % work_unit.node_revision % parent_revision); + //L(F("after merging from work revision %s to parent %s lineage_merge_node is:\n") % work_unit.revision % parent_revision); //lmn->second.dump(); if (lmn->second.iscomplete()) { nodes_to_process.push_back(lmn->second.get_work()); @@ -605,15 +644,7 @@ } } - I(added_in_parent_count <= rev.edges.size()); - if (added_in_parent_count == rev.edges.size()) - { - //L(F("added_in_parent_count == rev.edges.size(), credit_mapped_lines to %s\n") % work_unit.node_revision); - work_unit.lineage->credit_mapped_lines(work_unit.annotations); - } - - work_unit.annotations->evaluate(work_unit.node_revision); - nodes_complete.insert(work_unit.node_revision); + ... done */ } @@ -650,11 +681,11 @@ } void -do_annotate (app_state &app, file_path fpath, file_id fid, revision_id rid) +do_annotate (app_state &app, file_t file_node, revision_id rid) { - L(F("annotating file %s with id %s in revision %s\n") % fpath % fid % rid); + L(F("annotating file %s with content %s in revision %s\n") % file_node->self % file_node->content % rid); - boost::shared_ptr acp(new annotate_context(fid, app)); + boost::shared_ptr acp(new annotate_context(file_node->content, app)); boost::shared_ptr lineage = acp->initial_lineage(); std::set nodes_complete; @@ -664,14 +695,16 @@ // build node work unit std::deque nodes_to_process; - annotate_node_work workunit(acp, lineage, rid, fid, fpath); + annotate_node_work workunit(acp, lineage, rid, file_node->self); //, fpath); nodes_to_process.push_back(workunit); - while (nodes_to_process.size() && !acp->is_complete()) { - annotate_node_work work = nodes_to_process.front(); - nodes_to_process.pop_front(); - do_annotate_node(work, app, nodes_to_process, nodes_complete, paths_to_nodes, pending_merge_nodes); - } + while (nodes_to_process.size() && !acp->is_complete()) + { + annotate_node_work work = nodes_to_process.front(); + nodes_to_process.pop_front(); + do_annotate_node(work, app, nodes_to_process, nodes_complete, paths_to_nodes, pending_merge_nodes); + } + I(pending_merge_nodes.size() == 0); acp->annotate_equivalent_lines(); I(acp->is_complete()); ======================================================================== --- annotate.hh c18c25ad6a2f8244aee67bb4948a8eadccafe7c4 +++ annotate.hh fa08bd0d934bb739c0ac61726c9c6b698605ad9f @@ -11,6 +11,6 @@ #include "revision.hh" #include "app_state.hh" -extern void do_annotate (app_state &app, file_path fpath, file_id fid, revision_id rid); +extern void do_annotate (app_state &app, file_t file_node, revision_id rid); #endif // defined __ANNOTATE_HH__ ======================================================================== --- commands.cc 5d703f0d21ba088792d9d367d6dc063761c9ac1f +++ commands.cc 54c07a8e6bef36f960a7794e8a48830f8ad3477d @@ -1365,8 +1365,6 @@ cout << ident << endl; } -/* -// FIXME_ROSTERS: disabled until rewritten to use rosters CMD(cat, N_("informative"), N_("FILENAME"), N_("write file from database to stdout"), @@ -1380,7 +1378,6 @@ transaction_guard guard(app.db); - file_id ident; revision_id rid; if (app.revision_selectors.size() == 0) get_revision_id(rid); @@ -1391,15 +1388,18 @@ // paths are interpreted as standard external ones when we're in a // working copy, but as project-rooted external ones otherwise file_path fp; + split_path sp; fp = file_path_external(idx(args, 0)); - manifest_id mid; - app.db.get_revision_manifest(rid, mid); - manifest_map m; - app.db.get_manifest(mid, m); - manifest_map::const_iterator i = m.find(fp); - N(i != m.end(), F("no file '%s' found in revision '%s'\n") % fp % rid); - ident = manifest_entry_id(i); - + fp.split(sp); + + roster_t roster; + marking_map marks; + app.db.get_roster(rid, roster, marks); + node_t node = roster.get_node(sp); + N((!null_node(node->self) && is_file_t(node)), F("no file '%s' found in revision '%s'\n") % fp % rid); + + file_t file_node = downcast_to_file_t(node); + file_id ident = file_node->content; file_data dat; L(F("dumping file '%s'\n") % ident); app.db.get_file_version(ident, dat); @@ -1408,6 +1408,8 @@ guard.commit(); } +/* +// FIXME_ROSTERS: disabled until rewritten to use rosters CMD(checkout, N_("tree"), N_("[DIRECTORY]\n"), N_("check out a revision from database into directory.\n" "If a revision is given, that's the one that will be checked out.\n" @@ -3515,10 +3517,14 @@ } +/* +// FIXME_ROSTERS: disabled until rewritten to use rosters CMD(annotate, N_("informative"), N_("PATH"), N_("print annotated copy of the file from REVISION"), OPT_REVISION) { + // this function compiles, but the do_annotate() stuff in annotate.cc is + // still in flux, so disabling command here. revision_id rid; if (app.revision_selectors.size() == 0) @@ -3528,6 +3534,9 @@ throw usage(name); file_path file = file_path_external(idx(args, 0)); + split_path sp; + file.split(sp); + if (app.revision_selectors.size() == 0) get_revision_id(rid); else @@ -3539,21 +3548,17 @@ L(F("annotate file file_path '%s'\n") % file); // find the version of the file requested - manifest_map mm; - revision_set rev; - app.db.get_revision(rid, rev); - app.db.get_manifest(rev.new_manifest, mm); - manifest_map::const_iterator i = mm.find(file); - N(i != mm.end(), - F("no such file '%s' in revision '%s'\n") % file % rid); - file_id fid = manifest_entry_id(*i); - L(F("annotate for file_id %s\n") % manifest_entry_id(*i)); + roster_t roster; + marking_map marks; + app.db.get_roster(rid, roster, marks); + node_t node = roster.get_node(sp); + N((!null_node(node->self) && is_file_t(node)), F("no file '%s' found in revision '%s'\n") % file % rid); - do_annotate(app, file, fid, rid); + file_t file_node = downcast_to_file_t(node); + L(F("annotate for file_id %s\n") % file_node->self); + do_annotate(app, file_node, rid); } -/* -// FIXME_ROSTERS: disabled until rewritten to use rosters CMD(log, N_("informative"), N_("[FILE]"), N_("print history in reverse order (filtering by 'FILE'). If one or more\n" "revisions are given, use them as a starting point."),