void load_command_list(const char *prefix, struct cmdnames *main_cmds, struct cmdnames *other_cmds) { const char *env_path = getenv("PATH"); const char *exec_path = git_exec_path(); if (exec_path) { list_commands_in_dir(main_cmds, exec_path, prefix); qsort(main_cmds->names, main_cmds->cnt, sizeof(*main_cmds->names), cmdname_compare); uniq(main_cmds); } if (env_path) { char *paths, *path, *colon; path = paths = xstrdup(env_path); while (1) { if ((colon = strchr(path, PATH_SEP))) *colon = 0; if (!exec_path || strcmp(path, exec_path)) list_commands_in_dir(other_cmds, path, prefix); if (!colon) break; path = colon + 1; } free(paths); qsort(other_cmds->names, other_cmds->cnt, sizeof(*other_cmds->names), cmdname_compare); uniq(other_cmds); } exclude_cmds(other_cmds, main_cmds); }
void list_commands(const char *title, struct cmdnames *main_cmds, struct cmdnames *other_cmds) { int i, longest = 0; for (i = 0; i < main_cmds->cnt; i++) if (longest < main_cmds->names[i]->len) longest = main_cmds->names[i]->len; for (i = 0; i < other_cmds->cnt; i++) if (longest < other_cmds->names[i]->len) longest = other_cmds->names[i]->len; if (main_cmds->cnt) { const char *exec_path = git_exec_path(); printf("available %s in '%s'\n", title, exec_path); printf("----------------"); mput_char('-', strlen(title) + strlen(exec_path)); putchar('\n'); pretty_print_string_list(main_cmds, longest); putchar('\n'); } if (other_cmds->cnt) { printf("%s available from elsewhere on your $PATH\n", title); printf("---------------------------------------"); mput_char('-', strlen(title)); putchar('\n'); pretty_print_string_list(other_cmds, longest); putchar('\n'); } }
const char *git_etc_gitconfig(void) { static const char *system_wide; if (!system_wide) { system_wide = ETC_GITCONFIG; if (!is_absolute_path(system_wide)) { /* interpret path relative to exec-dir */ struct strbuf d = STRBUF_INIT; strbuf_addf(&d, "%s/%s", git_exec_path(), system_wide); system_wide = strbuf_detach(&d, NULL); } } return system_wide; }
void setup_path(void) { const char *old_path = getenv("PATH"); struct strbuf new_path = STRBUF_INIT; add_path(&new_path, git_exec_path()); if (old_path) strbuf_addstr(&new_path, old_path); else strbuf_addstr(&new_path, _PATH_DEFPATH); setenv("PATH", new_path.buf, 1); strbuf_release(&new_path); }
void setup_path(void) { const char *old_path = getenv("PATH"); struct strbuf new_path = STRBUF_INIT; add_path(&new_path, git_exec_path()); add_path(&new_path, argv0_path); if (old_path) strbuf_addstr(&new_path, old_path); else strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin"); setenv("PATH", new_path.buf, 1); strbuf_release(&new_path); }
void list_commands(unsigned int colopts, struct cmdnames *main_cmds, struct cmdnames *other_cmds) { if (main_cmds->cnt) { const char *exec_path = git_exec_path(); printf_ln(_("available git commands in '%s'"), exec_path); putchar('\n'); pretty_print_cmdnames(main_cmds, colopts); putchar('\n'); } if (other_cmds->cnt) { printf_ln(_("git commands available from elsewhere on your $PATH")); putchar('\n'); pretty_print_cmdnames(other_cmds, colopts); putchar('\n'); } }
static int handle_options(const char ***argv, int *argc, int *envchanged) { const char **orig_argv = *argv; while (*argc > 0) { const char *cmd = (*argv)[0]; if (cmd[0] != '-') break; /* * For legacy reasons, the "version" and "help" * commands can be written with "--" prepended * to make them look like flags. */ if (!strcmp(cmd, "--help") || !strcmp(cmd, "--version")) break; /* * Check remaining flags. */ if (skip_prefix(cmd, "--exec-path", &cmd)) { if (*cmd == '=') git_set_exec_path(cmd + 1); else { puts(git_exec_path()); exit(0); } } else if (!strcmp(cmd, "--html-path")) { puts(system_path(GIT_HTML_PATH)); exit(0); } else if (!strcmp(cmd, "--man-path")) { puts(system_path(GIT_MAN_PATH)); exit(0); } else if (!strcmp(cmd, "--info-path")) { puts(system_path(GIT_INFO_PATH)); exit(0); } else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) { use_pager = 1; } else if (!strcmp(cmd, "-P") || !strcmp(cmd, "--no-pager")) { use_pager = 0; if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--no-replace-objects")) { check_replace_refs = 0; setenv(NO_REPLACE_OBJECTS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--git-dir")) { if (*argc < 2) { fprintf(stderr, _("no directory given for --git-dir\n" )); usage(git_usage_string); } setenv(GIT_DIR_ENVIRONMENT, (*argv)[1], 1); if (envchanged) *envchanged = 1; (*argv)++; (*argc)--; } else if (skip_prefix(cmd, "--git-dir=", &cmd)) { setenv(GIT_DIR_ENVIRONMENT, cmd, 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--namespace")) { if (*argc < 2) { fprintf(stderr, _("no namespace given for --namespace\n" )); usage(git_usage_string); } setenv(GIT_NAMESPACE_ENVIRONMENT, (*argv)[1], 1); if (envchanged) *envchanged = 1; (*argv)++; (*argc)--; } else if (skip_prefix(cmd, "--namespace=", &cmd)) { setenv(GIT_NAMESPACE_ENVIRONMENT, cmd, 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--work-tree")) { if (*argc < 2) { fprintf(stderr, _("no directory given for --work-tree\n" )); usage(git_usage_string); } setenv(GIT_WORK_TREE_ENVIRONMENT, (*argv)[1], 1); if (envchanged) *envchanged = 1; (*argv)++; (*argc)--; } else if (skip_prefix(cmd, "--work-tree=", &cmd)) { setenv(GIT_WORK_TREE_ENVIRONMENT, cmd, 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--super-prefix")) { if (*argc < 2) { fprintf(stderr, _("no prefix given for --super-prefix\n" )); usage(git_usage_string); } setenv(GIT_SUPER_PREFIX_ENVIRONMENT, (*argv)[1], 1); if (envchanged) *envchanged = 1; (*argv)++; (*argc)--; } else if (skip_prefix(cmd, "--super-prefix=", &cmd)) { setenv(GIT_SUPER_PREFIX_ENVIRONMENT, cmd, 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--bare")) { char *cwd = xgetcwd(); is_bare_repository_cfg = 1; setenv(GIT_DIR_ENVIRONMENT, cwd, 0); free(cwd); setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "-c")) { if (*argc < 2) { fprintf(stderr, _("-c expects a configuration string\n" )); usage(git_usage_string); } git_config_push_parameter((*argv)[1]); (*argv)++; (*argc)--; } else if (!strcmp(cmd, "--literal-pathspecs")) { setenv(GIT_LITERAL_PATHSPECS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--no-literal-pathspecs")) { setenv(GIT_LITERAL_PATHSPECS_ENVIRONMENT, "0", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--glob-pathspecs")) { setenv(GIT_GLOB_PATHSPECS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--noglob-pathspecs")) { setenv(GIT_NOGLOB_PATHSPECS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--icase-pathspecs")) { setenv(GIT_ICASE_PATHSPECS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--no-optional-locks")) { setenv(GIT_OPTIONAL_LOCKS_ENVIRONMENT, "0", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--shallow-file")) { (*argv)++; (*argc)--; set_alternate_shallow_file((*argv)[0], 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "-C")) { if (*argc < 2) { fprintf(stderr, _("no directory given for -C\n" )); usage(git_usage_string); } if ((*argv)[1][0]) { if (chdir((*argv)[1])) die_errno("cannot change to '%s'", (*argv)[1]); if (envchanged) *envchanged = 1; } (*argv)++; (*argc)--; } else if (skip_prefix(cmd, "--list-cmds=", &cmd)) { if (!strcmp(cmd, "parseopt")) { struct string_list list = STRING_LIST_INIT_DUP; int i; list_builtins(&list, NO_PARSEOPT); for (i = 0; i < list.nr; i++) printf("%s ", list.items[i].string); string_list_clear(&list, 0); exit(0); } else { exit(list_cmds(cmd)); } } else { fprintf(stderr, _("unknown option: %s\n"), cmd); usage(git_usage_string); } (*argv)++; (*argc)--; } return (*argv) - orig_argv; }
int cmd_stash(int argc, const char **argv, const char *prefix) { int i = -1; pid_t pid = getpid(); const char *index_file; struct argv_array args = ARGV_ARRAY_INIT; struct option options[] = { OPT_END() }; if (!use_builtin_stash()) { const char *path = mkpath("%s/git-legacy-stash", git_exec_path()); if (sane_execvp(path, (char **)argv) < 0) die_errno(_("could not exec %s"), path); else BUG("sane_execvp() returned???"); } prefix = setup_git_directory(); trace_repo_setup(prefix); setup_work_tree(); git_config(git_diff_basic_config, NULL); argc = parse_options(argc, argv, prefix, options, git_stash_usage, PARSE_OPT_KEEP_UNKNOWN | PARSE_OPT_KEEP_DASHDASH); index_file = get_index_file(); strbuf_addf(&stash_index_path, "%s.stash.%" PRIuMAX, index_file, (uintmax_t)pid); if (!argc) return !!push_stash(0, NULL, prefix); else if (!strcmp(argv[0], "apply")) return !!apply_stash(argc, argv, prefix); else if (!strcmp(argv[0], "clear")) return !!clear_stash(argc, argv, prefix); else if (!strcmp(argv[0], "drop")) return !!drop_stash(argc, argv, prefix); else if (!strcmp(argv[0], "pop")) return !!pop_stash(argc, argv, prefix); else if (!strcmp(argv[0], "branch")) return !!branch_stash(argc, argv, prefix); else if (!strcmp(argv[0], "list")) return !!list_stash(argc, argv, prefix); else if (!strcmp(argv[0], "show")) return !!show_stash(argc, argv, prefix); else if (!strcmp(argv[0], "store")) return !!store_stash(argc, argv, prefix); else if (!strcmp(argv[0], "create")) return !!create_stash(argc, argv, prefix); else if (!strcmp(argv[0], "push")) return !!push_stash(argc, argv, prefix); else if (!strcmp(argv[0], "save")) return !!save_stash(argc, argv, prefix); else if (*argv[0] != '-') usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]), git_stash_usage, options); if (strcmp(argv[0], "-p")) { while (++i < argc && strcmp(argv[i], "--")) { /* * `akpqu` is a string which contains all short options, * except `-m` which is verified separately. */ if ((strlen(argv[i]) == 2) && *argv[i] == '-' && strchr("akpqu", argv[i][1])) continue; if (!strcmp(argv[i], "--all") || !strcmp(argv[i], "--keep-index") || !strcmp(argv[i], "--no-keep-index") || !strcmp(argv[i], "--patch") || !strcmp(argv[i], "--quiet") || !strcmp(argv[i], "--include-untracked")) continue; /* * `-m` and `--message=` are verified separately because * they need to be immediately followed by a string * (i.e.`-m"foobar"` or `--message="foobar"`). */ if (starts_with(argv[i], "-m") || starts_with(argv[i], "--message=")) continue; usage_with_options(git_stash_usage, options); } } argv_array_push(&args, "push"); argv_array_pushv(&args, argv); return !!push_stash(args.argc, args.argv, prefix); }
static int handle_options(const char ***argv, int *argc, int *envchanged) { int handled = 0; while (*argc > 0) { const char *cmd = (*argv)[0]; if (cmd[0] != '-') break; /* * For legacy reasons, the "version" and "help" * commands can be written with "--" prepended * to make them look like flags. */ if (!strcmp(cmd, "--help") || !strcmp(cmd, "--version")) break; /* * Check remaining flags. */ if (!prefixcmp(cmd, "--exec-path")) { cmd += 11; if (*cmd == '=') git_set_argv_exec_path(cmd + 1); else { puts(git_exec_path()); exit(0); } } else if (!strcmp(cmd, "--html-path")) { puts(system_path(GIT_HTML_PATH)); exit(0); } else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) { use_pager = 1; } else if (!strcmp(cmd, "--no-pager")) { use_pager = 0; if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--no-replace-objects")) { read_replace_refs = 0; setenv(NO_REPLACE_OBJECTS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--git-dir")) { if (*argc < 2) { fprintf(stderr, "No directory given for --git-dir.\n" ); usage(git_usage_string); } setenv(GIT_DIR_ENVIRONMENT, (*argv)[1], 1); if (envchanged) *envchanged = 1; (*argv)++; (*argc)--; handled++; } else if (!prefixcmp(cmd, "--git-dir=")) { setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--work-tree")) { if (*argc < 2) { fprintf(stderr, "No directory given for --work-tree.\n" ); usage(git_usage_string); } setenv(GIT_WORK_TREE_ENVIRONMENT, (*argv)[1], 1); if (envchanged) *envchanged = 1; (*argv)++; (*argc)--; } else if (!prefixcmp(cmd, "--work-tree=")) { setenv(GIT_WORK_TREE_ENVIRONMENT, cmd + 12, 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--bare")) { static char git_dir[PATH_MAX+1]; is_bare_repository_cfg = 1; setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "-c")) { if (*argc < 2) { fprintf(stderr, "-c expects a configuration string\n" ); usage(git_usage_string); } git_config_push_parameter((*argv)[1]); (*argv)++; (*argc)--; } else { fprintf(stderr, "Unknown option: %s\n", cmd); usage(git_usage_string); } (*argv)++; (*argc)--; handled++; } return handled; }
static int handle_options(const char ***argv, int *argc, int *envchanged) { const char **orig_argv = *argv; while (*argc > 0) { const char *cmd = (*argv)[0]; if (cmd[0] != '-') break; /* * For legacy reasons, the "version" and "help" * commands can be written with "--" prepended * to make them look like flags. */ if (!strcmp(cmd, "--help") || !strcmp(cmd, "--version")) break; /* * Check remaining flags. */ if (starts_with(cmd, "--exec-path")) { cmd += 11; if (*cmd == '=') git_set_argv_exec_path(cmd + 1); else { puts(git_exec_path()); exit(0); } } else if (!strcmp(cmd, "--html-path")) { puts(system_path(GIT_HTML_PATH)); exit(0); } else if (!strcmp(cmd, "--man-path")) { puts(system_path(GIT_MAN_PATH)); exit(0); } else if (!strcmp(cmd, "--info-path")) { puts(system_path(GIT_INFO_PATH)); exit(0); } else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) { use_pager = 1; } else if (!strcmp(cmd, "--no-pager")) { use_pager = 0; if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--no-replace-objects")) { check_replace_refs = 0; setenv(NO_REPLACE_OBJECTS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--git-dir")) { if (*argc < 2) { fprintf(stderr, "No directory given for --git-dir.\n" ); usage(git_usage_string); } setenv(GIT_DIR_ENVIRONMENT, (*argv)[1], 1); if (envchanged) *envchanged = 1; (*argv)++; (*argc)--; } else if (starts_with(cmd, "--git-dir=")) { setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--namespace")) { if (*argc < 2) { fprintf(stderr, "No namespace given for --namespace.\n" ); usage(git_usage_string); } setenv(GIT_NAMESPACE_ENVIRONMENT, (*argv)[1], 1); if (envchanged) *envchanged = 1; (*argv)++; (*argc)--; } else if (starts_with(cmd, "--namespace=")) { setenv(GIT_NAMESPACE_ENVIRONMENT, cmd + 12, 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--work-tree")) { if (*argc < 2) { fprintf(stderr, "No directory given for --work-tree.\n" ); usage(git_usage_string); } setenv(GIT_WORK_TREE_ENVIRONMENT, (*argv)[1], 1); if (envchanged) *envchanged = 1; (*argv)++; (*argc)--; } else if (starts_with(cmd, "--work-tree=")) { setenv(GIT_WORK_TREE_ENVIRONMENT, cmd + 12, 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--bare")) { static char git_dir[PATH_MAX+1]; is_bare_repository_cfg = 1; setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0); setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "-c")) { if (*argc < 2) { fprintf(stderr, "-c expects a configuration string\n" ); usage(git_usage_string); } git_config_push_parameter((*argv)[1]); (*argv)++; (*argc)--; } else if (!strcmp(cmd, "--literal-pathspecs")) { setenv(GIT_LITERAL_PATHSPECS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--no-literal-pathspecs")) { setenv(GIT_LITERAL_PATHSPECS_ENVIRONMENT, "0", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--glob-pathspecs")) { setenv(GIT_GLOB_PATHSPECS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--noglob-pathspecs")) { setenv(GIT_NOGLOB_PATHSPECS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--icase-pathspecs")) { setenv(GIT_ICASE_PATHSPECS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--shallow-file")) { (*argv)++; (*argc)--; set_alternate_shallow_file((*argv)[0], 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "-C")) { if (*argc < 2) { fprintf(stderr, "No directory given for -C.\n" ); usage(git_usage_string); } if (chdir((*argv)[1])) die_errno("Cannot change to '%s'", (*argv)[1]); if (envchanged) *envchanged = 1; (*argv)++; (*argc)--; } else { fprintf(stderr, "Unknown option: %s\n", cmd); usage(git_usage_string); } (*argv)++; (*argc)--; } return (*argv) - orig_argv; }
int cmd_difftool(int argc, const char **argv, const char *prefix) { int use_gui_tool = 0, dir_diff = 0, prompt = -1, symlinks = 0, tool_help = 0; static char *difftool_cmd = NULL, *extcmd = NULL; struct option builtin_difftool_options[] = { OPT_BOOL('g', "gui", &use_gui_tool, N_("use `diff.guitool` instead of `diff.tool`")), OPT_BOOL('d', "dir-diff", &dir_diff, N_("perform a full-directory diff")), { OPTION_SET_INT, 'y', "no-prompt", &prompt, NULL, N_("do not prompt before launching a diff tool"), PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 0 }, { OPTION_SET_INT, 0, "prompt", &prompt, NULL, NULL, PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_HIDDEN, NULL, 1 }, OPT_BOOL(0, "symlinks", &symlinks, N_("use symlinks in dir-diff mode")), OPT_STRING('t', "tool", &difftool_cmd, N_("<tool>"), N_("use the specified diff tool")), OPT_BOOL(0, "tool-help", &tool_help, N_("print a list of diff tools that may be used with " "`--tool`")), OPT_BOOL(0, "trust-exit-code", &trust_exit_code, N_("make 'git-difftool' exit when an invoked diff " "tool returns a non - zero exit code")), OPT_STRING('x', "extcmd", &extcmd, N_("<command>"), N_("specify a custom command for viewing diffs")), OPT_END() }; /* * NEEDSWORK: Once the builtin difftool has been tested enough * and git-legacy-difftool.perl is retired to contrib/, this preamble * can be removed. */ if (!use_builtin_difftool()) { const char *path = mkpath("%s/git-legacy-difftool", git_exec_path()); if (sane_execvp(path, (char **)argv) < 0) die_errno("could not exec %s", path); return 0; } prefix = setup_git_directory(); trace_repo_setup(prefix); setup_work_tree(); /* NEEDSWORK: once we no longer spawn anything, remove this */ setenv(GIT_DIR_ENVIRONMENT, absolute_path(get_git_dir()), 1); setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(get_git_work_tree()), 1); git_config(difftool_config, NULL); symlinks = has_symlinks; argc = parse_options(argc, argv, prefix, builtin_difftool_options, builtin_difftool_usage, PARSE_OPT_KEEP_UNKNOWN | PARSE_OPT_KEEP_DASHDASH); if (tool_help) return print_tool_help(); if (use_gui_tool && diff_gui_tool && *diff_gui_tool) setenv("GIT_DIFF_TOOL", diff_gui_tool, 1); else if (difftool_cmd) { if (*difftool_cmd) setenv("GIT_DIFF_TOOL", difftool_cmd, 1); else die(_("no <tool> given for --tool=<tool>")); } if (extcmd) { if (*extcmd) setenv("GIT_DIFFTOOL_EXTCMD", extcmd, 1); else die(_("no <cmd> given for --extcmd=<cmd>")); } setenv("GIT_DIFFTOOL_TRUST_EXIT_CODE", trust_exit_code ? "true" : "false", 1); /* * In directory diff mode, 'git-difftool--helper' is called once * to compare the a / b directories. In file diff mode, 'git diff' * will invoke a separate instance of 'git-difftool--helper' for * each file that changed. */ if (dir_diff) return run_dir_diff(extcmd, symlinks, prefix, argc, argv); return run_file_diff(prompt, prefix, argc, argv); }