#
# 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)