Skip to content

Commit 1cd863f

Browse files
committed
attr: include the filename in the attr source
The attribute source object is now the type and the path.
1 parent 96dc1ff commit 1cd863f

File tree

6 files changed

+104
-78
lines changed

6 files changed

+104
-78
lines changed

src/attr.c

Lines changed: 67 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -253,28 +253,43 @@ int git_attr_foreach(
253253
return error;
254254
}
255255

256-
static int preload_attr_file(
256+
static int preload_attr_source(
257257
git_repository *repo,
258258
git_attr_session *attr_session,
259-
git_attr_file_source_t source_type,
260-
const char *base,
261-
const char *file,
262-
bool allow_macros)
259+
git_attr_file_source *source)
263260
{
264261
int error;
265262
git_attr_file *preload = NULL;
266263

267-
if (!file)
264+
if (!source)
268265
return 0;
269-
if (!(error = git_attr_cache__get(&preload, repo, attr_session,
270-
source_type, base, file,
271-
git_attr_file__parse_buffer,
272-
allow_macros)))
266+
267+
error = git_attr_cache__get(&preload, repo, attr_session, source,
268+
git_attr_file__parse_buffer, true);
269+
270+
if (!error)
273271
git_attr_file__free(preload);
274272

275273
return error;
276274
}
277275

276+
GIT_INLINE(int) preload_attr_file(
277+
git_repository *repo,
278+
git_attr_session *attr_session,
279+
const char *base,
280+
const char *filename)
281+
{
282+
git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_FILE };
283+
284+
if (!filename)
285+
return 0;
286+
287+
source.base = base;
288+
source.filename = filename;
289+
290+
return preload_attr_source(repo, attr_session, &source);
291+
}
292+
278293
static int system_attr_file(
279294
git_buf *out,
280295
git_attr_session *attr_session)
@@ -318,7 +333,9 @@ static int attr_setup(
318333
git_attr_session *attr_session,
319334
uint32_t flags)
320335
{
321-
git_buf path = GIT_BUF_INIT;
336+
git_buf system = GIT_BUF_INIT, info = GIT_BUF_INIT;
337+
git_attr_file_source index_source = { GIT_ATTR_FILE_SOURCE_INDEX, NULL, GIT_ATTR_FILE };
338+
git_attr_file_source head_source = { GIT_ATTR_FILE_SOURCE_COMMIT, NULL, GIT_ATTR_FILE };
322339
git_index *idx = NULL;
323340
const char *workdir;
324341
int error = 0;
@@ -334,45 +351,44 @@ static int attr_setup(
334351
* definitions will be available for later file parsing.
335352
*/
336353

337-
if ((error = system_attr_file(&path, attr_session)) < 0 ||
338-
(error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE,
339-
NULL, path.ptr, true)) < 0) {
354+
if ((error = system_attr_file(&system, attr_session)) < 0 ||
355+
(error = preload_attr_file(repo, attr_session, NULL, system.ptr)) < 0) {
340356
if (error != GIT_ENOTFOUND)
341357
goto out;
358+
359+
error = 0;
342360
}
343361

344-
if ((error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE,
345-
NULL, git_repository_attr_cache(repo)->cfg_attr_file, true)) < 0)
362+
if ((error = preload_attr_file(repo, attr_session, NULL,
363+
git_repository_attr_cache(repo)->cfg_attr_file)) < 0)
346364
goto out;
347365

348-
git_buf_clear(&path); /* git_repository_item_path expects an empty buffer, because it uses git_buf_set */
349-
if ((error = git_repository_item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 ||
350-
(error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE,
351-
path.ptr, GIT_ATTR_FILE_INREPO, true)) < 0) {
366+
if ((error = git_repository_item_path(&info, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 ||
367+
(error = preload_attr_file(repo, attr_session, info.ptr, GIT_ATTR_FILE_INREPO)) < 0) {
352368
if (error != GIT_ENOTFOUND)
353369
goto out;
370+
371+
error = 0;
354372
}
355373

356374
if ((workdir = git_repository_workdir(repo)) != NULL &&
357-
(error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE,
358-
workdir, GIT_ATTR_FILE, true)) < 0)
375+
(error = preload_attr_file(repo, attr_session, workdir, GIT_ATTR_FILE)) < 0)
359376
goto out;
360377

361378
if ((error = git_repository_index__weakptr(&idx, repo)) < 0 ||
362-
(error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_INDEX,
363-
NULL, GIT_ATTR_FILE, true)) < 0)
379+
(error = preload_attr_source(repo, attr_session, &index_source)) < 0)
364380
goto out;
365381

