@@ -109,6 +109,8 @@ int git_attr_file__load(
109109 bool allow_macros )
110110{
111111 int error = 0 ;
112+ git_tree * tree = NULL ;
113+ git_tree_entry * tree_entry = NULL ;
112114 git_blob * blob = NULL ;
113115 git_buf content = GIT_BUF_INIT ;
114116 const char * content_str ;
@@ -117,6 +119,8 @@ int git_attr_file__load(
117119 bool nonexistent = false;
118120 int bom_offset ;
119121 git_bom_t bom ;
122+ git_oid id ;
123+ git_off_t blobsize ;
120124
121125 * out = NULL ;
122126
@@ -125,9 +129,6 @@ int git_attr_file__load(
125129 /* in-memory attribute file doesn't need data */
126130 break ;
127131 case GIT_ATTR_FILE__FROM_INDEX : {
128- git_oid id ;
129- git_off_t blobsize ;
130-
131132 if ((error = attr_file_oid_from_index (& id , repo , entry -> path )) < 0 ||
132133 (error = git_blob_lookup (& blob , repo , & id )) < 0 )
133134 return error ;
@@ -157,6 +158,25 @@ int git_attr_file__load(
157158
158159 break ;
159160 }
161+ case GIT_ATTR_FILE__FROM_HEAD : {
162+ if ((error = git_repository_head_tree (& tree , repo )) < 0 ||
163+ (error = git_tree_entry_bypath (& tree_entry , tree , entry -> path )) < 0 ||
164+ (error = git_blob_lookup (& blob , repo , git_tree_entry_id (tree_entry ))) < 0 )
165+ goto cleanup ;
166+
167+ /*
168+ * Do not assume that data straight from the ODB is NULL-terminated;
169+ * copy the contents of a file to a buffer to work on.
170+ */
171+ blobsize = git_blob_rawsize (blob );
172+
173+ GIT_ERROR_CHECK_BLOBSIZE (blobsize );
174+ if ((error = git_buf_put (& content ,
175+ git_blob_rawcontent (blob ), (size_t )blobsize )) < 0 )
176+ goto cleanup ;
177+
178+ break ;
179+ }
160180 default :
161181 git_error_set (GIT_ERROR_INVALID , "unknown file source %d" , source );
162182 return -1 ;
@@ -188,6 +208,8 @@ int git_attr_file__load(
188208 file -> nonexistent = 1 ;
189209 else if (source == GIT_ATTR_FILE__FROM_INDEX )
190210 git_oid_cpy (& file -> cache_data .oid , git_blob_id (blob ));
211+ else if (source == GIT_ATTR_FILE__FROM_HEAD )
212+ git_oid_cpy (& file -> cache_data .oid , git_tree_id (tree ));
191213 else if (source == GIT_ATTR_FILE__FROM_FILE )
192214 git_futils_filestamp_set_from_stat (& file -> cache_data .stamp , & st );
193215 /* else always cacheable */
@@ -196,6 +218,8 @@ int git_attr_file__load(
196218
197219cleanup :
198220 git_blob_free (blob );
221+ git_tree_entry_free (tree_entry );
222+ git_tree_free (tree );
199223 git_buf_dispose (& content );
200224
201225 return error ;
@@ -236,6 +260,19 @@ int git_attr_file__out_of_date(
236260 return (git_oid__cmp (& file -> cache_data .oid , & id ) != 0 );
237261 }
238262
263+ case GIT_ATTR_FILE__FROM_HEAD : {
264+ git_tree * tree ;
265+ int error ;
266+
267+ if ((error = git_repository_head_tree (& tree , repo )) < 0 )
268+ return error ;
269+
270+ error = git_oid__cmp (& file -> cache_data .oid , git_tree_id (tree ));
271+
272+ git_tree_free (tree );
273+ return error ;
274+ }
275+
239276 default :
240277 git_error_set (GIT_ERROR_INVALID , "invalid file type %d" , file -> source );
241278 return -1 ;
0 commit comments