6
6
#include "quote.h"
7
7
#include "xdiff-interface.h"
8
8
#include "log-tree.h"
9
+ #include "refs.h"
9
10
10
11
static struct combine_diff_path * intersect_paths (struct combine_diff_path * curr , int n , int num_parent )
11
12
{
@@ -90,18 +91,24 @@ struct sline {
90
91
unsigned long * p_lno ;
91
92
};
92
93
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 )
94
95
{
95
96
char * blob ;
96
97
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 )) {
98
104
/* deleted blob */
99
105
* size = 0 ;
100
106
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 ));
101
111
}
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 ));
105
112
return blob ;
106
113
}
107
114
@@ -195,7 +202,8 @@ static void consume_line(void *state_, char *line, unsigned long len)
195
202
}
196
203
}
197
204
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 ,
199
207
struct sline * sline , unsigned int cnt , int n ,
200
208
int num_parent )
201
209
{
@@ -211,7 +219,7 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file,
211
219
if (!cnt )
212
220
return ; /* result deleted */
213
221
214
- parent_file .ptr = grab_blob (parent , & sz );
222
+ parent_file .ptr = grab_blob (parent , mode , & sz );
215
223
parent_file .size = sz ;
216
224
memset (& xpp , 0 , sizeof (xpp ));
217
225
xpp .flags = XDF_NEED_MINIMAL ;
@@ -693,7 +701,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
693
701
694
702
/* Read the result of merge first */
695
703
if (!working_tree_file )
696
- result = grab_blob (elem -> sha1 , & result_size );
704
+ result = grab_blob (elem -> sha1 , elem -> mode , & result_size );
697
705
else {
698
706
/* Used by diff-tree to read from the working tree */
699
707
struct stat st ;
@@ -713,9 +721,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
713
721
result_size = buf .len ;
714
722
result = strbuf_detach (& buf , NULL );
715
723
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 ))) {
719
731
size_t len = xsize_t (st .st_size );
720
732
ssize_t done ;
721
733
int is_file , i ;
@@ -807,7 +819,9 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
807
819
}
808
820
}
809
821
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 ,
811
825
cnt , i , num_parent );
812
826
if (elem -> parent [i ].mode != elem -> mode )
813
827
mode_differs = 1 ;
0 commit comments