Skip to content

Commit 4e7ce1f

Browse files
committed
config_file: reimplement config_readonly_open generically
The `config_readonly_open` function currently receives as input a diskfile backend and will copy its entries to a new snapshot. This is rather intimate, as we need to assume that the source config backend is in fact a diskfile entry. We can do better than this though by using generic methods to copy contents of the provided backend, e.g. by using a config iterator. This also allows us to decouple the read-only backend from the read-write backend.
1 parent 76182e8 commit 4e7ce1f

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

src/config_file.c

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ typedef struct {
5757
typedef struct {
5858
diskfile_header header;
5959

60-
diskfile_backend *snapshot_from;
60+
git_config_backend *source;
6161
} diskfile_readonly_backend;
6262

6363
typedef struct {
@@ -595,26 +595,39 @@ static void backend_readonly_free(git_config_backend *_backend)
595595
static int config_readonly_open(git_config_backend *cfg, git_config_level_t level, const git_repository *repo)
596596
{
597597
diskfile_readonly_backend *b = GIT_CONTAINER_OF(cfg, diskfile_readonly_backend, header.parent);
598-
diskfile_backend *src = b->snapshot_from;
599-
diskfile_header *src_header = &src->header;
600-
git_config_entries *entries;
598+
git_config_entries *entries = NULL;
599+
git_config_iterator *it = NULL;
600+
git_config_entry *entry;
601601
int error;
602602

603-
if (!src_header->parent.readonly && (error = config_refresh(&src_header->parent)) < 0)
604-
return error;
605-
606603
/* We're just copying data, don't care about the level or repo*/
607604
GIT_UNUSED(level);
608605
GIT_UNUSED(repo);
609606

610-
if ((entries = diskfile_entries_take(src_header)) == NULL)
611-
return -1;
607+
if ((error = git_config_entries_new(&entries)) < 0 ||
608+
(error = b->source->iterator(&it, b->source)) < 0)
609+
goto out;
610+
611+
while ((error = git_config_next(&entry, it)) == 0)
612+
if ((error = git_config_entries_dup_entry(entries, entry)) < 0)
613+
goto out;
614+
615+
if (error < 0) {
616+
if (error != GIT_ITEROVER)
617+
goto out;
618+
error = 0;
619+
}
620+
612621
b->header.entries = entries;
613622

614-
return 0;
623+
out:
624+
git_config_iterator_free(it);
625+
if (error)
626+
git_config_entries_free(entries);
627+
return error;
615628
}
616629

617-
static int config_snapshot(git_config_backend **out, git_config_backend *in)
630+
static int config_snapshot(git_config_backend **out, git_config_backend *source)
618631
{
619632
diskfile_readonly_backend *backend;
620633

@@ -624,7 +637,7 @@ static int config_snapshot(git_config_backend **out, git_config_backend *in)
624637
backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
625638
git_mutex_init(&backend->header.values_mutex);
626639

627-
backend->snapshot_from = GIT_CONTAINER_OF(in, diskfile_backend, header.parent);
640+
backend->source = source;
628641

629642
backend->header.parent.readonly = 1;
630643
backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;

0 commit comments

Comments
 (0)