Skip to content
Open
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
49 changes: 49 additions & 0 deletions src/subcommand/rm_subcommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <filesystem>
#include "rm_subcommand.hpp"
#include "../utils/common.hpp"
#include "../utils/git_exception.hpp"
#include "../wrapper/index_wrapper.hpp"
#include "../wrapper/repository_wrapper.hpp"

namespace fs = std::filesystem;

rm_subcommand::rm_subcommand(const libgit2_object&, CLI::App& app)
{
auto* rm = app.add_subcommand("rm", "Remove files from the working tree and from the index");
rm->add_option("<pathspec>", m_pathspec, "Files to remove");
rm->add_flag("-r", m_recursive, "Allow recursive removal when a leading directory name is given");

rm->add_callback([this]() { this->run(); });
}

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

index_wrapper index = repo.make_index();

std::vector<std::string> files;
std::vector<std::string> directories;

std::for_each(m_pathspec.begin(), m_pathspec.end(), [&](const std::string& path)
{
if (fs::is_directory)
{
directories.push_back(path);
}
else
{
files.push_back(path);
}
});

if (!directories.empty() && !m_recursive)
{
std::string msg = "fatal: not removing '" + directories.front() + "' recursively without -r";
throw git_exception(msg, 128);
}

index.remove_entries(files);
index.remove_directories(directories);
}
21 changes: 21 additions & 0 deletions src/subcommand/rm_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 <vector>

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

class rm_subcommand
{
public:

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

private:

std::vector<std::string> m_pathspec;
bool m_recursive = false;
};

15 changes: 15 additions & 0 deletions src/wrapper/index_wrapper.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <git2/index.h>
#include <algorithm>
#include <iostream>
#include <vector>

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

void index_wrapper::remove_entries(std::vector<std::string> paths)
{
git_strarray_wrapper array{paths};
throw_if_error(git_index_remove_all(*this, array, NULL, NULL));
}

void index_wrapper::remove_directories(std::vector<std::string> entries)
{
std::for_each(entries.cbegin(), entries.cend(), [this](const std::string& path)
{
throw_if_error(git_index_remove_directory(*this, path.c_str(), 0));
});
}

void index_wrapper::write()
{
throw_if_error(git_index_write(*this));
Expand Down
2 changes: 2 additions & 0 deletions src/wrapper/index_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class index_wrapper : public wrapper_base<git_index>
void add_all();

void remove_entry(const std::string& path);
void remove_entries(std::vector<std::string> paths);
void remove_directories(std::vector<std::string> paths);

bool has_conflict() const;
void output_conflicts();
Expand Down