/* Remove one revision, marking it so that it can't be readded. Copyright (C) 2004 Walter Landry This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Parsed_Name.hpp" #include "parse_common_options.hpp" #include "parse_unknown_options.hpp" #include "check_extra_args.hpp" #include "command_initializer.hpp" #include "arx_error.hpp" #include "gvfs.hpp" #include "valid_package_name.hpp" #include "Temp_Directory.hpp" #include #include #include "get_config_option.hpp" #include "boost/date_time/posix_time/posix_time.hpp" #include "boost/filesystem/fstream.hpp" #include "Branch_Lock.hpp" #include "boost/archive/text_oarchive.hpp" #include "boost/serialization/map.hpp" #include "boost/serialization/list.hpp" #include "output_changelog.hpp" #include "Patch_Log.hpp" #include "tempdir.hpp" using namespace std; using namespace boost; using namespace boost::posix_time; namespace fs=boost::filesystem; using fs::path; int delete_revision(list &argument_list, const command &cmd); static command_initializer delete_revision_init(command("delete-revision", "IRREVOCABLY delete a revision within an archive", "usage: delete-revision [options] revision", "This command will IRREVOCABLY delete a revision within an archive,\n\ freeing up any space it takes up. It will also delete the cached revision\n\ in the archive if it exists. THIS IS NOT A COMMAND TO BE USED LIGHTLY.\n\ This command is useful if you have checked in some materials that are\n\ illegal, too large, makes your boss look stupid, etc. However, the revision\n\ name will still be reserved, so you will have to use \"fork\" in order to\n\ continue development along that line of development. As an example, to\n\ delete hello.1.0,234 and continue development in a directory named hello:\n\ \n\ arx delete-revision hello.1.0,234\n\ arx fork hello.1.0,233 hello.1.0 hello\n\ \n\ Once again, this command will permanently delete whatever is in that\n\ revision. This command will present the output of the patch log for that\n\ revision, and prompt to make sure to continue.", delete_revision,"Administrative",true)); int delete_revision(list &argument_list, const command &cmd) { Command_Info info(cmd); bool done=false; while(!argument_list.empty() && !done) { if(!parse_common_options(argument_list,info)) { parse_unknown_options(argument_list); done=true; } } if(argument_list.size()<1) { throw arx_error ("Not enough arguments"); } Parsed_Name name(*(argument_list.begin())); argument_list.pop_front(); check_extra_args(argument_list,info); valid_package_name(name,Revision); output_changelog(name,cout); string response; cout << "Really delete this revision? (y/n)"; cin >> response; if(response=="y" || response=="Y") { gvfs::Init(); gvfs::uri location(name.archive_location()); gvfs::remove_all(location / name.revision_path_no_archive()); /* Make a new patch */ Temp_Directory delete_revision_dir(tempdir(),",,delete_revision"); Patch_Log log; log.headers["Summary"]="Deleted revision"; log.headers["Revision"]=name.revision(); log.headers["Archive"]=name.archive(); log.headers["Creator"]=get_config_option("id"); log.headers["Date"]=to_simple_string(second_clock::local_time()); log.headers["Standard-Date"]= to_simple_string(second_clock::universal_time()); log.headers["Continuation-of"]=name.revision(); { fs::ofstream new_log(delete_revision_dir.path/"log"); archive::text_oarchive new_archive(new_log); new_archive << log.headers << log.header_lists << log.rename_lists << log.body; } Branch_Lock lock(name); gvfs::copy((delete_revision_dir.path/"log").native_file_string(), lock.uri()/"log"); gvfs::rename(lock.uri(),location / name.revision_path_no_archive()); gvfs::remove(name.archive_location() / name.branch_path_no_archive() / ",cache" / (name.revision() + ".tar.gz")); } return 0; }