Skip to content

Commit 4315421

Browse files
committed
group untracked files to show only the root folder
1 parent fcd5972 commit 4315421

File tree

1 file changed

+114
-44
lines changed

1 file changed

+114
-44
lines changed

src/subcommand/status_subcommand.cpp

Lines changed: 114 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <iostream>
22
#include <ostream>
3+
#include <set>
34
#include <string>
45

56
#include <git2.h>
@@ -71,52 +72,117 @@ enum class output_format
7172
SHORT = 2
7273
};
7374

74-
void print_entries(git_status_t status, status_list_wrapper& sl, bool head_selector, output_format of) // TODO: add different mods
75+
struct print_entry
7576
{
76-
const auto& entry_list = sl.get_entry_list(status);
77-
if (!entry_list.empty())
77+
std::string status;
78+
std::string item;
79+
};
80+
81+
std::string get_print_status(git_status_t status, output_format of)
82+
{
83+
std::string entry_status;
84+
if ((of == output_format::DEFAULT) || (of == output_format::LONG))
7885
{
79-
for (auto* entry : entry_list)
86+
entry_status = status_msg_map.at(status).long_mod + "\t";
87+
}
88+
else if (of == output_format::SHORT)
89+
{
90+
entry_status = status_msg_map.at(status).short_mod;
91+
}
92+
return entry_status;
93+
}
94+
95+
void update_tracked_dir_set(const char* old_path, const char* new_path, std::set<std::string>* tracked_dir_set = nullptr)
96+
{
97+
if (tracked_dir_set)
98+
{
99+
const size_t first_slash_idx = std::string_view(old_path).find('/');
100+
if (std::string::npos != first_slash_idx)
80101
{
81-
if ((of == output_format::DEFAULT) || (of == output_format::LONG))
82-
{
83-
std::cout << status_msg_map.at(status).long_mod << "\t";
84-
}
85-
else if (of == output_format::SHORT)
86-
{
87-
std::cout << status_msg_map.at(status).short_mod;
88-
}
102+
auto directory = std::string_view(old_path).substr(0, first_slash_idx);
103+
tracked_dir_set->insert(std::string(directory));
104+
}
105+
}
106+
}
89107

90-
git_diff_delta* diff_delta;
91-
if (head_selector)
92-
{
93-
diff_delta = entry->head_to_index;
94-
}
95-
else
96-
{
97-
diff_delta = entry->index_to_workdir;
98-
}
99-
const char* old_path = diff_delta->old_file.path;
100-
const char* new_path = diff_delta->new_file.path;
101-
if (old_path && new_path && std::strcmp(old_path, new_path))
108+
std::string get_print_item(const char* old_path, const char* new_path)
109+
{
110+
std::string entry_item;
111+
if (old_path && new_path && std::strcmp(old_path, new_path))
112+
{
113+
entry_item = std::string(old_path) + " -> " + std::string(new_path);
114+
}
115+
else
116+
{
117+
entry_item = old_path ? old_path : new_path;
118+
}
119+
return entry_item;
120+
}
121+
122+
std::vector<print_entry> get_entries_to_print(git_status_t status, status_list_wrapper& sl,
123+
bool head_selector, output_format of, std::set<std::string>* tracked_dir_set = nullptr)
124+
{
125+
std::vector<print_entry> entries_to_print{};
126+
const auto& entry_list = sl.get_entry_list(status);
127+
if (entry_list.empty())
128+
{
129+
return entries_to_print;
130+
}
131+
132+
for (auto* entry : entry_list)
133+
{
134+
git_diff_delta* diff_delta = head_selector ? entry->head_to_index : entry->index_to_workdir;
135+
const char* old_path = diff_delta->old_file.path;
136+
const char* new_path = diff_delta->new_file.path;
137+
138+
update_tracked_dir_set(old_path, new_path, tracked_dir_set);
139+
140+
print_entry e = { get_print_status(status, of), get_print_item(old_path, new_path)};
141+
142+
entries_to_print.push_back(std::move(e));
143+
}
144+
return entries_to_print;
145+
}
146+
147+
void print_entries(std::vector<print_entry> entries_to_print)
148+
{
149+
for (auto e: entries_to_print)
150+
{
151+
std::cout << e.status << e.item << std::endl;
152+
}
153+
}
154+
155+
void print_not_tracked(std::vector<print_entry> entries_to_print, const std::set<std::string>& tracked_dir_set,
156+
std::set<std::string>& untracked_dir_set)
157+
{
158+
std::vector<print_entry> not_tracked_entries_to_print{};
159+
for (auto e: entries_to_print)
160+
{
161+
const size_t first_slash_idx = e.item.find('/');
162+
if (std::string::npos != first_slash_idx)
163+
{
164+
auto directory = e.item.substr(0, first_slash_idx);
165+
if (tracked_dir_set.contains(directory))
102166
{
103-
std::cout << old_path << " -> " << new_path << std::endl;
167+
not_tracked_entries_to_print.push_back(e);
104168
}
105169
else
106170
{
107-
if (old_path)
108-
{
109-
std::cout << old_path << std::endl;
110-
}
171+
if (untracked_dir_set.contains(directory))
172+
{}
111173
else
112174
{
113-
std::cout << new_path << std::endl;
175+
not_tracked_entries_to_print.push_back({e.status, directory});
176+
untracked_dir_set.insert(std::string(directory));
114177
}
115178
}
116179
}
180+
else
181+
{
182+
not_tracked_entries_to_print.push_back(e);
183+
}
117184
}
118-
else
119-
{}
185+
print_entries(not_tracked_entries_to_print);
120186
}
121187

