# # # patch "ChangeLog" # from [4714a67c78c948868a09ed8add6e3a610eaa70a1] # to [ad68b2fb9f2d4b838df4ea4ac2df15c3ad37694c] # # patch "commands.cc" # from [119a3d642f8c1e38fa2e455ee708523b805d1faf] # to [44215afc9d7c1dace2bae56ae8427e4e906e1251] # # patch "tests/t_update_to_revision.at" # from [883c66fa494c93d79518368f88752de1821a0951] # to [b6f804cced8a6863a91e4fef319b8f427762001e] # ============================================================ --- ChangeLog 4714a67c78c948868a09ed8add6e3a610eaa70a1 +++ ChangeLog ad68b2fb9f2d4b838df4ea4ac2df15c3ad37694c @@ -1,3 +1,8 @@ +2005-01-24 Timothy Brownawell + + * commands.cc (update): Allow backwards/sideways updates. + tests/t_update_to_revision.at: remove XFAIL + 2006-01-24 Vinzenz Feenstra * query_args.hh: Introduced struct query_args and struct ============================================================ --- commands.cc 119a3d642f8c1e38fa2e455ee708523b805d1faf +++ commands.cc 44215afc9d7c1dace2bae56ae8427e4e906e1251 @@ -2807,10 +2807,10 @@ OPT_BRANCH_NAME % OPT_REVISION) { revision_set r_old, r_working, r_new; - roster_t working_roster, chosen_roster; + roster_t working_roster, chosen_roster, target_roster; boost::shared_ptr old_roster = boost::shared_ptr(new roster_t()); - marking_map working_mm, chosen_mm, merged_mm; - revision_id r_old_id, r_working_id, r_chosen_id; + marking_map working_mm, chosen_mm, merged_mm, target_mm; + revision_id r_old_id, r_working_id, r_chosen_id, r_target_id; if (args.size() > 0) throw usage(name); @@ -2911,18 +2911,34 @@ // updates". That is, you can only "update" to new base revisions which // are descendents of the base revision you have in your working copy. - N(is_ancestor(r_old_id, r_chosen_id, app), - F("Update target is not a descendent of working copy base revision\n")); - app.db.get_roster(r_chosen_id, chosen_roster, chosen_mm); std::set working_uncommon_ancestors, chosen_uncommon_ancestors; - app.db.get_uncommon_ancestors(r_old_id, r_chosen_id, - working_uncommon_ancestors, - chosen_uncommon_ancestors); + if (is_ancestor(r_old_id, r_chosen_id, app)) + { + target_roster = chosen_roster; + target_mm = chosen_mm; + r_target_id = r_chosen_id; + app.db.get_uncommon_ancestors(r_old_id, r_chosen_id, + working_uncommon_ancestors, + chosen_uncommon_ancestors); + } + else + { + cset transplant; + make_cset (*old_roster, chosen_roster, transplant); + // just pick something, all that's important is that it not + // match the work revision or any ancestors of the base revision. + r_target_id = revision_id(hexenc("5432100000000000000000000500000000000000")); + make_roster_for_base_plus_cset(r_old_id, + transplant, + r_target_id, + target_roster, target_mm, app); + chosen_uncommon_ancestors.insert(r_target_id); + } // Note that under the definition of mark-merge, the working copy is an // "uncommon ancestor" if itself too, even though it was not present in @@ -2934,19 +2950,20 @@ roster_merge_result result; roster_merge(working_roster, working_mm, working_uncommon_ancestors, - chosen_roster, chosen_mm, chosen_uncommon_ancestors, + target_roster, target_mm, chosen_uncommon_ancestors, result); roster_t & merged_roster = result.roster; content_merge_working_copy_adaptor wca(app, old_roster); - resolve_merge_conflicts (r_old_id, r_chosen_id, - working_roster, chosen_roster, - working_mm, chosen_mm, + resolve_merge_conflicts (r_old_id, r_target_id, + working_roster, target_roster, + working_mm, target_mm, result, wca, app); I(result.is_clean()); - merged_roster.check_sane(); + // temporary node ids may appear if updating to a non-ancestor + merged_roster.check_sane(true); // we have the following // @@ -2965,7 +2982,7 @@ cset update, remaining; make_cset (working_roster, merged_roster, update); - make_cset (chosen_roster, merged_roster, remaining); + make_cset (target_roster, merged_roster, remaining); // { // data t1, t2, t3; ============================================================ --- tests/t_update_to_revision.at 883c66fa494c93d79518368f88752de1821a0951 +++ tests/t_update_to_revision.at b6f804cced8a6863a91e4fef319b8f427762001e @@ -1,13 +1,9 @@ # -*- Autoconf -*- AT_SETUP([updating to a given revision]) MONOTONE_SETUP -# This test relies on forward updating -# (which is disabled in monotone at the moment) -AT_XFAIL_IF(true) - AT_DATA(root, [first line of the file second line of the file third line of the file