Skip to content

Commit 085145f

Browse files
committed
Add stash (draft)
1 parent 56a4eba commit 085145f

File tree

7 files changed

+230
-0
lines changed

7 files changed

+230
-0
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ set(GIT2CPP_SRC
7070
${GIT2CPP_SOURCE_DIR}/subcommand/revlist_subcommand.hpp
7171
${GIT2CPP_SOURCE_DIR}/subcommand/revparse_subcommand.cpp
7272
${GIT2CPP_SOURCE_DIR}/subcommand/revparse_subcommand.hpp
73+
${GIT2CPP_SOURCE_DIR}/subcommand/stash_subcommand.cpp
74+
${GIT2CPP_SOURCE_DIR}/subcommand/stash_subcommand.hpp
7375
${GIT2CPP_SOURCE_DIR}/subcommand/status_subcommand.cpp
7476
${GIT2CPP_SOURCE_DIR}/subcommand/status_subcommand.hpp
7577
${GIT2CPP_SOURCE_DIR}/utils/ansi_code.cpp

src/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "subcommand/push_subcommand.hpp"
1919
#include "subcommand/remote_subcommand.hpp"
2020
#include "subcommand/reset_subcommand.hpp"
21+
#include "subcommand/stash_subcommand.hpp"
2122
#include "subcommand/status_subcommand.hpp"
2223
#include "subcommand/revparse_subcommand.hpp"
2324
#include "subcommand/revlist_subcommand.hpp"
@@ -50,6 +51,7 @@ int main(int argc, char** argv)
5051
remote_subcommand remote(lg2_obj, app);
5152
revparse_subcommand revparse(lg2_obj, app);
5253
revlist_subcommand revlist(lg2_obj, app);
54+
stash_subcommand stash(lg2_obj, app);
5355

5456
app.require_subcommand(/* min */ 0, /* max */ 1);
5557

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include <git2/stash.h>
2+
#include <iostream>
3+
4+
#include <git2/remote.h>
5+
6+
#include "../subcommand/stash_subcommand.hpp"
7+
#include "../wrapper/repository_wrapper.hpp"
8+
9+
stash_subcommand::stash_subcommand(const libgit2_object&, CLI::App& app)
10+
{
11+
auto* stash = app.add_subcommand("stash", "Stash the changes in a dirty working directory away");
12+
auto* push = stash->add_subcommand("push", "");
13+
auto* list = stash->add_subcommand("list", "");
14+
auto* pop = stash->add_subcommand("pop", "");
15+
auto* apply = stash->add_subcommand("apply", "");
16+
17+
push->add_option("-m", m_message, "");
18+
pop->add_option("--index", m_index, "");
19+
apply->add_option("--index", m_index, "");
20+
21+
stash->callback([this]() { this->run_push(); });
22+
push->callback([this]() { this->run_push(); });
23+
list->callback([this]() { this->run_list(); });
24+
pop->callback([this]() { this->run_pop(); });
25+
apply->callback([this]() { this->run_apply(); });
26+
}
27+
28+
void stash_subcommand::run_push()
29+
{
30+
auto directory = get_current_git_path();
31+
auto repo = repository_wrapper::open(directory);
32+
auto author_committer_signatures = signature_wrapper::get_default_signature_from_env(repo);
33+
34+
git_oid stash_id;
35+
git_stash_save(&stash_id, repo, author_committer_signatures.first, m_message.c_str(), GIT_STASH_DEFAULT);
36+
auto stash = repo.find_commit(stash_id);
37+
std::cout << "Saved working directory " << stash.summary() << std::endl;
38+
}
39+
40+
static int list_stash_cb(size_t index, const char* message, const git_oid* stash_id, void* payload)
41+
{
42+
std::cout << "stash@{" << index << "}: " << message << std::endl;
43+
return 0;
44+
}
45+
46+
void stash_subcommand::run_list()
47+
{
48+
auto directory = get_current_git_path();
49+
auto repo = repository_wrapper::open(directory);
50+
51+
git_stash_foreach(repo, list_stash_cb, NULL);
52+
}
53+
54+
void stash_subcommand::run_pop()
55+
{
56+
auto directory = get_current_git_path();
57+
auto repo = repository_wrapper::open(directory);
58+
59+
git_stash_pop(repo, m_index, NULL);
60+
}
61+
62+
void stash_subcommand::run_apply()
63+
{
64+
auto directory = get_current_git_path();
65+
auto repo = repository_wrapper::open(directory);
66+
67+
git_stash_apply(repo, m_index, NULL);
68+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
#include <CLI/CLI.hpp>
4+
5+
#include "../utils/common.hpp"
6+
7+
class stash_subcommand
8+
{
9+
public:
10+
11+
explicit stash_subcommand(const libgit2_object&, CLI::App& app);
12+
void run_push();
13+
void run_list();
14+
void run_pop();
15+
void run_apply();
16+
17+
std::vector<std::string> m_options;
18+
std::string m_message = "";
19+
size_t m_index = 0;
20+
};

src/wrapper/commit_wrapper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "../wrapper/commit_wrapper.hpp"
2+
#include <git2/commit.h>
23

34
commit_wrapper::commit_wrapper(git_commit* commit)
45
: base_type(commit)
@@ -27,6 +28,11 @@ std::string commit_wrapper::commit_oid_tostr() const
2728
return git_oid_tostr(buf, sizeof(buf), &this->oid());
2829
}
2930

31+
std::string commit_wrapper::summary() const
32+
{
33+
return git_commit_summary(*this);
34+
}
35+
3036
commit_list_wrapper commit_wrapper::get_parents_list() const
3137
{
3238
size_t parent_count = git_commit_parentcount(*this);

src/wrapper/commit_wrapper.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class commit_wrapper : public wrapper_base<git_commit>
2424
const git_oid& oid() const;
2525
std::string commit_oid_tostr() const;
2626

27+
std::string summary() const;
28+
2729
commit_list_wrapper get_parents_list() const;
2830

2931
private:

test/test_stash.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import subprocess
2+
3+
import pytest
4+
5+
6+
def test_stash_push(xtl_clone, commit_env_config, git2cpp_path, tmp_path):
7+
assert (tmp_path / "xtl").exists()
8+
xtl_path = tmp_path / "xtl"
9+
10+
p = xtl_path / "mook_file.txt"
11+
p.write_text("")
12+
13+
cmd_add = [git2cpp_path, "add", "mook_file.txt"]
14+
p_add = subprocess.run(cmd_add, cwd=xtl_path, text=True)
15+
assert p_add.returncode == 0
16+
17+
cmd_status = [git2cpp_path, "status"]
18+
p_status = subprocess.run(cmd_status, capture_output=True, cwd=xtl_path, text=True)
19+
assert p_status.returncode == 0
20+
assert "mook_file" in p_status.stdout
21+
22+
cmd_stash = [git2cpp_path, "stash"]
23+
p_stash = subprocess.run(cmd_stash, capture_output=True, cwd=xtl_path, text=True)
24+
assert p_stash.returncode == 0
25+
26+
p_status_2 = subprocess.run(
27+
cmd_status, capture_output=True, cwd=xtl_path, text=True
28+
)
29+
assert p_status_2.returncode == 0
30+
assert "mook_file" not in p_status_2.stdout
31+
32+
33+
def test_stash_list(xtl_clone, commit_env_config, git2cpp_path, tmp_path):
34+
assert (tmp_path / "xtl").exists()
35+
xtl_path = tmp_path / "xtl"
36+
37+
p = xtl_path / "mook_file.txt"
38+
p.write_text("")
39+
40+
cmd_add = [git2cpp_path, "add", "mook_file.txt"]
41+
p_add = subprocess.run(cmd_add, cwd=xtl_path, text=True)
42+
assert p_add.returncode == 0
43+
44+
cmd_list = [git2cpp_path, "stash", "list"]
45+
p_list = subprocess.run(cmd_list, capture_output=True, cwd=xtl_path, text=True)
46+
assert p_list.returncode == 0
47+
assert "stash@" not in p_list.stdout
48+
49+
cmd_stash = [git2cpp_path, "stash"]
50+
p_stash = subprocess.run(cmd_stash, capture_output=True, cwd=xtl_path, text=True)
51+
assert p_stash.returncode == 0
52+
53+
# p_list_2 = subprocess.run(cmd_list, capture_output=True, cwd=xtl_path, text=True)
54+
# assert p_list_2.returncode == 0
55+
# print("second: \n", p_list_2.stdout, "\n\n")
56+
# # assert "stash@{0}" in p_list_2.stdout
57+
58+
59+
def test_stash_pop(xtl_clone, commit_env_config, git2cpp_path, tmp_path):
60+
assert (tmp_path / "xtl").exists()
61+
xtl_path = tmp_path / "xtl"
62+
63+
p = xtl_path / "mook_file.txt"
64+
p.write_text("")
65+
66+
cmd_add = [git2cpp_path, "add", "mook_file.txt"]
67+
p_add = subprocess.run(cmd_add, cwd=xtl_path, text=True)
68+
assert p_add.returncode == 0
69+
70+
cmd_stash = [git2cpp_path, "stash"]
71+
p_stash = subprocess.run(cmd_stash, capture_output=True, cwd=xtl_path, text=True)
72+
assert p_stash.returncode == 0
73+
74+
cmd_status = [git2cpp_path, "status"]
75+
p_status = subprocess.run(cmd_status, capture_output=True, cwd=xtl_path, text=True)
76+
assert p_status.returncode == 0
77+
assert "mook_file" not in p_status.stdout
78+
79+
# cmd_pop = [git2cpp_path, "stash", "pop"]
80+
# p_pop = subprocess.run(cmd_pop, capture_output=True, cwd=xtl_path, text=True)
81+
# assert p_pop.returncode == 0
82+
83+
# p_status_2 = subprocess.run(
84+
# cmd_status, capture_output=True, cwd=xtl_path, text=True
85+
# )
86+
# assert p_status_2.returncode == 0
87+
# print(p_status_2.stdout)
88+
# assert "mook_file" in p_status.stdout
89+
#
90+
# cmd_list = [git2cpp_path, "stash", "list"]
91+
# p_list = subprocess.run(cmd_list, capture_output=True, cwd=xtl_path, text=True)
92+
# assert p_list.returncode == 0
93+
# assert p_list.stdout == ""
94+
95+
96+
def test_stash_apply(xtl_clone, commit_env_config, git2cpp_path, tmp_path):
97+
assert (tmp_path / "xtl").exists()
98+
xtl_path = tmp_path / "xtl"
99+
100+
p = xtl_path / "mook_file.txt"
101+
p.write_text("")
102+
103+
cmd_add = [git2cpp_path, "add", "mook_file.txt"]
104+
p_add = subprocess.run(cmd_add, cwd=xtl_path, text=True)
105+
assert p_add.returncode == 0
106+
107+
cmd_stash = [git2cpp_path, "stash"]
108+
p_stash = subprocess.run(cmd_stash, capture_output=True, cwd=xtl_path, text=True)
109+
assert p_stash.returncode == 0
110+
111+
cmd_status = [git2cpp_path, "status"]
112+
p_status = subprocess.run(cmd_status, capture_output=True, cwd=xtl_path, text=True)
113+
assert p_status.returncode == 0
114+
assert "mook_file" not in p_status.stdout
115+
116+
# cmd_pop = [git2cpp_path, "stash", "pop"]
117+
# p_pop = subprocess.run(cmd_pop, capture_output=True, cwd=xtl_path, text=True)
118+
# assert p_pop.returncode == 0
119+
120+
# p_status_2 = subprocess.run(
121+
# cmd_status, capture_output=True, cwd=xtl_path, text=True
122+
# )
123+
# assert p_status_2.returncode == 0
124+
# print(p_status_2.stdout)
125+
# assert "mook_file" in p_status.stdout
126+
#
127+
# cmd_list = [git2cpp_path, "stash", "list"]
128+
# p_list = subprocess.run(cmd_list, capture_output=True, cwd=xtl_path, text=True)
129+
# assert p_list.returncode == 0
130+
# assert "stash@{0}" in p_list.stdout

0 commit comments

Comments
 (0)