122188
void status_subcommand::run()
@@ -127,7 +193,10 @@ void status_subcommand::run()
127193
auto sl = status_list_wrapper::status_list(repo);
128194
auto branch_name = reference_wrapper::get_ref_name(repo);
129195

130-
// TODO: add branch info
196+
std::set<std::string> tracked_dir_set{};
197+
std::set<std::string> untracked_dir_set{};
198+
std::vector<std::string> untracked_to_print{};
199+
std::vector<std::string> ignored_to_print{};
131200

132201
output_format of = output_format::DEFAULT;
133202
if (short_flag)
@@ -162,11 +231,11 @@ void status_subcommand::run()
162231
{
163232
std::cout << tobecommited_header << std::endl;
164233
}
165-
print_entries(GIT_STATUS_INDEX_NEW, sl, true, of);
166-
print_entries(GIT_STATUS_INDEX_MODIFIED, sl, true, of);
167-
print_entries(GIT_STATUS_INDEX_DELETED, sl, true, of);
168-
print_entries(GIT_STATUS_INDEX_RENAMED, sl, true, of);
169-
print_entries(GIT_STATUS_INDEX_TYPECHANGE, sl, true, of);
234+
print_entries(get_entries_to_print(GIT_STATUS_INDEX_NEW, sl, true, of, &tracked_dir_set));
235+
print_entries(get_entries_to_print(GIT_STATUS_INDEX_MODIFIED, sl, true, of, &tracked_dir_set));
236+
print_entries(get_entries_to_print(GIT_STATUS_INDEX_DELETED, sl, true, of, &tracked_dir_set));
237+
print_entries(get_entries_to_print(GIT_STATUS_INDEX_RENAMED, sl, true, of, &tracked_dir_set));
238+
print_entries(get_entries_to_print(GIT_STATUS_INDEX_TYPECHANGE, sl, true, of, &tracked_dir_set));
170239
if (is_long)
171240
{
172241
std::cout << std::endl;
@@ -179,23 +248,24 @@ void status_subcommand::run()
179248
{
180249
std::cout << notstagged_header << std::endl;
181250
}
182-
print_entries(GIT_STATUS_WT_MODIFIED, sl, false, of);
183-
print_entries(GIT_STATUS_WT_DELETED, sl, false, of);
184-
print_entries(GIT_STATUS_WT_TYPECHANGE, sl, false, of);
185-
print_entries(GIT_STATUS_WT_RENAMED, sl, false, of);
251+
print_entries(get_entries_to_print(GIT_STATUS_WT_MODIFIED, sl, false, of, &tracked_dir_set));
252+
print_entries(get_entries_to_print(GIT_STATUS_WT_DELETED, sl, false, of, &tracked_dir_set));
253+
print_entries(get_entries_to_print(GIT_STATUS_WT_TYPECHANGE, sl, false, of, &tracked_dir_set));
254+
print_entries(get_entries_to_print(GIT_STATUS_WT_RENAMED, sl, false, of, &tracked_dir_set));
186255
if (is_long)
187256
{
188257
std::cout << std::endl;
189258
}
190259
}
191260

261+
192262
if (sl.has_untracked_header())
193263
{
194264
if (is_long)
195265
{
196266
std::cout << untracked_header << std::endl;
197267
}
198-
print_entries(GIT_STATUS_WT_NEW, sl, false, of);
268+
print_not_tracked(get_entries_to_print(GIT_STATUS_WT_NEW, sl, false, of), tracked_dir_set, untracked_dir_set);
199269
if (is_long)
200270
{
201271
std::cout << std::endl;
@@ -208,7 +278,7 @@ void status_subcommand::run()
208278
{
209279
std::cout << ignored_header << std::endl;
210280
}
211-
print_entries(GIT_STATUS_IGNORED, sl, false, of);
281+
print_not_tracked(get_entries_to_print(GIT_STATUS_IGNORED, sl, false, of), tracked_dir_set, untracked_dir_set);
212282
if (is_long)
213283
{
214284
std::cout << std::endl;

0 commit comments

Comments
 (0)