2
#include "cache.h"
3
#include "color.h"
4
#include "parse-options.h"
5
+#include "urlmatch.h"
6
7
static const char *const builtin_config_usage[] = {
8
N_("git config [options]"),
42
#define ACTION_SET_ALL (1<<12)
43
#define ACTION_GET_COLOR (1<<13)
44
#define ACTION_GET_COLORBOOL (1<<14)
45
+#define ACTION_GET_URLMATCH (1<<15)
46
47
#define TYPE_BOOL (1<<0)
48
#define TYPE_INT (1<<1)
59
OPT_BIT(0, "get", &actions, N_("get value: name [value-regex]"), ACTION_GET),
60
OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-regex]"), ACTION_GET_ALL),
61
OPT_BIT(0, "get-regexp", &actions, N_("get values for regexp: name-regex [value-regex]"), ACTION_GET_REGEXP),
62
+ OPT_BIT(0, "get-urlmatch", &actions, N_("get value specific for the URL: section[.var] URL"), ACTION_GET_URLMATCH),
63
OPT_BIT(0, "replace-all", &actions, N_("replace all matching variables: name value [value_regex]"), ACTION_REPLACE_ALL),
64
OPT_BIT(0, "add", &actions, N_("add a new variable: name value"), ACTION_ADD),
65
OPT_BIT(0, "unset", &actions, N_("remove a variable: name [value-regex]"), ACTION_UNSET),
351
return get_colorbool_found ? 0 : 1;
352
}
353
354
+struct urlmatch_current_candidate_value {
355
+ char value_is_null;
356
+ struct strbuf value;
357
+};
358
+
359
+static int urlmatch_collect_fn(const char *var, const char *value, void *cb)
360
+{
361
+ struct string_list *values = cb;
362
+ struct string_list_item *item = string_list_insert(values, var);
363
+ struct urlmatch_current_candidate_value *matched = item->util;
364
+
365
+ if (!matched) {
366
+ matched = xmalloc(sizeof(*matched));
367
+ strbuf_init(&matched->value, 0);
368
+ item->util = matched;
369
+ } else {
370
+ strbuf_reset(&matched->value);
371
+ }
372
+
373
+ if (value) {
374
+ strbuf_addstr(&matched->value, value);
375
+ matched->value_is_null = 0;
376
+ } else {
377
+ matched->value_is_null = 1;
378
+ }
379
+ return 0;
380
+}
381
+
382
+static char *dup_downcase(const char *string)
383
+{
384
+ char *result;
385
+ size_t len, i;
386
+
387
+ len = strlen(string);
388
+ result = xmalloc(len + 1);
389
+ for (i = 0; i < len; i++)
390
+ result[i] = tolower(string[i]);
391
+ result[i] = '\0';
392
+ return result;
393
+}
394
+
395
+static int get_urlmatch(const char *var, const char *url)
396
+{
397
+ char *section_tail;
398
+ struct string_list_item *item;
399
+ struct urlmatch_config config = { STRING_LIST_INIT_DUP };
400
+ struct string_list values = STRING_LIST_INIT_DUP;
401
+
402
+ config.collect_fn = urlmatch_collect_fn;
403
+ config.cascade_fn = NULL;
404
+ config.cb = &values;
405
+
406
+ if (!url_normalize(url, &config.url))
407
+ die(config.url.err);
408
+
409
+ config.section = dup_downcase(var);
410
+ section_tail = strchr(config.section, '.');
411
+ if (section_tail) {
412
+ *section_tail = '\0';
413
+ config.key = section_tail + 1;
414
+ show_keys = 0;
415
+ } else {
416
+ config.key = NULL;
417
+ show_keys = 1;
418
+ }
419
+
420
+ git_config_with_options(urlmatch_config_entry, &config,
421
+ given_config_file, respect_includes);
422
+
423
+ for_each_string_list_item(item, &values) {
424
+ struct urlmatch_current_candidate_value *matched = item->util;
425
+ struct strbuf key = STRBUF_INIT;
426
+ struct strbuf buf = STRBUF_INIT;
427
+
428
+ strbuf_addstr(&key, item->string);
429
+ format_config(&buf, key.buf,
430
+ matched->value_is_null ? NULL : matched->value.buf);
431
+ fwrite(buf.buf, 1, buf.len, stdout);
432
+ strbuf_release(&key);
433
+ strbuf_release(&buf);
434
+
435
+ strbuf_release(&matched->value);
436
+ }
437
+ string_list_clear(&config.vars, 1);
438
+ string_list_clear(&values, 1);
439
+ free(config.url.url);
440
+
441
+ free((void *)config.section);
442
+ return 0;
443
+}
444
+
445
int cmd_config(int argc, const char **argv, const char *prefix)
446
{
447
int nongit = !startup_info->have_repository;
593
check_argc(argc, 1, 2);
594
return get_value(argv[0], argv[1]);
595
}
596
+ else if (actions == ACTION_GET_URLMATCH) {
597
+ check_argc(argc, 2, 2);
598
+ return get_urlmatch(argv[0], argv[1]);
599
+ }
600
else if (actions == ACTION_UNSET) {
601
check_argc(argc, 1, 2);
602
if (argc == 2)