@@ -173,6 +173,13 @@ static VALUE rb_git_diff_patch_stat(VALUE self)
173
173
return rb_ary_new3 (2 , INT2FIX (additions ), INT2FIX (deletions ));
174
174
}
175
175
176
+ enum {
177
+ EXCLUDE_CONTEXT = (1u << 0 ),
178
+ EXCLUDE_ADDITIONS = (1u << 1 ),
179
+ EXCLUDE_DELETIONS = (1u << 2 ),
180
+ EXCLUDE_EOFNL = (1u << 3 )
181
+ };
182
+
176
183
/*
177
184
* call-seq:
178
185
* patch.lines(options = {}) -> int
@@ -191,41 +198,82 @@ static VALUE rb_git_diff_patch_stat(VALUE self)
191
198
* Boolean value specifying that deletion line counts should be excluded from
192
199
* the returned total.
193
200
*
201
+ * :exclude_eofnl ::
202
+ * Boolean value specifying that end-of-file newline change lines should
203
+ * be excluded from the returned total.
204
+ *
194
205
* Returns the total number of lines in the patch, depending on the options
195
206
* specified.
196
207
*/
197
208
static VALUE rb_git_diff_patch_lines (int argc , VALUE * argv , VALUE self )
198
209
{
199
210
git_patch * patch ;
200
- size_t context_lines , additions , deletions ;
201
- size_t total_out ;
211
+ size_t lines = 0 ;
202
212
VALUE rb_options ;
203
213
Data_Get_Struct (self , git_patch , patch );
204
214
205
- context_lines = 0 ;
206
- additions = 0 ;
207
- deletions = 0 ;
208
-
209
- git_patch_line_stats (& context_lines , & additions , & deletions , patch );
210
-
211
- total_out = context_lines + additions + deletions ;
215
+ int options = 0 ;
212
216
213
217
rb_scan_args (argc , argv , "0:" , & rb_options );
214
218
if (!NIL_P (rb_options )) {
215
219
if (RTEST (rb_hash_aref (rb_options , CSTR2SYM ("exclude_context" )))) {
216
- total_out -= context_lines ;
220
+ options |= EXCLUDE_CONTEXT ;
217
221
}
218
222
219
223
if (RTEST (rb_hash_aref (rb_options , CSTR2SYM ("exclude_additions" )))) {
220
- total_out -= additions ;
224
+ options |= EXCLUDE_ADDITIONS ;
221
225
}
222
226
223
227
if (RTEST (rb_hash_aref (rb_options , CSTR2SYM ("exclude_deletions" )))) {
224
- total_out -= deletions ;
228
+ options |= EXCLUDE_DELETIONS ;
229
+ }
230
+
231
+ if (RTEST (rb_hash_aref (rb_options , CSTR2SYM ("exclude_eofnl" )))) {
232
+ options |= EXCLUDE_EOFNL ;
225
233
}
226
234
}
227
235
228
- return INT2FIX (total_out );
236
+ if (options == 0 ) {
237
+ size_t i = 0 , hunks_count = git_patch_num_hunks (patch );
238
+ for (i = 0 ; i < hunks_count ; ++ i ) {
239
+ lines += git_patch_num_lines_in_hunk (patch , i );
240
+ }
241
+ } else {
242
+ size_t i = 0 , hunks_count = git_patch_num_hunks (patch );
243
+ for (i = 0 ; i < hunks_count ; ++ i ) {
244
+ size_t lines_in_hunk = git_patch_num_lines_in_hunk (patch , i ), l = 0 ;
245
+
246
+ for (l = 0 ; l < lines_in_hunk ; ++ l ) {
247
+ const git_diff_line * line ;
248
+ rugged_exception_check (
249
+ git_patch_get_line_in_hunk (& line , patch , i , l )
250
+ );
251
+
252
+ switch (line -> origin ) {
253
+ case GIT_DIFF_LINE_CONTEXT :
254
+ if (options & EXCLUDE_CONTEXT ) continue ;
255
+ break ;
256
+
257
+ case GIT_DIFF_LINE_ADDITION :
258
+ if (options & EXCLUDE_ADDITIONS ) continue ;
259
+ break ;
260
+
261
+ case GIT_DIFF_LINE_DELETION :
262
+ if (options & EXCLUDE_DELETIONS ) continue ;
263
+ break ;
264
+
265
+ case GIT_DIFF_LINE_ADD_EOFNL :
266
+ case GIT_DIFF_LINE_DEL_EOFNL :
267
+ if (options & EXCLUDE_EOFNL ) continue ;
268
+ break ;
269
+ }
270
+
271
+ lines += 1 ;
272
+ }
273
+ }
274
+ }
275
+
276
+ return INT2FIX (lines );
229
277
}
230
278
/*
231
279
* call-seq:
@@ -256,21 +304,19 @@ static VALUE rb_git_diff_patch_bytesize(int argc, VALUE *argv, VALUE self)
256
304
int include_context , include_hunk_headers , include_file_headers ;
257
305
Data_Get_Struct (self , git_patch , patch );
258
306
259
- include_context = 1 ;
260
- include_hunk_headers = 1 ;
261
- include_file_headers = 1 ;
307
+ include_context = include_hunk_headers = include_file_headers = 1 ;
262
308
263
309
rb_scan_args (argc , argv , "0:" , & rb_options );
264
310
if (!NIL_P (rb_options )) {
265
- if (rb_hash_aref (rb_options , CSTR2SYM ("include_context " )) == Qfalse ) {
311
+ if (RTEST ( rb_hash_aref (rb_options , CSTR2SYM ("exclude_context " ))) ) {
266
312
include_context = 0 ;
267
313
}
268
314
269
- if (rb_hash_aref (rb_options , CSTR2SYM ("include_hunk_headers " )) == Qfalse ) {
315
+ if (RTEST ( rb_hash_aref (rb_options , CSTR2SYM ("exclude_hunk_headers " ))) ) {
270
316
include_hunk_headers = 0 ;
271
317
}
272
318
273
- if (rb_hash_aref (rb_options , CSTR2SYM ("include_file_headers " )) == Qfalse ) {
319
+ if (RTEST ( rb_hash_aref (rb_options , CSTR2SYM ("exclude_file_headers " ))) ) {
274
320
include_file_headers = 0 ;
275
321
}
276
322
}
0 commit comments