@@ -71,6 +71,129 @@ diff_subcommand::diff_subcommand(const libgit2_object&, CLI::App& app)
7171 );
7272}
7373
74+ namespace
75+ {
76+ int colour_printer (
77+ [[maybe_unused]] const git_diff_delta* delta,
78+ [[maybe_unused]] const git_diff_hunk* hunk,
79+ const git_diff_line* line,
80+ void * payload
81+ )
82+ {
83+ bool use_colour = *reinterpret_cast <bool *>(payload);
84+
85+ // Only print origin for context/addition/deletion lines
86+ bool print_origin = (line->origin == GIT_DIFF_LINE_CONTEXT || line->origin == GIT_DIFF_LINE_ADDITION || line->origin == GIT_DIFF_LINE_DELETION);
87+
88+ if (use_colour)
89+ {
90+ switch (line->origin )
91+ {
92+ case GIT_DIFF_LINE_ADDITION:
93+ std::cout << termcolor::green;
94+ break ;
95+ case GIT_DIFF_LINE_DELETION:
96+ std::cout << termcolor::red;
97+ break ;
98+ case GIT_DIFF_LINE_ADD_EOFNL:
99+ std::cout << termcolor::green;
100+ break ;
101+ case GIT_DIFF_LINE_DEL_EOFNL:
102+ std::cout << termcolor::red;
103+ break ;
104+ case GIT_DIFF_LINE_FILE_HDR:
105+ std::cout << termcolor::bold;
106+ break ;
107+ case GIT_DIFF_LINE_HUNK_HDR:
108+ std::cout << termcolor::cyan;
109+ break ;
110+ default :
111+ break ;
112+ }
113+ }
114+
115+ if (print_origin)
116+ {
117+ std::cout << line->origin ;
118+ }
119+
120+ std::cout << std::string_view (line->content , line->content_len );
121+
122+ if (use_colour)
123+ {
124+ std::cout << termcolor::reset;
125+ }
126+
127+ // Print copy/rename headers ONLY after the "diff --git" line
128+ if (line->origin == GIT_DIFF_LINE_FILE_HDR)
129+ {
130+ if (delta->status == GIT_DELTA_COPIED)
131+ {
132+ if (use_colour)
133+ {
134+ std::cout << termcolor::bold;
135+ }
136+ std::cout << " similarity index " << delta->similarity << " %\n " ;
137+ std::cout << " copy from " << delta->old_file .path << " \n " ;
138+ std::cout << " copy to " << delta->new_file .path << " \n " ;
139+ if (use_colour)
140+ {
141+ std::cout << termcolor::reset;
142+ }
143+ }
144+ else if (delta->status == GIT_DELTA_RENAMED)
145+ {
146+ if (use_colour)
147+ {
148+ std::cout << termcolor::bold;
149+ }
150+ std::cout << " similarity index " << delta->similarity << " %\n " ;
151+ std::cout << " rename from " << delta->old_file .path << " \n " ;
152+ std::cout << " rename to " << delta->new_file .path << " \n " ;
153+ if (use_colour)
154+ {
155+ std::cout << termcolor::reset;
156+ }
157+ }
158+ }
159+
160+ return 0 ;
161+ }
162+
163+ diff_wrapper compute_diff_no_index (std::vector<std::string> files, git_diff_options& diffopts)
164+ {
165+ if (files.size () != 2 )
166+ {
167+ throw git_exception (
168+ " usage: git diff --no-index [<options>] <path> <path> [<pathspec>...]" ,
169+ git2cpp_error_code::BAD_ARGUMENT
170+ );
171+ }
172+
173+ git_diff_options_init (&diffopts, GIT_DIFF_OPTIONS_VERSION);
174+
175+ std::string file1_str = read_file (files[0 ]);
176+ std::string file2_str = read_file (files[1 ]);
177+
178+ if (file1_str.empty ())
179+ {
180+ throw git_exception (" Cannot read file: " + files[0 ], git2cpp_error_code::GENERIC_ERROR);
181+ }
182+ if (file2_str.empty ())
183+ {
184+ throw git_exception (" Cannot read file: " + files[1 ], git2cpp_error_code::GENERIC_ERROR);
185+ }
186+
187+ auto patch = patch_wrapper::patch_from_files (files[0 ], file1_str, files[1 ], file2_str, &diffopts);
188+ auto buf = patch.to_buf ();
189+ auto diff = diff_wrapper::diff_from_buffer (buf);
190+
191+ git_buf_dispose (&buf);
192+
193+ return diff;
194+ }
195+ }
196+
74197void print_stats (
75198 const diff_wrapper& diff,
76199 bool use_colour,
@@ -170,93 +293,6 @@ void print_stats(
170293 git_buf_dispose (&buf);
171294}
172295
173- static int colour_printer (
174- [[maybe_unused]] const git_diff_delta* delta,
175- [[maybe_unused]] const git_diff_hunk* hunk,
176- const git_diff_line* line,
177- void * payload
178- )
179- {
180- bool use_colour = *reinterpret_cast <bool *>(payload);
181-
182- // Only print origin for context/addition/deletion lines
183- bool print_origin = (line->origin == GIT_DIFF_LINE_CONTEXT || line->origin == GIT_DIFF_LINE_ADDITION || line->origin == GIT_DIFF_LINE_DELETION);
184-
185- if (use_colour)
186- {
187- switch (line->origin )
188- {
189- case GIT_DIFF_LINE_ADDITION:
190- std::cout << termcolor::green;
191- break ;
192- case GIT_DIFF_LINE_DELETION:
193- std::cout << termcolor::red;
194- break ;
195- case GIT_DIFF_LINE_ADD_EOFNL:
196- std::cout << termcolor::green;
197- break ;
198- case GIT_DIFF_LINE_DEL_EOFNL:
199- std::cout << termcolor::red;
200- break ;
201- case GIT_DIFF_LINE_FILE_HDR:
202- std::cout << termcolor::bold;
203- break ;
204- case GIT_DIFF_LINE_HUNK_HDR:
205- std::cout << termcolor::cyan;
206- break ;
207- default :
208- break ;
209- }
210- }
211-
212- if (print_origin)
213- {
214- std::cout << line->origin ;
215- }
216-
217- std::cout << std::string_view (line->content , line->content_len );
218-
219- if (use_colour)
220- {
221- std::cout << termcolor::reset;
222- }
223-
224- // Print copy/rename headers ONLY after the "diff --git" line
225- if (line->origin == GIT_DIFF_LINE_FILE_HDR)
226- {
227- if (delta->status == GIT_DELTA_COPIED)
228- {
229- if (use_colour)
230- {
231- std::cout << termcolor::bold;
232- }
233- std::cout << " similarity index " << delta->similarity << " %\n " ;
234- std::cout << " copy from " << delta->old_file .path << " \n " ;
235- std::cout << " copy to " << delta->new_file .path << " \n " ;
236- if (use_colour)
237- {
238- std::cout << termcolor::reset;
239- }
240- }
241- else if (delta->status == GIT_DELTA_RENAMED)
242- {
243- if (use_colour)
244- {
245- std::cout << termcolor::bold;
246- }
247- std::cout << " similarity index " << delta->similarity << " %\n " ;
248- std::cout << " rename from " << delta->old_file .path << " \n " ;
249- std::cout << " rename to " << delta->new_file .path << " \n " ;
250- if (use_colour)
251- {
252- std::cout << termcolor::reset;
253- }
254- }
255- }
256-
257- return 0 ;
258- }
259-
260296void diff_subcommand::print_diff (diff_wrapper& diff, bool use_colour)
261297{
262298 if (m_stat_flag || m_shortstat_flag || m_numstat_flag || m_summary_flag)
@@ -307,39 +343,6 @@ void diff_subcommand::print_diff(diff_wrapper& diff, bool use_colour)
307343 diff.print (format, colour_printer, &use_colour);
308344}
309345
310- diff_wrapper compute_diff_no_index (std::vector<std::string> files, git_diff_options& diffopts)
311- {
312- if (files.size () != 2 )
313- {
314- throw git_exception (
315- " usage: git diff --no-index [<options>] <path> <path> [<pathspec>...]" ,
316- git2cpp_error_code::BAD_ARGUMENT
317- );
318- }
319-
320- git_diff_options_init (&diffopts, GIT_DIFF_OPTIONS_VERSION);
321-
322- std::string file1_str = read_file (files[0 ]);
323- std::string file2_str = read_file (files[1 ]);
324-
325- if (file1_str.empty ())
326- {
327- throw git_exception (" Cannot read file: " + files[0 ], git2cpp_error_code::GENERIC_ERROR);
328- }
329- if (file2_str.empty ())
330- {
331- throw git_exception (" Cannot read file: " + files[1 ], git2cpp_error_code::GENERIC_ERROR);
332- }
333-
334- auto patch = patch_wrapper::patch_from_files (files[0 ], file1_str, files[1 ], file2_str, &diffopts);
335- auto buf = patch.to_buf ();
336- auto diff = diff_wrapper::diff_from_buffer (buf);
337-
338- git_buf_dispose (&buf);
339-
340- return diff;
341- }
342-
343346void diff_subcommand::run ()
344347{
345348 git_diff_options diffopts;
0 commit comments