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
@@ -195,7 +202,8 @@ static void consume_line(void *state_, char *line, unsigned long len)
195202 }
196203}
197204
198- static void combine_diff (const unsigned char * parent , mmfile_t * result_file ,
205+ static void combine_diff (const unsigned char * parent , unsigned int mode ,
206+ mmfile_t * result_file ,
199207 struct sline * sline , unsigned int cnt , int n ,
200208 int num_parent )
201209{
@@ -211,7 +219,7 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file,
211219 if (!cnt )
212220 return ; /* result deleted */
213221
214- parent_file .ptr = grab_blob (parent , & sz );
222+ parent_file .ptr = grab_blob (parent , mode , & sz );
215223 parent_file .size = sz ;
216224 memset (& xpp , 0 , sizeof (xpp ));
217225 xpp .flags = XDF_NEED_MINIMAL ;
@@ -693,7 +701,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
693701
694702 /* Read the result of merge first */
695703 if (!working_tree_file )
696- result = grab_blob (elem -> sha1 , & result_size );
704+ result = grab_blob (elem -> sha1 , elem -> mode , & result_size );
697705 else {
698706 /* Used by diff-tree to read from the working tree */
699707 struct stat st ;
@@ -713,9 +721,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
713721 result_size = buf .len ;
714722 result = strbuf_detach (& buf , NULL );
715723 elem -> mode = canon_mode (st .st_mode );
716- }
717- else if (0 <= (fd = open (elem -> path , O_RDONLY )) &&
718- !fstat (fd , & st )) {
724+ } else if (S_ISDIR (st .st_mode )) {
725+ unsigned char sha1 [20 ];
726+ if (resolve_gitlink_ref (elem -> path , "HEAD" , sha1 ) < 0 )
727+ result = grab_blob (elem -> sha1 , elem -> mode , & result_size );
728+ else
729+ result = grab_blob (sha1 , elem -> mode , & result_size );
730+ } else if (0 <= (fd = open (elem -> path , O_RDONLY ))) {
719731 size_t len = xsize_t (st .st_size );
720732 ssize_t done ;
721733 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