1
+ #define NO_THE_INDEX_COMPATIBILITY_MACROS
1
2
#include "cache.h"
2
3
#include "attr.h"
3
4
@@ -318,6 +319,9 @@ static struct attr_stack *read_attr_from_array(const char **list)
318
319
return res ;
319
320
}
320
321
322
+ static enum git_attr_direction direction ;
323
+ static struct index_state * use_index ;
324
+
321
325
static struct attr_stack * read_attr_from_file (const char * path , int macro_ok )
322
326
{
323
327
FILE * fp = fopen (path , "r" );
@@ -340,53 +344,44 @@ static void *read_index_data(const char *path)
340
344
unsigned long sz ;
341
345
enum object_type type ;
342
346
void * data ;
347
+ struct index_state * istate = use_index ? use_index : & the_index ;
343
348
344
349
len = strlen (path );
345
- pos = cache_name_pos ( path , len );
350
+ pos = index_name_pos ( istate , path , len );
346
351
if (pos < 0 ) {
347
352
/*
348
353
* We might be in the middle of a merge, in which
349
354
* case we would read stage #2 (ours).
350
355
*/
351
356
int i ;
352
357
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 ));
355
360
i ++ )
356
- if (ce_stage (active_cache [i ]) == 2 )
361
+ if (ce_stage (istate -> cache [i ]) == 2 )
357
362
pos = i ;
358
363
}
359
364
if (pos < 0 )
360
365
return NULL ;
361
- data = read_sha1_file (active_cache [pos ]-> sha1 , & type , & sz );
366
+ data = read_sha1_file (istate -> cache [pos ]-> sha1 , & type , & sz );
362
367
if (!data || type != OBJ_BLOB ) {
363
368
free (data );
364
369
return NULL ;
365
370
}
366
371
return data ;
367
372
}
368
373
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 )
370
375
{
371
376
struct attr_stack * res ;
372
377
char * buf , * sp ;
373
378
int lineno = 0 ;
374
379
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
- */
386
380
buf = read_index_data (path );
387
381
if (!buf )
388
- return res ;
382
+ return NULL ;
389
383
384
+ res = xcalloc (1 , sizeof (* res ));
390
385
for (sp = buf ; * sp ; ) {
391
386
char * ep ;
392
387
int more ;
@@ -401,6 +396,30 @@ static struct attr_stack *read_attr(const char *path, int macro_ok)
401
396
return res ;
402
397
}
403
398
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
+
404
423
#if DEBUG_ATTR
405
424
static void debug_info (const char * what , struct attr_stack * elem )
406
425
{
@@ -428,6 +447,15 @@ static void debug_set(const char *what, const char *match, struct git_attr *attr
428
447
#define debug_set (a ,b ,c ,d ) do { ; } while (0)
429
448
#endif
430
449
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
+
431
459
static void bootstrap_attr_stack (void )
432
460
{
433
461
if (!attr_stack ) {
@@ -642,3 +670,12 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
642
670
643
671
return 0 ;
644
672
}
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