Skip to content

Commit aae4150

Browse files
authored
Add checkout message (#103)
* Add message when checking out * Add checkout messages * address review comments
1 parent 90a295e commit aae4150

File tree

4 files changed

+302
-58
lines changed

4 files changed

+302
-58
lines changed

src/subcommand/checkout_subcommand.cpp

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#include <iostream>
22
#include <sstream>
3+
#include <set>
34

45
#include "../subcommand/checkout_subcommand.hpp"
6+
#include "../subcommand/status_subcommand.hpp"
57
#include "../utils/git_exception.hpp"
68
#include "../wrapper/repository_wrapper.hpp"
9+
#include "../wrapper/status_wrapper.hpp"
710

811
checkout_subcommand::checkout_subcommand(const libgit2_object&, CLI::App& app)
912
{
@@ -17,6 +20,23 @@ checkout_subcommand::checkout_subcommand(const libgit2_object&, CLI::App& app)
1720
sub->callback([this]() { this->run(); });
1821
}
1922

23+
void print_no_switch(status_list_wrapper& sl)
24+
{
25+
std::cout << "Your local changes to the following files would be overwritten by checkout:" << std::endl;
26+
27+
for (const auto* entry : sl.get_entry_list(GIT_STATUS_WT_MODIFIED))
28+
{
29+
std::cout << "\t" << entry->index_to_workdir->new_file.path << std::endl;
30+
}
31+
for (const auto* entry : sl.get_entry_list(GIT_STATUS_WT_DELETED))
32+
{
33+
std::cout << "\t" << entry->index_to_workdir->old_file.path << std::endl;
34+
}
35+
36+
std::cout << "Please commit your changes or stash them before you switch branches.\nAborting" << std::endl;
37+
return;
38+
}
39+
2040
void checkout_subcommand::run()
2141
{
2242
auto directory = get_current_git_path();
@@ -30,16 +50,22 @@ void checkout_subcommand::run()
3050
git_checkout_options options;
3151
git_checkout_options_init(&options, GIT_CHECKOUT_OPTIONS_VERSION);
3252

33-
if(m_force_checkout_flag)
53+
if (m_force_checkout_flag)
3454
{
3555
options.checkout_strategy = GIT_CHECKOUT_FORCE;
3656
}
57+
else
58+
{
59+
options.checkout_strategy = GIT_CHECKOUT_SAFE;
60+
}
3761

3862
if (m_create_flag || m_force_create_flag)
3963
{
4064
auto annotated_commit = create_local_branch(repo, m_branch_name, m_force_create_flag);
4165
checkout_tree(repo, annotated_commit, m_branch_name, options);
4266
update_head(repo, annotated_commit, m_branch_name);
67+
68+
std::cout << "Switched to a new branch '" << m_branch_name << "'" << std::endl;
4369
}
4470
else
4571
{
@@ -51,8 +77,38 @@ void checkout_subcommand::run()
5177
buffer << "error: could not resolve pathspec '" << m_branch_name << "'" << std::endl;
5278
throw std::runtime_error(buffer.str());
5379
}
54-
checkout_tree(repo, *optional_commit, m_branch_name, options);
55-
update_head(repo, *optional_commit, m_branch_name);
80+
81+
auto sl = status_list_wrapper::status_list(repo);
82+
try
83+
{
84+
checkout_tree(repo, *optional_commit, m_branch_name, options);
85+
update_head(repo, *optional_commit, m_branch_name);
86+
}
87+
catch (const git_exception& e)
88+
{
89+
if (sl.has_notstagged_header())
90+
{
91+
print_no_switch(sl);
92+
}
93+
throw e;
94+
}
95+
96+
if (sl.has_notstagged_header())
97+
{
98+
bool is_long = false;
99+
bool is_coloured = false;
100+
std::set<std::string> tracked_dir_set{};
101+
print_notstagged(sl, tracked_dir_set, is_long, is_coloured);
102+
}
103+
if (sl.has_tobecommited_header())
104+
{
105+
bool is_long = false;
106+
bool is_coloured = false;
107+
std::set<std::string> tracked_dir_set{};
108+
print_tobecommited(sl, tracked_dir_set, is_long, is_coloured);
109+
}
110+
std::cout << "Switched to branch '" << m_branch_name << "'" << std::endl;
111+
print_tracking_info(repo, sl, true);
56112
}
57113
}
58114

