@@ -354,183 +354,49 @@ static VALUE rb_git_tree_path(VALUE self, VALUE rb_path)
354
354
return rb_entry ;
355
355
}
356
356
357
- /*
358
- * call-seq:
359
- * Tree.diff(repo, tree, diffable[, options]) -> diff
360
- *
361
- * Returns a diff between the `tree` and the diffable object that was given.
362
- * +diffable+ can either be a +Rugged::Commit+, a +Rugged::Tree+, a +Rugged::Index+,
363
- * or +nil+.
364
- *
365
- * The +tree+ object will be used as the "old file" side of the diff, while the
366
- * parent tree or the +diffable+ object will be used for the "new file" side.
367
- *
368
- * If +tree+ or +diffable+ are nil, they will be treated as an empty tree. Passing
369
- * both as `nil` will raise an exception.
370
- *
371
- * The following options can be passed in the +options+ Hash:
372
- *
373
- * :paths ::
374
- * An array of paths / fnmatch patterns to constrain the diff to a specific
375
- * set of files. Also see +:disable_pathspec_match+.
376
- *
377
- * :max_size ::
378
- * An integer specifying the maximum byte size of a file before a it will
379
- * be treated as binary. The default value is 512MB.
380
- *
381
- * :context_lines ::
382
- * The number of unchanged lines that define the boundary of a hunk (and
383
- * to display before and after the actual changes). The default is 3.
384
- *
385
- * :interhunk_lines ::
386
- * The maximum number of unchanged lines between hunk boundaries before the hunks
387
- * will be merged into a one. The default is 0.
388
- *
389
- * :old_prefix ::
390
- * The virtual "directory" to prefix to old filenames in hunk headers.
391
- * The default is "a".
392
- *
393
- * :new_prefix ::
394
- * The virtual "directory" to prefix to new filenames in hunk headers.
395
- * The default is "b".
396
- *
397
- * :reverse ::
398
- * If true, the sides of the diff will be reversed.
399
- *
400
- * :force_text ::
401
- * If true, all files will be treated as text, disabling binary attributes & detection.
402
- *
403
- * :ignore_whitespace ::
404
- * If true, all whitespace will be ignored.
405
- *
406
- * :ignore_whitespace_change ::
407
- * If true, changes in amount of whitespace will be ignored.
408
- *
409
- * :ignore_whitespace_eol ::
410
- * If true, whitespace at end of line will be ignored.
411
- *
412
- * :ignore_submodules ::
413
- * if true, submodules will be excluded from the diff completely.
414
- *
415
- * :patience ::
416
- * If true, the "patience diff" algorithm will be used (currenlty unimplemented).
417
- *
418
- * :include_ignored ::
419
- * If true, ignored files will be included in the diff.
420
- *
421
- * :include_untracked ::
422
- * If true, untracked files will be included in the diff.
423
- *
424
- * :include_unmodified ::
425
- * If true, unmodified files will be included in the diff.
426
- *
427
- * :recurse_untracked_dirs ::
428
- * Even if +:include_untracked+ is true, untracked directories will only be
429
- * marked with a single entry in the diff. If this flag is set to true,
430
- * all files under ignored directories will be included in the diff, too.
431
- *
432
- * :disable_pathspec_match ::
433
- * If true, the given +:paths+ will be applied as exact matches, instead of
434
- * as fnmatch patterns.
435
- *
436
- * :deltas_are_icase ::
437
- * If true, filename comparisons will be made with case-insensitivity.
438
- *
439
- * :include_untracked_content ::
440
- * if true, untracked content will be contained in the the diff patch text.
441
- *
442
- * :skip_binary_check ::
443
- * If true, diff deltas will be generated without spending time on binary
444
- * detection. This is useful to improve performance in cases where the actual
445
- * file content difference is not needed.
446
- *
447
- * :include_typechange ::
448
- * If true, type changes for files will not be interpreted as deletion of
449
- * the "old file" and addition of the "new file", but will generate
450
- * typechange records.
451
- *
452
- * :include_typechange_trees ::
453
- * Even if +:include_typechange+ is true, blob -> tree changes will still
454
- * usually be handled as a deletion of the blob. If this flag is set to true,
455
- * blob -> tree changes will be marked as typechanges.
456
- *
457
- * :ignore_filemode ::
458
- * If true, file mode changes will be ignored.
459
- *
460
- * :recurse_ignored_dirs ::
461
- * Even if +:include_ignored+ is true, ignored directories will only be
462
- * marked with a single entry in the diff. If this flag is set to true,
463
- * all files under ignored directories will be included in the diff, too.
464
- *
465
- * Examples:
466
- *
467
- * # Emulating `git diff <treeish>`
468
- * tree = Rugged::Tree.lookup(repo, "d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
469
- * diff = tree.diff(repo.index)
470
- * diff.merge!(tree.diff)
471
- *
472
- * # Tree-to-Tree Diff
473
- * tree = Rugged::Tree.lookup(repo, "d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
474
- * other_tree = Rugged::Tree.lookup(repo, "7a9e0b02e63179929fed24f0a3e0f19168114d10")
475
- * diff = tree.diff(other_tree)
476
- */
477
- static VALUE rb_git_tree_diff_ (int argc , VALUE * argv , VALUE self )
357
+ static VALUE rb_git_diff_tree_to_index (VALUE self , VALUE rb_repo , VALUE rb_self , VALUE rb_other , VALUE rb_options )
478
358
{
479
359
git_tree * tree = NULL ;
480
360
git_diff_options opts = GIT_DIFF_OPTIONS_INIT ;
481
361
git_repository * repo = NULL ;
482
362
git_diff * diff = NULL ;
483
- VALUE rb_self , rb_repo , rb_other , rb_options ;
363
+ git_index * index ;
484
364
int error ;
485
365
486
- rb_scan_args (argc , argv , "22" , & rb_repo , & rb_self , & rb_other , & rb_options );
487
366
Data_Get_Struct (rb_repo , git_repository , repo );
488
- rugged_parse_diff_options ( & opts , rb_options );
367
+ Data_Get_Struct ( rb_other , git_index , index );
489
368
490
- if (!NIL_P (rb_self )) {
491
- if (!rb_obj_is_kind_of (rb_self , rb_cRuggedTree ))
492
- rb_raise (rb_eTypeError ,
493
- "At least a Rugged::Tree object is required for diffing" );
369
+ rugged_parse_diff_options (& opts , rb_options );
494
370
371
+ if (RTEST (rb_self )) {
495
372
Data_Get_Struct (rb_self , git_tree , tree );
496
373
}
497
374
498
- if (NIL_P (rb_other )) {
499
- if (tree == NULL ) {
500
- xfree (opts .pathspec .strings );
501
- rb_raise (rb_eTypeError , "Need 'old' or 'new' for diffing" );
502
- }
375
+ error = git_diff_tree_to_index (& diff , repo , tree , index , & opts );
503
376
504
- error = git_diff_tree_to_tree (& diff , repo , tree , NULL , & opts );
505
- } else {
506
- if (TYPE (rb_other ) == T_STRING )
507
- rb_other = rugged_object_rev_parse (rb_repo , rb_other , 1 );
377
+ xfree (opts .pathspec .strings );
378
+ rugged_exception_check (error );
508
379
509
- if (rb_obj_is_kind_of (rb_other , rb_cRuggedCommit )) {
510
- git_tree * other_tree ;
511
- git_commit * commit ;
380
+ return rugged_diff_new (rb_cRuggedDiff , rb_repo , diff );
381
+ }
512
382
513
- Data_Get_Struct (rb_other , git_commit , commit );
514
- error = git_commit_tree (& other_tree , commit );
383
+ static VALUE rb_git_diff_tree_to_tree (VALUE self , VALUE rb_repo , VALUE rb_tree , VALUE rb_other_tree , VALUE rb_options ) {
384
+ git_tree * tree = NULL ;
385
+ git_tree * other_tree = NULL ;
386
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT ;
387
+ git_repository * repo = NULL ;
388
+ git_diff * diff = NULL ;
389
+ int error ;
515
390
516
- if (!error ) {
517
- error = git_diff_tree_to_tree (& diff , repo , tree , other_tree , & opts );
518
- git_tree_free (other_tree );
519
- }
520
- } else if (rb_obj_is_kind_of (rb_other , rb_cRuggedTree )) {
521
- git_tree * other_tree ;
522
-
523
- Data_Get_Struct (rb_other , git_tree , other_tree );
524
- error = git_diff_tree_to_tree (& diff , repo , tree , other_tree , & opts );
525
- } else if (rb_obj_is_kind_of (rb_other , rb_cRuggedIndex )) {
526
- git_index * index ;
527
- Data_Get_Struct (rb_other , git_index , index );
528
- error = git_diff_tree_to_index (& diff , repo , tree , index , & opts );
529
- } else {
530
- xfree (opts .pathspec .strings );
531
- rb_raise (rb_eTypeError , "A Rugged::Commit, Rugged::Tree or Rugged::Index instance is required" );
532
- }
533
- }
391
+ Data_Get_Struct (rb_repo , git_repository , repo );
392
+ Data_Get_Struct (rb_tree , git_tree , tree );
393
+
394
+ if (RTEST (rb_other_tree ))
395
+ Data_Get_Struct (rb_other_tree , git_tree , other_tree );
396
+
397
+ rugged_parse_diff_options (& opts , rb_options );
398
+
399
+ error = git_diff_tree_to_tree (& diff , repo , tree , other_tree , & opts );
534
400
535
401
xfree (opts .pathspec .strings );
536
402
rugged_exception_check (error );
@@ -1036,7 +902,8 @@ void Init_rugged_tree(void)
1036
902
rb_define_method (rb_cRuggedTree , "update" , rb_git_tree_update , 1 );
1037
903
rb_define_singleton_method (rb_cRuggedTree , "empty" , rb_git_tree_empty , 1 );
1038
904
1039
- rb_define_singleton_method (rb_cRuggedTree , "diff" , rb_git_tree_diff_ , -1 );
905
+ rb_define_private_method (rb_singleton_class (rb_cRuggedTree ), "diff_tree_to_index" , rb_git_diff_tree_to_index , 4 );
906
+ rb_define_private_method (rb_singleton_class (rb_cRuggedTree ), "diff_tree_to_tree" , rb_git_diff_tree_to_tree , 4 );
1040
907
1041
908
rb_cRuggedTreeBuilder = rb_define_class_under (rb_cRuggedTree , "Builder" , rb_cObject );
1042
909
rb_define_singleton_method (rb_cRuggedTreeBuilder , "new" , rb_git_treebuilder_new , -1 );
0 commit comments