blob: f3d1660d023f7893373436617a9f729ce1d60f4d [file] [log] [blame]
Matthias Kestenholze12c0952006-08-02 23:51:59 +02001#include "builtin.h"
Johannes Schindelin1b1e59c2005-11-17 22:44:55 +01002#include "cache.h"
Junio C Hamano9ce03522007-11-27 22:41:05 -08003#include "color.h"
Felipe Contrerasd64ec162009-02-21 02:49:25 +02004#include "parse-options.h"
Johannes Schindelin1b1e59c2005-11-17 22:44:55 +01005
Felipe Contrerasd64ec162009-02-21 02:49:25 +02006static const char *const builtin_config_usage[] = {
7 "git config [options]",
8 NULL
9};
Johannes Schindelin4ddba792005-11-20 06:52:22 +010010
David Rientjes96f1e582006-08-15 10:23:48 -070011static char *key;
12static regex_t *key_regexp;
13static regex_t *regexp;
14static int show_keys;
15static int use_key_regexp;
16static int do_all;
17static int do_not_match;
18static int seen;
Frank Lichtenheld2275d502007-06-25 16:03:55 +020019static char delim = '=';
20static char key_delim = ' ';
21static char term = '\n';
Johannes Schindelin4ddba792005-11-20 06:52:22 +010022
Felipe Contrerasd64ec162009-02-21 02:49:25 +020023static int use_global_config, use_system_config;
24static const char *given_config_file;
Felipe Contreras16c1e932009-02-21 02:49:27 +020025static int actions, types;
Felipe Contrerasd64ec162009-02-21 02:49:25 +020026static const char *get_color_slot, *get_colorbool_slot;
27static int end_null;
28
29#define ACTION_GET (1<<0)
30#define ACTION_GET_ALL (1<<1)
31#define ACTION_GET_REGEXP (1<<2)
32#define ACTION_REPLACE_ALL (1<<3)
33#define ACTION_ADD (1<<4)
34#define ACTION_UNSET (1<<5)
35#define ACTION_UNSET_ALL (1<<6)
36#define ACTION_RENAME_SECTION (1<<7)
37#define ACTION_REMOVE_SECTION (1<<8)
38#define ACTION_LIST (1<<9)
39#define ACTION_EDIT (1<<10)
40#define ACTION_SET (1<<11)
41#define ACTION_SET_ALL (1<<12)
42#define ACTION_GET_COLOR (1<<13)
43#define ACTION_GET_COLORBOOL (1<<14)
44
Felipe Contreras16c1e932009-02-21 02:49:27 +020045#define TYPE_BOOL (1<<0)
46#define TYPE_INT (1<<1)
47#define TYPE_BOOL_OR_INT (1<<2)
Matthieu Moy13494842009-12-30 17:51:53 +010048#define TYPE_PATH (1<<3)
Felipe Contreras16c1e932009-02-21 02:49:27 +020049
Felipe Contrerasd64ec162009-02-21 02:49:25 +020050static struct option builtin_config_options[] = {
51 OPT_GROUP("Config file location"),
52 OPT_BOOLEAN(0, "global", &use_global_config, "use global config file"),
53 OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
54 OPT_STRING('f', "file", &given_config_file, "FILE", "use given config file"),
55 OPT_GROUP("Action"),
56 OPT_BIT(0, "get", &actions, "get value: name [value-regex]", ACTION_GET),
57 OPT_BIT(0, "get-all", &actions, "get all values: key [value-regex]", ACTION_GET_ALL),
58 OPT_BIT(0, "get-regexp", &actions, "get values for regexp: name-regex [value-regex]", ACTION_GET_REGEXP),
Carlos Ricabf71b4b2009-03-17 10:46:37 +010059 OPT_BIT(0, "replace-all", &actions, "replace all matching variables: name value [value_regex]", ACTION_REPLACE_ALL),
Felipe Contrerasd64ec162009-02-21 02:49:25 +020060 OPT_BIT(0, "add", &actions, "adds a new variable: name value", ACTION_ADD),
61 OPT_BIT(0, "unset", &actions, "removes a variable: name [value-regex]", ACTION_UNSET),
62 OPT_BIT(0, "unset-all", &actions, "removes all matches: name [value-regex]", ACTION_UNSET_ALL),
63 OPT_BIT(0, "rename-section", &actions, "rename section: old-name new-name", ACTION_RENAME_SECTION),
64 OPT_BIT(0, "remove-section", &actions, "remove a section: name", ACTION_REMOVE_SECTION),
65 OPT_BIT('l', "list", &actions, "list all", ACTION_LIST),
66 OPT_BIT('e', "edit", &actions, "opens an editor", ACTION_EDIT),
67 OPT_STRING(0, "get-color", &get_color_slot, "slot", "find the color configured: [default]"),
68 OPT_STRING(0, "get-colorbool", &get_colorbool_slot, "slot", "find the color setting: [stdout-is-tty]"),
69 OPT_GROUP("Type"),
Felipe Contreras16c1e932009-02-21 02:49:27 +020070 OPT_BIT(0, "bool", &types, "value is \"true\" or \"false\"", TYPE_BOOL),
71 OPT_BIT(0, "int", &types, "value is decimal number", TYPE_INT),
Jeff Kingba048222009-03-07 12:14:05 -050072 OPT_BIT(0, "bool-or-int", &types, "value is --bool or --int", TYPE_BOOL_OR_INT),
Matthieu Moy13494842009-12-30 17:51:53 +010073 OPT_BIT(0, "path", &types, "value is a path (file or directory name)", TYPE_PATH),
Felipe Contrerasd64ec162009-02-21 02:49:25 +020074 OPT_GROUP("Other"),
75 OPT_BOOLEAN('z', "null", &end_null, "terminate values with NUL byte"),
76 OPT_END(),
77};
78
79static void check_argc(int argc, int min, int max) {
80 if (argc >= min && argc <= max)
81 return;
82 error("wrong number of arguments");
83 usage_with_options(builtin_config_usage, builtin_config_options);
84}
85
Johannes Schindelinef90d6d2008-05-14 18:46:53 +010086static int show_all_config(const char *key_, const char *value_, void *cb)
Petr Baudisde791f12006-04-25 00:59:25 +020087{
88 if (value_)
Frank Lichtenheld2275d502007-06-25 16:03:55 +020089 printf("%s%c%s%c", key_, delim, value_, term);
Petr Baudisde791f12006-04-25 00:59:25 +020090 else
Frank Lichtenheld2275d502007-06-25 16:03:55 +020091 printf("%s%c", key_, term);
Petr Baudisde791f12006-04-25 00:59:25 +020092 return 0;
93}
94
Felipe Contreras4b951b72009-02-21 02:48:53 +020095static int show_config(const char *key_, const char *value_, void *cb)
Johannes Schindelin4ddba792005-11-20 06:52:22 +010096{
Junio C Hamanoe098c6f2006-05-02 21:06:56 -070097 char value[256];
98 const char *vptr = value;
Matthieu Moy13494842009-12-30 17:51:53 +010099 int must_free_vptr = 0;
Johannes Schindelin8f5ff312006-05-03 14:41:03 +0200100 int dup_error = 0;
Junio C Hamanoe098c6f2006-05-02 21:06:56 -0700101
Johannes Schindelin8f5ff312006-05-03 14:41:03 +0200102 if (!use_key_regexp && strcmp(key_, key))
103 return 0;
104 if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
105 return 0;
106 if (regexp != NULL &&
Björn Steinbrink9e4bbeb2007-12-05 16:11:24 +0100107 (do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0)))
Johannes Schindelin8f5ff312006-05-03 14:41:03 +0200108 return 0;
109
Frank Lichtenheldb69ba462007-06-25 16:03:54 +0200110 if (show_keys) {
111 if (value_)
Frank Lichtenheld2275d502007-06-25 16:03:55 +0200112 printf("%s%c", key_, key_delim);
Frank Lichtenheldb69ba462007-06-25 16:03:54 +0200113 else
114 printf("%s", key_);
115 }
Johannes Schindelin8f5ff312006-05-03 14:41:03 +0200116 if (seen && !do_all)
117 dup_error = 1;
Felipe Contreras16c1e932009-02-21 02:49:27 +0200118 if (types == TYPE_INT)
Junio C Hamanoacb70142006-06-24 05:19:30 -0700119 sprintf(value, "%d", git_config_int(key_, value_?value_:""));
Felipe Contreras16c1e932009-02-21 02:49:27 +0200120 else if (types == TYPE_BOOL)
Johannes Schindelin8f5ff312006-05-03 14:41:03 +0200121 vptr = git_config_bool(key_, value_) ? "true" : "false";
Felipe Contreras16c1e932009-02-21 02:49:27 +0200122 else if (types == TYPE_BOOL_OR_INT) {
Junio C Hamanoc35b0b52008-04-13 12:11:11 -0700123 int is_bool, v;
124 v = git_config_bool_or_int(key_, value_, &is_bool);
125 if (is_bool)
126 vptr = v ? "true" : "false";
127 else
128 sprintf(value, "%d", v);
Matthieu Moy13494842009-12-30 17:51:53 +0100129 } else if (types == TYPE_PATH) {
130 git_config_pathname(&vptr, key_, value_);
131 must_free_vptr = 1;
Junio C Hamanoc35b0b52008-04-13 12:11:11 -0700132 }
Johannes Schindelin8f5ff312006-05-03 14:41:03 +0200133 else
Junio C Hamanoacb70142006-06-24 05:19:30 -0700134 vptr = value_?value_:"";
Johannes Schindelin8f5ff312006-05-03 14:41:03 +0200135 seen++;
136 if (dup_error) {
137 error("More than one value for the key %s: %s",
138 key_, vptr);
Johannes Schindelin4ddba792005-11-20 06:52:22 +0100139 }
Johannes Schindelin8f5ff312006-05-03 14:41:03 +0200140 else
Frank Lichtenheld2275d502007-06-25 16:03:55 +0200141 printf("%s%c", vptr, term);
Matthieu Moy13494842009-12-30 17:51:53 +0100142 if (must_free_vptr)
143 /* If vptr must be freed, it's a pointer to a
144 * dynamically allocated buffer, it's safe to cast to
145 * const.
146 */
147 free((char *)vptr);
Johannes Schindelin8f5ff312006-05-03 14:41:03 +0200148
Johannes Schindelin4ddba792005-11-20 06:52:22 +0100149 return 0;
150}
151
Felipe Contreras4b951b72009-02-21 02:48:53 +0200152static int get_value(const char *key_, const char *regex_)
Johannes Schindelin4ddba792005-11-20 06:52:22 +0100153{
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200154 int ret = -1;
Linus Torvaldsd14f7762006-05-09 12:24:02 -0700155 char *tl;
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200156 char *global = NULL, *repo_config = NULL;
Johannes Schindelin32043c92007-02-14 12:48:14 +0100157 const char *system_wide = NULL, *local;
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200158
Daniel Barkalowdc871832008-06-30 03:37:47 -0400159 local = config_exclusive_filename;
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200160 if (!local) {
161 const char *home = getenv("HOME");
Alex Riesena4f34cb2008-10-27 11:22:09 +0100162 local = repo_config = git_pathdup("config");
Jeff Kingab88c362008-02-06 05:11:18 -0500163 if (git_config_global() && home)
Shawn Pearce9befac42006-09-02 00:16:31 -0400164 global = xstrdup(mkpath("%s/.gitconfig", home));
Jeff Kingab88c362008-02-06 05:11:18 -0500165 if (git_config_system())
166 system_wide = git_etc_gitconfig();
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200167 }
Johannes Schindelin4ddba792005-11-20 06:52:22 +0100168
Shawn Pearce9befac42006-09-02 00:16:31 -0400169 key = xstrdup(key_);
Linus Torvaldsd14f7762006-05-09 12:24:02 -0700170 for (tl=key+strlen(key)-1; tl >= key && *tl != '.'; --tl)
171 *tl = tolower(*tl);
172 for (tl=key; *tl && *tl != '.'; ++tl)
173 *tl = tolower(*tl);
Johannes Schindelin4ddba792005-11-20 06:52:22 +0100174
Johannes Schindelin2fa9a0f2006-05-02 14:22:48 +0200175 if (use_key_regexp) {
Jonas Fonseca2d7320d2006-09-01 00:32:39 +0200176 key_regexp = (regex_t*)xmalloc(sizeof(regex_t));
Johannes Schindelin2fa9a0f2006-05-02 14:22:48 +0200177 if (regcomp(key_regexp, key, REG_EXTENDED)) {
Junio C Hamanoe098c6f2006-05-02 21:06:56 -0700178 fprintf(stderr, "Invalid key pattern: %s\n", key_);
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200179 goto free_strings;
Johannes Schindelin2fa9a0f2006-05-02 14:22:48 +0200180 }
181 }
182
Johannes Schindelin4ddba792005-11-20 06:52:22 +0100183 if (regex_) {
Johannes Schindelinf98d8632005-11-20 13:24:18 +0100184 if (regex_[0] == '!') {
185 do_not_match = 1;
186 regex_++;
187 }
188
Jonas Fonseca2d7320d2006-09-01 00:32:39 +0200189 regexp = (regex_t*)xmalloc(sizeof(regex_t));
Amos Waterland0a152172006-01-04 19:31:02 -0500190 if (regcomp(regexp, regex_, REG_EXTENDED)) {
Johannes Schindelin4ddba792005-11-20 06:52:22 +0100191 fprintf(stderr, "Invalid pattern: %s\n", regex_);
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200192 goto free_strings;
Johannes Schindelin4ddba792005-11-20 06:52:22 +0100193 }
194 }
195
Johannes Schindelin32043c92007-02-14 12:48:14 +0100196 if (do_all && system_wide)
Johannes Schindelinef90d6d2008-05-14 18:46:53 +0100197 git_config_from_file(show_config, system_wide, NULL);
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200198 if (do_all && global)
Johannes Schindelinef90d6d2008-05-14 18:46:53 +0100199 git_config_from_file(show_config, global, NULL);
Alex Riesen8b1fa772010-03-26 23:53:57 +0100200 if (do_all)
201 git_config_from_file(show_config, local, NULL);
202 git_config_from_parameters(show_config, NULL);
203 if (!do_all && !seen)
204 git_config_from_file(show_config, local, NULL);
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200205 if (!do_all && !seen && global)
Johannes Schindelinef90d6d2008-05-14 18:46:53 +0100206 git_config_from_file(show_config, global, NULL);
Johannes Schindelin32043c92007-02-14 12:48:14 +0100207 if (!do_all && !seen && system_wide)
Johannes Schindelinef90d6d2008-05-14 18:46:53 +0100208 git_config_from_file(show_config, system_wide, NULL);
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200209
Johannes Schindelin4ddba792005-11-20 06:52:22 +0100210 free(key);
Amos Waterland0a152172006-01-04 19:31:02 -0500211 if (regexp) {
212 regfree(regexp);
213 free(regexp);
Johannes Schindelin4ddba792005-11-20 06:52:22 +0100214 }
215
216 if (do_all)
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200217 ret = !seen;
218 else
Petr Baudisdc2613d2006-07-03 22:47:55 +0200219 ret = (seen == 1) ? 0 : seen > 1 ? 2 : 1;
Johannes Schindelin4ddba792005-11-20 06:52:22 +0100220
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200221free_strings:
Junio C Hamano4cac42b2006-08-27 21:19:39 -0700222 free(repo_config);
223 free(global);
Johannes Schindelin5f1a63e2006-06-20 01:48:03 +0200224 return ret;
Johannes Schindelin4ddba792005-11-20 06:52:22 +0100225}
Johannes Schindelin1b1e59c2005-11-17 22:44:55 +0100226
Stephan Beyer186458b2008-07-24 01:09:35 +0200227static char *normalize_value(const char *key, const char *value)
Frank Lichtenhelddb1696b2007-06-25 16:00:24 +0200228{
229 char *normalized;
230
231 if (!value)
232 return NULL;
233
Matthieu Moy13494842009-12-30 17:51:53 +0100234 if (types == 0 || types == TYPE_PATH)
235 /*
236 * We don't do normalization for TYPE_PATH here: If
237 * the path is like ~/foobar/, we prefer to store
238 * "~/foobar/" in the config file, and to expand the ~
239 * when retrieving the value.
240 */
Frank Lichtenhelddb1696b2007-06-25 16:00:24 +0200241 normalized = xstrdup(value);
242 else {
243 normalized = xmalloc(64);
Felipe Contreras16c1e932009-02-21 02:49:27 +0200244 if (types == TYPE_INT) {
Frank Lichtenhelddb1696b2007-06-25 16:00:24 +0200245 int v = git_config_int(key, value);
246 sprintf(normalized, "%d", v);
247 }
Felipe Contreras16c1e932009-02-21 02:49:27 +0200248 else if (types == TYPE_BOOL)
Frank Lichtenhelddb1696b2007-06-25 16:00:24 +0200249 sprintf(normalized, "%s",
250 git_config_bool(key, value) ? "true" : "false");
Felipe Contreras16c1e932009-02-21 02:49:27 +0200251 else if (types == TYPE_BOOL_OR_INT) {
Junio C Hamanoc35b0b52008-04-13 12:11:11 -0700252 int is_bool, v;
253 v = git_config_bool_or_int(key, value, &is_bool);
254 if (!is_bool)
255 sprintf(normalized, "%d", v);
256 else
257 sprintf(normalized, "%s", v ? "true" : "false");
258 }
Frank Lichtenhelddb1696b2007-06-25 16:00:24 +0200259 }
260
261 return normalized;
262}
263
Junio C Hamano9ce03522007-11-27 22:41:05 -0800264static int get_color_found;
265static const char *get_color_slot;
Felipe Contrerasb4084572009-02-21 02:48:56 +0200266static const char *get_colorbool_slot;
Junio C Hamano9ce03522007-11-27 22:41:05 -0800267static char parsed_color[COLOR_MAXLEN];
268
Johannes Schindelinef90d6d2008-05-14 18:46:53 +0100269static int git_get_color_config(const char *var, const char *value, void *cb)
Junio C Hamano9ce03522007-11-27 22:41:05 -0800270{
271 if (!strcmp(var, get_color_slot)) {
Junio C Hamanof7699822008-02-11 10:48:12 -0800272 if (!value)
273 config_error_nonbool(var);
Junio C Hamano9ce03522007-11-27 22:41:05 -0800274 color_parse(value, var, parsed_color);
275 get_color_found = 1;
276 }
277 return 0;
278}
279
Felipe Contreras0e854a22009-02-21 02:48:57 +0200280static void get_color(const char *def_color)
Junio C Hamano9ce03522007-11-27 22:41:05 -0800281{
Junio C Hamano9ce03522007-11-27 22:41:05 -0800282 get_color_found = 0;
283 parsed_color[0] = '\0';
Johannes Schindelinef90d6d2008-05-14 18:46:53 +0100284 git_config(git_get_color_config, NULL);
Junio C Hamano9ce03522007-11-27 22:41:05 -0800285
286 if (!get_color_found && def_color)
287 color_parse(def_color, "command line", parsed_color);
288
289 fputs(parsed_color, stdout);
Junio C Hamano9ce03522007-11-27 22:41:05 -0800290}
291
Junio C Hamano0f6f5a42007-12-05 17:26:11 -0800292static int stdout_is_tty;
293static int get_colorbool_found;
Junio C Hamano69243c22007-12-05 22:12:07 -0800294static int get_diff_color_found;
Johannes Schindelinef90d6d2008-05-14 18:46:53 +0100295static int git_get_colorbool_config(const char *var, const char *value,
296 void *cb)
Junio C Hamano0f6f5a42007-12-05 17:26:11 -0800297{
Felipe Contrerasb4084572009-02-21 02:48:56 +0200298 if (!strcmp(var, get_colorbool_slot)) {
Junio C Hamano0f6f5a42007-12-05 17:26:11 -0800299 get_colorbool_found =
300 git_config_colorbool(var, value, stdout_is_tty);
Junio C Hamano69243c22007-12-05 22:12:07 -0800301 }
302 if (!strcmp(var, "diff.color")) {
303 get_diff_color_found =
304 git_config_colorbool(var, value, stdout_is_tty);
305 }
Matthias Kestenholz4d4f5ba2008-04-09 21:32:06 +0200306 if (!strcmp(var, "color.ui")) {
307 git_use_color_default = git_config_colorbool(var, value, stdout_is_tty);
308 return 0;
309 }
Junio C Hamano0f6f5a42007-12-05 17:26:11 -0800310 return 0;
311}
312
Felipe Contreras0e854a22009-02-21 02:48:57 +0200313static int get_colorbool(int print)
Junio C Hamano0f6f5a42007-12-05 17:26:11 -0800314{
Junio C Hamano69243c22007-12-05 22:12:07 -0800315 get_colorbool_found = -1;
316 get_diff_color_found = -1;
Johannes Schindelinef90d6d2008-05-14 18:46:53 +0100317 git_config(git_get_colorbool_config, NULL);
Junio C Hamano0f6f5a42007-12-05 17:26:11 -0800318
Junio C Hamano69243c22007-12-05 22:12:07 -0800319 if (get_colorbool_found < 0) {
Felipe Contrerasb4084572009-02-21 02:48:56 +0200320 if (!strcmp(get_colorbool_slot, "color.diff"))
Junio C Hamano69243c22007-12-05 22:12:07 -0800321 get_colorbool_found = get_diff_color_found;
322 if (get_colorbool_found < 0)
Matthias Kestenholz4d4f5ba2008-04-09 21:32:06 +0200323 get_colorbool_found = git_use_color_default;
Junio C Hamano69243c22007-12-05 22:12:07 -0800324 }
325
Felipe Contreras0e854a22009-02-21 02:48:57 +0200326 if (print) {
Junio C Hamano0f6f5a42007-12-05 17:26:11 -0800327 printf("%s\n", get_colorbool_found ? "true" : "false");
328 return 0;
Felipe Contreras0e854a22009-02-21 02:48:57 +0200329 } else
330 return get_colorbool_found ? 0 : 1;
Junio C Hamano0f6f5a42007-12-05 17:26:11 -0800331}
332
Felipe Contrerasb4084572009-02-21 02:48:56 +0200333int cmd_config(int argc, const char **argv, const char *unused_prefix)
Johannes Schindelin1b1e59c2005-11-17 22:44:55 +0100334{
SZEDER Gáboraf05d672008-03-25 22:06:26 +0100335 int nongit;
Felipe Contreras4b951b72009-02-21 02:48:53 +0200336 char *value;
Felipe Contrerasb4084572009-02-21 02:48:56 +0200337 const char *prefix = setup_git_directory_gently(&nongit);
Petr Baudis7162dff2006-02-12 04:14:48 +0100338
Daniel Barkalowdc871832008-06-30 03:37:47 -0400339 config_exclusive_filename = getenv(CONFIG_ENVIRONMENT);
340
Stephen Boyd37782922009-05-23 11:53:12 -0700341 argc = parse_options(argc, argv, prefix, builtin_config_options,
342 builtin_config_usage,
Felipe Contrerasd64ec162009-02-21 02:49:25 +0200343 PARSE_OPT_STOP_AT_NON_OPTION);
344
Felipe Contreras67052c92009-02-21 02:49:26 +0200345 if (use_global_config + use_system_config + !!given_config_file > 1) {
346 error("only one config file at a time.");
347 usage_with_options(builtin_config_usage, builtin_config_options);
348 }
349
Felipe Contrerasd64ec162009-02-21 02:49:25 +0200350 if (use_global_config) {
351 char *home = getenv("HOME");
352 if (home) {
353 char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
354 config_exclusive_filename = user_config;
355 } else {
356 die("$HOME not set");
Frank Lichtenhelda72c8742007-10-05 22:16:44 +0200357 }
Felipe Contrerasd64ec162009-02-21 02:49:25 +0200358 }
359 else if (use_system_config)
360 config_exclusive_filename = git_etc_gitconfig();
361 else if (given_config_file) {
362 if (!is_absolute_path(given_config_file) && prefix)
363 config_exclusive_filename = prefix_filename(prefix,
364 strlen(prefix),
Johan Herland65807ee2010-01-26 16:02:16 +0100365 given_config_file);
Felipe Contrerasd64ec162009-02-21 02:49:25 +0200366 else
367 config_exclusive_filename = given_config_file;
Petr Baudis7162dff2006-02-12 04:14:48 +0100368 }
369
Felipe Contrerasd64ec162009-02-21 02:49:25 +0200370 if (end_null) {
371 term = '\0';
372 delim = '\n';
373 key_delim = '\n';
Johannes Schindelin1b1e59c2005-11-17 22:44:55 +0100374 }
Felipe Contrerasd64ec162009-02-21 02:49:25 +0200375
Felipe Contreras16c1e932009-02-21 02:49:27 +0200376 if (HAS_MULTI_BITS(types)) {
377 error("only one type at a time.");
378 usage_with_options(builtin_config_usage, builtin_config_options);
379 }
380
Felipe Contrerasd64ec162009-02-21 02:49:25 +0200381 if (get_color_slot)
382 actions |= ACTION_GET_COLOR;
383 if (get_colorbool_slot)
384 actions |= ACTION_GET_COLORBOOL;
385
Felipe Contrerasc2387352009-02-21 02:49:29 +0200386 if ((get_color_slot || get_colorbool_slot) && types) {
387 error("--get-color and variable type are incoherent");
388 usage_with_options(builtin_config_usage, builtin_config_options);
389 }
390
Felipe Contrerasd64ec162009-02-21 02:49:25 +0200391 if (HAS_MULTI_BITS(actions)) {
392 error("only one action at a time.");
393 usage_with_options(builtin_config_usage, builtin_config_options);
394 }
395 if (actions == 0)
396 switch (argc) {
397 case 1: actions = ACTION_GET; break;
398 case 2: actions = ACTION_SET; break;
399 case 3: actions = ACTION_SET_ALL; break;
400 default:
401 usage_with_options(builtin_config_usage, builtin_config_options);
402 }
403
404 if (actions == ACTION_LIST) {
Felipe Contreras225a9ca2009-02-21 02:49:28 +0200405 check_argc(argc, 0, 0);
Felipe Contrerasd64ec162009-02-21 02:49:25 +0200406 if (git_config(show_all_config, NULL) < 0) {
407 if (config_exclusive_filename)
Thomas Rastd824cbb2009-06-27 17:58:46 +0200408 die_errno("unable to read config file '%s'",
409 config_exclusive_filename);
Felipe Contrerasd64ec162009-02-21 02:49:25 +0200410 else
411 die("error processing config file(s)");
412 }
413 }
414 else if (actions == ACTION_EDIT) {
Felipe Contreras225a9ca2009-02-21 02:49:28 +0200415 check_argc(argc, 0, 0);
Felipe Contrerasd212ca12009-04-30 01:49:47 +0300416 if (!config_exclusive_filename && nongit)
417 die("not in a git directory");
Felipe Contrerasd64ec162009-02-21 02:49:25 +0200418 git_config(git_default_config, NULL);
419 launch_editor(config_exclusive_filename ?
420 config_exclusive_filename : git_path("config"),
421 NULL, NULL);
422 }
423 else if (actions == ACTION_SET) {
424 check_argc(argc, 2, 2);
425 value = normalize_value(argv[0], argv[1]);
426 return git_config_set(argv[0], value);
427 }
428 else if (actions == ACTION_SET_ALL) {
429 check_argc(argc, 2, 3);
430 value = normalize_value(argv[0], argv[1]);
431 return git_config_set_multivar(argv[0], value, argv[2], 0);
432 }
433 else if (actions == ACTION_ADD) {
434 check_argc(argc, 2, 2);
435 value = normalize_value(argv[0], argv[1]);
436 return git_config_set_multivar(argv[0], value, "^$", 0);
437 }
438 else if (actions == ACTION_REPLACE_ALL) {
439 check_argc(argc, 2, 3);
440 value = normalize_value(argv[0], argv[1]);
441 return git_config_set_multivar(argv[0], value, argv[2], 1);
442 }
443 else if (actions == ACTION_GET) {
444 check_argc(argc, 1, 2);
445 return get_value(argv[0], argv[1]);
446 }
447 else if (actions == ACTION_GET_ALL) {
448 do_all = 1;
449 check_argc(argc, 1, 2);
450 return get_value(argv[0], argv[1]);
451 }
452 else if (actions == ACTION_GET_REGEXP) {
453 show_keys = 1;
454 use_key_regexp = 1;
455 do_all = 1;
456 check_argc(argc, 1, 2);
457 return get_value(argv[0], argv[1]);
458 }
459 else if (actions == ACTION_UNSET) {
460 check_argc(argc, 1, 2);
461 if (argc == 2)
462 return git_config_set_multivar(argv[0], NULL, argv[1], 0);
463 else
464 return git_config_set(argv[0], NULL);
465 }
466 else if (actions == ACTION_UNSET_ALL) {
467 check_argc(argc, 1, 2);
468 return git_config_set_multivar(argv[0], NULL, argv[1], 1);
469 }
470 else if (actions == ACTION_RENAME_SECTION) {
471 int ret;
472 check_argc(argc, 2, 2);
473 ret = git_config_rename_section(argv[0], argv[1]);
474 if (ret < 0)
475 return ret;
476 if (ret == 0)
477 die("No such section!");
478 }
479 else if (actions == ACTION_REMOVE_SECTION) {
480 int ret;
481 check_argc(argc, 1, 1);
482 ret = git_config_rename_section(argv[0], NULL);
483 if (ret < 0)
484 return ret;
485 if (ret == 0)
486 die("No such section!");
487 }
488 else if (actions == ACTION_GET_COLOR) {
489 get_color(argv[0]);
490 }
491 else if (actions == ACTION_GET_COLORBOOL) {
492 if (argc == 1)
493 stdout_is_tty = git_config_bool("command line", argv[0]);
494 else if (argc == 0)
495 stdout_is_tty = isatty(1);
496 return get_colorbool(argc != 0);
497 }
498
Johannes Schindelin1b1e59c2005-11-17 22:44:55 +0100499 return 0;
500}