8
8
#include "exec_cmd.h"
9
#include "common-cmds.h"
10
9
#include "parse-options.h"
11
10
#include "run-command.h"
14
#ifndef DEFAULT_HELP_FORMAT
15
#define DEFAULT_HELP_FORMAT "man"
14
18
static struct man_viewer_list {
15
19
struct man_viewer_list *next;
16
20
char name[FLEX_ARRAY];
36
static const char *html_path;
32
38
static int show_all = 0;
39
static int show_guides = 0;
40
static unsigned int colopts;
33
41
static enum help_format help_format = HELP_FORMAT_NONE;
34
42
static struct option builtin_help_options[] = {
35
OPT_BOOLEAN('a', "all", &show_all, "print all available commands"),
36
OPT_SET_INT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN),
37
OPT_SET_INT('w', "web", &help_format, "show manual in web browser",
43
OPT_BOOL('a', "all", &show_all, N_("print all available commands")),
44
OPT_BOOL('g', "guides", &show_guides, N_("print list of useful guides")),
45
OPT_SET_INT('m', "man", &help_format, N_("show man page"), HELP_FORMAT_MAN),
46
OPT_SET_INT('w', "web", &help_format, N_("show manual in web browser"),
39
OPT_SET_INT('i', "info", &help_format, "show info page",
48
OPT_SET_INT('i', "info", &help_format, N_("show info page"),
44
53
static const char * const builtin_help_usage[] = {
45
"git help [--all] [--man|--web|--info] [command]",
54
N_("git help [--all] [--guides] [--man|--web|--info] [command]"),
54
63
return HELP_FORMAT_INFO;
55
64
if (!strcmp(format, "web") || !strcmp(format, "html"))
56
65
return HELP_FORMAT_WEB;
57
die("unrecognized help format '%s'", format);
66
die(_("unrecognized help format '%s'"), format);
60
69
static const char *get_man_viewer_info(const char *name)
82
91
ec_process.err = -1;
83
92
ec_process.stdout_to_stderr = 1;
84
93
if (start_command(&ec_process))
85
return error("Failed to start emacsclient.");
94
return error(_("Failed to start emacsclient."));
87
96
strbuf_read(&buffer, ec_process.err, 20);
88
97
close(ec_process.err);
96
105
if (prefixcmp(buffer.buf, "emacsclient")) {
97
106
strbuf_release(&buffer);
98
return error("Failed to parse emacsclient version.");
107
return error(_("Failed to parse emacsclient version."));
101
110
strbuf_remove(&buffer, 0, strlen("emacsclient"));
121
130
path = "emacsclient";
122
131
strbuf_addf(&man_page, "(woman \"%s\")", page);
123
132
execlp(path, "emacsclient", "-e", man_page.buf, (char *)NULL);
124
warning("failed to exec '%s': %s", path, strerror(errno));
133
warning(_("failed to exec '%s': %s"), path, strerror(errno));
149
158
path = "kfmclient";
150
159
strbuf_addf(&man_page, "man:%s(1)", page);
151
160
execlp(path, filename, "newTab", man_page.buf, (char *)NULL);
152
warning("failed to exec '%s': %s", path, strerror(errno));
161
warning(_("failed to exec '%s': %s"), path, strerror(errno));
160
169
execlp(path, "man", page, (char *)NULL);
161
warning("failed to exec '%s': %s", path, strerror(errno));
170
warning(_("failed to exec '%s': %s"), path, strerror(errno));
164
173
static void exec_man_cmd(const char *cmd, const char *page)
166
175
struct strbuf shell_cmd = STRBUF_INIT;
167
176
strbuf_addf(&shell_cmd, "%s %s", cmd, page);
168
177
execl("/bin/sh", "sh", "-c", shell_cmd.buf, (char *)NULL);
169
warning("failed to exec '%s': %s", cmd, strerror(errno));
178
warning(_("failed to exec '%s': %s"), cmd, strerror(errno));
172
181
static void add_man_viewer(const char *name)
206
215
if (supported_man_viewer(name, len))
207
216
do_add_man_viewer_info(name, len, value);
209
warning("'%s': path for unsupported man viewer.\n"
210
"Please consider using 'man.<tool>.cmd' instead.",
218
warning(_("'%s': path for unsupported man viewer.\n"
219
"Please consider using 'man.<tool>.cmd' instead."),
218
227
const char *value)
220
229
if (supported_man_viewer(name, len))
221
warning("'%s': cmd for supported man viewer.\n"
222
"Please consider using 'man.<tool>.path' instead.",
230
warning(_("'%s': cmd for supported man viewer.\n"
231
"Please consider using 'man.<tool>.path' instead."),
225
234
do_add_man_viewer_info(name, len, value);
230
239
static int add_man_viewer_info(const char *var, const char *value)
232
const char *name = var + 4;
233
const char *subkey = strrchr(name, '.');
241
const char *name, *subkey;
244
if (parse_config_key(var, "man", &name, &namelen, &subkey) < 0 || !name)
238
if (!strcmp(subkey, ".path")) {
247
if (!strcmp(subkey, "path")) {
240
249
return config_error_nonbool(var);
241
return add_man_viewer_path(name, subkey - name, value);
250
return add_man_viewer_path(name, namelen, value);
243
if (!strcmp(subkey, ".cmd")) {
252
if (!strcmp(subkey, "cmd")) {
245
254
return config_error_nonbool(var);
246
return add_man_viewer_cmd(name, subkey - name, value);
255
return add_man_viewer_cmd(name, namelen, value);
252
261
static int git_help_config(const char *var, const char *value, void *cb)
263
if (!prefixcmp(var, "column."))
264
return git_column_config(var, value, "help", &colopts);
254
265
if (!strcmp(var, "help.format")) {
256
267
return config_error_nonbool(var);
257
268
help_format = parse_help_format(value);
271
if (!strcmp(var, "help.htmlpath")) {
273
return config_error_nonbool(var);
274
html_path = xstrdup(value);
260
277
if (!strcmp(var, "man.viewer")) {
262
279
return config_error_nonbool(var);
272
289
static struct cmdnames main_cmds, other_cmds;
274
void list_common_cmds_help(void)
278
for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
279
if (longest < strlen(common_cmds[i].name))
280
longest = strlen(common_cmds[i].name);
283
puts("The most commonly used git commands are:");
284
for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
285
printf(" %s ", common_cmds[i].name);
286
mput_char(' ', longest - strlen(common_cmds[i].name));
287
puts(common_cmds[i].help);
291
291
static int is_git_command(const char *s)
293
293
return is_in_cmdlist(&main_cmds, s) ||
349
349
exec_man_cmd(info, page);
351
warning("'%s': unknown man viewer.", name);
351
warning(_("'%s': unknown man viewer."), name);
354
354
static void show_man_page(const char *git_cmd)
366
366
exec_viewer(fallback, page);
367
367
exec_viewer("man", page);
368
die("no man viewer handled the request");
368
die(_("no man viewer handled the request"));
371
371
static void show_info_page(const char *git_cmd)
373
373
const char *page = cmd_to_page(git_cmd);
374
374
setenv("INFOPATH", system_path(GIT_INFO_PATH), 1);
375
375
execlp("info", "info", "gitman", page, (char *)NULL);
376
die("no info viewer handled the request");
376
die(_("no info viewer handled the request"));
379
379
static void get_html_page_path(struct strbuf *page_path, const char *page)
382
const char *html_path = system_path(GIT_HTML_PATH);
383
html_path = system_path(GIT_HTML_PATH);
384
385
/* Check that we have a git documentation directory. */
385
if (stat(mkpath("%s/git.html", html_path), &st)
386
|| !S_ISREG(st.st_mode))
387
die("'%s': not a documentation directory.", html_path);
386
if (!strstr(html_path, "://")) {
387
if (stat(mkpath("%s/git.html", html_path), &st)
388
|| !S_ISREG(st.st_mode))
389
die("'%s': not a documentation directory.", html_path);
389
392
strbuf_init(page_path, 0);
390
393
strbuf_addf(page_path, "%s/%s.html", html_path, page);
412
415
open_html(page_path.buf);
421
} common_guides[] = {
422
{ "attributes", N_("Defining attributes per path") },
423
{ "glossary", N_("A Git glossary") },
424
{ "ignore", N_("Specifies intentionally untracked files to ignore") },
425
{ "modules", N_("Defining submodule properties") },
426
{ "revisions", N_("Specifying revisions and ranges for Git") },
427
{ "tutorial", N_("A tutorial introduction to Git (for version 1.5.1 or newer)") },
428
{ "workflows", N_("An overview of recommended workflows with Git") },
431
static void list_common_guides_help(void)
435
for (i = 0; i < ARRAY_SIZE(common_guides); i++) {
436
if (longest < strlen(common_guides[i].name))
437
longest = strlen(common_guides[i].name);
440
puts(_("The common Git guides are:\n"));
441
for (i = 0; i < ARRAY_SIZE(common_guides); i++) {
442
printf(" %s ", common_guides[i].name);
443
mput_char(' ', longest - strlen(common_guides[i].name));
444
puts(_(common_guides[i].help));
415
449
int cmd_help(int argc, const char **argv, const char *prefix)
424
458
parsed_help_format = help_format;
427
printf("usage: %s\n\n", git_usage_string);
428
list_commands("git commands", &main_cmds, &other_cmds);
429
printf("%s\n", git_more_info_string);
461
git_config(git_help_config, NULL);
462
printf(_("usage: %s%s"), _(git_usage_string), "\n\n");
463
list_commands(colopts, &main_cmds, &other_cmds);
467
list_common_guides_help();
469
if (show_all || show_guides) {
470
printf("%s\n", _(git_more_info_string));
472
* We're done. Ignore any remaining args
434
printf("usage: %s\n\n", git_usage_string);
478
printf(_("usage: %s%s"), _(git_usage_string), "\n\n");
435
479
list_common_cmds_help();
436
printf("\n%s\n", git_more_info_string);
480
printf("\n%s\n", _(git_more_info_string));
443
487
if (parsed_help_format != HELP_FORMAT_NONE)
444
488
help_format = parsed_help_format;
489
if (help_format == HELP_FORMAT_NONE)
490
help_format = parse_help_format(DEFAULT_HELP_FORMAT);
446
492
alias = alias_lookup(argv[0]);
447
493
if (alias && !is_git_command(argv[0])) {
448
printf("`git %s' is aliased to `%s'\n", argv[0], alias);
494
printf_ln(_("`git %s' is aliased to `%s'"), argv[0], alias);