Implemented mv subcommand by JohanMabille · Pull Request #93 · QuantStack/git2cpp · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
2 changes: 2 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "subcommand/init_subcommand.hpp"
#include "subcommand/log_subcommand.hpp"
#include "subcommand/merge_subcommand.hpp"
#include "subcommand/mv_subcommand.hpp"
#include "subcommand/push_subcommand.hpp"
#include "subcommand/rebase_subcommand.hpp"
#include "subcommand/remote_subcommand.hpp"
Expand Down Expand Up @@ -48,6 +49,7 @@ int main(int argc, char** argv)
reset_subcommand reset(lg2_obj, app);
log_subcommand log(lg2_obj, app);
merge_subcommand merge(lg2_obj, app);
mv_subcommand mv(lg2_obj, app);
push_subcommand push(lg2_obj, app);
rebase_subcommand rebase(lg2_obj, app);
remote_subcommand remote(lg2_obj, app);
Expand Down
45 changes: 45 additions & 0 deletions src/subcommand/mv_subcommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <filesystem>
#include <system_error>
#include "mv_subcommand.hpp"

#include "../utils/git_exception.hpp"
#include "../wrapper/index_wrapper.hpp"
#include "../wrapper/repository_wrapper.hpp"

namespace fs = std::filesystem;

mv_subcommand::mv_subcommand(const libgit2_object&, CLI::App& app)
{
auto* sub = app.add_subcommand("mv" , "Move or rename a file, a directory, or a symlink");
sub->add_option("<source>", m_source_path, "The path of the source to move")->required()->check(CLI::ExistingFile);
sub->add_option("<destination>", m_destination_path, "The path of the destination")->required();
sub->add_flag("-f,--force", m_force, "Force renaming or moving of a file even if the <destination> exists.");

sub->callback([this]() { this->run(); });
}

void mv_subcommand::run()
{
auto directory = get_current_git_path();
auto repo = repository_wrapper::open(directory);

bool exists = fs::exists(m_destination_path) && !fs::is_directory(m_destination_path);
if (exists && !m_force)
{
// TODO: replace magic number with enum when diff command is merged
throw git_exception("destination already exists", 128);
}

std::error_code ec;
fs::rename(m_source_path, m_destination_path, ec);

if(ec)
{
throw git_exception("Could not move file", ec.value());
}

auto index = repo.make_index();
index.remove_entry(m_source_path);
index.add_entry(m_destination_path);
index.write();
}
21 changes: 21 additions & 0 deletions src/subcommand/mv_subcommand.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include <CLI/CLI.hpp>
#include <string>

#include "../utils/common.hpp"

class mv_subcommand
{
public:

explicit mv_subcommand(const libgit2_object&, CLI::App& app);
void run();

private:

std::string m_source_path;
std::string m_destination_path;
bool m_force = false;
};

10 changes: 10 additions & 0 deletions src/wrapper/index_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ index_wrapper index_wrapper::init(repository_wrapper& rw)
return index;
}

void index_wrapper::add_entry(const std::string& path)
{
throw_if_error(git_index_add_bypath(*this, path.c_str()));
}

void index_wrapper::add_entries(std::vector<std::string> patterns)
{
add_impl(std::move(patterns));
Expand All @@ -37,6 +42,11 @@ void index_wrapper::add_impl(std::vector<std::string> patterns)
throw_if_error(git_index_add_all(*this, array, 0, NULL, NULL));
}

void index_wrapper::remove_entry(const std::string& path)
{
throw_if_error(git_index_remove_bypath(*this, path.c_str()));
}

void index_wrapper::write()
{
throw_if_error(git_index_write(*this));
Expand Down
3 changes: 3 additions & 0 deletions src/wrapper/index_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ class index_wrapper : public wrapper_base<git_index>
void write();
git_oid write_tree();

void add_entry(const std::string& path);
void add_entries(std::vector<std::string> patterns);
void add_all();

void remove_entry(const std::string& path);

bool has_conflict() const;
void output_conflicts();
void conflict_cleanup();
Expand Down
1 change: 1 addition & 0 deletions test/conftest_wasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def pytest_ignore_collect(collection_path: pathlib.Path) -> bool:
"test_init.py",
"test_log.py",
"test_merge.py",
"test_mv.py",
"test_rebase.py",
"test_remote.py",
"test_reset.py",
Expand Down
250 changes: 250 additions & 0 deletions test/test_mv.py