66#include "quote.h"
77#include "xdiff-interface.h"
88#include "log-tree.h"
9+ #include "refs.h"
910
1011static struct combine_diff_path * intersect_paths (struct combine_diff_path * curr , int n , int num_parent )
1112{
@@ -90,18 +91,24 @@ struct sline {
9091 unsigned long * p_lno ;
9192};
9293
93- static char * grab_blob (const unsigned char * sha1 , unsigned long * size )
94+ static char * grab_blob (const unsigned char * sha1 , unsigned int mode , unsigned long * size )
9495{
9596 char * blob ;
9697 enum object_type type ;
97- if (is_null_sha1 (sha1 )) {
98+
99+ if (S_ISGITLINK (mode )) {
100+ blob = xmalloc (100 );
101+ * size = snprintf (blob , 100 ,
102+ "Subproject commit %s\n" , sha1_to_hex (sha1 ));
103+ } else if (is_null_sha1 (sha1 )) {
98104 /* deleted blob */
99105 * size = 0 ;
100106 return xcalloc (1 , 1 );
107+ } else {
108+ blob = read_sha1_file (sha1 , & type , size );
109+ if (type != OBJ_BLOB )
110+ die ("object '%s' is not a blob!" , sha1_to_hex (sha1 ));
101111 }
102- blob = read_sha1_file (sha1 , & type , size );
103- if (type != OBJ_BLOB )
104- die ("object '%s' is not a blob!" , sha1_to_hex (sha1 ));
105112 return blob ;
106113}
107114
@@ -197,7 +204,8 @@ static void consume_line(void *state_, char *line, unsigned long len)
197204 }
198205}
199206
200- static void combine_diff (const unsigned char * parent , mmfile_t * result_file ,
207+ static void combine_diff (const unsigned char * parent , unsigned int mode ,
208+ mmfile_t * result_file ,
201209 struct sline * sline , unsigned int cnt , int n ,
202210 int num_parent )
203211{
@@ -213,7 +221,7 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file,
213221 if (!cnt )
214222 return ; /* result deleted */
215223
216- parent_file .ptr = grab_blob (parent , & sz );
224+ parent_file .ptr = grab_blob (parent , mode , & sz );
217225 parent_file .size = sz ;
218226 xpp .flags = XDF_NEED_MINIMAL ;
219227 memset (& xecfg , 0 , sizeof (xecfg ));
@@ -692,7 +700,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
692700 context = opt -> context ;
693701 /* Read the result of merge first */
694702 if (!working_tree_file )
695- result = grab_blob (elem -> sha1 , & result_size );
703+ result = grab_blob (elem -> sha1 , elem -> mode , & result_size );
696704 else {
697705 /* Used by diff-tree to read from the working tree */
698706 struct stat st ;
@@ -712,9 +720,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
712720 }
713721 result [len ] = 0 ;
714722 elem -> mode = canon_mode (st .st_mode );
715- }
716- else if (0 <= (fd = open (elem -> path , O_RDONLY )) &&
717- !fstat (fd , & st )) {
723+ } else if (S_ISDIR (st .st_mode )) {
724+ unsigned char sha1 [20 ];
725+ if (resolve_gitlink_ref (elem -> path , "HEAD" , sha1 ) < 0 )
726+ result = grab_blob (elem -> sha1 , elem -> mode , & result_size );
727+ else
728+ result = grab_blob (sha1 , elem -> mode , & result_size );
729+ } else if (0 <= (fd = open (elem -> path , O_RDONLY ))) {
718730 size_t len = xsize_t (st .st_size );
719731 ssize_t done ;
720732 int is_file , i ;
@@ -807,7 +819,9 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
807819 }
808820 }
809821 if (i <= j )
810- combine_diff (elem -> parent [i ].sha1 , & result_file , sline ,
822+ combine_diff (elem -> parent [i ].sha1 ,
823+ elem -> parent [i ].mode ,
824+ & result_file , sline ,
811825 cnt , i , num_parent );
812826 if (elem -> parent [i ].mode != elem -> mode )
813827 mode_differs = 1 ;
0 commit comments