config: really delete variables

Instead of just setting the value to NULL, which gives unwanted
results when asking for that variable after deleting it, delete the
variable from the list and re-write the file.
This commit is contained in:
Carlos Martín Nieto 2011-12-16 02:28:39 +01:00
parent 7b2b4adfb1
commit 80a665aaca
3 changed files with 38 additions and 1 deletions

View File

@ -30,6 +30,7 @@ struct git_config_file {
int (*open)(struct git_config_file *);
int (*get)(struct git_config_file *, const char *key, const char **value);
int (*set)(struct git_config_file *, const char *key, const char *value);
int (*delete)(struct git_config_file *, const char *key);
int (*foreach)(struct git_config_file *, int (*fn)(const char *, const char *, void *), void *data);
void (*free)(struct git_config_file *);
};

View File

@ -162,7 +162,16 @@ int git_config_foreach(git_config *cfg, int (*fn)(const char *, const char *, vo
int git_config_delete(git_config *cfg, const char *name)
{
return git_config_set_string(cfg, name, NULL);
file_internal *internal;
git_config_file *file;
if (cfg->files.length == 0)
return git__throw(GIT_EINVALIDARGS, "Cannot delete variable; no files open in the `git_config` instance");
internal = git_vector_get(&cfg->files, 0);
file = internal->file;
return file->delete(file, name);
}
/**************

View File

@ -404,6 +404,32 @@ static int config_get(git_config_file *cfg, const char *name, const char **out)
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to get config value for %s", name);
}
static int config_delete(git_config_file *cfg, const char *name)
{
cvar_t *iter, *prev;
diskfile_backend *b = (diskfile_backend *)cfg;
CVAR_LIST_FOREACH (&b->var_list, iter) {
/* This is a bit hacky because we use a singly-linked list */
if (cvar_match_name(iter, name)) {
if (CVAR_LIST_HEAD(&b->var_list) == iter)
CVAR_LIST_HEAD(&b->var_list) = CVAR_LIST_NEXT(iter);
else
CVAR_LIST_REMOVE_AFTER(prev);
git__free(iter->value);
iter->value = NULL;
config_write(b, iter);
cvar_free(iter);
return GIT_SUCCESS;
}
/* Store it for the next round */
prev = iter;
}
return git__throw(GIT_ENOTFOUND, "Variable '%s' not found", name);
}
int git_config_file__ondisk(git_config_file **out, const char *path)
{
diskfile_backend *backend;
@ -423,6 +449,7 @@ int git_config_file__ondisk(git_config_file **out, const char *path)
backend->parent.open = config_open;
backend->parent.get = config_get;
backend->parent.set = config_set;
backend->parent.delete = config_delete;
backend->parent.foreach = file_foreach;
backend->parent.free = backend_free;