/* Break the lock on a revision 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; version 2 dated June, 1991. 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 "parse_common_options.hpp" #include "parse_unknown_options.hpp" #include "check_extra_args.hpp" #include "command_initializer.hpp" #include "arx_error.hpp" #include #include "get_config_option.hpp" #include "Parsed_Name.hpp" #include "gvfs.hpp" #include "valid_package_name.hpp" using namespace std; int break_lock(list &argument_list, const command &cmd); static command_initializer break_lock_init(command("break-lock", "Break a branch lock", "usage: break-lock [options] revision", " -f --force Break the lock, even if you don't own it\n\ \n\ When creating revisions, ArX creates a lock directory. If ArX is\n\ suddenly interrupted or the network connection goes down, that\n\ lock will remain, preventing anyone from commit'ing new revisions.\n\ \"arx break-lock\" will remove that lock if it belongs to you. If\n\ it belongs to someone else, you must use the --force option.", break_lock,"Administrative",true)); int break_lock(list &argument_list, const command &cmd) { Command_Info info(cmd); bool force(false); while(!argument_list.empty()) if(!parse_common_options(argument_list,info)) { if(*(argument_list.begin())=="-f" || *(argument_list.begin())=="--force") { force=true; argument_list.pop_front(); } else { parse_unknown_options(argument_list); break; } } if(argument_list.empty()) 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,Branch); gvfs::Init(); gvfs::uri location(name.archive_location()); gvfs::uri base_uri(location/name.branch_path_no_archive()); gvfs::uri lock_location(base_uri/"++revision_lock"); gvfs::uri uid(base_uri/",,uid"); if(!exists(lock_location)) throw arx_error("The branch is not locked\n\t" + name.complete_branch()); if(!force) { if(!exists(uid)) throw arx_error("I don't know who owns the lock on this branch.\n\t" + name.complete_branch() + "\nUse --force to break the lock anyway."); string lock_owner(read_archive(uid)); if(lock_owner!=get_config_option("id")) throw arx_error("This lock is owned by someone else: " + lock_owner + "\nUse --force to break the lock anyway."); } /* We first rename the directory, so that we don't have a case where someone is deleting a directory while the other moves it. */ gvfs::remove(uid); gvfs::uri deleted_lock(base_uri/",,deleted_lock"); gvfs::remove_all(deleted_lock); gvfs::rename(lock_location,deleted_lock); gvfs::remove_all(deleted_lock); return 0; }