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 ;
@@ -692,7 +700,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
692
700
693
701
/* Read the result of merge first */
694
702
if (!working_tree_file )
695
- result = grab_blob (elem -> sha1 , & result_size );
703
+ result = grab_blob (elem -> sha1 , elem -> mode , & result_size );
696
704
else {
697
705
/* Used by diff-tree to read from the working tree */
698
706
struct stat st ;
@@ -712,6 +720,12 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
712
720
result_size = buf .len ;
713
721
result = strbuf_detach (& buf , NULL );
714
722
elem -> mode = canon_mode (st .st_mode );
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 );
715
729
} else if (0 <= (fd = open (elem -> path , O_RDONLY ))) {
716
730
size_t len = xsize_t (st .st_size );
717
731
ssize_t done ;
@@ -804,7 +818,9 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
804
818
}
805
819
}
806
820
if (i <= j )
807
- combine_diff (elem -> parent [i ].sha1 , & result_file , sline ,
821
+ combine_diff (elem -> parent [i ].sha1 ,
822
+ elem -> parent [i ].mode ,
823
+ & result_file , sline ,
808
824
cnt , i , num_parent );
809
825
if (elem -> parent [i ].mode != elem -> mode )
810
826
mode_differs = 1 ;
0 commit comments