summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/git2/config.h1
-rw-r--r--src/config.c11
-rw-r--r--src/config_file.c27
3 files changed, 38 insertions, 1 deletions
diff --git a/include/git2/config.h b/include/git2/config.h
index 36647591a..f78fe40a0 100644
--- a/include/git2/config.h
+++ b/include/git2/config.h
@@ -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 *);
};
diff --git a/src/config.c b/src/config.c
index 2e341d256..ed7c947ed 100644
--- a/src/config.c
+++ b/src/config.c
@@ -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);
}
/**************
diff --git a/src/config_file.c b/src/config_file.c
index 7a5865210..207bd2bdd 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -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;