# # # patch "ChangeLog" # from [2e64be656aa168b0195d9ec59b23da88704d43e4] # to [dc1b51ef14de6d7aeddaf154b013e7329683378a] # # patch "roster.cc" # from [11db51bb0cfb000c9ae885ad56380534823fd56c] # to [154575704f1a004137ef81787e9adc2fe817aa75] # # patch "roster.hh" # from [7789b477fbc1249740d9ca6a665bd535c6d3a5b8] # to [df9734188140268cc35c9476f1cd65630d60de3a] # ============================================================ --- ChangeLog 2e64be656aa168b0195d9ec59b23da88704d43e4 +++ ChangeLog dc1b51ef14de6d7aeddaf154b013e7329683378a @@ -1,5 +1,11 @@ 2006-07-08 Nathaniel Smith + * roster.cc (mark_roster_with_no_parents) + (mark_roster_with_one_parent): New functions. + Plus tests, etc. + +2006-07-08 Nathaniel Smith + * cmd_merging.cc (pluck): Check that revisions exist before using them. ============================================================ --- roster.cc 11db51bb0cfb000c9ae885ad56380534823fd56c +++ roster.cc 154575704f1a004137ef81787e9adc2fe817aa75 @@ -1669,6 +1669,9 @@ // Warning: this function expects the parent's roster and markings in the // 'new_roster' and 'new_markings' parameters, and they are modified // destructively! + // This function performs an almost identical task to + // mark_roster_with_one_parent; however, for efficiency, it is implemented + // in a different, destructive way. void make_roster_for_nonmerge(cset const & cs, revision_id const & new_rid, @@ -1694,6 +1697,8 @@ } } +// WARNING: this function is not tested directly (no unit tests). Do not +// put real logic in it. void make_roster_for_base_plus_cset(revision_id const & base, cset const & cs, revision_id const & new_rid, @@ -1704,10 +1709,52 @@ MM(base); MM(cs); app.db.get_roster(base, new_roster, new_markings); - editable_roster_for_nonmerge er(new_roster, nis, new_rid, new_markings); - cs.apply_to(er); + make_roster_for_nonmerge(cs, new_rid, new_roster, new_markings, nis); } +void +mark_roster_with_no_parents(revision_id const & rid, + roster_t const & roster, + marking_map & markings) +{ + roster_t mock_parent; + marking_map mock_parent_markings; + mark_roster_with_one_parent(mock_parent, mock_parent_markings, + rid, roster, markings); +} + +void +mark_roster_with_one_parent(roster_t const & parent, + marking_map const & parent_markings, + revision_id const & child_rid, + roster_t const & child, + marking_map & child_markings) +{ + MM(parent); + MM(parent_markings); + MM(child_rid); + MM(child); + MM(child_markings); + + I(!null_id(child_rid)); + child_markings.clear(); + + for (node_map::const_iterator i = child.all_nodes().begin(); + i != child.all_nodes().end(); ++i) + { + marking_t new_marking; + if (parent.has_node(i->first)) + mark_unmerged_node(safe_get(parent_markings, i->first), + parent.get_node(i->first), + child_rid, i->second, new_marking); + else + mark_new_node(child_rid, i->second, new_marking); + safe_insert(child_markings, std::make_pair(i->first, new_marking)); + } + + child.check_sane_against(child_markings); +} + // WARNING: this function is not tested directly (no unit tests). Do not put // real logic in it. void @@ -3656,6 +3703,17 @@ I(equal_up_to_renumbering(expected_roster, expected_markings, new_roster, new_markings)); + + marking_map new_markings2; MM(new_markings2); + mark_roster_with_no_parents(old_rid, new_roster, new_markings2); + I(new_markings == new_markings2); + + marking_map new_markings3; MM(new_markings3); + roster_t parent3; + marking_map old_markings3; + mark_roster_with_one_parent(parent3, old_markings3, old_rid, new_roster, + new_markings3); + I(new_markings == new_markings3); } static void @@ -3692,6 +3750,11 @@ I(equal_up_to_renumbering(expected_roster, expected_markings, new_roster, new_markings)); + + marking_map new_markings2; MM(new_markings2); + mark_roster_with_one_parent(parent_roster, parent_markings, + new_rid, new_roster, new_markings2); + I(new_markings == new_markings2); } static void ============================================================ --- roster.hh 7789b477fbc1249740d9ca6a665bd535c6d3a5b8 +++ roster.hh df9734188140268cc35c9476f1cd65630d60de3a @@ -373,15 +373,30 @@ extract_roster_path_set(roster_t const & ros, path_set & paths); +// These three functions are for the use of things like 'update' or 'pluck', +// that need to construct fake rosters and/or markings in-memory, to achieve +// particular merge results. void make_roster_for_base_plus_cset(revision_id const & base, cset const & cs, revision_id const & new_rid, - roster_t & result, - marking_map & marking, + roster_t & new_rister, + marking_map & new_markings, node_id_source & nis, app_state & app); +void +mark_roster_with_no_parents(revision_id const & rid, + roster_t const & roster, + marking_map & markings); +void +mark_roster_with_one_parent(roster_t const & parent, + marking_map const & parent_markings, + revision_id const & child_rid, + roster_t const & child, + marking_map & child_markings); +// This is for revisions that are being written to the db, only. It assigns +// permanent node ids. void make_roster_for_revision(revision_set const & rev, revision_id const & rid,