1+ #define NO_THE_INDEX_COMPATIBILITY_MACROS
12#include "cache.h"
23#include "attr.h"
34
@@ -318,6 +319,9 @@ static struct attr_stack *read_attr_from_array(const char **list)
318319 return res ;
319320}
320321
322+ static enum git_attr_direction direction ;
323+ static struct index_state * use_index ;
324+
321325static struct attr_stack * read_attr_from_file (const char * path , int macro_ok )
322326{
323327 FILE * fp = fopen (path , "r" );
@@ -340,53 +344,44 @@ static void *read_index_data(const char *path)
340344 unsigned long sz ;
341345 enum object_type type ;
342346 void * data ;
347+ struct index_state * istate = use_index ? use_index : & the_index ;
343348
344349 len = strlen (path );
345- pos = cache_name_pos ( path , len );
350+ pos = index_name_pos ( istate , path , len );
346351 if (pos < 0 ) {
347352 /*
348353 * We might be in the middle of a merge, in which
349354 * case we would read stage #2 (ours).
350355 */
351356 int i ;
352357 for (i = - pos - 1 ;
353- (pos < 0 && i < active_nr &&
354- !strcmp (active_cache [i ]-> name , path ));
358+ (pos < 0 && i < istate -> cache_nr &&
359+ !strcmp (istate -> cache [i ]-> name , path ));
355360 i ++ )
356- if (ce_stage (active_cache [i ]) == 2 )
361+ if (ce_stage (istate -> cache [i ]) == 2 )
357362 pos = i ;
358363 }
359364 if (pos < 0 )
360365 return NULL ;
361- data = read_sha1_file (active_cache [pos ]-> sha1 , & type , & sz );
366+ data = read_sha1_file (istate -> cache [pos ]-> sha1 , & type , & sz );
362367 if (!data || type != OBJ_BLOB ) {
363368 free (data );
364369 return NULL ;
365370 }
366371 return data ;
367372}
368373
369- static struct attr_stack * read_attr (const char * path , int macro_ok )
374+ static struct attr_stack * read_attr_from_index (const char * path , int macro_ok )
370375{
371376 struct attr_stack * res ;
372377 char * buf , * sp ;
373378 int lineno = 0 ;
374379
375- res = read_attr_from_file (path , macro_ok );
376- if (res )
377- return res ;
378-
379- res = xcalloc (1 , sizeof (* res ));
380-
381- /*
382- * There is no checked out .gitattributes file there, but
383- * we might have it in the index. We allow operation in a
384- * sparsely checked out work tree, so read from it.
385- */
386380 buf = read_index_data (path );
387381 if (!buf )
388- return res ;
382+ return NULL ;
389383
384+ res = xcalloc (1 , sizeof (* res ));
390385 for (sp = buf ; * sp ; ) {
391386 char * ep ;
392387 int more ;
@@ -401,6 +396,30 @@ static struct attr_stack *read_attr(const char *path, int macro_ok)
401396 return res ;
402397}
403398
399+ static struct attr_stack * read_attr (const char * path , int macro_ok )
400+ {
401+ struct attr_stack * res ;
402+
403+ if (direction == GIT_ATTR_CHECKOUT ) {
404+ res = read_attr_from_index (path , macro_ok );
405+ if (!res )
406+ res = read_attr_from_file (path , macro_ok );
407+ }
408+ else {
409+ res = read_attr_from_file (path , macro_ok );
410+ if (!res )
411+ /*
412+ * There is no checked out .gitattributes file there, but
413+ * we might have it in the index. We allow operation in a
414+ * sparsely checked out work tree, so read from it.
415+ */
416+ res = read_attr_from_index (path , macro_ok );
417+ }
418+ if (!res )
419+ res = xcalloc (1 , sizeof (* res ));
420+ return res ;
421+ }
422+
404423#if DEBUG_ATTR
405424static void debug_info (const char * what , struct attr_stack * elem )
406425{
@@ -428,6 +447,15 @@ static void debug_set(const char *what, const char *match, struct git_attr *attr
428447#define debug_set (a ,b ,c ,d ) do { ; } while (0)
429448#endif
430449
450+ static void drop_attr_stack (void )
451+ {
452+ while (attr_stack ) {
453+ struct attr_stack * elem = attr_stack ;
454+ attr_stack = elem -> prev ;
455+ free_attr_elem (elem );
456+ }
457+ }
458+
431459static void bootstrap_attr_stack (void )
432460{
433461 if (!attr_stack ) {
@@ -642,3 +670,12 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
642670
643671 return 0 ;
644672}
673+
674+ void git_attr_set_direction (enum git_attr_direction new , struct index_state * istate )
675+ {
676+ enum git_attr_direction old = direction ;
677+ direction = new ;
678+ if (new != old )
679+ drop_attr_stack ();
680+ use_index = istate ;
681+ }
0 commit comments