@@ -376,7 +376,7 @@ static unsigned long diff_filespec_size(struct diff_filespec *one)
376376{
377377 if (!DIFF_FILE_VALID (one ))
378378 return 0 ;
379- diff_populate_filespec (one , 1 );
379+ diff_populate_filespec (one , CHECK_SIZE_ONLY );
380380 return one -> size ;
381381}
382382
@@ -1910,11 +1910,11 @@ static void show_dirstat(struct diff_options *options)
19101910 diff_free_filespec_data (p -> one );
19111911 diff_free_filespec_data (p -> two );
19121912 } else if (DIFF_FILE_VALID (p -> one )) {
1913- diff_populate_filespec (p -> one , 1 );
1913+ diff_populate_filespec (p -> one , CHECK_SIZE_ONLY );
19141914 copied = added = 0 ;
19151915 diff_free_filespec_data (p -> one );
19161916 } else if (DIFF_FILE_VALID (p -> two )) {
1917- diff_populate_filespec (p -> two , 1 );
1917+ diff_populate_filespec (p -> two , CHECK_SIZE_ONLY );
19181918 copied = 0 ;
19191919 added = p -> two -> size ;
19201920 diff_free_filespec_data (p -> two );
@@ -2188,8 +2188,8 @@ int diff_filespec_is_binary(struct diff_filespec *one)
21882188 one -> is_binary = one -> driver -> binary ;
21892189 else {
21902190 if (!one -> data && DIFF_FILE_VALID (one ))
2191- diff_populate_filespec (one , 0 );
2192- if (one -> data )
2191+ diff_populate_filespec (one , CHECK_BINARY );
2192+ if (one -> is_binary == -1 && one -> data )
21932193 one -> is_binary = buffer_is_binary (one -> data ,
21942194 one -> size );
21952195 if (one -> is_binary == -1 )
@@ -2324,6 +2324,19 @@ static void builtin_diff(const char *name_a,
23242324 } else if (!DIFF_OPT_TST (o , TEXT ) &&
23252325 ( (!textconv_one && diff_filespec_is_binary (one )) ||
23262326 (!textconv_two && diff_filespec_is_binary (two )) )) {
2327+ if (!one -> data && !two -> data &&
2328+ S_ISREG (one -> mode ) && S_ISREG (two -> mode ) &&
2329+ !DIFF_OPT_TST (o , BINARY )) {
2330+ if (!hashcmp (one -> sha1 , two -> sha1 )) {
2331+ if (must_show_header )
2332+ fprintf (o -> file , "%s" , header .buf );
2333+ goto free_ab_and_return ;
2334+ }
2335+ fprintf (o -> file , "%s" , header .buf );
2336+ fprintf (o -> file , "%sBinary files %s and %s differ\n" ,
2337+ line_prefix , lbl [0 ], lbl [1 ]);
2338+ goto free_ab_and_return ;
2339+ }
23272340 if (fill_mmfile (& mf1 , one ) < 0 || fill_mmfile (& mf2 , two ) < 0 )
23282341 die ("unable to read files to diff" );
23292342 /* Quite common confusing case */
@@ -2668,8 +2681,9 @@ static int diff_populate_gitlink(struct diff_filespec *s, int size_only)
26682681 * grab the data for the blob (or file) for our own in-core comparison.
26692682 * diff_filespec has data and size fields for this purpose.
26702683 */
2671- int diff_populate_filespec (struct diff_filespec * s , int size_only )
2684+ int diff_populate_filespec (struct diff_filespec * s , unsigned int flags )
26722685{
2686+ int size_only = flags & CHECK_SIZE_ONLY ;
26732687 int err = 0 ;
26742688 /*
26752689 * demote FAIL to WARN to allow inspecting the situation
@@ -2724,6 +2738,11 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
27242738 }
27252739 if (size_only )
27262740 return 0 ;
2741+ if ((flags & CHECK_BINARY ) &&
2742+ s -> size > big_file_threshold && s -> is_binary == -1 ) {
2743+ s -> is_binary = 1 ;
2744+ return 0 ;
2745+ }
27272746 fd = open (s -> path , O_RDONLY );
27282747 if (fd < 0 )
27292748 goto err_empty ;
@@ -2745,16 +2764,21 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
27452764 }
27462765 else {
27472766 enum object_type type ;
2748- if (size_only ) {
2767+ if (size_only || ( flags & CHECK_BINARY ) ) {
27492768 type = sha1_object_info (s -> sha1 , & s -> size );
27502769 if (type < 0 )
27512770 die ("unable to read %s" , sha1_to_hex (s -> sha1 ));
2752- } else {
2753- s -> data = read_sha1_file (s -> sha1 , & type , & s -> size );
2754- if (!s -> data )
2755- die ("unable to read %s" , sha1_to_hex (s -> sha1 ));
2756- s -> should_free = 1 ;
2771+ if (size_only )
2772+ return 0 ;
2773+ if (s -> size > big_file_threshold && s -> is_binary == -1 ) {
2774+ s -> is_binary = 1 ;
2775+ return 0 ;
2776+ }
27572777 }
2778+ s -> data = read_sha1_file (s -> sha1 , & type , & s -> size );
2779+ if (!s -> data )
2780+ die ("unable to read %s" , sha1_to_hex (s -> sha1 ));
2781+ s -> should_free = 1 ;
27582782 }
27592783 return 0 ;
27602784}
@@ -4688,8 +4712,8 @@ static int diff_filespec_check_stat_unmatch(struct diff_filepair *p)
46884712 !DIFF_FILE_VALID (p -> two ) ||
46894713 (p -> one -> sha1_valid && p -> two -> sha1_valid ) ||
46904714 (p -> one -> mode != p -> two -> mode ) ||
4691- diff_populate_filespec (p -> one , 1 ) ||
4692- diff_populate_filespec (p -> two , 1 ) ||
4715+ diff_populate_filespec (p -> one , CHECK_SIZE_ONLY ) ||
4716+ diff_populate_filespec (p -> two , CHECK_SIZE_ONLY ) ||
46934717 (p -> one -> size != p -> two -> size ) ||
46944718 !diff_filespec_is_identical (p -> one , p -> two )) /* (2) */
46954719 p -> skip_stat_unmatch_result = 1 ;
0 commit comments