summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/var.c252
1 files changed, 202 insertions, 50 deletions
diff --git a/builtin/var.c b/builtin/var.c
index cc3a43cde2..e8472ac722 100644
--- a/builtin/var.c
+++ b/builtin/var.c
@@ -12,25 +12,109 @@
#include "config.h"
#include "editor.h"
#include "environment.h"
+#include "gpg-interface.h"
#include "ident.h"
#include "pager.h"
-#include "refs.h"
+#include "parse-options.h"
#include "path.h"
-#include "strbuf.h"
+#include "refs.h"
#include "run-command.h"
+#include "strbuf.h"
+#include "string-list.h"
-static const char var_usage[] = "git var (-l | <variable>)";
+static const char * const var_usage[] = {
+ N_("git var [-z] -l"),
+ N_("git var [-z] <variable>..."),
+ NULL
+};
+
+enum ident_part {
+ IDENT_NAME,
+ IDENT_MAIL,
+ IDENT_DATE,
+};
static char *committer(int ident_flag)
{
return xstrdup_or_null(git_committer_info(ident_flag));
}
+static char *ident_part(const char *ident, enum ident_part part)
+{
+ struct ident_split split;
+
+ if (!ident)
+ return NULL;
+ if (split_ident_line(&split, ident, strlen(ident)))
+ return NULL;
+
+ switch (part) {
+ case IDENT_NAME:
+ if (!split.name_begin || !split.name_end)
+ BUG("split_ident_line() gave NULL names???");
+ return xmemdupz(split.name_begin,
+ split.name_end - split.name_begin);
+ case IDENT_MAIL:
+ if (!split.mail_begin || !split.mail_end)
+ BUG("split_ident_line() gave NULL mail???");
+ return xmemdupz(split.mail_begin,
+ split.mail_end - split.mail_begin);
+ case IDENT_DATE:
+ if (!split.date_begin || !split.tz_end)
+ BUG("split_ident_line() gave NULL date/tz???");
+ return xmemdupz(split.date_begin,
+ split.tz_end - split.date_begin);
+ default:
+ BUG("unknown ident_part %d", part);
+ }
+}
+
+static char *committer_name(int ident_flag)
+{
+ return ident_part(git_committer_info(ident_flag), IDENT_NAME);
+}
+
+static char *committer_email(int ident_flag)
+{
+ return ident_part(git_committer_info(ident_flag), IDENT_MAIL);
+}
+
+static char *committer_date(int ident_flag)
+{
+ return ident_part(git_committer_info(ident_flag), IDENT_DATE);
+}
+
static char *author(int ident_flag)
{
return xstrdup_or_null(git_author_info(ident_flag));
}
+static char *author_name(int ident_flag)
+{
+ return ident_part(git_author_info(ident_flag), IDENT_NAME);
+}
+
+static char *author_email(int ident_flag)
+{
+ return ident_part(git_author_info(ident_flag), IDENT_MAIL);
+}
+
+static char *author_date(int ident_flag)
+{
+ return ident_part(git_author_info(ident_flag), IDENT_DATE);
+}
+
+static char *git_signing_key(int ident_flag UNUSED)
+{
+ char *signing_key = get_signing_key();
+
+ if (signing_key && !*signing_key) {
+ free(signing_key);
+ return NULL;
+ }
+ return signing_key;
+}
+
static char *editor(int ident_flag UNUSED)
{
return xstrdup_or_null(git_editor());
@@ -90,35 +174,27 @@ static char *git_config_val_system(int ident_flag UNUSED)
return NULL;
}
-static char *git_config_val_global(int ident_flag UNUSED)
+static void git_config_val_global(struct string_list *list)
{
- struct strbuf buf = STRBUF_INIT;
char *user, *xdg;
- size_t unused;
git_global_config_paths(&user, &xdg);
if (xdg && *xdg) {
normalize_path_copy(xdg, xdg);
- strbuf_addf(&buf, "%s\n", xdg);
+ string_list_append(list, xdg);
}
if (user && *user) {
normalize_path_copy(user, user);
- strbuf_addf(&buf, "%s\n", user);
+ string_list_append(list, user);
}
free(xdg);
free(user);
- strbuf_trim_trailing_newline(&buf);
- if (buf.len == 0) {
- strbuf_release(&buf);
- return NULL;
- }
- return strbuf_detach(&buf, &unused);
}
struct git_var {
const char *name;
char *(*read)(int);
- int multivalued;
+ void (*multiread)(struct string_list *);
};
static struct git_var git_vars[] = {
{
@@ -126,10 +202,34 @@ static struct git_var git_vars[] = {
.read = committer,
},
{
+ .name = "GIT_COMMITTER_NAME",
+ .read = committer_name,
+ },
+ {
+ .name = "GIT_COMMITTER_EMAIL",
+ .read = committer_email,
+ },
+ {
+ .name = "GIT_COMMITTER_DATE",
+ .read = committer_date,
+ },
+ {
.name = "GIT_AUTHOR_IDENT",
.read = author,
},
{
+ .name = "GIT_AUTHOR_NAME",
+ .read = author_name,
+ },
+ {
+ .name = "GIT_AUTHOR_EMAIL",
+ .read = author_email,
+ },
+ {
+ .name = "GIT_AUTHOR_DATE",
+ .read = author_date,
+ },
+ {
.name = "GIT_EDITOR",
.read = editor,
},
@@ -146,6 +246,10 @@ static struct git_var git_vars[] = {
.read = default_branch,
},
{
+ .name = "GIT_SIGNING_KEY",
+ .read = git_signing_key,
+ },
+ {
.name = "GIT_SHELL_PATH",
.read = shell_path,
},
@@ -163,8 +267,7 @@ static struct git_var git_vars[] = {
},
{
.name = "GIT_CONFIG_GLOBAL",
- .read = git_config_val_global,
- .multivalued = 1,
+ .multiread = git_config_val_global,
},
{
.name = "",
@@ -172,31 +275,37 @@ static struct git_var git_vars[] = {
},
};
-static void list_vars(void)
+static void list_vars(int nul_term)
{
struct git_var *ptr;
- char *val;
+ char delim = nul_term ? '\n' : '=';
+ char term = nul_term ? '\0' : '\n';
- for (ptr = git_vars; ptr->read; ptr++)
- if ((val = ptr->read(0))) {
- if (ptr->multivalued && *val) {
- struct string_list list = STRING_LIST_INIT_DUP;
+ for (ptr = git_vars; ptr->read || ptr->multiread; ptr++) {
+ if (ptr->read) {
+ char *val = ptr->read(0);
- string_list_split(&list, val, "\n", -1);
- for (size_t i = 0; i < list.nr; i++)
- printf("%s=%s\n", ptr->name, list.items[i].string);
- string_list_clear(&list, 0);
- } else {
- printf("%s=%s\n", ptr->name, val);
+ if (val) {
+ printf("%s%c%s%c", ptr->name, delim, val, term);
+ free(val);
}
- free(val);
+ } else {
+ struct string_list list = STRING_LIST_INIT_DUP;
+ size_t i;
+
+ ptr->multiread(&list);
+ for (i = 0; i < list.nr; i++)
+ printf("%s%c%s%c", ptr->name, delim,
+ list.items[i].string, term);
+ string_list_clear(&list, 0);
}
+ }
}
static const struct git_var *get_git_var(const char *var)
{
struct git_var *ptr;
- for (ptr = git_vars; ptr->read; ptr++) {
+ for (ptr = git_vars; ptr->read || ptr->multiread; ptr++) {
if (strcmp(var, ptr->name) == 0) {
return ptr;
}
@@ -207,42 +316,85 @@ static const struct git_var *get_git_var(const char *var)
static int show_config(const char *var, const char *value,
const struct config_context *ctx, void *cb)
{
+ int *nul_term = cb;
+ char delim = *nul_term ? '\n' : '=';
+ char term = *nul_term ? '\0' : '\n';
+
if (value)
- printf("%s=%s\n", var, value);
+ printf("%s%c%s%c", var, delim, value, term);
else
- printf("%s\n", var);
+ printf("%s%c", var, term);
return git_default_config(var, value, ctx, cb);
}
int cmd_var(int argc,
const char **argv,
- const char *prefix UNUSED,
+ const char *prefix,
struct repository *repo UNUSED)
{
- const struct git_var *git_var;
- char *val;
+ int list = 0;
+ int nul_term = 0;
+ int i;
+ char term;
+ struct option options[] = {
+ OPT_BOOL('l', NULL, &list,
+ N_("list all variables")),
+ OPT_BOOL('z', NULL, &nul_term,
+ N_("terminate entries with NUL")),
+ OPT_END(),
+ };
- show_usage_if_asked(argc, argv, var_usage);
- if (argc != 2)
- usage(var_usage);
+ argc = parse_options(argc, argv, prefix, options,
+ var_usage, PARSE_OPT_STOP_AT_NON_OPTION);
- if (strcmp(argv[1], "-l") == 0) {
- repo_config(the_repository, show_config, NULL);
- list_vars();
+ if (list) {
+ if (argc)
+ usage_with_options(var_usage, options);
+ repo_config(the_repository, show_config, &nul_term);
+ list_vars(nul_term);
return 0;
}
+
+ if (!argc)
+ usage_with_options(var_usage, options);
+
repo_config(the_repository, git_default_config, NULL);
- git_var = get_git_var(argv[1]);
- if (!git_var)
- usage(var_usage);
+ term = nul_term ? '\0' : '\n';
+
+ for (i = 0; i < argc; i++) {
+ const struct git_var *git_var = get_git_var(argv[i]);
- val = git_var->read(IDENT_STRICT);
- if (!val)
- return 1;
+ if (!git_var)
+ usage_with_options(var_usage, options);
- printf("%s\n", val);
- free(val);
+ if (git_var->read) {
+ char *val = git_var->read(IDENT_STRICT);
+
+ if (!val) {
+ if (argc == 1)
+ return 1;
+ putc(term, stdout);
+ continue;
+ }
+ printf("%s%c", val, term);
+ free(val);
+ } else {
+ struct string_list list = STRING_LIST_INIT_DUP;
+ size_t j;
+
+ git_var->multiread(&list);
+ if (argc == 1 && !list.nr) {
+ string_list_clear(&list, 0);
+ return 1;
+ }
+ for (j = 0; j < list.nr; j++)
+ printf("%s%c", list.items[j].string, term);
+ if (argc > 1)
+ putc(term, stdout);
+ string_list_clear(&list, 0);
+ }
+ }
return 0;
}