Skip to content

Commit 24532d3

Browse files
committed
Implemented git rm
1 parent a61ab26 commit 24532d3

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

src/subcommand/rm_subcommand.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include <filesystem>
2+
#include "rm_subcommand.hpp"
3+
#include "../utils/common.hpp"
4+
#include "../utils/git_exception.hpp"
5+
#include "../wrapper/index_wrapper.hpp"
6+
#include "../wrapper/repository_wrapper.hpp"
7+
8+
namespace fs = std::filesystem;
9+
10+
rm_subcommand::rm_subcommand(const libgit2_object&, CLI::App& app)
11+
{
12+
auto* rm = app.add_subcommand("rm", "Remove files from the working tree and from the index");
13+
rm->add_option("<pathspec>", m_pathspec, "Files to remove");
14+
rm->add_flag("-r", m_recursive, "Allow recursive removal when a leading directory name is given");
15+
16+
rm->add_callback([this]() { this->run(); });
17+
}
18+
19+
void rm_subcommand::run()
20+
{
21+
auto directory = get_current_git_path();
22+
auto repo = repository_wrapper::open(directory);
23+
24+
index_wrapper index = repo.make_index();
25+
26+
std::vector<std::string> files;
27+
std::vector<std::string> directories;
28+
29+
std::for_each(m_pathspec.begin(), m_pathspec.end(), [&](const std::string& path)
30+
{
31+
if (fs::is_directory)
32+
{
33+
directories.push_back(path);
34+
}
35+
else
36+
{
37+
files.push_back(path);
38+
}
39+
});
40+
41+
if (!directories.empty() && !m_recursive)
42+
{
43+
std::string msg = "fatal: not removing '" + directories.front() + "' recursively without -r";
44+
throw git_exception(msg, 128);
45+
}
46+
47+
index.remove_entries(files);
48+
index.remove_directories(directories);
49+
}

src/subcommand/rm_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+
#include <vector>
6+
7+
#include "../utils/common.hpp"
8+
9+
class rm_subcommand
10+
{
11+
public:
12+
13+
explicit rm_subcommand(const libgit2_object&, CLI::App& app);
14+
void run();
15+
16+
private:
17+
18+
std::vector<std::string> m_pathspec;
19+
bool m_recursive = false;
20+
};
21+

src/wrapper/index_wrapper.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <git2/index.h>
2+
#include <algorithm>
23
#include <iostream>
34
#include <vector>
45

@@ -47,6 +48,20 @@ void index_wrapper::remove_entry(const std::string& path)
4748
throw_if_error(git_index_remove_bypath(*this, path.c_str()));
4849
}
4950

51+
void index_wrapper::remove_entries(std::vector<std::string> paths)
52+
{
53+
git_strarray_wrapper array{paths};
54+
throw_if_error(git_index_remove_all(*this, array, NULL, NULL));
55+
}
56+
57+
void index_wrapper::remove_directories(std::vector<std::string> entries)
58+
{
59+
std::for_each(entries.cbegin(), entries.cend(), [this](const std::string& path)
60+
{
61+
throw_if_error(git_index_remove_directory(*this, path.c_str(), 0));
62+
});
63+
}
64+
5065
void index_wrapper::write()
5166
{
5267
throw_if_error(git_index_write(*this));

src/wrapper/index_wrapper.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class index_wrapper : public wrapper_base<git_index>
2828
void add_all();
2929

3030
void remove_entry(const std::string& path);
31+
void remove_entries(std::vector<std::string> paths);
32+
void remove_directories(std::vector<std::string> paths);
3133

3234
bool has_conflict() const;
3335
void output_conflicts();

0 commit comments

Comments
 (0)