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
@@ -197,7 +204,8 @@ static void consume_line(void *state_, char *line, unsigned long len)
197
204
}
198
205
}
199
206
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 ,
201
209
struct sline * sline , unsigned int cnt , int n ,
202
210
int num_parent )
203
211
{
@@ -213,7 +221,7 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file,
213
221
if (!cnt )
214
222
return ; /* result deleted */
215
223
216
- parent_file .ptr = grab_blob (parent , & sz );
224
+ parent_file .ptr = grab_blob (parent , mode , & sz );
217
225
parent_file .size = sz ;
218
226
xpp .flags = XDF_NEED_MINIMAL ;
219
227
memset (& xecfg , 0 , sizeof (xecfg ));
@@ -692,7 +700,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
692
700
context = opt -> context ;
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,9 +720,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
712
720
}
713
721
result [len ] = 0 ;
714
722
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 ))) {
718
730
size_t len = xsize_t (st .st_size );
719
731
ssize_t done ;
720
732
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