src/subcommand/status_subcommand.cpp

Lines changed: 78 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <termcolor/termcolor.hpp>
88

99
#include "status_subcommand.hpp"
10-
#include "../wrapper/status_wrapper.hpp"
1110

1211

1312
status_subcommand::status_subcommand(const libgit2_object&, CLI::App& app)
@@ -47,14 +46,14 @@ struct print_entry
4746
std::string item;
4847
};
4948

50-
std::string get_print_status(git_status_t status, output_format of)
49+
std::string get_print_status(git_status_t status, bool is_long)
5150
{
5251
std::string entry_status;
53-
if ((of == output_format::DEFAULT) || (of == output_format::LONG))
52+
if (is_long)
5453
{
5554
entry_status = get_status_msg(status).long_mod;
5655
}
57-
else if (of == output_format::SHORT)
56+
else
5857
{
5958
entry_status = get_status_msg(status).short_mod;
6059
}
@@ -89,7 +88,7 @@ std::string get_print_item(const char* old_path, const char* new_path)
8988
}
9089

9190
std::vector<print_entry> get_entries_to_print(git_status_t status, status_list_wrapper& sl,
92-
bool head_selector, output_format of, std::set<std::string>* tracked_dir_set = nullptr)
91+
bool head_selector, bool is_long, std::set<std::string>* tracked_dir_set = nullptr)
9392
{
9493
std::vector<print_entry> entries_to_print{};
9594
const auto& entry_list = sl.get_entry_list(status);
@@ -106,7 +105,7 @@ std::vector<print_entry> get_entries_to_print(git_status_t status, status_list_w
106105

107106
update_tracked_dir_set(old_path, tracked_dir_set);
108107

109-
print_entry e = { get_print_status(status, of), get_print_item(old_path, new_path)};
108+
print_entry e = { get_print_status(status, is_long), get_print_item(old_path, new_path)};
110109

111110
entries_to_print.push_back(std::move(e));
112111
}
@@ -161,15 +160,12 @@ void print_not_tracked(const std::vector<print_entry>& entries_to_print, const s
161160
print_entries(not_tracked_entries_to_print, is_long, colour);
162161
}
163162

164-
void print_tracking_info(repository_wrapper& repo, status_list_wrapper& sl, status_subcommand_options options, bool is_long)
163+
void print_tracking_info(repository_wrapper& repo, status_list_wrapper& sl, bool is_long)
165164
{
166-
auto branch_name = repo.head_short_name();
167165
auto tracking_info = repo.get_tracking_info();
168166

169167
if (is_long)
170168
{
171-
std::cout << "On branch " << branch_name << std::endl;
172-
173169
if (tracking_info.has_upstream)
174170
{
175171
if(tracking_info.ahead > 0 && tracking_info.behind == 0)
@@ -215,11 +211,6 @@ void print_tracking_info(repository_wrapper& repo, status_list_wrapper& sl, stat
215211
}
216212
else
217213
{
218-
if (options.m_branch_flag)
219-
{
220-
std::cout << "## " << branch_name << std::endl;
221-
}
222-
223214
if (tracking_info.has_upstream)
224215
{
225216
std::cout << "..." << tracking_info.upstream_name;
@@ -246,63 +237,100 @@ void print_tracking_info(repository_wrapper& repo, status_list_wrapper& sl, stat
246237
}
247238
}
248239

249-
void print_tobecommited(status_list_wrapper& sl, output_format of, std::set<std::string> tracked_dir_set, bool is_long)
240+
void print_tobecommited(status_list_wrapper& sl, std::set<std::string> tracked_dir_set, bool is_long, bool is_coloured)
250241
{
251-
stream_colour_fn colour = termcolor::green;
242+
243+
stream_colour_fn colour;
244+
if (is_coloured)
245+
{
246+
colour = termcolor::green;
247+
}
248+
else
249+
{
250+
colour = termcolor::bright_white;
251+
}
252+
252253
if (is_long)
253254
{
254255
std::cout << tobecommited_header;
255256
}
256-
print_entries(get_entries_to_print(GIT_STATUS_INDEX_NEW, sl, true, of, &tracked_dir_set), is_long, colour);
257-
print_entries(get_entries_to_print(GIT_STATUS_INDEX_MODIFIED, sl, true, of, &tracked_dir_set), is_long, colour);
258-
print_entries(get_entries_to_print(GIT_STATUS_INDEX_DELETED, sl, true, of, &tracked_dir_set), is_long, colour);
259-
print_entries(get_entries_to_print(GIT_STATUS_INDEX_RENAMED, sl, true, of, &tracked_dir_set), is_long, colour);
260-
print_entries(get_entries_to_print(GIT_STATUS_INDEX_TYPECHANGE, sl, true, of, &tracked_dir_set), is_long, colour);
257+
print_entries(get_entries_to_print(GIT_STATUS_INDEX_NEW, sl, true, is_long, &tracked_dir_set), is_long, colour);
258+
print_entries(get_entries_to_print(GIT_STATUS_INDEX_MODIFIED, sl, true, is_long, &tracked_dir_set), is_long, colour);
259+
print_entries(get_entries_to_print(GIT_STATUS_INDEX_DELETED, sl, true, is_long, &tracked_dir_set), is_long, colour);
260+
print_entries(get_entries_to_print(GIT_STATUS_INDEX_RENAMED, sl, true, is_long, &tracked_dir_set), is_long, colour);
261+
print_entries(get_entries_to_print(GIT_STATUS_INDEX_TYPECHANGE, sl, true, is_long, &tracked_dir_set), is_long, colour);
261262
if (is_long)
262263
{
263264
std::cout << std::endl;
264265
}
265266
}
266267

267-
void print_notstagged(status_list_wrapper& sl, output_format of, std::set<std::string> tracked_dir_set, bool is_long)
268+
void print_notstagged(status_list_wrapper& sl, std::set<std::string> tracked_dir_set, bool is_long, bool is_coloured)
268269
{
269-
stream_colour_fn colour = termcolor::red;
270+
stream_colour_fn colour;
271+
if (is_coloured)
272+
{
273+
colour = termcolor::red;
274+
}
275+
else
276+
{
277+
colour = termcolor::bright_white;
278+
}
279+
270280
if (is_long)
271281
{
272282
std::cout << notstagged_header;
273283
}
274-
print_entries(get_entries_to_print(GIT_STATUS_WT_MODIFIED, sl, false, of, &tracked_dir_set), is_long, colour);
275-
print_entries(get_entries_to_print(GIT_STATUS_WT_DELETED, sl, false, of, &tracked_dir_set), is_long, colour);
276-
print_entries(get_entries_to_print(GIT_STATUS_WT_TYPECHANGE, sl, false, of, &tracked_dir_set), is_long, colour);
277-
print_entries(get_entries_to_print(GIT_STATUS_WT_RENAMED, sl, false, of, &tracked_dir_set), is_long, colour);
284+
print_entries(get_entries_to_print(GIT_STATUS_WT_MODIFIED, sl, false, is_long, &tracked_dir_set), is_long, colour);
285+
print_entries(get_entries_to_print(GIT_STATUS_WT_DELETED, sl, false, is_long, &tracked_dir_set), is_long, colour);
286+
print_entries(get_entries_to_print(GIT_STATUS_WT_TYPECHANGE, sl, false, is_long, &tracked_dir_set), is_long, colour);
287+
print_entries(get_entries_to_print(GIT_STATUS_WT_RENAMED, sl, false, is_long, &tracked_dir_set), is_long, colour);
278288
if (is_long)
279289
{
280290
std::cout << std::endl;
281291
}
282292
}
283293

284-
void print_unmerged(status_list_wrapper& sl, output_format of, std::set<std::string> tracked_dir_set, std::set<std::string> untracked_dir_set, bool is_long)
294+
void print_unmerged(status_list_wrapper& sl, std::set<std::string> tracked_dir_set, std::set<std::string> untracked_dir_set, bool is_long, bool is_coloured)
285295
{
286-
stream_colour_fn colour = termcolor::red;
296+
stream_colour_fn colour;
297+
if (is_coloured)
298+
{
299+
colour = termcolor::red;
300+
}
301+
else
302+
{
303+
colour = termcolor::bright_white;
304+
}
305+
287306
if (is_long)
288307
{
289308
std::cout << unmerged_header;
290309
}
291-
print_not_tracked(get_entries_to_print(GIT_STATUS_CONFLICTED, sl, false, of), tracked_dir_set, untracked_dir_set, is_long, colour);
310+
print_not_tracked(get_entries_to_print(GIT_STATUS_CONFLICTED, sl, false, is_long), tracked_dir_set, untracked_dir_set, is_long, colour);
292311
if (is_long)
293312
{
294313
std::cout << std::endl;
295314
}
296315
}
297316

298-
void print_untracked(status_list_wrapper& sl, output_format of, std::set<std::string> tracked_dir_set, std::set<std::string> untracked_dir_set, bool is_long)
317+
void print_untracked(status_list_wrapper& sl, std::set<std::string> tracked_dir_set, std::set<std::string> untracked_dir_set, bool is_long, bool is_coloured)
299318
{
300-
stream_colour_fn colour = termcolor::red;
319+
stream_colour_fn colour;
320+
if (is_coloured)
321+
{
322+
colour = termcolor::red;
323+
}
324+
else
325+
{
326+
colour = termcolor::bright_white;
327+
}
328+
301329
if (is_long)
302330
{
303331
std::cout << untracked_header;
304332
}
305-
print_not_tracked(get_entries_to_print(GIT_STATUS_WT_NEW, sl, false, of), tracked_dir_set, untracked_dir_set, is_long, colour);
333+
print_not_tracked(get_entries_to_print(GIT_STATUS_WT_NEW, sl, false, is_long), tracked_dir_set, untracked_dir_set, is_long, colour);
306334
if (is_long)
307335
{
308336
std::cout << std::endl;
@@ -341,27 +369,38 @@ void status_run(status_subcommand_options options)
341369

342370
bool is_long;
343371
is_long = ((of == output_format::DEFAULT) || (of == output_format::LONG));
344-
print_tracking_info(repo, sl, options, is_long);
372+
373+
auto branch_name = repo.head_short_name();
374+
if (is_long)
375+
{
376+
std::cout << "On branch " << branch_name << std::endl;
377+
}
378+
else if (options.m_branch_flag)
379+
{
380+
std::cout << "## " << branch_name << std::endl;
381+
}
382+
bool is_coloured = true;
383+
print_tracking_info(repo, sl, is_long);
345384

346385
if (sl.has_tobecommited_header())
347386
{
348-
print_tobecommited(sl, of, tracked_dir_set,is_long);
387+
print_tobecommited(sl, tracked_dir_set, is_long, is_coloured);
349388
}
350389

351390
if (sl.has_notstagged_header())
352391
{
353-
print_notstagged(sl, of, tracked_dir_set, is_long);
392+
print_notstagged(sl, tracked_dir_set, is_long, is_coloured);
354393
}
355394

356395
// TODO: check if should be printed before "not stagged" files
357396
if (sl.has_unmerged_header())
358397
{
359-
print_unmerged(sl, of, tracked_dir_set, untracked_dir_set, is_long);
398+
print_unmerged(sl, tracked_dir_set, untracked_dir_set, is_long, is_coloured);
360399
}
361400

362401
if (sl.has_untracked_header())
363402
{
364-
print_untracked(sl, of, tracked_dir_set, untracked_dir_set, is_long);
403+
print_untracked(sl, tracked_dir_set, untracked_dir_set, is_long, is_coloured);
365404
}
366405

367406
// TODO: check if this message should be displayed even if there are untracked files

src/subcommand/status_subcommand.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <CLI/CLI.hpp>
44

55
#include "../utils/common.hpp"
6+
#include "../wrapper/status_wrapper.hpp"
67

78
struct status_subcommand_options
89
{
@@ -22,4 +23,7 @@ class status_subcommand
2223
status_subcommand_options m_options;
2324
};
2425

26+
void print_tobecommited(status_list_wrapper& sl, std::set<std::string> tracked_dir_set, bool is_long, bool is_coloured);
27+
void print_notstagged(status_list_wrapper& sl, std::set<std::string> tracked_dir_set, bool is_long, bool is_coloured);
28+
void print_tracking_info(repository_wrapper& repo, status_list_wrapper& sl, bool is_long);
2529
void status_run(status_subcommand_options fl = {});

0 commit comments

Comments
 (0)