Merge pull request #513 from carlosmn/development Really delete variables
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
diff --git a/include/git2/config.h b/include/git2/config.h
index 3664759..f78fe40 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 2e341d2..ed7c947 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 45b43b7..207bd2b 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -391,15 +391,43 @@ static int config_set(git_config_file *cfg, const char *name, const char *value)
static int config_get(git_config_file *cfg, const char *name, const char **out)
{
cvar_t *var;
+ int error = GIT_SUCCESS;
diskfile_backend *b = (diskfile_backend *)cfg;
var = cvar_list_find(&b->var_list, name);
- if (var == NULL || var->value == NULL)
+ if (var == NULL)
return git__throw(GIT_ENOTFOUND, "Variable '%s' not found", name);
*out = var->value;
- return GIT_SUCCESS;
+
+ 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)
@@ -421,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;