Git fork
1/*
2 * GIT - The information manager from hell
3 *
4 * Copyright (C) Eric Biederman, 2005
5 */
6
7#define USE_THE_REPOSITORY_VARIABLE
8
9#include "builtin.h"
10
11#include "attr.h"
12#include "config.h"
13#include "editor.h"
14#include "environment.h"
15#include "ident.h"
16#include "pager.h"
17#include "refs.h"
18#include "path.h"
19#include "strbuf.h"
20#include "run-command.h"
21
22static const char var_usage[] = "git var (-l | <variable>)";
23
24static char *committer(int ident_flag)
25{
26 return xstrdup_or_null(git_committer_info(ident_flag));
27}
28
29static char *author(int ident_flag)
30{
31 return xstrdup_or_null(git_author_info(ident_flag));
32}
33
34static char *editor(int ident_flag UNUSED)
35{
36 return xstrdup_or_null(git_editor());
37}
38
39static char *sequence_editor(int ident_flag UNUSED)
40{
41 return xstrdup_or_null(git_sequence_editor());
42}
43
44static char *pager(int ident_flag UNUSED)
45{
46 const char *pgm = git_pager(the_repository, 1);
47
48 if (!pgm)
49 pgm = "cat";
50 return xstrdup(pgm);
51}
52
53static char *default_branch(int ident_flag UNUSED)
54{
55 return repo_default_branch_name(the_repository, 1);
56}
57
58static char *shell_path(int ident_flag UNUSED)
59{
60 return git_shell_path();
61}
62
63static char *git_attr_val_system(int ident_flag UNUSED)
64{
65 if (git_attr_system_is_enabled()) {
66 char *file = xstrdup(git_attr_system_file());
67 normalize_path_copy(file, file);
68 return file;
69 }
70 return NULL;
71}
72
73static char *git_attr_val_global(int ident_flag UNUSED)
74{
75 char *file = xstrdup_or_null(git_attr_global_file());
76 if (file) {
77 normalize_path_copy(file, file);
78 return file;
79 }
80 return NULL;
81}
82
83static char *git_config_val_system(int ident_flag UNUSED)
84{
85 if (git_config_system()) {
86 char *file = git_system_config();
87 normalize_path_copy(file, file);
88 return file;
89 }
90 return NULL;
91}
92
93static char *git_config_val_global(int ident_flag UNUSED)
94{
95 struct strbuf buf = STRBUF_INIT;
96 char *user, *xdg;
97 size_t unused;
98
99 git_global_config_paths(&user, &xdg);
100 if (xdg && *xdg) {
101 normalize_path_copy(xdg, xdg);
102 strbuf_addf(&buf, "%s\n", xdg);
103 }
104 if (user && *user) {
105 normalize_path_copy(user, user);
106 strbuf_addf(&buf, "%s\n", user);
107 }
108 free(xdg);
109 free(user);
110 strbuf_trim_trailing_newline(&buf);
111 if (buf.len == 0) {
112 strbuf_release(&buf);
113 return NULL;
114 }
115 return strbuf_detach(&buf, &unused);
116}
117
118struct git_var {
119 const char *name;
120 char *(*read)(int);
121 int multivalued;
122};
123static struct git_var git_vars[] = {
124 {
125 .name = "GIT_COMMITTER_IDENT",
126 .read = committer,
127 },
128 {
129 .name = "GIT_AUTHOR_IDENT",
130 .read = author,
131 },
132 {
133 .name = "GIT_EDITOR",
134 .read = editor,
135 },
136 {
137 .name = "GIT_SEQUENCE_EDITOR",
138 .read = sequence_editor,
139 },
140 {
141 .name = "GIT_PAGER",
142 .read = pager,
143 },
144 {
145 .name = "GIT_DEFAULT_BRANCH",
146 .read = default_branch,
147 },
148 {
149 .name = "GIT_SHELL_PATH",
150 .read = shell_path,
151 },
152 {
153 .name = "GIT_ATTR_SYSTEM",
154 .read = git_attr_val_system,
155 },
156 {
157 .name = "GIT_ATTR_GLOBAL",
158 .read = git_attr_val_global,
159 },
160 {
161 .name = "GIT_CONFIG_SYSTEM",
162 .read = git_config_val_system,
163 },
164 {
165 .name = "GIT_CONFIG_GLOBAL",
166 .read = git_config_val_global,
167 .multivalued = 1,
168 },
169 {
170 .name = "",
171 .read = NULL,
172 },
173};
174
175static void list_vars(void)
176{
177 struct git_var *ptr;
178 char *val;
179
180 for (ptr = git_vars; ptr->read; ptr++)
181 if ((val = ptr->read(0))) {
182 if (ptr->multivalued && *val) {
183 struct string_list list = STRING_LIST_INIT_DUP;
184
185 string_list_split(&list, val, "\n", -1);
186 for (size_t i = 0; i < list.nr; i++)
187 printf("%s=%s\n", ptr->name, list.items[i].string);
188 string_list_clear(&list, 0);
189 } else {
190 printf("%s=%s\n", ptr->name, val);
191 }
192 free(val);
193 }
194}
195
196static const struct git_var *get_git_var(const char *var)
197{
198 struct git_var *ptr;
199 for (ptr = git_vars; ptr->read; ptr++) {
200 if (strcmp(var, ptr->name) == 0) {
201 return ptr;
202 }
203 }
204 return NULL;
205}
206
207static int show_config(const char *var, const char *value,
208 const struct config_context *ctx, void *cb)
209{
210 if (value)
211 printf("%s=%s\n", var, value);
212 else
213 printf("%s\n", var);
214 return git_default_config(var, value, ctx, cb);
215}
216
217int cmd_var(int argc,
218 const char **argv,
219 const char *prefix UNUSED,
220 struct repository *repo UNUSED)
221{
222 const struct git_var *git_var;
223 char *val;
224
225 show_usage_if_asked(argc, argv, var_usage);
226 if (argc != 2)
227 usage(var_usage);
228
229 if (strcmp(argv[1], "-l") == 0) {
230 repo_config(the_repository, show_config, NULL);
231 list_vars();
232 return 0;
233 }
234 repo_config(the_repository, git_default_config, NULL);
235
236 git_var = get_git_var(argv[1]);
237 if (!git_var)
238 usage(var_usage);
239
240 val = git_var->read(IDENT_STRICT);
241 if (!val)
242 return 1;
243
244 printf("%s\n", val);
245 free(val);
246
247 return 0;
248}