# # # patch "cmd_netsync.cc" # from [d9f67662d472a86633a273dfd0116d735e14293c] # to [ecf459ce845f38db058d30ad04910d57ee1310f2] # # patch "cmd_ws_commit.cc" # from [3acb12cd36656e3d9cb12c0eadb9021930a9b3cc] # to [10d33763a838c34d36cdacf987678905f77762be] # # patch "file_io.hh" # from [bd4beae86ace6c7e07f54e6466e22571793b75f0] # to [1ecc0d6d6f9dddeb676ac95ca074c2dfb82e58d0] # ============================================================ --- cmd_netsync.cc d9f67662d472a86633a273dfd0116d735e14293c +++ cmd_netsync.cc ecf459ce845f38db058d30ad04910d57ee1310f2 @@ -15,6 +15,7 @@ #include "merge_content.hh" #include "netcmd.hh" #include "network/connection_info.hh" +#include "file_io.hh" #include "globish.hh" #include "keys.hh" #include "key_store.hh" @@ -637,51 +638,6 @@ CMD_AUTOMATE(sync, N_("[ADDRESS[:PORTNUM client_voice, source_and_sink_role, info); } -class dir_cleanup_helper -{ -public: - dir_cleanup_helper(system_path const & new_dir, bool i_db) - : committed(false), internal_db(i_db), dir(new_dir) - {} - ~dir_cleanup_helper() - { - if (!committed && directory_exists(dir)) - { - // Don't need to worry about where the db is on Unix. -#ifndef WIN32 - internal_db = false; -#endif - - // This is probably happening in the middle of another exception. - // Do not let anything that delete_dir_recursive throws escape, or - // the runtime will call std::terminate... - if (!internal_db) - { - try - { - delete_dir_recursive(dir); - } - catch (std::exception const & ex) - { - ui.fatal_exception(ex); - } - catch (...) - { - ui.fatal_exception(); - } - } - } - } - void commit(void) - { - committed = true; - } -private: - bool committed; - bool internal_db; - system_path dir; -}; - CMD(clone, "clone", "", CMD_REF(network), N_("ADDRESS[:PORTNUMBER] BRANCH [DIRECTORY]"), N_("Checks out a revision from a remote database into a directory"), @@ -730,14 +686,13 @@ CMD(clone, "clone", "", CMD_REF(network) // db URIs will work system_path start_dir(get_current_working_dir(), origin::system); - bool internal_db = !app.opts.dbname_given || app.opts.dbname.empty(); - system_path _MTN_dir = workspace_dir / path_component("_MTN"); - dir_cleanup_helper remove_on_fail(target_is_current_dir ? _MTN_dir : workspace_dir, - internal_db); + directory_cleanup_helper remove_on_fail( + target_is_current_dir ? _MTN_dir : workspace_dir + ); // paths.cc's idea of the current workspace root is wrong at this point - if (internal_db) + if (!app.opts.dbname_given || app.opts.dbname.empty()) app.opts.dbname = system_path(workspace_dir / bookkeeping_root_component / bookkeeping_internal_db_file_name); ============================================================ --- cmd_ws_commit.cc 3acb12cd36656e3d9cb12c0eadb9021930a9b3cc +++ cmd_ws_commit.cc 10d33763a838c34d36cdacf987678905f77762be @@ -1383,12 +1383,20 @@ CMD_NO_WORKSPACE(setup, "setup", "", CMD string dir; if (args.size() == 1) - dir = idx(args,0)(); + dir = idx(args,0)(); else - dir = "."; + dir = "."; system_path workspace_dir(dir, origin::user); + // only try to remove the complete workspace directory + // if we're about to create it anyways + directory_cleanup_helper remove_on_fail( + directory_exists(workspace_dir) + ? workspace_dir / bookkeeping_root_component + : workspace_dir + ); + workspace::create_workspace(app.opts, app.lua, workspace_dir); if (!app.opts.dbname_given || app.opts.dbname.empty()) @@ -1411,6 +1419,8 @@ CMD_NO_WORKSPACE(setup, "setup", "", CMD revision_t rev; make_revision_for_workspace(revision_id(), cset(), rev); work.put_work_rev(rev); + + remove_on_fail.commit(); } CMD_NO_WORKSPACE(import, "import", "", CMD_REF(tree), N_("DIRECTORY"), ============================================================ --- file_io.hh bd4beae86ace6c7e07f54e6466e22571793b75f0 +++ file_io.hh 1ecc0d6d6f9dddeb676ac95ca074c2dfb82e58d0 @@ -14,6 +14,7 @@ #include "paths.hh" #include "platform-wrapped.hh" #include "vector.hh" +#include "ui.hh" // this layer deals with talking to the filesystem, loading and saving // files, walking trees, etc. @@ -114,6 +115,38 @@ void walk_tree(file_path const & path, tree_walker & walker); +class directory_cleanup_helper +{ +public: + directory_cleanup_helper(system_path const & new_dir) + : committed(false), dir(new_dir) {} + ~directory_cleanup_helper() + { + if (!committed && directory_exists(dir)) + { + // This is probably happening in the middle of another exception. + // Do not let anything that delete_dir_recursive throws escape, or + // the runtime will call std::terminate... + try + { + delete_dir_recursive(dir); + } + catch (std::exception const & ex) + { + ui.fatal_exception(ex); + } + catch (...) + { + ui.fatal_exception(); + } + } + } + void commit(void) { committed = true; } +private: + bool committed; + system_path dir; +}; + bool ident_existing_file(file_path const & p, file_id & ident); bool ident_existing_file(file_path const & p, file_id & ident, path::status status);