# # add_file "tests/t_annotate_copy_all.at" # # patch "ChangeLog" # from [b70f4bc635272fbf3619bec37793b47dc9bdb0a9] # to [83de8f650b69109fed31390b06c3e9abf390f387] # # patch "annotate.cc" # from [1dd789567a3f3a5fee5a3f1c0756e3a85c5486cd] # to [9a6c5f09fe709c2d8e38f82508bdc1b88871757d] # # patch "tests/t_annotate_copy_all.at" # from [] # to [a8469eb56dee949ccd34ee480ee4fae8cbc73e17] # # patch "testsuite.at" # from [0a779c26fbcdad4634e0d15f4449931709e18f81] # to [2bdc42e2de266df08209e216afe489f69de95fa1] # --- ChangeLog +++ ChangeLog @@ -1,3 +1,11 @@ +2005-05-01 Emile Snyder + + * annotate.cc: Fix bug that njs pointed out when a merge has one + side with no changes. Be smarter about how we get parent + file_id's to do file diffs; give another big speedup. + * tests/t_annotate_copy_all.at: New test for the bug that is fixed. + * testsuite.at: Add the new test. + 2005-05-02 Richard Levitte * tests/t_override_author_date.at: Adapt to the new way to give --- annotate.cc +++ annotate.cc @@ -139,6 +139,8 @@ void credit_mapped_lines (boost::shared_ptr acp) const; + void set_copied_all_mapped (boost::shared_ptr acp) const; + private: void init_with_lines(const std::vector &lines); @@ -424,18 +426,13 @@ } -static file_id -find_file_id_in_revision(app_state &app, file_path fpath, revision_id rid) +void +annotate_lineage_mapping::set_copied_all_mapped (boost::shared_ptr acp) const { - // 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(fpath); - I(i != mm.end()); - file_id fid = manifest_entry_id(*i); - return fid; + std::vector::const_iterator i; + for (i=mapping.begin(); i != mapping.end(); i++) { + acp->set_copied(*i); + } } @@ -449,11 +446,6 @@ nodes_seen.insert(work_unit.node_revision); revision_id null_revision; // initialized to 0 by default? - // get the revisions parents - std::set parents; - app.db.get_revision_parents(work_unit.node_revision, parents); - //L(F("do_annotate_node found %d parents for node %s\n") % parents.size() % work_unit.node_revision); - int added_in_parent_count = 0; revision_set rev; @@ -461,13 +453,13 @@ if (rev.edges.size() == 0) { // work_unit.node_revision is a root node - I(parents.size() == 1); 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); return; } + // 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++) { L(F("do_annotate_node processing edge from parent %s to child %s\n") % edge_old_revision(i) % work_unit.node_revision); @@ -483,11 +475,15 @@ file_path parent_fpath = apply_change_set_inverse(cs, work_unit.node_fpath); L(F("file %s in parent revision %s is %s\n") % work_unit.node_fpath % edge_old_revision(i) % parent_fpath); I(!(parent_fpath == std::string(""))); - file_id parent_fid = find_file_id_in_revision(app, parent_fpath, edge_old_revision(i)); + //file_id parent_fid = find_file_id_in_revision(app, parent_fpath, edge_old_manifest(i)); + change_set::delta_map::const_iterator fdelta_iter = cs.deltas.find(parent_fpath); + file_id parent_fid = work_unit.node_fid; boost::shared_ptr parent_lineage; - if (! (work_unit.node_fid == parent_fid)) { + if (fdelta_iter != cs.deltas.end()) { // then the file changed + I(delta_entry_dst(fdelta_iter) == work_unit.node_fid); + parent_fid = delta_entry_src(fdelta_iter); file_data data; app.db.get_file_version(parent_fid, data); @@ -496,6 +492,7 @@ data); } else { parent_lineage = work_unit.lineage; + parent_lineage->set_copied_all_mapped(work_unit.annotations); } // if this parent has not yet been queued for processing, create the work unit for it. @@ -507,9 +504,9 @@ } I(added_in_parent_count >= 0); - I((size_t)added_in_parent_count <= parents.size()); - if ((size_t)added_in_parent_count == parents.size()) { - //L(F("added_in_parent_count == parents.size(), credit_mapped_lines to %s\n") + I((size_t)added_in_parent_count <= rev.edges.size()); + if ((size_t)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); } --- tests/t_annotate_copy_all.at +++ tests/t_annotate_copy_all.at @@ -0,0 +1,67 @@ +AT_SETUP([annotate where one parent is full copy]) +MONOTONE_SETUP + +# +# A Where B -> D is no change, but +# / \ C -> D shows a delta for a line modified in +# B C B. +# \ / +# D +# + +AT_DATA(A, [a +b +c +]) + +AT_DATA(B, [a +b +x +y +c +]) + +# C == A +# D == B + +AT_CHECK(cp A foo) +ADD_FILE(initialfile, [foo +file +]) +AT_CHECK(MONOTONE add foo, [], [ignore], [ignore]) +COMMIT(testbranch) +REVA=`BASE_REVISION` + + +AT_CHECK(cp B foo) +COMMIT(testbranch) +REVB=`BASE_REVISION` + + +REVERT_TO($REVA) +AT_CHECK(cp A initialfile) +COMMIT(testbranch) +REVC=`BASE_REVISION` + + +AT_CHECK(MONOTONE merge, [], [ignore], [ignore]) +AT_CHECK(MONOTONE update, [], [ignore], [ignore]) +REVD=`BASE_REVISION` + +# +# annotate foo should now be +# REVA: a +# REVA: b +# REVB: x +# REVB: y +# REVA: c +# + +AT_CHECK(MONOTONE annotate foo, [], [stdout], [ignore]) +AT_CHECK(head -n 1 stdout | grep $REVA, [0], [ignore], [ignore]) +AT_CHECK(head -n 2 stdout | tail -n 1 | grep $REVA, [0], [ignore], [ignore]) +AT_CHECK(head -n 3 stdout | tail -n 1 | grep $REVB, [0], [ignore], [ignore]) +AT_CHECK(head -n 4 stdout | tail -n 1 | grep $REVB, [0], [ignore], [ignore]) +AT_CHECK(head -n 5 stdout | tail -n 1 | grep $REVA, [0], [ignore], [ignore]) + +AT_CLEANUP --- testsuite.at +++ testsuite.at @@ -595,3 +595,4 @@ m4_include(tests/t_annotate_branch_collision.at) m4_include(tests/t_netsync_error.at) m4_include(tests/t_options.at) +m4_include(tests/t_annotate_copy_all.at)