366382
if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0 &&
367-
(error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_HEAD,
368-
NULL, GIT_ATTR_FILE, true)) < 0)
383+
(error = preload_attr_source(repo, attr_session, &head_source)) < 0)
369384
goto out;
370385

371386
if (attr_session)
372387
attr_session->init_setup = 1;
373388

374389
out:
375-
git_buf_dispose(&path);
390+
git_buf_dispose(&system);
391+
git_buf_dispose(&info);
376392

377393
return error;
378394
}
@@ -451,25 +467,23 @@ static int attr_decide_sources(
451467
}
452468

453469
if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0)
454-
srcs[count++] = GIT_ATTR_FILE_SOURCE_HEAD;
470+
srcs[count++] = GIT_ATTR_FILE_SOURCE_COMMIT;
455471

456472
return count;
457473
}
458474

459-
static int push_attr_file(
475+
static int push_attr_source(
460476
git_repository *repo,
461477
git_attr_session *attr_session,
462478
git_vector *list,
463-
git_attr_file_source_t source_type,
464-
const char *base,
465-
const char *filename,
479+
git_attr_file_source *source,
466480
bool allow_macros)
467481
{
468482
int error = 0;
469483
git_attr_file *file = NULL;
470484

471485
error = git_attr_cache__get(&file, repo, attr_session,
472-
source_type, base, filename,
486+
source,
473487
git_attr_file__parse_buffer,
474488
allow_macros);
475489

@@ -484,6 +498,17 @@ static int push_attr_file(
484498
return error;
485499
}
486500

501+
GIT_INLINE(int) push_attr_file(
502+
git_repository *repo,
503+
git_attr_session *attr_session,
504+
git_vector *list,
505+
const char *base,
506+
const char *filename)
507+
{
508+
git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_FILE, base, filename };
509+
return push_attr_source(repo, attr_session, list, &source, true);
510+
}
511+
487512
static int push_one_attr(void *ref, const char *path)
488513
{
489514
attr_walk_up_info *info = (attr_walk_up_info *)ref;
@@ -495,9 +520,12 @@ static int push_one_attr(void *ref, const char *path)
495520
info->flags, info->workdir != NULL, info->index != NULL, src);
496521
allow_macros = info->workdir ? !strcmp(info->workdir, path) : false;
497522

498-
for (i = 0; !error && i < n_src; ++i)
499-
error = push_attr_file(info->repo, info->attr_session, info->files,
500-
src[i], path, GIT_ATTR_FILE, allow_macros);
523+
for (i = 0; !error && i < n_src; ++i) {
524+
git_attr_file_source source = { src[i], path, GIT_ATTR_FILE };
525+
526+
error = push_attr_source(info->repo, info->attr_session, info->files,
527+
&source, allow_macros);
528+
}
501529

502530
return error;
503531
}
@@ -549,8 +577,7 @@ static int collect_attr_files(
549577
*/
550578

551579
if ((error = git_repository_item_path(&attrfile, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 ||
552-
(error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE,
553-
attrfile.ptr, GIT_ATTR_FILE_INREPO, true)) < 0) {
580+
(error = push_attr_file(repo, attr_session, files, attrfile.ptr, GIT_ATTR_FILE_INREPO)) < 0) {
554581
if (error != GIT_ENOTFOUND)
555582
goto cleanup;
556583
}
@@ -572,8 +599,7 @@ static int collect_attr_files(
572599
goto cleanup;
573600

574601
if (git_repository_attr_cache(repo)->cfg_attr_file != NULL) {
575-
error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE,
576-
NULL, git_repository_attr_cache(repo)->cfg_attr_file, true);
602+
error = push_attr_file(repo, attr_session, files, NULL, git_repository_attr_cache(repo)->cfg_attr_file);
577603
if (error < 0)
578604
goto cleanup;
579605
}
@@ -582,8 +608,7 @@ static int collect_attr_files(
582608
error = system_attr_file(&dir, attr_session);
583609

584610
if (!error)
585-
error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE,
586-
NULL, dir.ptr, true);
611+
error = push_attr_file(repo, attr_session, files, NULL, dir.ptr);
587612
else if (error == GIT_ENOTFOUND)
588613
error = 0;
589614
}

src/attr_file.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ int git_attr_file__load(
162162

163163
break;
164164
}
165-
case GIT_ATTR_FILE_SOURCE_HEAD: {
165+
case GIT_ATTR_FILE_SOURCE_COMMIT: {
166166
if ((error = git_repository_head_tree(&tree, repo)) < 0 ||
167167
(error = git_tree_entry_bypath(&tree_entry, tree, entry->path)) < 0 ||
168168
(error = git_blob_lookup(&blob, repo, git_tree_entry_id(tree_entry))) < 0)
@@ -212,7 +212,7 @@ int git_attr_file__load(
212212
file->nonexistent = 1;
213213
else if (source->type == GIT_ATTR_FILE_SOURCE_INDEX)
214214
git_oid_cpy(&file->cache_data.oid, git_blob_id(blob));
215-
else if (source->type == GIT_ATTR_FILE_SOURCE_HEAD)
215+
else if (source->type == GIT_ATTR_FILE_SOURCE_COMMIT)
216216
git_oid_cpy(&file->cache_data.oid, git_tree_id(tree));
217217
else if (source->type == GIT_ATTR_FILE_SOURCE_FILE)
218218
git_futils_filestamp_set_from_stat(&file->cache_data.stamp, &st);
@@ -264,7 +264,7 @@ int git_attr_file__out_of_date(
264264
return (git_oid__cmp(&file->cache_data.oid, &id) != 0);
265265
}
266266

267-
case GIT_ATTR_FILE_SOURCE_HEAD: {
267+
case GIT_ATTR_FILE_SOURCE_COMMIT: {
268268
git_tree *tree;
269269
int error;
270270

src/attr_file.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,21 @@ typedef enum {
4040
GIT_ATTR_FILE_SOURCE_MEMORY = 0,
4141
GIT_ATTR_FILE_SOURCE_FILE = 1,
4242
GIT_ATTR_FILE_SOURCE_INDEX = 2,
43-
GIT_ATTR_FILE_SOURCE_HEAD = 3,
43+
GIT_ATTR_FILE_SOURCE_COMMIT = 3,
4444

4545
GIT_ATTR_FILE_NUM_SOURCES = 4
4646
} git_attr_file_source_t;
4747

4848
typedef struct {
49+
/* The source location for the attribute file. */
4950
git_attr_file_source_t type;
51+
52+
/*
53+
* The filename of the attribute file to read (relative to the
54+
* given base path).
55+
*/
56+
const char *base;
57+
const char *filename;
5058
} git_attr_file_source;
5159

5260
extern const char *git_attr__true;

src/attrcache.c

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -158,41 +158,42 @@ static int attr_cache_lookup(
158158
git_attr_file_entry **out_entry,
159159
git_repository *repo,
160160
git_attr_session *attr_session,
161-
git_attr_file_source_t source_type,
162-
const char *base,
163-
const char *filename)
161+
git_attr_file_source *source)
164162
{
165163
int error = 0;
166164
git_buf path = GIT_BUF_INIT;
167-
const char *wd = git_repository_workdir(repo), *relfile;
165+
const char *wd = git_repository_workdir(repo);
166+
const char *filename;
168167
git_attr_cache *cache = git_repository_attr_cache(repo);
169168
git_attr_file_entry *entry = NULL;
170169
git_attr_file *file = NULL;
171170

172171
/* join base and path as needed */
173-
if (base != NULL && git_path_root(filename) < 0) {
172+
if (source->base != NULL && git_path_root(source->filename) < 0) {
174173
git_buf *p = attr_session ? &attr_session->tmp : &path;
175174

176-
if (git_buf_joinpath(p, base, filename) < 0 ||
175+
if (git_buf_joinpath(p, source->base, source->filename) < 0 ||
177176
git_path_validate_workdir_buf(repo, p) < 0)
178177
return -1;
179178

180179
filename = p->ptr;
180+
} else {
181+
filename = source->filename;
181182
}
182183

183-
relfile = filename;
184-
if (wd && !git__prefixcmp(relfile, wd))
185-
relfile += strlen(wd);
184+
if (wd && !git__prefixcmp(filename, wd))
185+
filename += strlen(wd);
186186

187187
/* check cache for existing entry */
188188
if ((error = attr_cache_lock(cache)) < 0)
189189
goto cleanup;
190190

191-
entry = attr_cache_lookup_entry(cache, relfile);
192-
if (!entry)
193-
error = attr_cache_make_entry(&entry, repo, relfile);
194-
else if (entry->file[source_type] != NULL) {
195-
file = entry->file[source_type];
191+
entry = attr_cache_lookup_entry(cache, filename);
192+
193+
if (!entry) {
194+
error = attr_cache_make_entry(&entry, repo, filename);
195+
} else if (entry->file[source->type] != NULL) {
196+
file = entry->file[source->type];
196197
GIT_REFCOUNT_INC(file);
197198
}
198199

@@ -210,26 +211,22 @@ int git_attr_cache__get(
210211
git_attr_file **out,
211212
git_repository *repo,
212213
git_attr_session *attr_session,
213-
git_attr_file_source_t source_type,
214-
const char *base,
215-
const char *filename,
214+
git_attr_file_source *source,
216215
git_attr_file_parser parser,
217216
bool allow_macros)
218217
{
219218
int error = 0;
220219
git_attr_cache *cache = git_repository_attr_cache(repo);
221220
git_attr_file_entry *entry = NULL;
222221
git_attr_file *file = NULL, *updated = NULL;
223-
git_attr_file_source source = { source_type };
224222

225-
if ((error = attr_cache_lookup(&file, &entry, repo, attr_session,
226-
source_type, base, filename)) < 0)
223+
if ((error = attr_cache_lookup(&file, &entry, repo, attr_session, source)) < 0)
227224
return error;
228225

229226
/* load file if we don't have one or if existing one is out of date */
230227
if (!file || (error = git_attr_file__out_of_date(repo, attr_session, file)) > 0)
231228
error = git_attr_file__load(&updated, repo, attr_session,
232-
entry, &source, parser,
229+
entry, source, parser,
233230
allow_macros);
234231

235232
/* if we loaded the file, insert into and/or update cache */

src/attrcache.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,14 @@ extern int git_attr_cache__get(
3131
git_attr_file **file,
3232
git_repository *repo,
3333
git_attr_session *attr_session,
34-
git_attr_file_source_t source_type,
35-
const char *base,
36-
const char *filename,
34+
git_attr_file_source *source,
3735
git_attr_file_parser parser,
3836
bool allow_macros);
3937

4038
extern bool git_attr_cache__is_cached(
4139
git_repository *repo,
4240
git_attr_file_source_t source_type,
43-
const char *path);
41+
const char *filename);
4442

4543
extern int git_attr_cache__alloc_file_entry(
4644
git_attr_file_entry **out,

0 commit comments

Comments
 (0)