Skip to content

Commit 0447999

Browse files
committed
Implemented mv subcommand
1 parent 1e1c6b6 commit 0447999

File tree

6 files changed

+83
-0
lines changed

6 files changed

+83
-0
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ set(GIT2CPP_SRC
6060
${GIT2CPP_SOURCE_DIR}/subcommand/log_subcommand.hpp
6161
${GIT2CPP_SOURCE_DIR}/subcommand/merge_subcommand.cpp
6262
${GIT2CPP_SOURCE_DIR}/subcommand/merge_subcommand.hpp
63+
${GIT2CPP_SOURCE_DIR}/subcommand/mv_subcommand.cpp
64+
${GIT2CPP_SOURCE_DIR}/subcommand/mv_subcommand.hpp
6365
${GIT2CPP_SOURCE_DIR}/subcommand/push_subcommand.cpp
6466
${GIT2CPP_SOURCE_DIR}/subcommand/push_subcommand.hpp
6567
${GIT2CPP_SOURCE_DIR}/subcommand/rebase_subcommand.cpp

src/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "subcommand/init_subcommand.hpp"
1616
#include "subcommand/log_subcommand.hpp"
1717
#include "subcommand/merge_subcommand.hpp"
18+
#include "subcommand/mv_subcommand.hpp"
1819
#include "subcommand/push_subcommand.hpp"
1920
#include "subcommand/rebase_subcommand.hpp"
2021
#include "subcommand/remote_subcommand.hpp"
@@ -48,6 +49,7 @@ int main(int argc, char** argv)
4849
reset_subcommand reset(lg2_obj, app);
4950
log_subcommand log(lg2_obj, app);
5051
merge_subcommand merge(lg2_obj, app);
52+
mv_subcommand mv(lg2_obj, app);
5153
push_subcommand push(lg2_obj, app);
5254
rebase_subcommand rebase(lg2_obj, app);
5355
remote_subcommand remote(lg2_obj, app);

src/subcommand/mv_subcommand.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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+
}

src/subcommand/mv_subcommand.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
3+
#include <CLI/CLI.hpp>
4+
#include <string>
5+
6+
#include "../utils/common.hpp"
7+
8+
class mv_subcommand
9+
{
10+
public:
11+
12+
explicit mv_subcommand(const libgit2_object&, CLI::App& app);
13+
void run();
14+
15+
private:
16+
17+
std::string m_source_path;
18+
std::string m_destination_path;
19+
bool m_force = false;
20+
};
21+

src/wrapper/index_wrapper.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ index_wrapper index_wrapper::init(repository_wrapper& rw)
2121
return index;
2222
}
2323

24+
void index_wrapper::add_entry(const std::string& path)
25+
{
26+
throw_if_error(git_index_add_bypath(*this, path.c_str()));
27+
}
28+
2429
void index_wrapper::add_entries(std::vector<std::string> patterns)
2530
{
2631
add_impl(std::move(patterns));
@@ -37,6 +42,11 @@ void index_wrapper::add_impl(std::vector<std::string> patterns)
3742
throw_if_error(git_index_add_all(*this, array, 0, NULL, NULL));
3843
}
3944

45+
void index_wrapper::remove_entry(const std::string& path)
46+
{
47+
throw_if_error(git_index_remove_bypath(*this, path.c_str()));
48+
}
49+
4050
void index_wrapper::write()
4151
{
4252
throw_if_error(git_index_write(*this));

src/wrapper/index_wrapper.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@ class index_wrapper : public wrapper_base<git_index>
2323
void write();
2424
git_oid write_tree();
2525

26+
void add_entry(const std::string& path);
2627
void add_entries(std::vector<std::string> patterns);
2728
void add_all();
2829

30+
void remove_entry(const std::string& path);
31+
2932
bool has_conflict() const;
3033
void output_conflicts();
3134
void conflict_cleanup();

0 commit comments

Comments
 (0)