summaryrefslogtreecommitdiff
path: root/builtin-config.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2007-02-03 22:14:40 -0800
committerJunio C Hamano <junkio@cox.net>2007-02-03 23:05:34 -0800
commitd77ee72662a821d66ae218056f0103eb24d8d4b4 (patch)
treee22abdbd11735a0669362f934ae723d233c87e2b /builtin-config.c
parenteb8381c88518b10d683a29deea1d43ed671f14ec (diff)
parent8d0fc48f27304ac1bc7abf802ec53fe66fedb15a (diff)
downloadgit-d77ee72662a821d66ae218056f0103eb24d8d4b4.tar.gz
Merge branch 'master' into np/dreflog
This is to resolve conflicts early in preparation for possible inclusion of "reflog on detached HEAD" series by Nico, as having it in 1.5.0 would really help us remove confusion between detached and attached states. Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'builtin-config.c')
-rw-r--r--builtin-config.c220
1 files changed, 220 insertions, 0 deletions
diff --git a/builtin-config.c b/builtin-config.c
new file mode 100644
index 0000000000..0f9051da17
--- /dev/null
+++ b/builtin-config.c
@@ -0,0 +1,220 @@
+#include "builtin.h"
+#include "cache.h"
+
+static const char git_config_set_usage[] =
+"git-config [ --global ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --list";
+
+static char *key;
+static regex_t *key_regexp;
+static regex_t *regexp;
+static int show_keys;
+static int use_key_regexp;
+static int do_all;
+static int do_not_match;
+static int seen;
+static enum { T_RAW, T_INT, T_BOOL } type = T_RAW;
+
+static int show_all_config(const char *key_, const char *value_)
+{
+ if (value_)
+ printf("%s=%s\n", key_, value_);
+ else
+ printf("%s\n", key_);
+ return 0;
+}
+
+static int show_config(const char* key_, const char* value_)
+{
+ char value[256];
+ const char *vptr = value;
+ int dup_error = 0;
+
+ if (!use_key_regexp && strcmp(key_, key))
+ return 0;
+ if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
+ return 0;
+ if (regexp != NULL &&
+ (do_not_match ^
+ regexec(regexp, (value_?value_:""), 0, NULL, 0)))
+ return 0;
+
+ if (show_keys)
+ printf("%s ", key_);
+ if (seen && !do_all)
+ dup_error = 1;
+ if (type == T_INT)
+ sprintf(value, "%d", git_config_int(key_, value_?value_:""));
+ else if (type == T_BOOL)
+ vptr = git_config_bool(key_, value_) ? "true" : "false";
+ else
+ vptr = value_?value_:"";
+ seen++;
+ if (dup_error) {
+ error("More than one value for the key %s: %s",
+ key_, vptr);
+ }
+ else
+ printf("%s\n", vptr);
+
+ return 0;
+}
+
+static int get_value(const char* key_, const char* regex_)
+{
+ int ret = -1;
+ char *tl;
+ char *global = NULL, *repo_config = NULL;
+ const char *local;
+
+ local = getenv(CONFIG_ENVIRONMENT);
+ if (!local) {
+ const char *home = getenv("HOME");
+ local = getenv(CONFIG_LOCAL_ENVIRONMENT);
+ if (!local)
+ local = repo_config = xstrdup(git_path("config"));
+ if (home)
+ global = xstrdup(mkpath("%s/.gitconfig", home));
+ }
+
+ key = xstrdup(key_);
+ for (tl=key+strlen(key)-1; tl >= key && *tl != '.'; --tl)
+ *tl = tolower(*tl);
+ for (tl=key; *tl && *tl != '.'; ++tl)
+ *tl = tolower(*tl);
+
+ if (use_key_regexp) {
+ key_regexp = (regex_t*)xmalloc(sizeof(regex_t));
+ if (regcomp(key_regexp, key, REG_EXTENDED)) {
+ fprintf(stderr, "Invalid key pattern: %s\n", key_);
+ goto free_strings;
+ }
+ }
+
+ if (regex_) {
+ if (regex_[0] == '!') {
+ do_not_match = 1;
+ regex_++;
+ }
+
+ regexp = (regex_t*)xmalloc(sizeof(regex_t));
+ if (regcomp(regexp, regex_, REG_EXTENDED)) {
+ fprintf(stderr, "Invalid pattern: %s\n", regex_);
+ goto free_strings;
+ }
+ }
+
+ if (do_all && global)
+ git_config_from_file(show_config, global);
+ git_config_from_file(show_config, local);
+ if (!do_all && !seen && global)
+ git_config_from_file(show_config, global);
+
+ free(key);
+ if (regexp) {
+ regfree(regexp);
+ free(regexp);
+ }
+
+ if (do_all)
+ ret = !seen;
+ else
+ ret = (seen == 1) ? 0 : seen > 1 ? 2 : 1;
+
+free_strings:
+ free(repo_config);
+ free(global);
+ return ret;
+}
+
+int cmd_config(int argc, const char **argv, const char *prefix)
+{
+ int nongit = 0;
+ setup_git_directory_gently(&nongit);
+
+ while (1 < argc) {
+ if (!strcmp(argv[1], "--int"))
+ type = T_INT;
+ else if (!strcmp(argv[1], "--bool"))
+ type = T_BOOL;
+ else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l"))
+ return git_config(show_all_config);
+ else if (!strcmp(argv[1], "--global")) {
+ char *home = getenv("HOME");
+ if (home) {
+ char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
+ setenv("GIT_CONFIG", user_config, 1);
+ free(user_config);
+ } else {
+ die("$HOME not set");
+ }
+ } else if (!strcmp(argv[1], "--rename-section")) {
+ int ret;
+ if (argc != 4)
+ usage(git_config_set_usage);
+ ret = git_config_rename_section(argv[2], argv[3]);
+ if (ret < 0)
+ return ret;
+ if (ret == 0) {
+ fprintf(stderr, "No such section!\n");
+ return 1;
+ }
+ return 0;
+ } else
+ break;
+ argc--;
+ argv++;
+ }
+
+ switch (argc) {
+ case 2:
+ return get_value(argv[1], NULL);
+ case 3:
+ if (!strcmp(argv[1], "--unset"))
+ return git_config_set(argv[2], NULL);
+ else if (!strcmp(argv[1], "--unset-all"))
+ return git_config_set_multivar(argv[2], NULL, NULL, 1);
+ else if (!strcmp(argv[1], "--get"))
+ return get_value(argv[2], NULL);
+ else if (!strcmp(argv[1], "--get-all")) {
+ do_all = 1;
+ return get_value(argv[2], NULL);
+ } else if (!strcmp(argv[1], "--get-regexp")) {
+ show_keys = 1;
+ use_key_regexp = 1;
+ do_all = 1;
+ return get_value(argv[2], NULL);
+ } else
+
+ return git_config_set(argv[1], argv[2]);
+ case 4:
+ if (!strcmp(argv[1], "--unset"))
+ return git_config_set_multivar(argv[2], NULL, argv[3], 0);
+ else if (!strcmp(argv[1], "--unset-all"))
+ return git_config_set_multivar(argv[2], NULL, argv[3], 1);
+ else if (!strcmp(argv[1], "--get"))
+ return get_value(argv[2], argv[3]);
+ else if (!strcmp(argv[1], "--get-all")) {
+ do_all = 1;
+ return get_value(argv[2], argv[3]);
+ } else if (!strcmp(argv[1], "--get-regexp")) {
+ show_keys = 1;
+ use_key_regexp = 1;
+ do_all = 1;
+ return get_value(argv[2], argv[3]);
+ } else if (!strcmp(argv[1], "--add"))
+ return git_config_set_multivar(argv[2], argv[3], "^$", 0);
+ else if (!strcmp(argv[1], "--replace-all"))
+
+ return git_config_set_multivar(argv[2], argv[3], NULL, 1);
+ else
+
+ return git_config_set_multivar(argv[1], argv[2], argv[3], 0);
+ case 5:
+ if (!strcmp(argv[1], "--replace-all"))
+ return git_config_set_multivar(argv[2], argv[3], argv[4], 1);
+ case 1:
+ default:
+ usage(git_config_set_usage);
+ }
+ return 0;
+}