|
| 1 | +#include <filesystem> |
| 2 | +#include <system_error> |
| 3 | +#include "mv_subcommand.hpp" |
| 4 | + |
| 5 | +#include "../utils/git_exception.hpp" |
| 6 | +#include "../wrapper/index_wrapper.hpp" |
| 7 | +#include "../wrapper/repository_wrapper.hpp" |
| 8 | + |
| 9 | +namespace fs = std::filesystem; |
| 10 | + |
| 11 | +mv_subcommand::mv_subcommand(const libgit2_object&, CLI::App& app) |
| 12 | +{ |
| 13 | + auto* sub = app.add_subcommand("mv" , "Move or rename a file, a directory, or a symlink"); |
| 14 | + sub->add_option("<source>", m_source_path, "The path of the source to move")->required()->check(CLI::ExistingFile); |
| 15 | + sub->add_option("<destination>", m_destination_path, "The path of the destination")->required(); |
| 16 | + sub->add_flag("-f,--force", m_force, "Force renaming or moving of a file even if the <destination> exists."); |
| 17 | + |
| 18 | + sub->callback([this]() { this->run(); }); |
| 19 | +} |
| 20 | + |
| 21 | +void mv_subcommand::run() |
| 22 | +{ |
| 23 | + auto directory = get_current_git_path(); |
| 24 | + auto repo = repository_wrapper::open(directory); |
| 25 | + |
| 26 | + bool exists = fs::exists(m_destination_path) && !fs::is_directory(m_destination_path); |
| 27 | + if (exists && !m_force) |
| 28 | + { |
| 29 | + // TODO: replace magic number with enum when diff command is merged |
| 30 | + throw git_exception("destination already exists", 128); |
| 31 | + } |
| 32 | + |
| 33 | + std::error_code ec; |
| 34 | + fs::rename(m_source_path, m_destination_path, ec); |
| 35 | + |
| 36 | + if(ec) |
| 37 | + { |
| 38 | + throw git_exception("Could not move file", ec.value()); |
| 39 | + } |
| 40 | + |
| 41 | + auto index = repo.make_index(); |
| 42 | + index.remove_entry(m_source_path); |
| 43 | + index.add_entry(m_destination_path); |
| 44 | + index.write(); |
| 45 | +} |
0 commit comments