Git fork
at reftables-rust 248 lines 4.6 kB view raw
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}