# # # patch "cmd_db.cc" # from [249a3148b5f97e77a942f350028fb5a1e1e1db6e] # to [bae93d0020005d845ef331479b4fd2bc1e38f155] # # patch "work.cc" # from [3457f59b916125d93bc6441df70cc73a06b3166e] # to [fd25118fc6399fd14417b3cf570a212b034ea860] # # patch "work.hh" # from [76fd17a13f66cc7f9219c08313c27d4f6b1a8985] # to [8f753ef66b7b0eb6402f9b132f79e2615d4aa00d] # ============================================================ --- cmd_db.cc 249a3148b5f97e77a942f350028fb5a1e1e1db6e +++ cmd_db.cc bae93d0020005d845ef331479b4fd2bc1e38f155 @@ -137,45 +137,46 @@ CMD(db_kill_rev_locally, "kill_rev_local // particular revision to _MTN/revision to allow the user redo his (fixed) // commit afterwards. Of course we can't do this at all if // - // a) the user is currently not inside a workspace + // a) the user is currently not inside a workspace, or is in some other + // workspace // b) the user has updated the current workspace to another revision already // thus the working revision is no longer based on the revision we're // trying to kill - // c) there are uncomitted changes in the working revision of this workspace. - // this *eventually* could be handled with a workspace merge scenario, but - // is left out for now app.allow_workspace(); if (app.found_workspace) { - revision_t old_work_rev; - app.work.get_work_rev(old_work_rev); + parent_map parents; + roster_t curr_roster; + temp_node_id_source nis; + app.work.get_work_state_shape_only(parents, curr_roster, nis); - for (edge_map::const_iterator i = old_work_rev.edges.begin(); - i != old_work_rev.edges.end(); i++) + if (parents.size() == 1 && parent_id(parents.begin()) == revid) { - if (edge_old_revision(i) != revid) - continue; - - N(!app.work.has_changes(), - F("Cannot kill revision %s,\n" - "because it would leave the current workspace in an invalid\n" - "state, from which monotone cannot recover automatically since\n" - "the workspace contains uncommitted changes.\n" - "Consider updating your workspace to another revision first,\n" - "before you try to kill this revision again.") % revid); - - P(F("applying changes from %s on the current workspace") - % revid); - - revision_t new_work_rev; - app.db.get_revision(revid, new_work_rev); - new_work_rev.made_for = made_for_workspace; - app.work.put_work_rev(new_work_rev); - - // extra paranoia... we _should_ never run this section twice - // since a merged workspace would fail early with work.has_changes() - break; + W(F("This workspace is a child of the revision you are killing.\n" + "Pushing it back to be a child of its parents instead\n" + "(all changes will be preserved).")); + + revision_t oldrev; + app.db.get_revision(revid, oldrev); + parent_map new_parents; + app.db.get_parent_map(oldrev, new_parents); + app.work.set_work_state(new_parents, curr_roster); } + else if (parents.size() == 2) + { + for (parent_map::const_iterator i = parents.begin(); + i != parents.end(); ++i) + { + if (parent_id(i) == revid) + N(false, + F("The current workspace is a merge of the revision you are\n" + "killing and some other revision. If I killed the\n" + "revision, this workspace would become invalid, and I\n" + "can't fix this automatically. Aborting.")); + } + } + else + I(false); } app.db.delete_existing_rev_and_certs(revid); ============================================================ --- work.cc 3457f59b916125d93bc6441df70cc73a06b3166e +++ work.cc fd25118fc6399fd14417b3cf570a212b034ea860 @@ -189,41 +189,8 @@ workspace::get_work_state_shape_only(par // ancestors, for no reason! marking_map dummy; make_roster_for_revision(rev, parents, new_rid, ros, dummy, db, nis); - // If there is just one parent, it might be the null ID, which - // make_roster_for_revision does not handle correctly. - if (rev.edges.size() == 1 && null_id(edge_old_revision(rev.edges.begin()))) - { - I(ros.all_nodes().size() == 0); - editable_roster_base er(ros, nis); - edge_changes(rev.edges.begin()).apply_to(er); - } - else - { - marking_map dummy; - make_roster_for_revision(rev, new_rid, ros, dummy, db, nis); - } } -bool -workspace::has_changes() -{ - parent_map parents; - get_parent_rosters(parents); - - // if we have more than one parent roster then this workspace contains - // a merge which means this is always a committable change - if (parents.size() > 1) - return true; - - temp_node_id_source nis; - roster_t new_roster, old_roster = parent_roster(parents.begin()); - - get_current_roster_shape(new_roster, nis); - update_current_roster_from_filesystem(new_roster); - - return !(old_roster == new_roster); -} - // user log file void ============================================================ --- work.hh 76fd17a13f66cc7f9219c08313c27d4f6b1a8985 +++ work.hh 8f753ef66b7b0eb6402f9b132f79e2615d4aa00d @@ -98,8 +98,6 @@ struct workspace void update_any_attrs(); - bool has_changes(); - // write out a new (partial) revision describing the current workspace; // the important pieces of this are the base revision id and the "shape" // changeset (representing tree rearrangements).