7
7
#include "xdiff-interface.h"
8
8
#include "log-tree.h"
9
9
#include "refs.h"
10
+ #include "userdiff.h"
10
11
11
12
static struct combine_diff_path * intersect_paths (struct combine_diff_path * curr , int n , int num_parent )
12
13
{
@@ -92,7 +93,9 @@ struct sline {
92
93
unsigned long * p_lno ;
93
94
};
94
95
95
- static char * grab_blob (const unsigned char * sha1 , unsigned int mode , unsigned long * size )
96
+ static char * grab_blob (const unsigned char * sha1 , unsigned int mode ,
97
+ unsigned long * size , struct userdiff_driver * textconv ,
98
+ const char * path )
96
99
{
97
100
char * blob ;
98
101
enum object_type type ;
@@ -105,6 +108,11 @@ static char *grab_blob(const unsigned char *sha1, unsigned int mode, unsigned lo
105
108
/* deleted blob */
106
109
* size = 0 ;
107
110
return xcalloc (1 , 1 );
111
+ } else if (textconv ) {
112
+ struct diff_filespec * df = alloc_filespec (path );
113
+ fill_filespec (df , sha1 , mode );
114
+ * size = fill_textconv (textconv , df , & blob );
115
+ free_filespec (df );
108
116
} else {
109
117
blob = read_sha1_file (sha1 , & type , size );
110
118
if (type != OBJ_BLOB )
@@ -204,7 +212,9 @@ static void consume_line(void *state_, char *line, unsigned long len)
204
212
static void combine_diff (const unsigned char * parent , unsigned int mode ,
205
213
mmfile_t * result_file ,
206
214
struct sline * sline , unsigned int cnt , int n ,
207
- int num_parent , int result_deleted )
215
+ int num_parent , int result_deleted ,
216
+ struct userdiff_driver * textconv ,
217
+ const char * path )
208
218
{
209
219
unsigned int p_lno , lno ;
210
220
unsigned long nmask = (1UL << n );
@@ -217,7 +227,7 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
217
227
if (result_deleted )
218
228
return ; /* result deleted */
219
229
220
- parent_file .ptr = grab_blob (parent , mode , & sz );
230
+ parent_file .ptr = grab_blob (parent , mode , & sz , textconv , path );
221
231
parent_file .size = sz ;
222
232
memset (& xpp , 0 , sizeof (xpp ));
223
233
xpp .flags = 0 ;
@@ -681,6 +691,82 @@ static void dump_quoted_path(const char *head,
681
691
puts (buf .buf );
682
692
}
683
693
694
+ static void show_combined_header (struct combine_diff_path * elem ,
695
+ int num_parent ,
696
+ int dense ,
697
+ struct rev_info * rev ,
698
+ int mode_differs ,
699
+ int show_file_header )
700
+ {
701
+ struct diff_options * opt = & rev -> diffopt ;
702
+ int abbrev = DIFF_OPT_TST (opt , FULL_INDEX ) ? 40 : DEFAULT_ABBREV ;
703
+ const char * a_prefix = opt -> a_prefix ? opt -> a_prefix : "a/" ;
704
+ const char * b_prefix = opt -> b_prefix ? opt -> b_prefix : "b/" ;
705
+ int use_color = DIFF_OPT_TST (opt , COLOR_DIFF );
706
+ const char * c_meta = diff_get_color (use_color , DIFF_METAINFO );
707
+ const char * c_reset = diff_get_color (use_color , DIFF_RESET );
708
+ const char * abb ;
709
+ int added = 0 ;
710
+ int deleted = 0 ;
711
+ int i ;
712
+
713
+ if (rev -> loginfo && !rev -> no_commit_id )
714
+ show_log (rev );
715
+
716
+ dump_quoted_path (dense ? "diff --cc " : "diff --combined " ,
717
+ "" , elem -> path , c_meta , c_reset );
718
+ printf ("%sindex " , c_meta );
719
+ for (i = 0 ; i < num_parent ; i ++ ) {
720
+ abb = find_unique_abbrev (elem -> parent [i ].sha1 ,
721
+ abbrev );
722
+ printf ("%s%s" , i ? "," : "" , abb );
723
+ }
724
+ abb = find_unique_abbrev (elem -> sha1 , abbrev );
725
+ printf ("..%s%s\n" , abb , c_reset );
726
+
727
+ if (mode_differs ) {
728
+ deleted = !elem -> mode ;
729
+
730
+ /* We say it was added if nobody had it */
731
+ added = !deleted ;
732
+ for (i = 0 ; added && i < num_parent ; i ++ )
733
+ if (elem -> parent [i ].status !=
734
+ DIFF_STATUS_ADDED )
735
+ added = 0 ;
736
+ if (added )
737
+ printf ("%snew file mode %06o" ,
738
+ c_meta , elem -> mode );
739
+ else {
740
+ if (deleted )
741
+ printf ("%sdeleted file " , c_meta );
742
+ printf ("mode " );
743
+ for (i = 0 ; i < num_parent ; i ++ ) {
744
+ printf ("%s%06o" , i ? "," : "" ,
745
+ elem -> parent [i ].mode );
746
+ }
747
+ if (elem -> mode )
748
+ printf ("..%06o" , elem -> mode );
749
+ }
750
+ printf ("%s\n" , c_reset );
751
+ }
752
+
753
+ if (!show_file_header )
754
+ return ;
755
+
756
+ if (added )
757
+ dump_quoted_path ("--- " , "" , "/dev/null" ,
758
+ c_meta , c_reset );
759
+ else
760
+ dump_quoted_path ("--- " , a_prefix , elem -> path ,
761
+ c_meta , c_reset );
762
+ if (deleted )
763
+ dump_quoted_path ("+++ " , "" , "/dev/null" ,
764
+ c_meta , c_reset );
765
+ else
766
+ dump_quoted_path ("+++ " , b_prefix , elem -> path ,
767
+ c_meta , c_reset );
768
+ }
769
+
684
770
static void show_patch_diff (struct combine_diff_path * elem , int num_parent ,
685
771
int dense , struct rev_info * rev )
686
772
{
@@ -692,17 +778,22 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
692
778
int mode_differs = 0 ;
693
779
int i , show_hunks ;
694
780
int working_tree_file = is_null_sha1 (elem -> sha1 );
695
- int abbrev = DIFF_OPT_TST (opt , FULL_INDEX ) ? 40 : DEFAULT_ABBREV ;
696
- const char * a_prefix , * b_prefix ;
697
781
mmfile_t result_file ;
782
+ struct userdiff_driver * userdiff ;
783
+ struct userdiff_driver * textconv = NULL ;
784
+ int is_binary ;
698
785
699
786
context = opt -> context ;
700
- a_prefix = opt -> a_prefix ? opt -> a_prefix : "a/" ;
701
- b_prefix = opt -> b_prefix ? opt -> b_prefix : "b/" ;
787
+ userdiff = userdiff_find_by_path (elem -> path );
788
+ if (!userdiff )
789
+ userdiff = userdiff_find_by_name ("default" );
790
+ if (DIFF_OPT_TST (opt , ALLOW_TEXTCONV ))
791
+ textconv = userdiff_get_textconv (userdiff );
702
792
703
793
/* Read the result of merge first */
704
794
if (!working_tree_file )
705
- result = grab_blob (elem -> sha1 , elem -> mode , & result_size );
795
+ result = grab_blob (elem -> sha1 , elem -> mode , & result_size ,
796
+ textconv , elem -> path );
706
797
else {
707
798
/* Used by diff-tree to read from the working tree */
708
799
struct stat st ;
@@ -725,9 +816,16 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
725
816
} else if (S_ISDIR (st .st_mode )) {
726
817
unsigned char sha1 [20 ];
727
818
if (resolve_gitlink_ref (elem -> path , "HEAD" , sha1 ) < 0 )
728
- result = grab_blob (elem -> sha1 , elem -> mode , & result_size );
819
+ result = grab_blob (elem -> sha1 , elem -> mode ,
820
+ & result_size , NULL , NULL );
729
821
else
730
- result = grab_blob (sha1 , elem -> mode , & result_size );
822
+ result = grab_blob (sha1 , elem -> mode ,
823
+ & result_size , NULL , NULL );
824
+ } else if (textconv ) {
825
+ struct diff_filespec * df = alloc_filespec (elem -> path );
826
+ fill_filespec (df , null_sha1 , st .st_mode );
827
+ result_size = fill_textconv (textconv , df , & result );
828
+ free_filespec (df );
731
829
} else if (0 <= (fd = open (elem -> path , O_RDONLY ))) {
732
830
size_t len = xsize_t (st .st_size );
733
831
ssize_t done ;
@@ -777,6 +875,38 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
777
875
close (fd );
778
876
}
779
877
878
+ for (i = 0 ; i < num_parent ; i ++ ) {
879
+ if (elem -> parent [i ].mode != elem -> mode ) {
880
+ mode_differs = 1 ;
881
+ break ;
882
+ }
883
+ }
884
+
885
+ if (textconv )
886
+ is_binary = 0 ;
887
+ else if (userdiff -> binary != -1 )
888
+ is_binary = userdiff -> binary ;
889
+ else {
890
+ is_binary = buffer_is_binary (result , result_size );
891
+ for (i = 0 ; !is_binary && i < num_parent ; i ++ ) {
892
+ char * buf ;
893
+ unsigned long size ;
894
+ buf = grab_blob (elem -> parent [i ].sha1 ,
895
+ elem -> parent [i ].mode ,
896
+ & size , NULL , NULL );
897
+ if (buffer_is_binary (buf , size ))
898
+ is_binary = 1 ;
899
+ free (buf );
900
+ }
901
+ }
902
+ if (is_binary ) {
903
+ show_combined_header (elem , num_parent , dense , rev ,
904
+ mode_differs , 0 );
905
+ printf ("Binary files differ\n" );
906
+ free (result );
907
+ return ;
908
+ }
909
+
780
910
for (cnt = 0 , cp = result ; cp < result + result_size ; cp ++ ) {
781
911
if (* cp == '\n' )
782
912
cnt ++ ;
@@ -824,71 +954,15 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
824
954
combine_diff (elem -> parent [i ].sha1 ,
825
955
elem -> parent [i ].mode ,
826
956
& result_file , sline ,
827
- cnt , i , num_parent , result_deleted );
828
- if (elem -> parent [i ].mode != elem -> mode )
829
- mode_differs = 1 ;
957
+ cnt , i , num_parent , result_deleted ,
958
+ textconv , elem -> path );
830
959
}
831
960
832
961
show_hunks = make_hunks (sline , cnt , num_parent , dense );
833
962
834
963
if (show_hunks || mode_differs || working_tree_file ) {
835
- const char * abb ;
836
- int use_color = DIFF_OPT_TST (opt , COLOR_DIFF );
837
- const char * c_meta = diff_get_color (use_color , DIFF_METAINFO );
838
- const char * c_reset = diff_get_color (use_color , DIFF_RESET );
839
- int added = 0 ;
840
- int deleted = 0 ;
841
-
842
- if (rev -> loginfo && !rev -> no_commit_id )
843
- show_log (rev );
844
- dump_quoted_path (dense ? "diff --cc " : "diff --combined " ,
845
- "" , elem -> path , c_meta , c_reset );
846
- printf ("%sindex " , c_meta );
847
- for (i = 0 ; i < num_parent ; i ++ ) {
848
- abb = find_unique_abbrev (elem -> parent [i ].sha1 ,
849
- abbrev );
850
- printf ("%s%s" , i ? "," : "" , abb );
851
- }
852
- abb = find_unique_abbrev (elem -> sha1 , abbrev );
853
- printf ("..%s%s\n" , abb , c_reset );
854
-
855
- if (mode_differs ) {
856
- deleted = !elem -> mode ;
857
-
858
- /* We say it was added if nobody had it */
859
- added = !deleted ;
860
- for (i = 0 ; added && i < num_parent ; i ++ )
861
- if (elem -> parent [i ].status !=
862
- DIFF_STATUS_ADDED )
863
- added = 0 ;
864
- if (added )
865
- printf ("%snew file mode %06o" ,
866
- c_meta , elem -> mode );
867
- else {
868
- if (deleted )
869
- printf ("%sdeleted file " , c_meta );
870
- printf ("mode " );
871
- for (i = 0 ; i < num_parent ; i ++ ) {
872
- printf ("%s%06o" , i ? "," : "" ,
873
- elem -> parent [i ].mode );
874
- }
875
- if (elem -> mode )
876
- printf ("..%06o" , elem -> mode );
877
- }
878
- printf ("%s\n" , c_reset );
879
- }
880
- if (added )
881
- dump_quoted_path ("--- " , "" , "/dev/null" ,
882
- c_meta , c_reset );
883
- else
884
- dump_quoted_path ("--- " , a_prefix , elem -> path ,
885
- c_meta , c_reset );
886
- if (deleted )
887
- dump_quoted_path ("+++ " , "" , "/dev/null" ,
888
- c_meta , c_reset );
889
- else
890
- dump_quoted_path ("+++ " , b_prefix , elem -> path ,
891
- c_meta , c_reset );
964
+ show_combined_header (elem , num_parent , dense , rev ,
965
+ mode_differs , 1 );
892
966
dump_sline (sline , cnt , num_parent ,
893
967
DIFF_OPT_TST (opt , COLOR_DIFF ), result_deleted );
894
968
}
0 commit comments